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 2009 Emulex.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * Header file defining the HW IO elements
29  */
30 
31 #ifndef _OCE_IO_H_
32 #define	_OCE_IO_H_
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 #include <sys/types.h>
39 #include <sys/dditypes.h>
40 #include <sys/mutex.h>
41 #include <sys/stream.h>
42 #include <sys/debug.h>
43 #include <sys/byteorder.h>
44 #include <oce_hw.h>
45 #include <oce_buf.h>
46 
47 #define	DEFAULT_MQ_MBOX_TIMEOUT	(5 * 1000 * 1000) /* 5 sec (in usec) */
48 #define	MBX_TIMEOUT_SEC		5
49 #define	STAT_TIMEOUT		2000000 /* update stats every 2 sec */
50 
51 struct oce_dev;
52 
53 enum eq_len {
54 	EQ_LEN_256 = 256,
55 	EQ_LEN_512 = 512,
56 	EQ_LEN_1024 = 1024,
57 	EQ_LEN_2048 = 2048,
58 	EQ_LEN_4096 = 4096
59 };
60 
61 enum eqe_size {
62 	EQE_SIZE_4 = 4,
63 	EQE_SIZE_16 = 16
64 };
65 
66 struct eq_config {
67 	/* number of entries in the eq */
68 	enum eq_len q_len;
69 	/* size of each entry */
70 	enum eqe_size   item_size;
71 	/* vector associated with this eq */
72 	uint32_t    q_vector_num;
73 	/* minimum possible eq delay i usec */
74 	uint8_t		min_eqd;
75 	/* max eq delay in usec */
76 	uint8_t		max_eqd;
77 	/* currently configured eq delay in usec */
78 	uint8_t		cur_eqd;
79 	/* pad */
80 	uint8_t pad;
81 };
82 
83 struct oce_eq {
84 	/* configuration of this eq */
85 	struct eq_config eq_cfg;
86 	/* id assigned by the hw to this eq */
87 	uint32_t eq_id;
88 	/* handle to the creating parent dev */
89 	void *parent;
90 	/* callback context */
91 	void *cb_context;
92 	/* reference count of this structure */
93 	uint32_t ref_count;
94 	/* ring buffer for this eq */
95 	oce_ring_buffer_t *ring;
96 	/* Lock for this queue */
97 	kmutex_t lock;
98 };
99 
100 enum cq_len {
101 	CQ_LEN_256 = 256,
102 	CQ_LEN_512 = 512,
103 	CQ_LEN_1024 = 1024
104 };
105 
106 struct cq_config {
107 	/* length of queue */
108 	enum cq_len q_len;
109 	/* size of each item */
110 	uint32_t item_size;
111 	/* solicited eventable? */
112 	uint8_t sol_eventable;
113 	/* no delay? */
114 	uint8_t nodelay;
115 	/* dma coalescing */
116 	uint16_t dma_coalescing;
117 };
118 
119 typedef uint16_t (*cq_handler_t)(void *arg1);
120 
121 struct oce_cq {
122 	/* configuration of this cq */
123 	struct cq_config cq_cfg;
124 	/* reference count of this structure */
125 	uint32_t ref_count;
126 	/* id given by the hardware */
127 	uint32_t    cq_id;
128 	/* parent device to which this cq belongs */
129 	void *parent;
130 	/* event queue associated with this cq */
131 	struct oce_eq *eq;
132 	cq_handler_t cq_handler;
133 	/* placeholder for callback context */
134 	void *cb_arg;
135 	/* ring buffer for this cq */
136 	oce_ring_buffer_t *ring;
137 	/* lock */
138 	kmutex_t lock;
139 };
140 
141 struct mq_config {
142 	uint32_t eqd;
143 	uint8_t q_len;
144 	uint8_t pad[3];
145 
146 };
147 
148 struct oce_mq {
149 	/* configuration of this mq */
150 	struct mq_config cfg;
151 	/* handle to the parent device */
152 	void *parent;
153 	/* send queue */
154 	oce_ring_buffer_t *ring;
155 	/* idnetifier for the mq */
156 	uint32_t mq_id;
157 	struct oce_cq *cq;
158 	struct oce_cq *async_cq;
159 	/* free entries in Queue */
160 	uint32_t mq_free;
161 };
162 
163 enum qtype {
164 	QTYPE_EQ,
165 	QTYPE_MQ,
166 	QTYPE_WQ,
167 	QTYPE_RQ,
168 	QTYPE_CQ,
169 	QTYPE_RSS
170 };
171 
172 /*
173  * utility structure that handles context of mbx
174  */
175 struct oce_mbx_ctx {
176 	/* pointer to mbx */
177 	struct oce_mbx *mbx;
178 	/* call back functioin [optional] */
179 	void (*cb)(void *ctx);
180 	/* call back context [optional] */
181 	void *cb_ctx;
182 };
183 
184 struct wq_config {
185 	/* qtype */
186 	uint8_t wq_type;
187 	uint8_t pad[3];
188 	uint32_t q_len; /* number of wqes */
189 	uint16_t pd_id; /* protection domain id */
190 	uint16_t pci_fn_num; /* pci function number */
191 	uint32_t eqd;	/* interrupt delay */
192 	uint32_t nbufs; /* copy buffers */
193 	uint32_t nhdl; /* preallocated memory handles */
194 };
195 
196 struct oce_wq {
197 	struct wq_config cfg; /* q config */
198 	void *parent; /* parent of this wq */
199 	uint16_t wq_id; /* wq ID */
200 	oce_ring_buffer_t *ring; /* ring buffer managing the wqes */
201 	struct oce_cq	*cq; 	/* cq associated with this wq */
202 	kmem_cache_t	*wqed_cache; /* packet desc cache */
203 	OCE_LIST_T	wqe_desc_list; /* packet descriptor list */
204 	oce_wq_bdesc_t  *wq_bdesc_array; /* buffer desc array */
205 	OCE_LIST_T	wq_buf_list; /* buffer list */
206 	OCE_LIST_T 	wq_mdesc_list; /* free list of memory handles */
207 	oce_wq_mdesc_t  *wq_mdesc_array; /* preallocated memory handles */
208 	uint32_t	wqm_used; /* memory handles uses */
209 	boolean_t	resched; /* used for mac_tx_update */
210 	uint32_t	wq_free; /* Wqe free */
211 	uint32_t	tx_deferd; /* Wqe free */
212 	uint32_t	pkt_drops; /* drops */
213 	kmutex_t lock; /* lock for the WQ */
214 };
215 
216 struct rq_config {
217 	uint32_t q_len; /* q length */
218 	uint32_t frag_size; /* fragment size. Send log2(size) in commmand */
219 	uint32_t mtu; /* max frame size for this RQ */
220 	uint32_t if_id; /* interface ID to associate this RQ with */
221 	uint32_t is_rss_queue; /* is this RQ an RSS queue? */
222 	uint32_t eqd;  /* interrupt delay */
223 	uint32_t nbufs; /* Total data buffers */
224 };
225 
226 struct rq_shadow_entry {
227 	oce_rq_bdesc_t *rqbd;
228 };
229 
230 struct oce_rq {
231 	/* RQ config */
232 	struct rq_config cfg;
233 	/* RQ id */
234 	uint32_t rq_id;
235 	/* parent of this rq */
236 	void *parent;
237 	/* CPU ID assigend to this RQ if it is an RSS queue */
238 	uint32_t rss_cpuid;
239 	/* ring buffer managing the RQEs */
240 	oce_ring_buffer_t *ring;
241 	/* RQ Buffer cache  */
242 	/* kmem_cache_t *rqb_cache; */
243 	/* shadow list of mblk for rq ring */
244 	struct rq_shadow_entry *shadow_ring;
245 	/* cq associated with this queue */
246 	struct oce_cq *cq;
247 	oce_rq_bdesc_t  *rq_bdesc_array;
248 	OCE_LIST_T rq_buf_list; /* Free list */
249 	uint32_t buf_avail; /* buffer avaialable with hw */
250 	uint32_t pending; /* Buffers sent up */
251 	/* rq lock */
252 	kmutex_t lock;
253 };
254 
255 struct link_status {
256 	/* dw 0 */
257 	uint8_t physical_port;
258 	uint8_t mac_duplex;
259 	uint8_t mac_speed;
260 	uint8_t mac_fault;
261 	/* dw 1 */
262 	uint8_t mgmt_mac_duplex;
263 	uint8_t mgmt_mac_speed;
264 	uint16_t rsvd0;
265 };
266 
267 oce_dma_buf_t *oce_alloc_dma_buffer(struct oce_dev *dev,
268     uint32_t size, uint32_t flags);
269 void oce_free_dma_buffer(struct oce_dev *dev, oce_dma_buf_t *dbuf);
270 
271 oce_ring_buffer_t *create_ring_buffer(struct oce_dev *dev,
272     uint32_t num_items, uint32_t item_size,
273     uint32_t flags);
274 void destroy_ring_buffer(struct oce_dev *dev, oce_ring_buffer_t *ring);
275 
276 /* Queues */
277 struct oce_eq *oce_eq_create(struct oce_dev *dev, uint32_t q_len,
278     uint32_t item_size, uint32_t eq_delay);
279 
280 int oce_eq_del(struct oce_dev *dev, struct oce_eq *eq);
281 int oce_set_eq_delay(struct oce_dev *dev, uint32_t *eq_arr,
282     uint32_t eq_cnt, uint32_t eq_delay);
283 void oce_arm_eq(struct oce_dev *dev, int16_t qid, int npopped,
284     boolean_t rearm, boolean_t clearint);
285 void oce_arm_cq(struct oce_dev *dev, int16_t qid, int npopped,
286     boolean_t rearm);
287 void oce_drain_eq(struct oce_eq *eq);
288 
289 
290 /* Bootstrap */
291 int oce_mbox_init(struct oce_dev *dev);
292 int oce_mbox_fini(struct oce_dev *dev);
293 int oce_mbox_dispatch(struct  oce_dev *dev, uint32_t tmo_sec);
294 int oce_mbox_wait(struct  oce_dev *dev, uint32_t tmo_sec);
295 int oce_mbox_post(struct oce_dev *dev, struct oce_mbx *mbx,
296     struct  oce_mbx_ctx *mbxctx);
297 
298 /* Hardware */
299 boolean_t oce_is_reset_pci(struct oce_dev *dev);
300 int oce_pci_soft_reset(struct oce_dev *dev);
301 int oce_POST(struct oce_dev *dev);
302 int oce_pci_init(struct oce_dev *dev);
303 void oce_pci_fini(struct oce_dev *dev);
304 
305 /* Transmit */
306 struct oce_wq *oce_wq_create(struct oce_dev *dev, struct oce_eq *eq,
307     uint32_t q_len, int wq_type);
308 
309 int oce_wq_del(struct oce_dev *dev, struct oce_wq *wq);
310 struct oce_wq *oce_get_wq(struct oce_dev *dev, mblk_t *pkt);
311 uint16_t  oce_drain_wq_cq(void *arg);
312 mblk_t *oce_send_packet(struct oce_wq *wq, mblk_t *mp);
313 int oce_start_wq(struct oce_wq *wq);
314 void oce_stop_wq(struct oce_wq *wq);
315 
316 /* Recieve */
317 uint16_t oce_drain_rq_cq(void *arg);
318 struct oce_rq *oce_rq_create(struct oce_dev *dev, struct oce_eq *eq,
319     uint32_t q_len, uint32_t frag_size, uint32_t mtu,
320     int16_t if_id, boolean_t rss);
321 int oce_rq_del(struct oce_dev *dev, struct oce_rq *rq);
322 int oce_start_rq(struct oce_rq *rq);
323 void oce_stop_rq(struct oce_rq *rq);
324 
325 /* event handling */
326 struct oce_mq *oce_mq_create(struct oce_dev *dev,
327     struct oce_eq *eq, uint32_t q_len);
328 int oce_mq_del(struct oce_dev *dev, struct oce_mq *mq);
329 uint16_t oce_drain_mq_cq(void *arg);
330 
331 int oce_mq_mbox_post(struct  oce_dev *dev, struct  oce_mbx *mbx,
332     struct oce_mbx_ctx *mbxctx);
333 struct oce_mbx *oce_mq_get_mbx(struct oce_dev *dev);
334 void oce_stop_mq(struct oce_mq *mq);
335 void oce_rq_discharge(struct oce_rq *rq);
336 
337 /* mbx functions */
338 void mbx_common_req_hdr_init(struct mbx_hdr *hdr, uint8_t dom,
339     uint8_t port, uint8_t subsys, uint8_t opcode,
340     uint32_t timeout, uint32_t pyld_len);
341 void mbx_nic_req_hdr_init(struct mbx_hdr *hdr, uint8_t dom, uint8_t port,
342     uint8_t opcode, uint32_t timeout, uint32_t pyld_len);
343 int oce_get_fw_version(struct oce_dev *dev);
344 int oce_read_mac_addr(struct oce_dev *dev, uint16_t if_id, uint8_t perm,
345     uint8_t type, struct mac_address_format *mac);
346 int oce_if_create(struct oce_dev *dev, uint32_t cap_flags, uint32_t en_flags,
347     uint16_t vlan_tag, uint8_t *mac_addr, uint32_t *if_id);
348 int oce_if_del(struct oce_dev *dev, uint32_t if_id);
349 int oce_num_intr_vectors_set(struct oce_dev *dev, uint32_t num_vectors);
350 
351 int oce_get_link_status(struct oce_dev *dev, struct link_status *link);
352 int oce_set_rx_filter(struct oce_dev *dev,
353     struct mbx_set_common_ntwk_rx_filter *filter);
354 int oce_set_multicast_table(struct oce_dev *dev, struct ether_addr *mca_table,
355     uint8_t mca_cnt, boolean_t enable_promisc);
356 int oce_get_fw_config(struct oce_dev *dev);
357 int oce_get_hw_stats(struct oce_dev *dev);
358 int oce_set_flow_control(struct oce_dev *dev, uint32_t flow_control);
359 int oce_get_flow_control(struct oce_dev *dev, uint32_t *flow_control);
360 int oce_set_promiscuous(struct oce_dev *dev, boolean_t enable);
361 int oce_add_mac(struct oce_dev *dev, const uint8_t *mac, uint32_t *pmac_id);
362 int oce_del_mac(struct oce_dev *dev, uint32_t *pmac_id);
363 int oce_config_vlan(struct oce_dev *dev, uint8_t if_id,
364     struct normal_vlan *vtag_arr,
365     uint8_t vtag_cnt,  boolean_t untagged,
366     boolean_t enable_promisc);
367 int oce_config_link(struct oce_dev *dev, boolean_t enable);
368 
369 int oce_hw_init(struct oce_dev *dev);
370 void oce_hw_fini(struct oce_dev *dev);
371 int oce_chip_hw_init(struct oce_dev *dev);
372 void oce_chip_hw_fini(struct oce_dev *dev);
373 
374 int oce_issue_mbox(struct oce_dev *dev, queue_t *wq, mblk_t *mp,
375     uint32_t *payload_length);
376 
377 #ifdef __cplusplus
378 }
379 #endif
380 
381 #endif /* _OCE_IO_H_ */
382