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