xref: /dragonfly/sys/dev/netif/oce/oce_if.h (revision 2b3f93ea)
1229aec1cSSascha Wildner /*-
2c976b08eSSascha Wildner  * Copyright (C) 2013 Emulex
3229aec1cSSascha Wildner  * All rights reserved.
4229aec1cSSascha Wildner  *
5229aec1cSSascha Wildner  * Redistribution and use in source and binary forms, with or without
6229aec1cSSascha Wildner  * modification, are permitted provided that the following conditions are met:
7229aec1cSSascha Wildner  *
8229aec1cSSascha Wildner  * 1. Redistributions of source code must retain the above copyright notice,
9229aec1cSSascha Wildner  *    this list of conditions and the following disclaimer.
10229aec1cSSascha Wildner  *
11229aec1cSSascha Wildner  * 2. Redistributions in binary form must reproduce the above copyright
12229aec1cSSascha Wildner  *    notice, this list of conditions and the following disclaimer in the
13229aec1cSSascha Wildner  *    documentation and/or other materials provided with the distribution.
14229aec1cSSascha Wildner  *
15229aec1cSSascha Wildner  * 3. Neither the name of the Emulex Corporation nor the names of its
16229aec1cSSascha Wildner  *    contributors may be used to endorse or promote products derived from
17229aec1cSSascha Wildner  *    this software without specific prior written permission.
18229aec1cSSascha Wildner  *
19229aec1cSSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20229aec1cSSascha Wildner  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21229aec1cSSascha Wildner  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22229aec1cSSascha Wildner  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23229aec1cSSascha Wildner  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24229aec1cSSascha Wildner  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25229aec1cSSascha Wildner  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26229aec1cSSascha Wildner  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27229aec1cSSascha Wildner  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28229aec1cSSascha Wildner  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29229aec1cSSascha Wildner  * POSSIBILITY OF SUCH DAMAGE.
30229aec1cSSascha Wildner  *
31229aec1cSSascha Wildner  * Contact Information:
32229aec1cSSascha Wildner  * freebsd-drivers@emulex.com
33229aec1cSSascha Wildner  *
34229aec1cSSascha Wildner  * Emulex
35229aec1cSSascha Wildner  * 3333 Susan Street
36229aec1cSSascha Wildner  * Costa Mesa, CA 92626
37229aec1cSSascha Wildner  */
38229aec1cSSascha Wildner 
39229aec1cSSascha Wildner 
40c976b08eSSascha Wildner /* $FreeBSD: src/sys/dev/oce/oce_if.h,v 1.6 2013/07/07 00:30:13 svnexp Exp $ */
41229aec1cSSascha Wildner 
42229aec1cSSascha Wildner #include <sys/param.h>
43229aec1cSSascha Wildner #include <sys/endian.h>
44229aec1cSSascha Wildner #include <sys/module.h>
45229aec1cSSascha Wildner #include <sys/kernel.h>
46229aec1cSSascha Wildner #include <sys/bus.h>
47c443c74fSzrj #include <sys/malloc.h>	/* for M_NOWAIT */
48229aec1cSSascha Wildner #include <sys/mbuf.h>
49229aec1cSSascha Wildner #include <sys/rman.h>
50229aec1cSSascha Wildner #include <sys/socket.h>
51229aec1cSSascha Wildner #include <sys/sockio.h>
52229aec1cSSascha Wildner #include <sys/queue.h>
53229aec1cSSascha Wildner #include <sys/taskqueue.h>
54229aec1cSSascha Wildner #include <sys/lock.h>
55229aec1cSSascha Wildner #include <sys/sysctl.h>
56229aec1cSSascha Wildner #include <sys/random.h>
57229aec1cSSascha Wildner #include <sys/firmware.h>
58229aec1cSSascha Wildner #include <sys/systm.h>
59*2b3f93eaSMatthew Dillon #include <sys/caps.h>
60229aec1cSSascha Wildner #include <sys/proc.h>
61229aec1cSSascha Wildner 
62229aec1cSSascha Wildner #include <bus/pci/pcireg.h>
63229aec1cSSascha Wildner #include <bus/pci/pcivar.h>
64229aec1cSSascha Wildner 
65229aec1cSSascha Wildner #include <net/bpf.h>
66229aec1cSSascha Wildner #include <net/ethernet.h>
67229aec1cSSascha Wildner #include <net/if.h>
68229aec1cSSascha Wildner #include <net/if_types.h>
69229aec1cSSascha Wildner #include <net/if_media.h>
70229aec1cSSascha Wildner #include <net/ifq_var.h>
71229aec1cSSascha Wildner #include <net/vlan/if_vlan_ether.h>
72229aec1cSSascha Wildner #include <net/vlan/if_vlan_var.h>
73229aec1cSSascha Wildner #include <net/if_dl.h>
74229aec1cSSascha Wildner 
75229aec1cSSascha Wildner #include <netinet/in.h>
76229aec1cSSascha Wildner #include <netinet/in_systm.h>
77229aec1cSSascha Wildner #include <netinet/in_var.h>
78229aec1cSSascha Wildner #include <netinet/if_ether.h>
79229aec1cSSascha Wildner #include <netinet/ip.h>
80229aec1cSSascha Wildner #include <netinet/ip6.h>
81229aec1cSSascha Wildner #include <netinet6/in6_var.h>
82229aec1cSSascha Wildner #include <netinet6/ip6_mroute.h>
83229aec1cSSascha Wildner 
84229aec1cSSascha Wildner #include <netinet/udp.h>
85229aec1cSSascha Wildner #include <netinet/tcp.h>
86229aec1cSSascha Wildner #if 0 /* XXX swildner: LRO */
87229aec1cSSascha Wildner #include <netinet/tcp_lro.h>
88229aec1cSSascha Wildner #endif
89229aec1cSSascha Wildner 
90229aec1cSSascha Wildner #include "oce_hw.h"
91229aec1cSSascha Wildner 
92229aec1cSSascha Wildner #define COMPONENT_REVISION "4.6.95.0"
93229aec1cSSascha Wildner 
94229aec1cSSascha Wildner /* OCE devices supported by this driver */
95229aec1cSSascha Wildner #define PCI_VENDOR_EMULEX		0x10df	/* Emulex */
96229aec1cSSascha Wildner #define PCI_VENDOR_SERVERENGINES	0x19a2	/* ServerEngines (BE) */
97229aec1cSSascha Wildner #define PCI_PRODUCT_BE2			0x0700	/* BE2 network adapter */
98229aec1cSSascha Wildner #define PCI_PRODUCT_BE3			0x0710	/* BE3 network adapter */
99229aec1cSSascha Wildner #define PCI_PRODUCT_XE201		0xe220	/* XE201 network adapter */
100229aec1cSSascha Wildner #define PCI_PRODUCT_XE201_VF		0xe228	/* XE201 with VF in Lancer */
101c976b08eSSascha Wildner #define PCI_PRODUCT_SH			0x0720	/* Skyhawk network adapter */
102229aec1cSSascha Wildner 
103229aec1cSSascha Wildner #define IS_BE(sc)	(((sc->flags & OCE_FLAGS_BE3) | \
104229aec1cSSascha Wildner 			 (sc->flags & OCE_FLAGS_BE2))? 1:0)
105c976b08eSSascha Wildner #define IS_BE3(sc)	(sc->flags & OCE_FLAGS_BE3)
106c976b08eSSascha Wildner #define IS_BE2(sc)	(sc->flags & OCE_FLAGS_BE2)
107229aec1cSSascha Wildner #define IS_XE201(sc)	((sc->flags & OCE_FLAGS_XE201) ? 1:0)
108229aec1cSSascha Wildner #define HAS_A0_CHIP(sc)	((sc->flags & OCE_FLAGS_HAS_A0_CHIP) ? 1:0)
109c976b08eSSascha Wildner #define IS_SH(sc)	((sc->flags & OCE_FLAGS_SH) ? 1 : 0)
110c976b08eSSascha Wildner 
111c976b08eSSascha Wildner #define is_be_mode_mc(sc)	((sc->function_mode & FNM_FLEX10_MODE) ||	\
112c976b08eSSascha Wildner 				(sc->function_mode & FNM_UMC_MODE)    ||	\
113c976b08eSSascha Wildner 				(sc->function_mode & FNM_VNIC_MODE))
114c976b08eSSascha Wildner #define OCE_FUNCTION_CAPS_SUPER_NIC	0x40
115c976b08eSSascha Wildner #define IS_PROFILE_SUPER_NIC(sc) (sc->function_caps & OCE_FUNCTION_CAPS_SUPER_NIC)
116229aec1cSSascha Wildner 
117229aec1cSSascha Wildner 
118229aec1cSSascha Wildner /* proportion Service Level Interface queues */
119229aec1cSSascha Wildner #define OCE_MAX_UNITS			2
120229aec1cSSascha Wildner #define OCE_MAX_PPORT			OCE_MAX_UNITS
121229aec1cSSascha Wildner #define OCE_MAX_VPORT			OCE_MAX_UNITS
122229aec1cSSascha Wildner 
123229aec1cSSascha Wildner #define OCE_NCPUS			ncpus
124229aec1cSSascha Wildner 
125229aec1cSSascha Wildner /* This should be powers of 2. Like 2,4,8 & 16 */
126c976b08eSSascha Wildner #define OCE_MAX_RSS			8
127229aec1cSSascha Wildner #define OCE_LEGACY_MODE_RSS		4 /* For BE3 Legacy mode*/
128c976b08eSSascha Wildner #if 0 /* XXX swildner: RSS */
129c976b08eSSascha Wildner #define is_rss_enabled(sc)		((sc->function_caps & FNC_RSS) && !is_be_mode_mc(sc))
130c976b08eSSascha Wildner #else
131c976b08eSSascha Wildner #define is_rss_enabled(sc)		0
132c976b08eSSascha Wildner #endif
133229aec1cSSascha Wildner 
134229aec1cSSascha Wildner #define OCE_MIN_RQ			1
135229aec1cSSascha Wildner #define OCE_MIN_WQ			1
136229aec1cSSascha Wildner 
137229aec1cSSascha Wildner #define OCE_MAX_RQ			OCE_MAX_RSS + 1 /* one default queue */
138229aec1cSSascha Wildner #define OCE_MAX_WQ			8
139229aec1cSSascha Wildner 
140229aec1cSSascha Wildner #define OCE_MAX_EQ			32
141229aec1cSSascha Wildner #define OCE_MAX_CQ			OCE_MAX_RQ + OCE_MAX_WQ + 1 /* one MCC queue */
142229aec1cSSascha Wildner #define OCE_MAX_CQ_EQ			8 /* Max CQ that can attached to an EQ */
143229aec1cSSascha Wildner 
144229aec1cSSascha Wildner #define OCE_DEFAULT_WQ_EQD		16
145229aec1cSSascha Wildner #define OCE_MAX_PACKET_Q		16
146229aec1cSSascha Wildner #define OCE_RQ_BUF_SIZE			2048
147229aec1cSSascha Wildner #define OCE_LSO_MAX_SIZE		(64 * 1024)
148229aec1cSSascha Wildner #define LONG_TIMEOUT			30
149229aec1cSSascha Wildner #define OCE_MAX_JUMBO_FRAME_SIZE	9018
150229aec1cSSascha Wildner #define OCE_MAX_MTU			(OCE_MAX_JUMBO_FRAME_SIZE - \
151229aec1cSSascha Wildner 						ETHER_VLAN_ENCAP_LEN - \
152229aec1cSSascha Wildner 						ETHER_HDR_LEN)
153229aec1cSSascha Wildner 
154229aec1cSSascha Wildner #define OCE_MAX_TX_ELEMENTS		29
155229aec1cSSascha Wildner #define OCE_MAX_TX_DESC			1024
156229aec1cSSascha Wildner #define OCE_MAX_TX_SIZE			65535
157229aec1cSSascha Wildner #define OCE_MAX_RX_SIZE			4096
158229aec1cSSascha Wildner #define OCE_MAX_RQ_POSTS		255
159229aec1cSSascha Wildner #define OCE_DEFAULT_PROMISCUOUS		0
160229aec1cSSascha Wildner 
161229aec1cSSascha Wildner 
162229aec1cSSascha Wildner #define RSS_ENABLE_IPV4			0x1
163229aec1cSSascha Wildner #define RSS_ENABLE_TCP_IPV4		0x2
164229aec1cSSascha Wildner #define RSS_ENABLE_IPV6			0x4
165229aec1cSSascha Wildner #define RSS_ENABLE_TCP_IPV6		0x8
166229aec1cSSascha Wildner 
167c976b08eSSascha Wildner #define INDIRECTION_TABLE_ENTRIES	128
168229aec1cSSascha Wildner 
169229aec1cSSascha Wildner /* flow control definitions */
170229aec1cSSascha Wildner #define OCE_FC_NONE			0x00000000
171229aec1cSSascha Wildner #define OCE_FC_TX			0x00000001
172229aec1cSSascha Wildner #define OCE_FC_RX			0x00000002
173229aec1cSSascha Wildner #define OCE_DEFAULT_FLOW_CONTROL	(OCE_FC_TX | OCE_FC_RX)
174229aec1cSSascha Wildner 
175229aec1cSSascha Wildner 
176229aec1cSSascha Wildner /* Interface capabilities to give device when creating interface */
177229aec1cSSascha Wildner #define  OCE_CAPAB_FLAGS 		(MBX_RX_IFACE_FLAGS_BROADCAST    | \
178229aec1cSSascha Wildner 					MBX_RX_IFACE_FLAGS_UNTAGGED      | \
179229aec1cSSascha Wildner 					MBX_RX_IFACE_FLAGS_PROMISCUOUS      | \
180229aec1cSSascha Wildner 					MBX_RX_IFACE_FLAGS_MCAST_PROMISCUOUS   | \
181229aec1cSSascha Wildner 					MBX_RX_IFACE_FLAGS_RSS | \
182229aec1cSSascha Wildner 					MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR)
183229aec1cSSascha Wildner 
184229aec1cSSascha Wildner /* Interface capabilities to enable by default (others set dynamically) */
185229aec1cSSascha Wildner #define  OCE_CAPAB_ENABLE		(MBX_RX_IFACE_FLAGS_BROADCAST | \
186229aec1cSSascha Wildner 					MBX_RX_IFACE_FLAGS_UNTAGGED   | \
187229aec1cSSascha Wildner 					MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR)
188229aec1cSSascha Wildner 
189229aec1cSSascha Wildner #define OCE_IF_HWASSIST			(CSUM_IP | CSUM_TCP | CSUM_UDP)
190229aec1cSSascha Wildner #define OCE_IF_CAPABILITIES		(IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \
191229aec1cSSascha Wildner 					IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | \
192229aec1cSSascha Wildner 					IFCAP_JUMBO_MTU | IFCAP_VLAN_MTU)
193229aec1cSSascha Wildner #define OCE_IF_HWASSIST_NONE		0
194229aec1cSSascha Wildner #define OCE_IF_CAPABILITIES_NONE 	0
195229aec1cSSascha Wildner 
196229aec1cSSascha Wildner 
197229aec1cSSascha Wildner #define ETH_ADDR_LEN			6
198229aec1cSSascha Wildner #define MAX_VLANFILTER_SIZE		64
199229aec1cSSascha Wildner #define MAX_VLANS			4096
200229aec1cSSascha Wildner 
201229aec1cSSascha Wildner #define upper_32_bits(n)		((uint32_t)(((n) >> 16) >> 16))
202229aec1cSSascha Wildner #define BSWAP_8(x)			((x) & 0xff)
203229aec1cSSascha Wildner #define BSWAP_16(x)			((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
204229aec1cSSascha Wildner #define BSWAP_32(x)			((BSWAP_16(x) << 16) | \
205229aec1cSSascha Wildner 					 BSWAP_16((x) >> 16))
206229aec1cSSascha Wildner #define BSWAP_64(x)			((BSWAP_32(x) << 32) | \
207229aec1cSSascha Wildner 					BSWAP_32((x) >> 32))
208229aec1cSSascha Wildner 
209229aec1cSSascha Wildner #define for_all_wq_queues(sc, wq, i) 	\
210229aec1cSSascha Wildner 		for (i = 0, wq = sc->wq[0]; i < sc->nwqs; i++, wq = sc->wq[i])
211229aec1cSSascha Wildner #define for_all_rq_queues(sc, rq, i) 	\
212229aec1cSSascha Wildner 		for (i = 0, rq = sc->rq[0]; i < sc->nrqs; i++, rq = sc->rq[i])
213c976b08eSSascha Wildner #define for_all_rss_queues(sc, rq, i) 	\
214c976b08eSSascha Wildner 		for (i = 0, rq = sc->rq[i + 1]; i < (sc->nrqs - 1); \
215c976b08eSSascha Wildner 		     i++, rq = sc->rq[i + 1])
216229aec1cSSascha Wildner #define for_all_evnt_queues(sc, eq, i) 	\
217229aec1cSSascha Wildner 		for (i = 0, eq = sc->eq[0]; i < sc->neqs; i++, eq = sc->eq[i])
218229aec1cSSascha Wildner #define for_all_cq_queues(sc, cq, i) 	\
219229aec1cSSascha Wildner 		for (i = 0, cq = sc->cq[0]; i < sc->ncqs; i++, cq = sc->cq[i])
220229aec1cSSascha Wildner 
221229aec1cSSascha Wildner 
222229aec1cSSascha Wildner /* Flash specific */
223229aec1cSSascha Wildner #define IOCTL_COOKIE			"SERVERENGINES CORP"
224229aec1cSSascha Wildner #define MAX_FLASH_COMP			32
225229aec1cSSascha Wildner 
226229aec1cSSascha Wildner #define IMG_ISCSI			160
227229aec1cSSascha Wildner #define IMG_REDBOOT			224
228229aec1cSSascha Wildner #define IMG_BIOS			34
229229aec1cSSascha Wildner #define IMG_PXEBIOS			32
230229aec1cSSascha Wildner #define IMG_FCOEBIOS			33
231229aec1cSSascha Wildner #define IMG_ISCSI_BAK			176
232229aec1cSSascha Wildner #define IMG_FCOE			162
233229aec1cSSascha Wildner #define IMG_FCOE_BAK			178
234229aec1cSSascha Wildner #define IMG_NCSI			16
235229aec1cSSascha Wildner #define IMG_PHY				192
236229aec1cSSascha Wildner #define FLASHROM_OPER_FLASH		1
237229aec1cSSascha Wildner #define FLASHROM_OPER_SAVE		2
238229aec1cSSascha Wildner #define FLASHROM_OPER_REPORT		4
239229aec1cSSascha Wildner #define FLASHROM_OPER_FLASH_PHY		9
240229aec1cSSascha Wildner #define FLASHROM_OPER_SAVE_PHY		10
241229aec1cSSascha Wildner #define TN_8022				13
242229aec1cSSascha Wildner 
243229aec1cSSascha Wildner enum {
244229aec1cSSascha Wildner 	PHY_TYPE_CX4_10GB = 0,
245229aec1cSSascha Wildner 	PHY_TYPE_XFP_10GB,
246229aec1cSSascha Wildner 	PHY_TYPE_SFP_1GB,
247229aec1cSSascha Wildner 	PHY_TYPE_SFP_PLUS_10GB,
248229aec1cSSascha Wildner 	PHY_TYPE_KR_10GB,
249229aec1cSSascha Wildner 	PHY_TYPE_KX4_10GB,
250229aec1cSSascha Wildner 	PHY_TYPE_BASET_10GB,
251229aec1cSSascha Wildner 	PHY_TYPE_BASET_1GB,
252229aec1cSSascha Wildner 	PHY_TYPE_BASEX_1GB,
253229aec1cSSascha Wildner 	PHY_TYPE_SGMII,
254229aec1cSSascha Wildner 	PHY_TYPE_DISABLED = 255
255229aec1cSSascha Wildner };
256229aec1cSSascha Wildner 
257229aec1cSSascha Wildner /**
258229aec1cSSascha Wildner  * @brief Define and hold all necessary info for a single interrupt
259229aec1cSSascha Wildner  */
260229aec1cSSascha Wildner #define OCE_MAX_MSI			32 /* Message Signaled Interrupts */
261229aec1cSSascha Wildner #define OCE_MAX_MSIX			2048 /* PCI Express MSI Interrrupts */
262229aec1cSSascha Wildner 
263229aec1cSSascha Wildner typedef struct oce_intr_info {
264229aec1cSSascha Wildner 	void *tag;		/* cookie returned by bus_setup_intr */
265229aec1cSSascha Wildner 	struct resource *intr_res;	/* PCI resource container */
266229aec1cSSascha Wildner 	int irq_rr;		/* resource id for the interrupt */
267229aec1cSSascha Wildner 	int irq_type;		/* interrupt type */
268229aec1cSSascha Wildner 	struct oce_softc *sc;	/* pointer to the parent soft c */
269229aec1cSSascha Wildner 	struct oce_eq *eq;	/* pointer to the connected EQ */
270229aec1cSSascha Wildner 	struct taskqueue *tq;	/* Associated task queue */
271229aec1cSSascha Wildner 	struct task task;	/* task queue task */
272229aec1cSSascha Wildner 	char task_name[32];	/* task name */
273229aec1cSSascha Wildner 	int vector;		/* interrupt vector number */
274229aec1cSSascha Wildner } OCE_INTR_INFO, *POCE_INTR_INFO;
275229aec1cSSascha Wildner 
276229aec1cSSascha Wildner 
277229aec1cSSascha Wildner /* Ring related */
278229aec1cSSascha Wildner #define	GET_Q_NEXT(_START, _STEP, _END)	\
279229aec1cSSascha Wildner 	(((_START) + (_STEP)) < (_END) ? ((_START) + (_STEP)) \
280229aec1cSSascha Wildner 	: (((_START) + (_STEP)) - (_END)))
281229aec1cSSascha Wildner 
282229aec1cSSascha Wildner #define	DBUF_PA(obj)			((obj)->addr)
283229aec1cSSascha Wildner #define	DBUF_VA(obj) 			((obj)->ptr)
284229aec1cSSascha Wildner #define	DBUF_TAG(obj) 			((obj)->tag)
285229aec1cSSascha Wildner #define	DBUF_MAP(obj) 			((obj)->map)
286229aec1cSSascha Wildner #define	DBUF_SYNC(obj, flags) 		\
287229aec1cSSascha Wildner 		(void) bus_dmamap_sync(DBUF_TAG(obj), DBUF_MAP(obj), (flags))
288229aec1cSSascha Wildner 
289229aec1cSSascha Wildner #define	RING_NUM_PENDING(ring)		ring->num_used
290229aec1cSSascha Wildner #define	RING_FULL(ring) 		(ring->num_used == ring->num_items)
291229aec1cSSascha Wildner #define	RING_EMPTY(ring) 		(ring->num_used == 0)
292229aec1cSSascha Wildner #define	RING_NUM_FREE(ring)		\
293229aec1cSSascha Wildner 		(uint32_t)(ring->num_items - ring->num_used)
294229aec1cSSascha Wildner #define	RING_GET(ring, n)		\
295229aec1cSSascha Wildner 		ring->cidx = GET_Q_NEXT(ring->cidx, n, ring->num_items)
296229aec1cSSascha Wildner #define	RING_PUT(ring, n)		\
297229aec1cSSascha Wildner 		ring->pidx = GET_Q_NEXT(ring->pidx, n, ring->num_items)
298229aec1cSSascha Wildner 
299229aec1cSSascha Wildner #define	RING_GET_CONSUMER_ITEM_VA(ring, type) 	\
300229aec1cSSascha Wildner 	(void*)((type *)DBUF_VA(&ring->dma) + ring->cidx)
301229aec1cSSascha Wildner #define	RING_GET_CONSUMER_ITEM_PA(ring, type)		\
302229aec1cSSascha Wildner 	(uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->cidx)
303229aec1cSSascha Wildner #define	RING_GET_PRODUCER_ITEM_VA(ring, type)		\
304229aec1cSSascha Wildner 	(void *)(((type *)DBUF_VA(&ring->dma)) + ring->pidx)
305229aec1cSSascha Wildner #define	RING_GET_PRODUCER_ITEM_PA(ring, type)		\
306229aec1cSSascha Wildner 	(uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->pidx)
307229aec1cSSascha Wildner 
308229aec1cSSascha Wildner #define OCE_DMAPTR(o, c) 		((c *)(o)->ptr)
309229aec1cSSascha Wildner 
310229aec1cSSascha Wildner struct oce_packet_desc {
311229aec1cSSascha Wildner 	struct mbuf *mbuf;
312229aec1cSSascha Wildner 	bus_dmamap_t map;
313229aec1cSSascha Wildner 	int nsegs;
314229aec1cSSascha Wildner 	uint32_t wqe_idx;
315229aec1cSSascha Wildner };
316229aec1cSSascha Wildner 
317229aec1cSSascha Wildner typedef struct oce_dma_mem {
318229aec1cSSascha Wildner 	bus_dma_tag_t tag;
319229aec1cSSascha Wildner 	bus_dmamap_t map;
320229aec1cSSascha Wildner 	void *ptr;
321229aec1cSSascha Wildner 	bus_addr_t paddr;
322229aec1cSSascha Wildner } OCE_DMA_MEM, *POCE_DMA_MEM;
323229aec1cSSascha Wildner 
324229aec1cSSascha Wildner typedef struct oce_ring_buffer_s {
325229aec1cSSascha Wildner 	uint16_t cidx;	/* Get ptr */
326229aec1cSSascha Wildner 	uint16_t pidx;	/* Put Ptr */
327229aec1cSSascha Wildner 	size_t item_size;
328229aec1cSSascha Wildner 	size_t num_items;
329229aec1cSSascha Wildner 	uint32_t num_used;
330229aec1cSSascha Wildner 	OCE_DMA_MEM dma;
331229aec1cSSascha Wildner } oce_ring_buffer_t;
332229aec1cSSascha Wildner 
333229aec1cSSascha Wildner /* Stats */
334229aec1cSSascha Wildner #define OCE_UNICAST_PACKET	0
335229aec1cSSascha Wildner #define OCE_MULTICAST_PACKET	1
336229aec1cSSascha Wildner #define OCE_BROADCAST_PACKET	2
337229aec1cSSascha Wildner #define OCE_RSVD_PACKET		3
338229aec1cSSascha Wildner 
339229aec1cSSascha Wildner struct oce_rx_stats {
340229aec1cSSascha Wildner 	/* Total Receive Stats*/
341229aec1cSSascha Wildner 	uint64_t t_rx_pkts;
342229aec1cSSascha Wildner 	uint64_t t_rx_bytes;
343229aec1cSSascha Wildner 	uint32_t t_rx_frags;
344229aec1cSSascha Wildner 	uint32_t t_rx_mcast_pkts;
345229aec1cSSascha Wildner 	uint32_t t_rx_ucast_pkts;
346229aec1cSSascha Wildner 	uint32_t t_rxcp_errs;
347229aec1cSSascha Wildner };
348229aec1cSSascha Wildner struct oce_tx_stats {
349229aec1cSSascha Wildner 	/*Total Transmit Stats */
350229aec1cSSascha Wildner 	uint64_t t_tx_pkts;
351229aec1cSSascha Wildner 	uint64_t t_tx_bytes;
352229aec1cSSascha Wildner 	uint32_t t_tx_reqs;
353229aec1cSSascha Wildner 	uint32_t t_tx_stops;
354229aec1cSSascha Wildner 	uint32_t t_tx_wrbs;
355229aec1cSSascha Wildner 	uint32_t t_tx_compl;
356229aec1cSSascha Wildner 	uint32_t t_ipv6_ext_hdr_tx_drop;
357229aec1cSSascha Wildner };
358229aec1cSSascha Wildner 
359229aec1cSSascha Wildner struct oce_be_stats {
360229aec1cSSascha Wildner 	uint8_t  be_on_die_temperature;
361229aec1cSSascha Wildner 	uint32_t be_tx_events;
362229aec1cSSascha Wildner 	uint32_t eth_red_drops;
363229aec1cSSascha Wildner 	uint32_t rx_drops_no_pbuf;
364229aec1cSSascha Wildner 	uint32_t rx_drops_no_txpb;
365229aec1cSSascha Wildner 	uint32_t rx_drops_no_erx_descr;
366229aec1cSSascha Wildner 	uint32_t rx_drops_no_tpre_descr;
367229aec1cSSascha Wildner 	uint32_t rx_drops_too_many_frags;
368229aec1cSSascha Wildner 	uint32_t rx_drops_invalid_ring;
369229aec1cSSascha Wildner 	uint32_t forwarded_packets;
370229aec1cSSascha Wildner 	uint32_t rx_drops_mtu;
371229aec1cSSascha Wildner 	uint32_t rx_crc_errors;
372229aec1cSSascha Wildner 	uint32_t rx_alignment_symbol_errors;
373229aec1cSSascha Wildner 	uint32_t rx_pause_frames;
374229aec1cSSascha Wildner 	uint32_t rx_priority_pause_frames;
375229aec1cSSascha Wildner 	uint32_t rx_control_frames;
376229aec1cSSascha Wildner 	uint32_t rx_in_range_errors;
377229aec1cSSascha Wildner 	uint32_t rx_out_range_errors;
378229aec1cSSascha Wildner 	uint32_t rx_frame_too_long;
379229aec1cSSascha Wildner 	uint32_t rx_address_match_errors;
380229aec1cSSascha Wildner 	uint32_t rx_dropped_too_small;
381229aec1cSSascha Wildner 	uint32_t rx_dropped_too_short;
382229aec1cSSascha Wildner 	uint32_t rx_dropped_header_too_small;
383229aec1cSSascha Wildner 	uint32_t rx_dropped_tcp_length;
384229aec1cSSascha Wildner 	uint32_t rx_dropped_runt;
385229aec1cSSascha Wildner 	uint32_t rx_ip_checksum_errs;
386229aec1cSSascha Wildner 	uint32_t rx_tcp_checksum_errs;
387229aec1cSSascha Wildner 	uint32_t rx_udp_checksum_errs;
388229aec1cSSascha Wildner 	uint32_t rx_switched_unicast_packets;
389229aec1cSSascha Wildner 	uint32_t rx_switched_multicast_packets;
390229aec1cSSascha Wildner 	uint32_t rx_switched_broadcast_packets;
391229aec1cSSascha Wildner 	uint32_t tx_pauseframes;
392229aec1cSSascha Wildner 	uint32_t tx_priority_pauseframes;
393229aec1cSSascha Wildner 	uint32_t tx_controlframes;
394229aec1cSSascha Wildner 	uint32_t rxpp_fifo_overflow_drop;
395229aec1cSSascha Wildner 	uint32_t rx_input_fifo_overflow_drop;
396229aec1cSSascha Wildner 	uint32_t pmem_fifo_overflow_drop;
397229aec1cSSascha Wildner 	uint32_t jabber_events;
398229aec1cSSascha Wildner };
399229aec1cSSascha Wildner 
400229aec1cSSascha Wildner struct oce_xe201_stats {
401229aec1cSSascha Wildner 	uint64_t tx_pkts;
402229aec1cSSascha Wildner 	uint64_t tx_unicast_pkts;
403229aec1cSSascha Wildner 	uint64_t tx_multicast_pkts;
404229aec1cSSascha Wildner 	uint64_t tx_broadcast_pkts;
405229aec1cSSascha Wildner 	uint64_t tx_bytes;
406229aec1cSSascha Wildner 	uint64_t tx_unicast_bytes;
407229aec1cSSascha Wildner 	uint64_t tx_multicast_bytes;
408229aec1cSSascha Wildner 	uint64_t tx_broadcast_bytes;
409229aec1cSSascha Wildner 	uint64_t tx_discards;
410229aec1cSSascha Wildner 	uint64_t tx_errors;
411229aec1cSSascha Wildner 	uint64_t tx_pause_frames;
412229aec1cSSascha Wildner 	uint64_t tx_pause_on_frames;
413229aec1cSSascha Wildner 	uint64_t tx_pause_off_frames;
414229aec1cSSascha Wildner 	uint64_t tx_internal_mac_errors;
415229aec1cSSascha Wildner 	uint64_t tx_control_frames;
416229aec1cSSascha Wildner 	uint64_t tx_pkts_64_bytes;
417229aec1cSSascha Wildner 	uint64_t tx_pkts_65_to_127_bytes;
418229aec1cSSascha Wildner 	uint64_t tx_pkts_128_to_255_bytes;
419229aec1cSSascha Wildner 	uint64_t tx_pkts_256_to_511_bytes;
420229aec1cSSascha Wildner 	uint64_t tx_pkts_512_to_1023_bytes;
421229aec1cSSascha Wildner 	uint64_t tx_pkts_1024_to_1518_bytes;
422229aec1cSSascha Wildner 	uint64_t tx_pkts_1519_to_2047_bytes;
423229aec1cSSascha Wildner 	uint64_t tx_pkts_2048_to_4095_bytes;
424229aec1cSSascha Wildner 	uint64_t tx_pkts_4096_to_8191_bytes;
425229aec1cSSascha Wildner 	uint64_t tx_pkts_8192_to_9216_bytes;
426229aec1cSSascha Wildner 	uint64_t tx_lso_pkts;
427229aec1cSSascha Wildner 	uint64_t rx_pkts;
428229aec1cSSascha Wildner 	uint64_t rx_unicast_pkts;
429229aec1cSSascha Wildner 	uint64_t rx_multicast_pkts;
430229aec1cSSascha Wildner 	uint64_t rx_broadcast_pkts;
431229aec1cSSascha Wildner 	uint64_t rx_bytes;
432229aec1cSSascha Wildner 	uint64_t rx_unicast_bytes;
433229aec1cSSascha Wildner 	uint64_t rx_multicast_bytes;
434229aec1cSSascha Wildner 	uint64_t rx_broadcast_bytes;
435229aec1cSSascha Wildner 	uint32_t rx_unknown_protos;
436229aec1cSSascha Wildner 	uint64_t rx_discards;
437229aec1cSSascha Wildner 	uint64_t rx_errors;
438229aec1cSSascha Wildner 	uint64_t rx_crc_errors;
439229aec1cSSascha Wildner 	uint64_t rx_alignment_errors;
440229aec1cSSascha Wildner 	uint64_t rx_symbol_errors;
441229aec1cSSascha Wildner 	uint64_t rx_pause_frames;
442229aec1cSSascha Wildner 	uint64_t rx_pause_on_frames;
443229aec1cSSascha Wildner 	uint64_t rx_pause_off_frames;
444229aec1cSSascha Wildner 	uint64_t rx_frames_too_long;
445229aec1cSSascha Wildner 	uint64_t rx_internal_mac_errors;
446229aec1cSSascha Wildner 	uint32_t rx_undersize_pkts;
447229aec1cSSascha Wildner 	uint32_t rx_oversize_pkts;
448229aec1cSSascha Wildner 	uint32_t rx_fragment_pkts;
449229aec1cSSascha Wildner 	uint32_t rx_jabbers;
450229aec1cSSascha Wildner 	uint64_t rx_control_frames;
451229aec1cSSascha Wildner 	uint64_t rx_control_frames_unknown_opcode;
452229aec1cSSascha Wildner 	uint32_t rx_in_range_errors;
453229aec1cSSascha Wildner 	uint32_t rx_out_of_range_errors;
454229aec1cSSascha Wildner 	uint32_t rx_address_match_errors;
455229aec1cSSascha Wildner 	uint32_t rx_vlan_mismatch_errors;
456229aec1cSSascha Wildner 	uint32_t rx_dropped_too_small;
457229aec1cSSascha Wildner 	uint32_t rx_dropped_too_short;
458229aec1cSSascha Wildner 	uint32_t rx_dropped_header_too_small;
459229aec1cSSascha Wildner 	uint32_t rx_dropped_invalid_tcp_length;
460229aec1cSSascha Wildner 	uint32_t rx_dropped_runt;
461229aec1cSSascha Wildner 	uint32_t rx_ip_checksum_errors;
462229aec1cSSascha Wildner 	uint32_t rx_tcp_checksum_errors;
463229aec1cSSascha Wildner 	uint32_t rx_udp_checksum_errors;
464229aec1cSSascha Wildner 	uint32_t rx_non_rss_pkts;
465229aec1cSSascha Wildner 	uint64_t rx_ipv4_pkts;
466229aec1cSSascha Wildner 	uint64_t rx_ipv6_pkts;
467229aec1cSSascha Wildner 	uint64_t rx_ipv4_bytes;
468229aec1cSSascha Wildner 	uint64_t rx_ipv6_bytes;
469229aec1cSSascha Wildner 	uint64_t rx_nic_pkts;
470229aec1cSSascha Wildner 	uint64_t rx_tcp_pkts;
471229aec1cSSascha Wildner 	uint64_t rx_iscsi_pkts;
472229aec1cSSascha Wildner 	uint64_t rx_management_pkts;
473229aec1cSSascha Wildner 	uint64_t rx_switched_unicast_pkts;
474229aec1cSSascha Wildner 	uint64_t rx_switched_multicast_pkts;
475229aec1cSSascha Wildner 	uint64_t rx_switched_broadcast_pkts;
476229aec1cSSascha Wildner 	uint64_t num_forwards;
477229aec1cSSascha Wildner 	uint32_t rx_fifo_overflow;
478229aec1cSSascha Wildner 	uint32_t rx_input_fifo_overflow;
479229aec1cSSascha Wildner 	uint64_t rx_drops_too_many_frags;
480229aec1cSSascha Wildner 	uint32_t rx_drops_invalid_queue;
481229aec1cSSascha Wildner 	uint64_t rx_drops_mtu;
482229aec1cSSascha Wildner 	uint64_t rx_pkts_64_bytes;
483229aec1cSSascha Wildner 	uint64_t rx_pkts_65_to_127_bytes;
484229aec1cSSascha Wildner 	uint64_t rx_pkts_128_to_255_bytes;
485229aec1cSSascha Wildner 	uint64_t rx_pkts_256_to_511_bytes;
486229aec1cSSascha Wildner 	uint64_t rx_pkts_512_to_1023_bytes;
487229aec1cSSascha Wildner 	uint64_t rx_pkts_1024_to_1518_bytes;
488229aec1cSSascha Wildner 	uint64_t rx_pkts_1519_to_2047_bytes;
489229aec1cSSascha Wildner 	uint64_t rx_pkts_2048_to_4095_bytes;
490229aec1cSSascha Wildner 	uint64_t rx_pkts_4096_to_8191_bytes;
491229aec1cSSascha Wildner 	uint64_t rx_pkts_8192_to_9216_bytes;
492229aec1cSSascha Wildner };
493229aec1cSSascha Wildner 
494229aec1cSSascha Wildner struct oce_drv_stats {
495229aec1cSSascha Wildner 	struct oce_rx_stats rx;
496229aec1cSSascha Wildner 	struct oce_tx_stats tx;
497229aec1cSSascha Wildner 	union {
498229aec1cSSascha Wildner 		struct oce_be_stats be;
499229aec1cSSascha Wildner 		struct oce_xe201_stats xe201;
500229aec1cSSascha Wildner 	} u0;
501229aec1cSSascha Wildner };
502229aec1cSSascha Wildner 
503229aec1cSSascha Wildner #define INTR_RATE_HWM                   15000
504229aec1cSSascha Wildner #define INTR_RATE_LWM                   10000
505229aec1cSSascha Wildner 
506229aec1cSSascha Wildner #define OCE_MAX_EQD 128u
507229aec1cSSascha Wildner #define OCE_MIN_EQD 50u
508229aec1cSSascha Wildner 
509229aec1cSSascha Wildner struct oce_set_eqd {
510229aec1cSSascha Wildner 	uint32_t eq_id;
511229aec1cSSascha Wildner 	uint32_t phase;
512229aec1cSSascha Wildner 	uint32_t delay_multiplier;
513229aec1cSSascha Wildner };
514229aec1cSSascha Wildner 
515229aec1cSSascha Wildner struct oce_aic_obj {             /* Adaptive interrupt coalescing (AIC) info */
516229aec1cSSascha Wildner 	boolean_t enable;
517229aec1cSSascha Wildner 	uint32_t  min_eqd;            /* in usecs */
518229aec1cSSascha Wildner 	uint32_t  max_eqd;            /* in usecs */
519229aec1cSSascha Wildner 	uint32_t  cur_eqd;            /* in usecs */
520229aec1cSSascha Wildner 	uint32_t  et_eqd;             /* configured value when aic is off */
521229aec1cSSascha Wildner 	uint64_t  ticks;
522229aec1cSSascha Wildner 	uint64_t  intr_prev;
523229aec1cSSascha Wildner };
524229aec1cSSascha Wildner 
525229aec1cSSascha Wildner #define MAX_LOCK_DESC_LEN			32
526229aec1cSSascha Wildner struct oce_lock {
527229aec1cSSascha Wildner 	struct lock lock;
528229aec1cSSascha Wildner 	char name[MAX_LOCK_DESC_LEN+1];
529229aec1cSSascha Wildner };
530229aec1cSSascha Wildner #define OCE_LOCK				struct oce_lock
531229aec1cSSascha Wildner 
532229aec1cSSascha Wildner #define LOCK_CREATE(ocelock, desc) 		{ \
533229aec1cSSascha Wildner 	strncpy((ocelock)->name, (desc), MAX_LOCK_DESC_LEN); \
534229aec1cSSascha Wildner 	(ocelock)->name[MAX_LOCK_DESC_LEN] = '\0'; \
535229aec1cSSascha Wildner 	lockinit(&(ocelock)->lock, (ocelock)->name, 0, LK_CANRECURSE); \
536229aec1cSSascha Wildner }
537229aec1cSSascha Wildner #define LOCK_DESTROY(ocelock) 			\
538229aec1cSSascha Wildner 		/* if (mtx_initialized(&(lock)->mutex))	*/ \
539229aec1cSSascha Wildner 			lockuninit(&(ocelock)->lock)
540229aec1cSSascha Wildner #define LOCK(ocelock)				lockmgr(&(ocelock)->lock, LK_EXCLUSIVE)
541229aec1cSSascha Wildner #define LOCKED(ocelock)				lockowned(&(ocelock)->lock)
542229aec1cSSascha Wildner #define UNLOCK(ocelock)				lockmgr(&(ocelock)->lock, LK_RELEASE)
543229aec1cSSascha Wildner 
544229aec1cSSascha Wildner #define	DEFAULT_MQ_MBOX_TIMEOUT			(5 * 1000 * 1000)
545229aec1cSSascha Wildner #define	MBX_READY_TIMEOUT			(1 * 1000 * 1000)
546229aec1cSSascha Wildner #define	DEFAULT_DRAIN_TIME			200
547229aec1cSSascha Wildner #define	MBX_TIMEOUT_SEC				5
548229aec1cSSascha Wildner #define	STAT_TIMEOUT				2000000
549229aec1cSSascha Wildner 
550229aec1cSSascha Wildner /* size of the packet descriptor array in a transmit queue */
551229aec1cSSascha Wildner #define OCE_TX_RING_SIZE			2048
552229aec1cSSascha Wildner #define OCE_RX_RING_SIZE			1024
553229aec1cSSascha Wildner #define OCE_WQ_PACKET_ARRAY_SIZE		(OCE_TX_RING_SIZE/2)
554229aec1cSSascha Wildner #define OCE_RQ_PACKET_ARRAY_SIZE		(OCE_RX_RING_SIZE)
555229aec1cSSascha Wildner 
556229aec1cSSascha Wildner struct oce_dev;
557229aec1cSSascha Wildner 
558229aec1cSSascha Wildner enum eq_len {
559229aec1cSSascha Wildner 	EQ_LEN_256  = 256,
560229aec1cSSascha Wildner 	EQ_LEN_512  = 512,
561229aec1cSSascha Wildner 	EQ_LEN_1024 = 1024,
562229aec1cSSascha Wildner 	EQ_LEN_2048 = 2048,
563229aec1cSSascha Wildner 	EQ_LEN_4096 = 4096
564229aec1cSSascha Wildner };
565229aec1cSSascha Wildner 
566229aec1cSSascha Wildner enum eqe_size {
567229aec1cSSascha Wildner 	EQE_SIZE_4  = 4,
568229aec1cSSascha Wildner 	EQE_SIZE_16 = 16
569229aec1cSSascha Wildner };
570229aec1cSSascha Wildner 
571229aec1cSSascha Wildner enum qtype {
572229aec1cSSascha Wildner 	QTYPE_EQ,
573229aec1cSSascha Wildner 	QTYPE_MQ,
574229aec1cSSascha Wildner 	QTYPE_WQ,
575229aec1cSSascha Wildner 	QTYPE_RQ,
576229aec1cSSascha Wildner 	QTYPE_CQ,
577229aec1cSSascha Wildner 	QTYPE_RSS
578229aec1cSSascha Wildner };
579229aec1cSSascha Wildner 
580229aec1cSSascha Wildner typedef enum qstate_e {
581229aec1cSSascha Wildner 	QDELETED = 0x0,
582229aec1cSSascha Wildner 	QCREATED = 0x1
583229aec1cSSascha Wildner } qstate_t;
584229aec1cSSascha Wildner 
585229aec1cSSascha Wildner struct eq_config {
586229aec1cSSascha Wildner 	enum eq_len q_len;
587229aec1cSSascha Wildner 	enum eqe_size item_size;
588229aec1cSSascha Wildner 	uint32_t q_vector_num;
589229aec1cSSascha Wildner 	uint8_t min_eqd;
590229aec1cSSascha Wildner 	uint8_t max_eqd;
591229aec1cSSascha Wildner 	uint8_t cur_eqd;
592229aec1cSSascha Wildner 	uint8_t pad;
593229aec1cSSascha Wildner };
594229aec1cSSascha Wildner 
595229aec1cSSascha Wildner struct oce_eq {
596229aec1cSSascha Wildner 	uint32_t eq_id;
597229aec1cSSascha Wildner 	void *parent;
598229aec1cSSascha Wildner 	void *cb_context;
599229aec1cSSascha Wildner 	oce_ring_buffer_t *ring;
600229aec1cSSascha Wildner 	uint32_t ref_count;
601229aec1cSSascha Wildner 	qstate_t qstate;
602229aec1cSSascha Wildner 	struct oce_cq *cq[OCE_MAX_CQ_EQ];
603229aec1cSSascha Wildner 	int cq_valid;
604229aec1cSSascha Wildner 	struct eq_config eq_cfg;
605229aec1cSSascha Wildner 	int vector;
606229aec1cSSascha Wildner 	uint64_t intr;
607229aec1cSSascha Wildner };
608229aec1cSSascha Wildner 
609229aec1cSSascha Wildner enum cq_len {
610229aec1cSSascha Wildner 	CQ_LEN_256  = 256,
611229aec1cSSascha Wildner 	CQ_LEN_512  = 512,
612229aec1cSSascha Wildner 	CQ_LEN_1024 = 1024
613229aec1cSSascha Wildner };
614229aec1cSSascha Wildner 
615229aec1cSSascha Wildner struct cq_config {
616229aec1cSSascha Wildner 	enum cq_len q_len;
617229aec1cSSascha Wildner 	uint32_t item_size;
618229aec1cSSascha Wildner 	boolean_t is_eventable;
619229aec1cSSascha Wildner 	boolean_t sol_eventable;
620229aec1cSSascha Wildner 	boolean_t nodelay;
621229aec1cSSascha Wildner 	uint16_t dma_coalescing;
622229aec1cSSascha Wildner };
623229aec1cSSascha Wildner 
624229aec1cSSascha Wildner typedef uint16_t(*cq_handler_t) (void *arg1);
625229aec1cSSascha Wildner 
626229aec1cSSascha Wildner struct oce_cq {
627229aec1cSSascha Wildner 	uint32_t cq_id;
628229aec1cSSascha Wildner 	void *parent;
629229aec1cSSascha Wildner 	struct oce_eq *eq;
630229aec1cSSascha Wildner 	cq_handler_t cq_handler;
631229aec1cSSascha Wildner 	void *cb_arg;
632229aec1cSSascha Wildner 	oce_ring_buffer_t *ring;
633229aec1cSSascha Wildner 	qstate_t qstate;
634229aec1cSSascha Wildner 	struct cq_config cq_cfg;
635229aec1cSSascha Wildner 	uint32_t ref_count;
636229aec1cSSascha Wildner };
637229aec1cSSascha Wildner 
638229aec1cSSascha Wildner 
639229aec1cSSascha Wildner struct mq_config {
640229aec1cSSascha Wildner 	uint32_t eqd;
641229aec1cSSascha Wildner 	uint8_t q_len;
642229aec1cSSascha Wildner 	uint8_t pad[3];
643229aec1cSSascha Wildner };
644229aec1cSSascha Wildner 
645229aec1cSSascha Wildner 
646229aec1cSSascha Wildner struct oce_mq {
647229aec1cSSascha Wildner 	void *parent;
648229aec1cSSascha Wildner 	oce_ring_buffer_t *ring;
649229aec1cSSascha Wildner 	uint32_t mq_id;
650229aec1cSSascha Wildner 	struct oce_cq *cq;
651229aec1cSSascha Wildner 	struct oce_cq *async_cq;
652229aec1cSSascha Wildner 	uint32_t mq_free;
653229aec1cSSascha Wildner 	qstate_t qstate;
654229aec1cSSascha Wildner 	struct mq_config cfg;
655229aec1cSSascha Wildner };
656229aec1cSSascha Wildner 
657229aec1cSSascha Wildner struct oce_mbx_ctx {
658229aec1cSSascha Wildner 	struct oce_mbx *mbx;
659229aec1cSSascha Wildner 	void (*cb) (void *ctx);
660229aec1cSSascha Wildner 	void *cb_ctx;
661229aec1cSSascha Wildner };
662229aec1cSSascha Wildner 
663229aec1cSSascha Wildner struct wq_config {
664229aec1cSSascha Wildner 	uint8_t wq_type;
665229aec1cSSascha Wildner 	uint16_t buf_size;
666229aec1cSSascha Wildner 	uint8_t pad[1];
667229aec1cSSascha Wildner 	uint32_t q_len;
668229aec1cSSascha Wildner 	uint16_t pd_id;
669229aec1cSSascha Wildner 	uint16_t pci_fn_num;
670229aec1cSSascha Wildner 	uint32_t eqd;	/* interrupt delay */
671229aec1cSSascha Wildner 	uint32_t nbufs;
672229aec1cSSascha Wildner 	uint32_t nhdl;
673229aec1cSSascha Wildner };
674229aec1cSSascha Wildner 
675229aec1cSSascha Wildner struct oce_tx_queue_stats {
676229aec1cSSascha Wildner 	uint64_t tx_pkts;
677229aec1cSSascha Wildner 	uint64_t tx_bytes;
678229aec1cSSascha Wildner 	uint32_t tx_reqs;
679229aec1cSSascha Wildner 	uint32_t tx_stops; /* number of times TX Q was stopped */
680229aec1cSSascha Wildner 	uint32_t tx_wrbs;
681229aec1cSSascha Wildner 	uint32_t tx_compl;
682229aec1cSSascha Wildner 	uint32_t tx_rate;
683229aec1cSSascha Wildner 	uint32_t ipv6_ext_hdr_tx_drop;
684229aec1cSSascha Wildner };
685229aec1cSSascha Wildner 
686229aec1cSSascha Wildner struct oce_wq {
687229aec1cSSascha Wildner 	OCE_LOCK tx_lock;
688229aec1cSSascha Wildner 	void *parent;
689229aec1cSSascha Wildner 	oce_ring_buffer_t *ring;
690229aec1cSSascha Wildner 	struct oce_cq *cq;
691229aec1cSSascha Wildner 	bus_dma_tag_t tag;
692229aec1cSSascha Wildner 	struct oce_packet_desc pckts[OCE_WQ_PACKET_ARRAY_SIZE];
693c976b08eSSascha Wildner 	uint32_t pkt_desc_tail;
694c976b08eSSascha Wildner 	uint32_t pkt_desc_head;
695229aec1cSSascha Wildner 	uint32_t wqm_used;
696229aec1cSSascha Wildner 	boolean_t resched;
697229aec1cSSascha Wildner 	uint32_t wq_free;
698229aec1cSSascha Wildner 	uint32_t tx_deferd;
699229aec1cSSascha Wildner 	uint32_t pkt_drops;
700229aec1cSSascha Wildner 	qstate_t qstate;
701229aec1cSSascha Wildner 	uint16_t wq_id;
702229aec1cSSascha Wildner 	struct wq_config cfg;
703229aec1cSSascha Wildner 	int queue_index;
704229aec1cSSascha Wildner 	struct oce_tx_queue_stats tx_stats;
705229aec1cSSascha Wildner 	struct buf_ring *br;
706229aec1cSSascha Wildner 	struct task txtask;
707c976b08eSSascha Wildner 	uint32_t db_offset;
708229aec1cSSascha Wildner };
709229aec1cSSascha Wildner 
710229aec1cSSascha Wildner struct rq_config {
711229aec1cSSascha Wildner 	uint32_t q_len;
712229aec1cSSascha Wildner 	uint32_t frag_size;
713229aec1cSSascha Wildner 	uint32_t mtu;
714229aec1cSSascha Wildner 	uint32_t if_id;
715229aec1cSSascha Wildner 	uint32_t is_rss_queue;
716229aec1cSSascha Wildner 	uint32_t eqd;
717229aec1cSSascha Wildner 	uint32_t nbufs;
718229aec1cSSascha Wildner };
719229aec1cSSascha Wildner 
720229aec1cSSascha Wildner struct oce_rx_queue_stats {
721229aec1cSSascha Wildner 	uint32_t rx_post_fail;
722229aec1cSSascha Wildner 	uint32_t rx_ucast_pkts;
723229aec1cSSascha Wildner 	uint32_t rx_compl;
724229aec1cSSascha Wildner 	uint64_t rx_bytes;
725229aec1cSSascha Wildner 	uint64_t rx_bytes_prev;
726229aec1cSSascha Wildner 	uint64_t rx_pkts;
727229aec1cSSascha Wildner 	uint32_t rx_rate;
728229aec1cSSascha Wildner 	uint32_t rx_mcast_pkts;
729229aec1cSSascha Wildner 	uint32_t rxcp_err;
730229aec1cSSascha Wildner 	uint32_t rx_frags;
731229aec1cSSascha Wildner 	uint32_t prev_rx_frags;
732229aec1cSSascha Wildner 	uint32_t rx_fps;
733229aec1cSSascha Wildner };
734229aec1cSSascha Wildner 
735229aec1cSSascha Wildner 
736229aec1cSSascha Wildner struct oce_rq {
737229aec1cSSascha Wildner 	struct rq_config cfg;
738229aec1cSSascha Wildner 	uint32_t rq_id;
739229aec1cSSascha Wildner 	int queue_index;
740229aec1cSSascha Wildner 	uint32_t rss_cpuid;
741229aec1cSSascha Wildner 	void *parent;
742229aec1cSSascha Wildner 	oce_ring_buffer_t *ring;
743229aec1cSSascha Wildner 	struct oce_cq *cq;
744229aec1cSSascha Wildner 	void *pad1;
745229aec1cSSascha Wildner 	bus_dma_tag_t tag;
746229aec1cSSascha Wildner 	struct oce_packet_desc pckts[OCE_RQ_PACKET_ARRAY_SIZE];
747229aec1cSSascha Wildner 	uint32_t packets_in;
748229aec1cSSascha Wildner 	uint32_t packets_out;
749229aec1cSSascha Wildner 	uint32_t pending;
750229aec1cSSascha Wildner #ifdef notdef
751229aec1cSSascha Wildner 	struct mbuf *head;
752229aec1cSSascha Wildner 	struct mbuf *tail;
753229aec1cSSascha Wildner 	int fragsleft;
754229aec1cSSascha Wildner #endif
755229aec1cSSascha Wildner 	qstate_t qstate;
756229aec1cSSascha Wildner 	OCE_LOCK rx_lock;
757229aec1cSSascha Wildner 	struct oce_rx_queue_stats rx_stats;
758229aec1cSSascha Wildner #if 0 /* XXX swildner: LRO */
759229aec1cSSascha Wildner 	struct lro_ctrl lro;
760229aec1cSSascha Wildner 	int lro_pkts_queued;
761229aec1cSSascha Wildner #endif
762229aec1cSSascha Wildner 
763229aec1cSSascha Wildner };
764229aec1cSSascha Wildner 
765229aec1cSSascha Wildner struct link_status {
766229aec1cSSascha Wildner 	uint8_t physical_port;
767229aec1cSSascha Wildner 	uint8_t mac_duplex;
768229aec1cSSascha Wildner 	uint8_t mac_speed;
769229aec1cSSascha Wildner 	uint8_t mac_fault;
770229aec1cSSascha Wildner 	uint8_t mgmt_mac_duplex;
771229aec1cSSascha Wildner 	uint8_t mgmt_mac_speed;
772229aec1cSSascha Wildner 	uint16_t qos_link_speed;
773229aec1cSSascha Wildner 	uint32_t logical_link_status;
774229aec1cSSascha Wildner };
775229aec1cSSascha Wildner 
776229aec1cSSascha Wildner 
777229aec1cSSascha Wildner 
778229aec1cSSascha Wildner #define OCE_FLAGS_PCIX			0x00000001
779229aec1cSSascha Wildner #define OCE_FLAGS_PCIE			0x00000002
780229aec1cSSascha Wildner #define OCE_FLAGS_MSI_CAPABLE		0x00000004
781229aec1cSSascha Wildner #define OCE_FLAGS_MSIX_CAPABLE		0x00000008
782229aec1cSSascha Wildner #define OCE_FLAGS_USING_MSI		0x00000010
783229aec1cSSascha Wildner #define OCE_FLAGS_USING_MSIX		0x00000020
784229aec1cSSascha Wildner #define OCE_FLAGS_FUNCRESET_RQD		0x00000040
785229aec1cSSascha Wildner #define OCE_FLAGS_VIRTUAL_PORT		0x00000080
786229aec1cSSascha Wildner #define OCE_FLAGS_MBOX_ENDIAN_RQD	0x00000100
787229aec1cSSascha Wildner #define OCE_FLAGS_BE3			0x00000200
788229aec1cSSascha Wildner #define OCE_FLAGS_XE201			0x00000400
789229aec1cSSascha Wildner #define OCE_FLAGS_BE2			0x00000800
790c976b08eSSascha Wildner #define OCE_FLAGS_SH			0x00001000
791229aec1cSSascha Wildner 
792229aec1cSSascha Wildner #define OCE_DEV_BE2_CFG_BAR		1
793229aec1cSSascha Wildner #define OCE_DEV_CFG_BAR			0
794229aec1cSSascha Wildner #define OCE_PCI_CSR_BAR			2
795229aec1cSSascha Wildner #define OCE_PCI_DB_BAR			4
796229aec1cSSascha Wildner 
797229aec1cSSascha Wildner typedef struct oce_softc {
798229aec1cSSascha Wildner 	device_t dev;
799229aec1cSSascha Wildner 	OCE_LOCK dev_lock;
800229aec1cSSascha Wildner 
801229aec1cSSascha Wildner 	uint32_t flags;
802229aec1cSSascha Wildner 
803229aec1cSSascha Wildner 	uint32_t pcie_link_speed;
804229aec1cSSascha Wildner 	uint32_t pcie_link_width;
805229aec1cSSascha Wildner 
806229aec1cSSascha Wildner 	uint8_t fn; /* PCI function number */
807229aec1cSSascha Wildner 
808229aec1cSSascha Wildner 	struct resource *devcfg_res;
809229aec1cSSascha Wildner 	bus_space_tag_t devcfg_btag;
810229aec1cSSascha Wildner 	bus_space_handle_t devcfg_bhandle;
811229aec1cSSascha Wildner 	void *devcfg_vhandle;
812229aec1cSSascha Wildner 
813229aec1cSSascha Wildner 	struct resource *csr_res;
814229aec1cSSascha Wildner 	bus_space_tag_t csr_btag;
815229aec1cSSascha Wildner 	bus_space_handle_t csr_bhandle;
816229aec1cSSascha Wildner 	void *csr_vhandle;
817229aec1cSSascha Wildner 
818229aec1cSSascha Wildner 	struct resource *db_res;
819229aec1cSSascha Wildner 	bus_space_tag_t db_btag;
820229aec1cSSascha Wildner 	bus_space_handle_t db_bhandle;
821229aec1cSSascha Wildner 	void *db_vhandle;
822229aec1cSSascha Wildner 
823229aec1cSSascha Wildner 	OCE_INTR_INFO intrs[OCE_MAX_EQ];
824229aec1cSSascha Wildner 	int intr_count;
825229aec1cSSascha Wildner 
826229aec1cSSascha Wildner 	struct ifnet *ifp;
827229aec1cSSascha Wildner 
828229aec1cSSascha Wildner 	struct ifmedia media;
829229aec1cSSascha Wildner 	uint8_t link_status;
830229aec1cSSascha Wildner 	uint8_t link_speed;
831229aec1cSSascha Wildner 	uint8_t duplex;
832229aec1cSSascha Wildner 	uint32_t qos_link_speed;
833229aec1cSSascha Wildner 	uint32_t speed;
834229aec1cSSascha Wildner 
835229aec1cSSascha Wildner 	char fw_version[32];
836229aec1cSSascha Wildner 	struct mac_address_format macaddr;
837229aec1cSSascha Wildner 
838229aec1cSSascha Wildner 	OCE_DMA_MEM bsmbx;
839229aec1cSSascha Wildner 	OCE_LOCK bmbx_lock;
840229aec1cSSascha Wildner 
841229aec1cSSascha Wildner 	uint32_t config_number;
842229aec1cSSascha Wildner 	uint32_t asic_revision;
843229aec1cSSascha Wildner 	uint32_t port_id;
844229aec1cSSascha Wildner 	uint32_t function_mode;
845229aec1cSSascha Wildner 	uint32_t function_caps;
846229aec1cSSascha Wildner 	uint32_t max_tx_rings;
847229aec1cSSascha Wildner 	uint32_t max_rx_rings;
848229aec1cSSascha Wildner 
849229aec1cSSascha Wildner 	struct oce_wq *wq[OCE_MAX_WQ];	/* TX work queues */
850229aec1cSSascha Wildner 	struct oce_rq *rq[OCE_MAX_RQ];	/* RX work queues */
851229aec1cSSascha Wildner 	struct oce_cq *cq[OCE_MAX_CQ];	/* Completion queues */
852229aec1cSSascha Wildner 	struct oce_eq *eq[OCE_MAX_EQ];	/* Event queues */
853229aec1cSSascha Wildner 	struct oce_mq *mq;		/* Mailbox queue */
854229aec1cSSascha Wildner 
855229aec1cSSascha Wildner 	uint32_t neqs;
856229aec1cSSascha Wildner 	uint32_t ncqs;
857229aec1cSSascha Wildner 	uint32_t nrqs;
858229aec1cSSascha Wildner 	uint32_t nwqs;
859c976b08eSSascha Wildner 	uint32_t nrssqs;
860229aec1cSSascha Wildner 
861229aec1cSSascha Wildner 	uint32_t tx_ring_size;
862229aec1cSSascha Wildner 	uint32_t rx_ring_size;
863229aec1cSSascha Wildner 	uint32_t rq_frag_size;
864229aec1cSSascha Wildner 
865229aec1cSSascha Wildner 	uint32_t if_id;		/* interface ID */
866229aec1cSSascha Wildner 	uint32_t nifs;		/* number of adapter interfaces, 0 or 1 */
867229aec1cSSascha Wildner 	uint32_t pmac_id;	/* PMAC id */
868229aec1cSSascha Wildner 
869229aec1cSSascha Wildner 	uint32_t if_cap_flags;
870229aec1cSSascha Wildner 
871229aec1cSSascha Wildner 	uint32_t flow_control;
872229aec1cSSascha Wildner 	uint32_t promisc;
873229aec1cSSascha Wildner 
874229aec1cSSascha Wildner 	struct oce_aic_obj aic_obj[OCE_MAX_EQ];
875229aec1cSSascha Wildner 
876229aec1cSSascha Wildner 	/*Vlan Filtering related */
877229aec1cSSascha Wildner 	eventhandler_tag vlan_attach;
878229aec1cSSascha Wildner 	eventhandler_tag vlan_detach;
879229aec1cSSascha Wildner 	uint16_t vlans_added;
880229aec1cSSascha Wildner 	uint8_t vlan_tag[MAX_VLANS];
881229aec1cSSascha Wildner 	/*stats */
882229aec1cSSascha Wildner 	OCE_DMA_MEM stats_mem;
883229aec1cSSascha Wildner 	struct oce_drv_stats oce_stats_info;
884229aec1cSSascha Wildner 	struct callout  timer;
885229aec1cSSascha Wildner 	int8_t be3_native;
886229aec1cSSascha Wildner 	uint16_t qnq_debug_event;
887229aec1cSSascha Wildner 	uint16_t qnqid;
888229aec1cSSascha Wildner 	uint16_t pvid;
889229aec1cSSascha Wildner 
890229aec1cSSascha Wildner } OCE_SOFTC, *POCE_SOFTC;
891229aec1cSSascha Wildner 
892229aec1cSSascha Wildner 
893229aec1cSSascha Wildner 
894229aec1cSSascha Wildner /**************************************************
895229aec1cSSascha Wildner  * BUS memory read/write macros
896229aec1cSSascha Wildner  * BE3: accesses three BAR spaces (CFG, CSR, DB)
897229aec1cSSascha Wildner  * Lancer: accesses one BAR space (CFG)
898229aec1cSSascha Wildner  **************************************************/
899c976b08eSSascha Wildner #define OCE_READ_CSR_MPU(sc, space, o) \
900229aec1cSSascha Wildner 	((IS_BE(sc)) ? (bus_space_read_4((sc)->space##_btag, \
901229aec1cSSascha Wildner 					(sc)->space##_bhandle,o)) \
902229aec1cSSascha Wildner 				: (bus_space_read_4((sc)->devcfg_btag, \
903229aec1cSSascha Wildner 					(sc)->devcfg_bhandle,o)))
904c976b08eSSascha Wildner #define OCE_READ_REG32(sc, space, o) \
905c976b08eSSascha Wildner 	((IS_BE(sc) || IS_SH(sc)) ? (bus_space_read_4((sc)->space##_btag, \
906c976b08eSSascha Wildner 					(sc)->space##_bhandle,o)) \
907c976b08eSSascha Wildner 				: (bus_space_read_4((sc)->devcfg_btag, \
908c976b08eSSascha Wildner 					(sc)->devcfg_bhandle,o)))
909229aec1cSSascha Wildner #define OCE_READ_REG16(sc, space, o) \
910c976b08eSSascha Wildner 	((IS_BE(sc) || IS_SH(sc)) ? (bus_space_read_2((sc)->space##_btag, \
911229aec1cSSascha Wildner 					(sc)->space##_bhandle,o)) \
912229aec1cSSascha Wildner 				: (bus_space_read_2((sc)->devcfg_btag, \
913229aec1cSSascha Wildner 					(sc)->devcfg_bhandle,o)))
914229aec1cSSascha Wildner #define OCE_READ_REG8(sc, space, o) \
915c976b08eSSascha Wildner 	((IS_BE(sc) || IS_SH(sc)) ? (bus_space_read_1((sc)->space##_btag, \
916229aec1cSSascha Wildner 					(sc)->space##_bhandle,o)) \
917229aec1cSSascha Wildner 				: (bus_space_read_1((sc)->devcfg_btag, \
918229aec1cSSascha Wildner 					(sc)->devcfg_bhandle,o)))
919229aec1cSSascha Wildner 
920c976b08eSSascha Wildner #define OCE_WRITE_CSR_MPU(sc, space, o, v) \
921229aec1cSSascha Wildner 	((IS_BE(sc)) ? (bus_space_write_4((sc)->space##_btag, \
922229aec1cSSascha Wildner 				       (sc)->space##_bhandle,o,v)) \
923229aec1cSSascha Wildner 				: (bus_space_write_4((sc)->devcfg_btag, \
924229aec1cSSascha Wildner 					(sc)->devcfg_bhandle,o,v)))
925c976b08eSSascha Wildner #define OCE_WRITE_REG32(sc, space, o, v) \
926c976b08eSSascha Wildner 	((IS_BE(sc) || IS_SH(sc)) ? (bus_space_write_4((sc)->space##_btag, \
927c976b08eSSascha Wildner 				       (sc)->space##_bhandle,o,v)) \
928c976b08eSSascha Wildner 				: (bus_space_write_4((sc)->devcfg_btag, \
929c976b08eSSascha Wildner 					(sc)->devcfg_bhandle,o,v)))
930229aec1cSSascha Wildner #define OCE_WRITE_REG16(sc, space, o, v) \
931c976b08eSSascha Wildner 	((IS_BE(sc) || IS_SH(sc)) ? (bus_space_write_2((sc)->space##_btag, \
932229aec1cSSascha Wildner 				       (sc)->space##_bhandle,o,v)) \
933229aec1cSSascha Wildner 				: (bus_space_write_2((sc)->devcfg_btag, \
934229aec1cSSascha Wildner 					(sc)->devcfg_bhandle,o,v)))
935229aec1cSSascha Wildner #define OCE_WRITE_REG8(sc, space, o, v) \
936c976b08eSSascha Wildner 	((IS_BE(sc) || IS_SH(sc)) ? (bus_space_write_1((sc)->space##_btag, \
937229aec1cSSascha Wildner 				       (sc)->space##_bhandle,o,v)) \
938229aec1cSSascha Wildner 				: (bus_space_write_1((sc)->devcfg_btag, \
939229aec1cSSascha Wildner 					(sc)->devcfg_bhandle,o,v)))
940229aec1cSSascha Wildner 
941229aec1cSSascha Wildner 
942229aec1cSSascha Wildner /***********************************************************
943229aec1cSSascha Wildner  * DMA memory functions
944229aec1cSSascha Wildner  ***********************************************************/
945229aec1cSSascha Wildner #define oce_dma_sync(d, f)		bus_dmamap_sync((d)->tag, (d)->map, f)
946229aec1cSSascha Wildner int oce_dma_alloc(POCE_SOFTC sc, bus_size_t size, POCE_DMA_MEM dma, int flags);
947229aec1cSSascha Wildner void oce_dma_free(POCE_SOFTC sc, POCE_DMA_MEM dma);
948229aec1cSSascha Wildner void oce_dma_map_addr(void *arg, bus_dma_segment_t * segs, int nseg, int error);
949229aec1cSSascha Wildner void oce_destroy_ring_buffer(POCE_SOFTC sc, oce_ring_buffer_t *ring);
950229aec1cSSascha Wildner oce_ring_buffer_t *oce_create_ring_buffer(POCE_SOFTC sc,
951229aec1cSSascha Wildner 					  uint32_t q_len, uint32_t num_entries);
952229aec1cSSascha Wildner /************************************************************
953229aec1cSSascha Wildner  * oce_hw_xxx functions
954229aec1cSSascha Wildner  ************************************************************/
955229aec1cSSascha Wildner int oce_clear_rx_buf(struct oce_rq *rq);
956229aec1cSSascha Wildner int oce_hw_pci_alloc(POCE_SOFTC sc);
957229aec1cSSascha Wildner int oce_hw_init(POCE_SOFTC sc);
958229aec1cSSascha Wildner int oce_hw_start(POCE_SOFTC sc);
959229aec1cSSascha Wildner int oce_create_nw_interface(POCE_SOFTC sc);
960229aec1cSSascha Wildner int oce_pci_soft_reset(POCE_SOFTC sc);
961229aec1cSSascha Wildner int oce_hw_update_multicast(POCE_SOFTC sc);
962229aec1cSSascha Wildner void oce_delete_nw_interface(POCE_SOFTC sc);
963229aec1cSSascha Wildner void oce_hw_shutdown(POCE_SOFTC sc);
964229aec1cSSascha Wildner void oce_hw_intr_enable(POCE_SOFTC sc);
965229aec1cSSascha Wildner void oce_hw_intr_disable(POCE_SOFTC sc);
966229aec1cSSascha Wildner void oce_hw_pci_free(POCE_SOFTC sc);
967229aec1cSSascha Wildner 
968229aec1cSSascha Wildner /***********************************************************
969229aec1cSSascha Wildner  * oce_queue_xxx functions
970229aec1cSSascha Wildner  ***********************************************************/
971229aec1cSSascha Wildner int oce_queue_init_all(POCE_SOFTC sc);
972229aec1cSSascha Wildner int oce_start_rq(struct oce_rq *rq);
973229aec1cSSascha Wildner int oce_start_wq(struct oce_wq *wq);
974229aec1cSSascha Wildner int oce_start_mq(struct oce_mq *mq);
975229aec1cSSascha Wildner int oce_start_rx(POCE_SOFTC sc);
976229aec1cSSascha Wildner void oce_arm_eq(POCE_SOFTC sc,
977229aec1cSSascha Wildner 		int16_t qid, int npopped, uint32_t rearm, uint32_t clearint);
978229aec1cSSascha Wildner void oce_queue_release_all(POCE_SOFTC sc);
979229aec1cSSascha Wildner void oce_arm_cq(POCE_SOFTC sc, int16_t qid, int npopped, uint32_t rearm);
980229aec1cSSascha Wildner void oce_drain_eq(struct oce_eq *eq);
981229aec1cSSascha Wildner void oce_drain_mq_cq(void *arg);
982229aec1cSSascha Wildner void oce_drain_rq_cq(struct oce_rq *rq);
983229aec1cSSascha Wildner void oce_drain_wq_cq(struct oce_wq *wq);
984229aec1cSSascha Wildner 
985229aec1cSSascha Wildner uint32_t oce_page_list(oce_ring_buffer_t *ring, struct phys_addr *pa_list);
986229aec1cSSascha Wildner 
987229aec1cSSascha Wildner /***********************************************************
988229aec1cSSascha Wildner  * cleanup  functions
989229aec1cSSascha Wildner  ***********************************************************/
990229aec1cSSascha Wildner void oce_stop_rx(POCE_SOFTC sc);
991229aec1cSSascha Wildner void oce_intr_free(POCE_SOFTC sc);
992229aec1cSSascha Wildner void oce_free_posted_rxbuf(struct oce_rq *rq);
993229aec1cSSascha Wildner #if defined(INET6) || defined(INET)
994229aec1cSSascha Wildner void oce_free_lro(POCE_SOFTC sc);
995229aec1cSSascha Wildner #endif
996229aec1cSSascha Wildner 
997229aec1cSSascha Wildner 
998229aec1cSSascha Wildner /************************************************************
999229aec1cSSascha Wildner  * Mailbox functions
1000229aec1cSSascha Wildner  ************************************************************/
1001229aec1cSSascha Wildner int oce_fw_clean(POCE_SOFTC sc);
1002229aec1cSSascha Wildner int oce_reset_fun(POCE_SOFTC sc);
1003229aec1cSSascha Wildner int oce_mbox_init(POCE_SOFTC sc);
1004229aec1cSSascha Wildner int oce_mbox_dispatch(POCE_SOFTC sc, uint32_t tmo_sec);
1005229aec1cSSascha Wildner int oce_get_fw_version(POCE_SOFTC sc);
1006229aec1cSSascha Wildner int oce_first_mcc_cmd(POCE_SOFTC sc);
1007229aec1cSSascha Wildner 
1008229aec1cSSascha Wildner int oce_read_mac_addr(POCE_SOFTC sc, uint32_t if_id, uint8_t perm,
1009229aec1cSSascha Wildner 			uint8_t type, struct mac_address_format *mac);
1010229aec1cSSascha Wildner int oce_get_fw_config(POCE_SOFTC sc);
1011229aec1cSSascha Wildner int oce_if_create(POCE_SOFTC sc, uint32_t cap_flags, uint32_t en_flags,
1012229aec1cSSascha Wildner 		uint16_t vlan_tag, uint8_t *mac_addr, uint32_t *if_id);
1013229aec1cSSascha Wildner int oce_if_del(POCE_SOFTC sc, uint32_t if_id);
1014229aec1cSSascha Wildner int oce_config_vlan(POCE_SOFTC sc, uint32_t if_id,
1015229aec1cSSascha Wildner 		struct normal_vlan *vtag_arr, uint8_t vtag_cnt,
1016229aec1cSSascha Wildner 		uint32_t untagged, uint32_t enable_promisc);
1017229aec1cSSascha Wildner int oce_set_flow_control(POCE_SOFTC sc, uint32_t flow_control);
1018229aec1cSSascha Wildner int oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss);
1019229aec1cSSascha Wildner int oce_rxf_set_promiscuous(POCE_SOFTC sc, uint32_t enable);
1020229aec1cSSascha Wildner int oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl);
1021229aec1cSSascha Wildner int oce_get_link_status(POCE_SOFTC sc, struct link_status *link);
1022229aec1cSSascha Wildner int oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem);
1023229aec1cSSascha Wildner int oce_mbox_get_nic_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem);
1024229aec1cSSascha Wildner int oce_mbox_get_pport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
1025229aec1cSSascha Wildner 				uint32_t reset_stats);
1026229aec1cSSascha Wildner int oce_mbox_get_vport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
1027229aec1cSSascha Wildner 				uint32_t req_size, uint32_t reset_stats);
1028229aec1cSSascha Wildner int oce_update_multicast(POCE_SOFTC sc, POCE_DMA_MEM pdma_mem);
1029229aec1cSSascha Wildner int oce_pass_through_mbox(POCE_SOFTC sc, POCE_DMA_MEM dma_mem, uint32_t req_size);
1030229aec1cSSascha Wildner int oce_mbox_macaddr_del(POCE_SOFTC sc, uint32_t if_id, uint32_t pmac_id);
1031229aec1cSSascha Wildner int oce_mbox_macaddr_add(POCE_SOFTC sc, uint8_t *mac_addr,
1032229aec1cSSascha Wildner 		uint32_t if_id, uint32_t *pmac_id);
1033229aec1cSSascha Wildner int oce_mbox_cmd_test_loopback(POCE_SOFTC sc, uint32_t port_num,
1034229aec1cSSascha Wildner 	uint32_t loopback_type, uint32_t pkt_size, uint32_t num_pkts,
1035229aec1cSSascha Wildner 	uint64_t pattern);
1036229aec1cSSascha Wildner 
1037229aec1cSSascha Wildner int oce_mbox_cmd_set_loopback(POCE_SOFTC sc, uint8_t port_num,
1038229aec1cSSascha Wildner 	uint8_t loopback_type, uint8_t enable);
1039229aec1cSSascha Wildner 
1040229aec1cSSascha Wildner int oce_mbox_check_native_mode(POCE_SOFTC sc);
1041229aec1cSSascha Wildner int oce_mbox_post(POCE_SOFTC sc,
1042229aec1cSSascha Wildner 		  struct oce_mbx *mbx, struct oce_mbx_ctx *mbxctx);
1043229aec1cSSascha Wildner int oce_mbox_write_flashrom(POCE_SOFTC sc, uint32_t optype,uint32_t opcode,
1044229aec1cSSascha Wildner 				POCE_DMA_MEM pdma_mem, uint32_t num_bytes);
1045229aec1cSSascha Wildner int oce_mbox_lancer_write_flashrom(POCE_SOFTC sc, uint32_t data_size,
1046229aec1cSSascha Wildner 			uint32_t data_offset,POCE_DMA_MEM pdma_mem,
1047229aec1cSSascha Wildner 			uint32_t *written_data, uint32_t *additional_status);
1048229aec1cSSascha Wildner 
1049229aec1cSSascha Wildner int oce_mbox_get_flashrom_crc(POCE_SOFTC sc, uint8_t *flash_crc,
1050229aec1cSSascha Wildner 				uint32_t offset, uint32_t optype);
1051229aec1cSSascha Wildner int oce_mbox_get_phy_info(POCE_SOFTC sc, struct oce_phy_info *phy_info);
1052229aec1cSSascha Wildner int oce_mbox_create_rq(struct oce_rq *rq);
1053229aec1cSSascha Wildner int oce_mbox_create_wq(struct oce_wq *wq);
1054229aec1cSSascha Wildner int oce_mbox_create_eq(struct oce_eq *eq);
1055229aec1cSSascha Wildner int oce_mbox_cq_create(struct oce_cq *cq, uint32_t ncoalesce,
1056229aec1cSSascha Wildner 			 uint32_t is_eventable);
1057229aec1cSSascha Wildner int oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num);
1058229aec1cSSascha Wildner void oce_mbox_eqd_modify_periodic(POCE_SOFTC sc, struct oce_set_eqd *set_eqd,
1059229aec1cSSascha Wildner 					int num);
1060c976b08eSSascha Wildner int oce_get_profile_config(POCE_SOFTC sc);
1061c976b08eSSascha Wildner int oce_get_func_config(POCE_SOFTC sc);
1062229aec1cSSascha Wildner void mbx_common_req_hdr_init(struct mbx_hdr *hdr,
1063229aec1cSSascha Wildner 			     uint8_t dom,
1064229aec1cSSascha Wildner 			     uint8_t port,
1065229aec1cSSascha Wildner 			     uint8_t subsys,
1066229aec1cSSascha Wildner 			     uint8_t opcode,
1067229aec1cSSascha Wildner 			     uint32_t timeout, uint32_t pyld_len,
1068229aec1cSSascha Wildner 			     uint8_t version);
1069229aec1cSSascha Wildner 
1070229aec1cSSascha Wildner 
1071229aec1cSSascha Wildner uint16_t oce_mq_handler(void *arg);
1072229aec1cSSascha Wildner 
1073229aec1cSSascha Wildner /************************************************************
1074229aec1cSSascha Wildner  * Transmit functions
1075229aec1cSSascha Wildner  ************************************************************/
1076229aec1cSSascha Wildner uint16_t oce_wq_handler(void *arg);
1077229aec1cSSascha Wildner void	 oce_start_locked(struct ifnet *ifp);
1078229aec1cSSascha Wildner void	 oce_start(struct ifnet *ifp, struct ifaltq_subque *ifsq);
1079229aec1cSSascha Wildner void	 oce_tx_task(void *arg, int npending);
1080229aec1cSSascha Wildner 
1081229aec1cSSascha Wildner /************************************************************
1082229aec1cSSascha Wildner  * Receive functions
1083229aec1cSSascha Wildner  ************************************************************/
1084229aec1cSSascha Wildner int	 oce_alloc_rx_bufs(struct oce_rq *rq, int count);
1085229aec1cSSascha Wildner uint16_t oce_rq_handler(void *arg);
1086229aec1cSSascha Wildner 
1087229aec1cSSascha Wildner 
1088229aec1cSSascha Wildner /* Sysctl functions */
1089229aec1cSSascha Wildner void oce_add_sysctls(POCE_SOFTC sc);
1090229aec1cSSascha Wildner void oce_refresh_queue_stats(POCE_SOFTC sc);
1091229aec1cSSascha Wildner int  oce_refresh_nic_stats(POCE_SOFTC sc);
1092229aec1cSSascha Wildner int  oce_stats_init(POCE_SOFTC sc);
1093229aec1cSSascha Wildner void oce_stats_free(POCE_SOFTC sc);
1094229aec1cSSascha Wildner 
1095229aec1cSSascha Wildner /* Capabilities */
1096229aec1cSSascha Wildner #define OCE_MODCAP_RSS			1
1097229aec1cSSascha Wildner #define OCE_MAX_RSP_HANDLED		64
1098229aec1cSSascha Wildner extern uint32_t oce_max_rsp_handled;	/* max responses */
1099229aec1cSSascha Wildner 
1100229aec1cSSascha Wildner #define OCE_MAC_LOOPBACK		0x0
1101229aec1cSSascha Wildner #define OCE_PHY_LOOPBACK		0x1
1102229aec1cSSascha Wildner #define OCE_ONE_PORT_EXT_LOOPBACK	0x2
1103229aec1cSSascha Wildner #define OCE_NO_LOOPBACK			0xff
1104229aec1cSSascha Wildner 
1105229aec1cSSascha Wildner #define atomic_inc_32(x)		atomic_add_32(x, 1)
1106229aec1cSSascha Wildner #define atomic_dec_32(x)		atomic_subtract_32(x, 1)
1107229aec1cSSascha Wildner 
1108229aec1cSSascha Wildner #define LE_64(x)			htole64(x)
1109229aec1cSSascha Wildner #define LE_32(x)			htole32(x)
1110229aec1cSSascha Wildner #define LE_16(x)			htole16(x)
1111c976b08eSSascha Wildner #define HOST_64(x)			le64toh(x)
1112c976b08eSSascha Wildner #define HOST_32(x)			le32toh(x)
1113c976b08eSSascha Wildner #define HOST_16(x)			le16toh(x)
1114229aec1cSSascha Wildner #define DW_SWAP(x, l)
1115229aec1cSSascha Wildner #define IS_ALIGNED(x,a)			((x % a) == 0)
1116229aec1cSSascha Wildner #define ADDR_HI(x)			((uint32_t)((uint64_t)(x) >> 32))
1117229aec1cSSascha Wildner #define ADDR_LO(x)			((uint32_t)((uint64_t)(x) & 0xffffffff));
1118229aec1cSSascha Wildner 
1119229aec1cSSascha Wildner #define IF_LRO_ENABLED(sc)  (((sc)->ifp->if_capenable & IFCAP_LRO) ? 1:0)
1120229aec1cSSascha Wildner #define IF_LSO_ENABLED(sc)  (((sc)->ifp->if_capenable & IFCAP_TSO4) ? 1:0)
1121229aec1cSSascha Wildner #define IF_CSUM_ENABLED(sc) (((sc)->ifp->if_capenable & IFCAP_HWCSUM) ? 1:0)
1122229aec1cSSascha Wildner 
1123229aec1cSSascha Wildner #define OCE_LOG2(x) 			(oce_highbit(x))
oce_highbit(uint32_t x)1124229aec1cSSascha Wildner static inline uint32_t oce_highbit(uint32_t x)
1125229aec1cSSascha Wildner {
1126229aec1cSSascha Wildner 	int i;
1127229aec1cSSascha Wildner 	int c;
1128229aec1cSSascha Wildner 	int b;
1129229aec1cSSascha Wildner 
1130229aec1cSSascha Wildner 	c = 0;
1131229aec1cSSascha Wildner 	b = 0;
1132229aec1cSSascha Wildner 
1133229aec1cSSascha Wildner 	for (i = 0; i < 32; i++) {
1134229aec1cSSascha Wildner 		if ((1 << i) & x) {
1135229aec1cSSascha Wildner 			c++;
1136229aec1cSSascha Wildner 			b = i;
1137229aec1cSSascha Wildner 		}
1138229aec1cSSascha Wildner 	}
1139229aec1cSSascha Wildner 
1140229aec1cSSascha Wildner 	if (c == 1)
1141229aec1cSSascha Wildner 		return b;
1142229aec1cSSascha Wildner 
1143229aec1cSSascha Wildner 	return 0;
1144229aec1cSSascha Wildner }
1145229aec1cSSascha Wildner 
MPU_EP_SEMAPHORE(POCE_SOFTC sc)1146c976b08eSSascha Wildner static inline int MPU_EP_SEMAPHORE(POCE_SOFTC sc)
1147c976b08eSSascha Wildner {
1148c976b08eSSascha Wildner 	if (IS_BE(sc))
1149c976b08eSSascha Wildner 		return MPU_EP_SEMAPHORE_BE3;
1150c976b08eSSascha Wildner 	else if (IS_SH(sc))
1151c976b08eSSascha Wildner 		return MPU_EP_SEMAPHORE_SH;
1152c976b08eSSascha Wildner 	else
1153c976b08eSSascha Wildner 		return MPU_EP_SEMAPHORE_XE201;
1154c976b08eSSascha Wildner }
1155c976b08eSSascha Wildner 
1156229aec1cSSascha Wildner #define TRANSCEIVER_DATA_NUM_ELE 64
1157229aec1cSSascha Wildner #define TRANSCEIVER_DATA_SIZE 256
1158229aec1cSSascha Wildner #define TRANSCEIVER_A0_SIZE 128
1159229aec1cSSascha Wildner #define TRANSCEIVER_A2_SIZE 128
1160229aec1cSSascha Wildner #define PAGE_NUM_A0 0xa0
1161229aec1cSSascha Wildner #define PAGE_NUM_A2 0xa2
1162229aec1cSSascha Wildner #define IS_QNQ_OR_UMC(sc) ((sc->pvid && (sc->function_mode & FNM_UMC_MODE ))\
1163229aec1cSSascha Wildner 		     || (sc->qnqid && (sc->function_mode & FNM_FLEX10_MODE)))
1164