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