1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2009-2012 Emulex. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27
28 /*
29 * Header file defining the driver buffer management interface
30 */
31
32 #ifndef _OCE_BUF_H_
33 #define _OCE_BUF_H_
34
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38
39 #include <sys/ddidmareq.h>
40 #include <oce_io.h>
41 #include <oce_utils.h>
42
43 #define GET_Q_NEXT(_START, _STEP, _END) \
44 (((_START) + (_STEP)) < (_END) ? ((_START) + (_STEP)) \
45 : (((_START) + (_STEP)) - (_END)))
46
47 #define OCE_MAX_TX_HDL 8
48 #define OCE_MAX_TXDMA_COOKIES 18
49 #define OCE_TXMAP_ALIGN 1
50 #define OCE_TX_MAX_FRAGS (OCE_MAX_TX_HDL * OCE_MAX_TXDMA_COOKIES)
51
52 /* helper structure to access OS addresses */
53 typedef union oce_addr_s {
54 uint64_t addr64;
55 struct {
56 #ifdef _BIG_ENDIAN
57 uint32_t addr_hi;
58 uint32_t addr_lo;
59 #else
60 uint32_t addr_lo;
61 uint32_t addr_hi;
62 #endif
63 }dw;
64 }oce_addr64_t;
65
66 typedef struct oce_dma_buf_s {
67 caddr_t base;
68 uint64_t addr;
69 ddi_acc_handle_t acc_handle;
70 ddi_dma_handle_t dma_handle;
71 /* size of the memory */
72 size_t size;
73 size_t off;
74 size_t len;
75 uint32_t num_pages;
76 uint32_t ncookies;
77 ddi_dma_cookie_t cookie;
78 }oce_dma_buf_t;
79
80 #define DBUF_PA(obj) ((obj).addr)
81 #define DBUF_VA(obj) ((obj).base)
82 #define DBUF_DHDL(obj) ((obj).dma_handle)
83 #define DBUF_AHDL(obj) ((obj).acc_handle)
84 #define DBUF_SYNC(obj, off, len, flags) \
85 (void) ddi_dma_sync(DBUF_DHDL(obj), off, len, (flags))
86
87 typedef struct oce_ring_buffer_s {
88 uint16_t cidx; /* Get ptr */
89 uint16_t pidx; /* Put Ptr */
90 size_t item_size; /* Size */
91 size_t num_items; /* count */
92 uint32_t num_used;
93 oce_dma_buf_t dbuf; /* dma buffer */
94 }oce_ring_buffer_t;
95
96 typedef struct oce_rq_bdesc_s {
97 oce_dma_buf_t rqb;
98 struct oce_rq *rq;
99 oce_addr64_t frag_addr;
100 mblk_t *mp;
101 frtn_t fr_rtn;
102 uint32_t ref_cnt;
103 }oce_rq_bdesc_t;
104
105 typedef struct oce_wq_bdesc_s {
106 oce_dma_buf_t wqb;
107 oce_addr64_t frag_addr;
108 } oce_wq_bdesc_t;
109
110 typedef struct oce_wq_mdesc_s {
111 ddi_dma_handle_t dma_handle;
112 } oce_wq_mdesc_t;
113
114 enum entry_type {
115 HEADER_WQE = 0x1, /* arbitrary value */
116 MAPPED_WQE,
117 COPY_WQE,
118 DUMMY_WQE
119 };
120
121 typedef struct _oce_handle_s {
122 enum entry_type type;
123 void *hdl; /* opaque handle */
124 }oce_handle_t;
125
126 typedef struct _oce_wqe_desc_s {
127 list_node_t link;
128 oce_handle_t hdesc[OCE_MAX_TX_HDL];
129 struct oce_nic_frag_wqe frag[OCE_TX_MAX_FRAGS];
130 struct oce_wq *wq;
131 mblk_t *mp;
132 uint16_t wqe_cnt;
133 uint16_t frag_idx;
134 uint16_t frag_cnt;
135 uint16_t nhdl;
136 }oce_wqe_desc_t;
137
138 #pragma pack(1)
139 /* Always keep it 2 mod 4 */
140 typedef struct _oce_rq_buf_hdr_s {
141 void *datap;
142 uint8_t pad[18];
143 /* ether_vlan_header_t vhdr; */
144 } oce_rq_buf_hdr_t;
145 #pragma pack()
146
147 #define OCE_RQE_BUF_HEADROOM 10 /* always 2 mod 4 */
148 #define OCE_IP_ALIGN 2 /* Align the IP header */
149 #define MAX_POOL_NAME 32
150
151 #define RING_NUM_PENDING(ring) ring->num_used
152
153 #define RING_NUM_FREE(ring) \
154 (uint32_t)(ring->num_items - ring->num_used)
155
156 #define RING_FULL(ring) (ring->num_used == ring->num_items)
157
158 #define RING_EMPTY(ring) (ring->num_used == 0)
159
160 #define RING_GET(ring, n) \
161 ring->cidx = GET_Q_NEXT(ring->cidx, n, ring->num_items)
162
163 #define RING_PUT(ring, n) \
164 ring->pidx = GET_Q_NEXT(ring->pidx, n, ring->num_items)
165
166 #define RING_GET_CONSUMER_ITEM_VA(ring, type) \
167 (void*)(((type *)DBUF_VA(ring->dbuf)) + ring->cidx)
168
169 #define RING_GET_CONSUMER_ITEM_PA(ring, type) \
170 (uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->cidx)
171
172 #define RING_GET_PRODUCER_ITEM_VA(ring, type) \
173 (void *)(((type *)DBUF_VA(ring->dbuf)) + ring->pidx)
174
175 #define RING_GET_PRODUCER_ITEM_PA(ring, type) \
176 (uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->pidx)
177
178 /* Rq cache */
179 int oce_rqb_cache_create(struct oce_rq *rq, size_t buf_size);
180 void oce_rqb_cache_destroy(struct oce_rq *rq);
181
182 /* Wq Cache */
183 int oce_wqe_desc_ctor(void *buf, void *arg, int kmflags);
184 void oce_wqe_desc_dtor(void *buf, void *arg);
185
186 int oce_wqb_cache_create(struct oce_wq *wq, size_t buf_size);
187 void oce_wqb_cache_destroy(struct oce_wq *wq);
188
189 void oce_wqm_cache_destroy(struct oce_wq *wq);
190 int oce_wqm_cache_create(struct oce_wq *wq);
191
192 void oce_page_list(oce_dma_buf_t *dbuf,
193 struct phys_addr *pa_list, int list_size);
194
195
196 #ifdef __cplusplus
197 }
198 #endif
199
200 #endif /* _OCE_BUF_H_ */