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