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 /* Copyright © 2003-2011 Emulex. All rights reserved.  */
23 
24 /*
25  * Header file defining the driver buffer management interface
26  */
27 
28 #ifndef _OCE_BUF_H_
29 #define	_OCE_BUF_H_
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 #include <sys/ddidmareq.h>
36 #include <oce_io.h>
37 #include <oce_utils.h>
38 
39 #define	GET_Q_NEXT(_START, _STEP, _END) \
40 	(((_START) + (_STEP)) < (_END) ? ((_START) + (_STEP)) \
41 	: (((_START) + (_STEP)) - (_END)))
42 
43 #define	OCE_MAX_TX_HDL		8
44 #define	OCE_MAX_TXDMA_COOKIES	18
45 #define	OCE_TXMAP_ALIGN		1
46 #define	OCE_TX_MAX_FRAGS	(OCE_MAX_TX_HDL * OCE_MAX_TXDMA_COOKIES)
47 
48 /* helper structure to access OS addresses */
49 typedef union  oce_addr_s {
50 	uint64_t addr64;
51 	struct {
52 #ifdef _BIG_ENDIAN
53 		uint32_t addr_hi;
54 		uint32_t addr_lo;
55 #else
56 		uint32_t addr_lo;
57 		uint32_t addr_hi;
58 #endif
59 	}dw;
60 }oce_addr64_t;
61 
62 typedef struct oce_dma_buf_s {
63 	caddr_t		base;
64 	uint64_t	addr;
65 	ddi_acc_handle_t acc_handle;
66 	ddi_dma_handle_t dma_handle;
67 	/* size of the memory */
68 	size_t		size;
69 	size_t		off;
70 	size_t		len;
71 	uint32_t	num_pages;
72 }oce_dma_buf_t;
73 
74 #define	DBUF_PA(obj) (((oce_dma_buf_t *)(obj))->addr)
75 #define	DBUF_VA(obj) (((oce_dma_buf_t *)(obj))->base)
76 #define	DBUF_DHDL(obj) (((oce_dma_buf_t *)(obj))->dma_handle)
77 #define	DBUF_AHDL(obj) (((oce_dma_buf_t *)obj))->acc_handle)
78 #define	DBUF_SYNC(obj, flags)	(void) ddi_dma_sync(DBUF_DHDL(obj), 0,\
79 			0, (flags))
80 
81 typedef struct oce_ring_buffer_s {
82 	uint16_t    cidx; 	/* Get ptr */
83 	uint16_t    pidx;	/* Put Ptr */
84 	size_t	item_size;	/* Size */
85 	size_t  num_items;	/* count */
86 	uint32_t  num_used;
87 	oce_dma_buf_t   *dbuf;	/* dma buffer */
88 }oce_ring_buffer_t;
89 
90 typedef struct oce_rq_bdesc_s {
91 	oce_dma_buf_t	*rqb;
92 	struct oce_rq	*rq;
93 	oce_addr64_t 	frag_addr;
94 	mblk_t		*mp;
95 	frtn_t		fr_rtn;
96     uint32_t    ref_cnt;
97 }oce_rq_bdesc_t;
98 
99 typedef struct oce_wq_bdesc_s {
100 	OCE_LIST_NODE_T  link;
101 	oce_dma_buf_t	*wqb;
102 	oce_addr64_t 	frag_addr;
103 } oce_wq_bdesc_t;
104 
105 typedef struct oce_wq_mdesc_s {
106 	OCE_LIST_NODE_T  	link;
107 	ddi_dma_handle_t	dma_handle;
108 } oce_wq_mdesc_t;
109 
110 enum entry_type {
111 	HEADER_WQE = 0x1, /* arbitrary value */
112 	MAPPED_WQE,
113 	COPY_WQE,
114 	DUMMY_WQE
115 };
116 
117 typedef struct _oce_handle_s {
118     enum entry_type	type;
119 	void		*hdl; /* opaque handle */
120 }oce_handle_t;
121 
122 typedef struct _oce_wqe_desc_s {
123 	OCE_LIST_NODE_T  link;
124 	oce_handle_t	hdesc[OCE_MAX_TX_HDL];
125 	struct oce_nic_frag_wqe frag[OCE_TX_MAX_FRAGS];
126 	struct oce_wq  *wq;
127 	mblk_t		*mp;
128 	uint16_t	wqe_cnt;
129 	uint16_t	frag_idx;
130 	uint16_t	frag_cnt;
131 	uint16_t	nhdl;
132 }oce_wqe_desc_t;
133 
134 #pragma pack(1)
135 /* Always keep it 2 mod 4 */
136 typedef struct _oce_rq_buf_hdr_s {
137 	void *datap;
138 	uint8_t pad[18];
139 	/* ether_vlan_header_t vhdr; */
140 } oce_rq_buf_hdr_t;
141 #pragma pack()
142 
143 #define	OCE_RQE_BUF_HEADROOM	18
144 #define	MAX_POOL_NAME		32
145 
146 #define	RING_NUM_PENDING(ring)	ring->num_used
147 
148 #define	RING_NUM_FREE(ring)	\
149 	(uint32_t)(ring->num_items - ring->num_used)
150 
151 #define	RING_FULL(ring) (ring->num_used == ring->num_items)
152 
153 #define	RING_EMPTY(ring) (ring->num_used == 0)
154 
155 #define	RING_GET(ring, n)			\
156 	ring->cidx = GET_Q_NEXT(ring->cidx, n, ring->num_items)
157 
158 #define	RING_PUT(ring, n)			\
159 	ring->pidx = GET_Q_NEXT(ring->pidx, n, ring->num_items)
160 
161 #define	RING_GET_CONSUMER_ITEM_VA(ring, type) 	\
162 	(void*)(((type *)DBUF_VA(ring->dbuf)) + ring->cidx)
163 
164 #define	RING_GET_CONSUMER_ITEM_PA(ring, type)		\
165 	(uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->cidx)
166 
167 #define	RING_GET_PRODUCER_ITEM_VA(ring, type)		\
168 	(void *)(((type *)DBUF_VA(ring->dbuf)) + ring->pidx)
169 
170 #define	RING_GET_PRODUCER_ITEM_PA(ring, type)		\
171 	(uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->pidx)
172 
173 /* Rq cache */
174 int oce_rqb_cache_create(struct oce_rq *rq, size_t buf_size);
175 void oce_rqb_cache_destroy(struct oce_rq *rq);
176 
177 /* Wq Cache */
178 int oce_wqe_desc_ctor(void *buf, void *arg, int kmflags);
179 void oce_wqe_desc_dtor(void *buf, void *arg);
180 
181 int oce_wqb_cache_create(struct oce_wq *wq, size_t buf_size);
182 void oce_wqb_cache_destroy(struct oce_wq *wq);
183 
184 void oce_wqm_cache_destroy(struct oce_wq *wq);
185 int oce_wqm_cache_create(struct oce_wq *wq);
186 
187 void oce_page_list(oce_dma_buf_t *dbuf,
188     struct phys_addr *pa_list, int list_size);
189 
190 
191 #ifdef __cplusplus
192 }
193 #endif
194 
195 #endif /* _OCE_BUF_H_ */
196