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	16
48 #define	OCE_TXMAP_ALIGN		1
49 #define	OCE_TX_MAX_FRAGS	(OCE_MAX_TX_HDL * OCE_MAX_TXDMA_COOKIES)
50 #define	OCE_TX_LO_WM		OCE_TX_MAX_FRAGS
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 }oce_dma_buf_t;
77 
78 #define	DBUF_PA(obj) (((oce_dma_buf_t *)(obj))->addr)
79 #define	DBUF_VA(obj) (((oce_dma_buf_t *)(obj))->base)
80 #define	DBUF_DHDL(obj) (((oce_dma_buf_t *)(obj))->dma_handle)
81 #define	DBUF_AHDL(obj) (((oce_dma_buf_t *)obj))->acc_handle)
82 #define	DBUF_SYNC(obj, flags)	ddi_dma_sync(DBUF_DHDL(obj), 0,\
83 			((oce_dma_buf_t *)obj)->len, (flags))
84 
85 typedef struct oce_ring_buffer_s {
86 	uint16_t    cidx; 	/* Get ptr */
87 	uint16_t    pidx;	/* Put Ptr */
88 	size_t	item_size;	/* Size */
89 	size_t  num_items;	/* count */
90 	uint32_t  num_used;
91 	oce_dma_buf_t   *dbuf;	/* dma buffer */
92 }oce_ring_buffer_t;
93 
94 typedef struct oce_rq_bdesc_s {
95 	OCE_LIST_NODE_T  link;
96 	oce_dma_buf_t	*rqb;
97 	struct oce_rq	*rq;
98 	oce_addr64_t 	frag_addr;
99 	mblk_t		*mp;
100 	frtn_t		fr_rtn;
101 }oce_rq_bdesc_t;
102 
103 typedef struct oce_wq_bdesc_s {
104 	OCE_LIST_NODE_T  link;
105 	oce_dma_buf_t	*wqb;
106 	oce_addr64_t 	frag_addr;
107 } oce_wq_bdesc_t;
108 
109 typedef struct oce_wq_mdesc_s {
110 	OCE_LIST_NODE_T  	link;
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 	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 	enum entry_type	type;
132 	uint16_t	wq_start_idx;
133 	uint16_t	wq_end_idx;
134 	uint16_t	wqe_cnt;
135 	uint16_t	pkt_len; /* 64K MAX */
136 	uint32_t	frag_cnt;
137 	uint32_t	nhdl;
138 }oce_wqe_desc_t;
139 
140 #pragma pack(1)
141 /* Always keep it 2 mod 4 */
142 typedef struct _oce_rq_buf_hdr_s {
143 	void *datap;
144 	uint8_t pad[18];
145 	/* ether_vlan_header_t vhdr; */
146 } oce_rq_buf_hdr_t;
147 #pragma pack()
148 
149 #define	OCE_RQE_BUF_HEADROOM	sizeof (oce_rq_buf_hdr_t)
150 #define	MAX_POOL_NAME		32
151 
152 #define	RING_NUM_PENDING(ring)	ring->num_used
153 
154 #define	RING_NUM_FREE(ring)	\
155 	(uint32_t)(ring->num_items - ring->num_used)
156 
157 #define	RING_FULL(ring) (ring->num_used == ring->num_items)
158 
159 #define	RING_EMPTY(ring) (ring->num_used == 0)
160 
161 #define	RING_GET(ring, n)			\
162 	ring->cidx = GET_Q_NEXT(ring->cidx, n, ring->num_items)
163 
164 #define	RING_PUT(ring, n)			\
165 	ring->pidx = GET_Q_NEXT(ring->pidx, n, ring->num_items)
166 
167 #define	RING_GET_CONSUMER_ITEM_VA(ring, type) 	\
168 	(void*)(((type *)DBUF_VA(ring->dbuf)) + ring->cidx)
169 
170 #define	RING_GET_CONSUMER_ITEM_PA(ring, type)		\
171 	(uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->cidx)
172 
173 #define	RING_GET_PRODUCER_ITEM_VA(ring, type)		\
174 	(void *)(((type *)DBUF_VA(ring->dbuf)) + ring->pidx)
175 
176 #define	RING_GET_PRODUCER_ITEM_PA(ring, type)		\
177 	(uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->pidx)
178 
179 /* Rq cache */
180 int oce_rqb_cache_create(struct oce_rq *rq, size_t buf_size);
181 void oce_rqb_cache_destroy(struct oce_rq *rq);
182 
183 /* Wq Cache */
184 int oce_wqe_desc_ctor(void *buf, void *arg, int kmflags);
185 void oce_wqe_desc_dtor(void *buf, void *arg);
186 
187 int oce_wqb_cache_create(struct oce_wq *wq, size_t buf_size);
188 void oce_wqb_cache_destroy(struct oce_wq *wq);
189 
190 void oce_wqm_cache_destroy(struct oce_wq *wq);
191 int oce_wqm_cache_create(struct oce_wq *wq);
192 
193 void oce_page_list(oce_dma_buf_t *dbuf,
194     struct phys_addr *pa_list, int list_size);
195 
196 
197 #ifdef __cplusplus
198 }
199 #endif
200 
201 #endif /* _OCE_BUF_H_ */
202