1/*	$OpenBSD: if_oce.c,v 1.109 2024/05/24 06:02:56 jsg Exp $	*/
2
3/*
4 * Copyright (c) 2012 Mike Belopuhov
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/*-
20 * Copyright (C) 2012 Emulex
21 * All rights reserved.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions are met:
25 *
26 * 1. Redistributions of source code must retain the above copyright notice,
27 *    this list of conditions and the following disclaimer.
28 *
29 * 2. Redistributions in binary form must reproduce the above copyright
30 *    notice, this list of conditions and the following disclaimer in the
31 *    documentation and/or other materials provided with the distribution.
32 *
33 * 3. Neither the name of the Emulex Corporation nor the names of its
34 *    contributors may be used to endorse or promote products derived from
35 *    this software without specific prior written permission.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
38 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
41 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
44 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
45 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
47 * POSSIBILITY OF SUCH DAMAGE.
48 *
49 * Contact Information:
50 * freebsd-drivers@emulex.com
51 *
52 * Emulex
53 * 3333 Susan Street
54 * Costa Mesa, CA 92626
55 */
56
57#include "bpfilter.h"
58#include "vlan.h"
59
60#include <sys/param.h>
61#include <sys/systm.h>
62#include <sys/sockio.h>
63#include <sys/mbuf.h>
64#include <sys/malloc.h>
65#include <sys/device.h>
66#include <sys/socket.h>
67#include <sys/queue.h>
68#include <sys/timeout.h>
69#include <sys/pool.h>
70
71#include <net/if.h>
72#include <net/if_media.h>
73
74#include <netinet/in.h>
75#include <netinet/if_ether.h>
76
77#if NBPFILTER > 0
78#include <net/bpf.h>
79#endif
80
81#include <dev/pci/pcireg.h>
82#include <dev/pci/pcivar.h>
83#include <dev/pci/pcidevs.h>
84
85#include <dev/pci/if_ocereg.h>
86
87#ifndef TRUE
88#define TRUE			1
89#endif
90#ifndef FALSE
91#define FALSE			0
92#endif
93
94#define OCE_MBX_TIMEOUT		5
95
96#define OCE_MAX_PAYLOAD		65536
97
98#define OCE_TX_RING_SIZE	512
99#define OCE_RX_RING_SIZE	1024
100
101/* This should be powers of 2. Like 2,4,8 & 16 */
102#define OCE_MAX_RSS		4 /* TODO: 8 */
103#define OCE_MAX_RQ		OCE_MAX_RSS + 1 /* one default queue */
104#define OCE_MAX_WQ		8
105
106#define OCE_MAX_EQ		32
107#define OCE_MAX_CQ		OCE_MAX_RQ + OCE_MAX_WQ + 1 /* one MCC queue */
108#define OCE_MAX_CQ_EQ		8 /* Max CQ that can attached to an EQ */
109
110#define OCE_DEFAULT_EQD		80
111
112#define OCE_MIN_MTU		256
113#define OCE_MAX_MTU		9000
114
115#define OCE_MAX_RQ_COMPL	64
116#define OCE_MAX_RQ_POSTS	255
117#define OCE_RX_BUF_SIZE		2048
118
119#define OCE_MAX_TX_ELEMENTS	29
120#define OCE_MAX_TX_DESC		1024
121#define OCE_MAX_TX_SIZE		65535
122
123#define OCE_MEM_KVA(_m)		((void *)((_m)->vaddr))
124#define OCE_MEM_DVA(_m)		((_m)->paddr)
125
126#define OCE_WQ_FOREACH(sc, wq, i) 	\
127	for (i = 0, wq = sc->sc_wq[0]; i < sc->sc_nwq; i++, wq = sc->sc_wq[i])
128#define OCE_RQ_FOREACH(sc, rq, i) 	\
129	for (i = 0, rq = sc->sc_rq[0]; i < sc->sc_nrq; i++, rq = sc->sc_rq[i])
130#define OCE_EQ_FOREACH(sc, eq, i) 	\
131	for (i = 0, eq = sc->sc_eq[0]; i < sc->sc_neq; i++, eq = sc->sc_eq[i])
132#define OCE_CQ_FOREACH(sc, cq, i) 	\
133	for (i = 0, cq = sc->sc_cq[0]; i < sc->sc_ncq; i++, cq = sc->sc_cq[i])
134#define OCE_RING_FOREACH(_r, _v, _c)	\
135	for ((_v) = oce_ring_first(_r); _c; (_v) = oce_ring_next(_r))
136
137static inline int
138ilog2(unsigned int v)
139{
140	int r = 0;
141
142	while (v >>= 1)
143		r++;
144	return (r);
145}
146
147struct oce_pkt {
148	struct mbuf *		mbuf;
149	bus_dmamap_t		map;
150	int			nsegs;
151	SIMPLEQ_ENTRY(oce_pkt)	entry;
152};
153SIMPLEQ_HEAD(oce_pkt_list, oce_pkt);
154
155struct oce_dma_mem {
156	bus_dma_tag_t		tag;
157	bus_dmamap_t		map;
158	bus_dma_segment_t	segs;
159	int			nsegs;
160	bus_size_t		size;
161	caddr_t			vaddr;
162	bus_addr_t		paddr;
163};
164
165struct oce_ring {
166	int			index;
167	int			nitems;
168	int			nused;
169	int			isize;
170	struct oce_dma_mem	dma;
171};
172
173struct oce_softc;
174
175enum cq_len {
176	CQ_LEN_256  = 256,
177	CQ_LEN_512  = 512,
178	CQ_LEN_1024 = 1024
179};
180
181enum eq_len {
182	EQ_LEN_256  = 256,
183	EQ_LEN_512  = 512,
184	EQ_LEN_1024 = 1024,
185	EQ_LEN_2048 = 2048,
186	EQ_LEN_4096 = 4096
187};
188
189enum eqe_size {
190	EQE_SIZE_4  = 4,
191	EQE_SIZE_16 = 16
192};
193
194enum qtype {
195	QTYPE_EQ,
196	QTYPE_MQ,
197	QTYPE_WQ,
198	QTYPE_RQ,
199	QTYPE_CQ,
200	QTYPE_RSS
201};
202
203struct oce_eq {
204	struct oce_softc *	sc;
205	struct oce_ring *	ring;
206	enum qtype		type;
207	int			id;
208
209	struct oce_cq *		cq[OCE_MAX_CQ_EQ];
210	int			cq_valid;
211
212	int			nitems;
213	int			isize;
214	int			delay;
215};
216
217struct oce_cq {
218	struct oce_softc *	sc;
219	struct oce_ring *	ring;
220	enum qtype		type;
221	int			id;
222
223	struct oce_eq *		eq;
224
225	void			(*cq_intr)(void *);
226	void *			cb_arg;
227
228	int			nitems;
229	int			nodelay;
230	int			eventable;
231	int			ncoalesce;
232};
233
234struct oce_mq {
235	struct oce_softc *	sc;
236	struct oce_ring *	ring;
237	enum qtype		type;
238	int			id;
239
240	struct oce_cq *		cq;
241
242	int			nitems;
243};
244
245struct oce_wq {
246	struct oce_softc *	sc;
247	struct oce_ring *	ring;
248	enum qtype		type;
249	int			id;
250
251	struct oce_cq *		cq;
252
253	struct oce_pkt_list	pkt_list;
254	struct oce_pkt_list	pkt_free;
255
256	int			nitems;
257};
258
259struct oce_rq {
260	struct oce_softc *	sc;
261	struct oce_ring *	ring;
262	enum qtype		type;
263	int			id;
264
265	struct oce_cq *		cq;
266
267	struct if_rxring	rxring;
268	struct oce_pkt_list	pkt_list;
269	struct oce_pkt_list	pkt_free;
270
271	uint32_t		rss_cpuid;
272
273#ifdef OCE_LRO
274	struct lro_ctrl		lro;
275	int			lro_pkts_queued;
276#endif
277
278	int			nitems;
279	int			fragsize;
280	int			mtu;
281	int			rss;
282};
283
284struct oce_softc {
285	struct device		sc_dev;
286
287	uint			sc_flags;
288#define  OCE_F_BE2		 0x00000001
289#define  OCE_F_BE3		 0x00000002
290#define  OCE_F_XE201		 0x00000008
291#define  OCE_F_BE3_NATIVE	 0x00000100
292#define  OCE_F_RESET_RQD	 0x00001000
293#define  OCE_F_MBOX_ENDIAN_RQD	 0x00002000
294
295	bus_dma_tag_t		sc_dmat;
296
297	bus_space_tag_t		sc_cfg_iot;
298	bus_space_handle_t	sc_cfg_ioh;
299	bus_size_t		sc_cfg_size;
300
301	bus_space_tag_t		sc_csr_iot;
302	bus_space_handle_t	sc_csr_ioh;
303	bus_size_t		sc_csr_size;
304
305	bus_space_tag_t		sc_db_iot;
306	bus_space_handle_t	sc_db_ioh;
307	bus_size_t		sc_db_size;
308
309	void *			sc_ih;
310
311	struct arpcom		sc_ac;
312	struct ifmedia		sc_media;
313	ushort			sc_link_up;
314	ushort			sc_link_speed;
315	uint64_t		sc_fc;
316
317	struct oce_dma_mem	sc_mbx;
318	struct oce_dma_mem	sc_pld;
319
320	uint			sc_port;
321	uint			sc_fmode;
322
323	struct oce_wq *		sc_wq[OCE_MAX_WQ];	/* TX work queues */
324	struct oce_rq *		sc_rq[OCE_MAX_RQ];	/* RX work queues */
325	struct oce_cq *		sc_cq[OCE_MAX_CQ];	/* Completion queues */
326	struct oce_eq *		sc_eq[OCE_MAX_EQ];	/* Event queues */
327	struct oce_mq *		sc_mq;			/* Mailbox queue */
328
329	ushort			sc_neq;
330	ushort			sc_ncq;
331	ushort			sc_nrq;
332	ushort			sc_nwq;
333	ushort			sc_nintr;
334
335	ushort			sc_tx_ring_size;
336	ushort			sc_rx_ring_size;
337	ushort			sc_rss_enable;
338
339	uint32_t		sc_if_id;	/* interface ID */
340	uint32_t		sc_pmac_id;	/* PMAC id */
341	char			sc_macaddr[ETHER_ADDR_LEN];
342
343	uint32_t		sc_pvid;
344
345	uint64_t		sc_rx_errors;
346	uint64_t		sc_tx_errors;
347
348	struct timeout		sc_tick;
349	struct timeout		sc_rxrefill;
350
351	void *			sc_statcmd;
352};
353
354#define IS_BE(sc)		ISSET((sc)->sc_flags, OCE_F_BE2 | OCE_F_BE3)
355#define IS_XE201(sc)		ISSET((sc)->sc_flags, OCE_F_XE201)
356
357#define ADDR_HI(x)		((uint32_t)((uint64_t)(x) >> 32))
358#define ADDR_LO(x)		((uint32_t)((uint64_t)(x) & 0xffffffff))
359
360#define IF_LRO_ENABLED(ifp)	ISSET((ifp)->if_capabilities, IFCAP_LRO)
361
362int 	oce_match(struct device *, void *, void *);
363void	oce_attach(struct device *, struct device *, void *);
364int 	oce_pci_alloc(struct oce_softc *, struct pci_attach_args *);
365void	oce_attachhook(struct device *);
366void	oce_attach_ifp(struct oce_softc *);
367int 	oce_ioctl(struct ifnet *, u_long, caddr_t);
368int	oce_rxrinfo(struct oce_softc *, struct if_rxrinfo *);
369void	oce_iff(struct oce_softc *);
370void	oce_link_status(struct oce_softc *);
371void	oce_media_status(struct ifnet *, struct ifmediareq *);
372int 	oce_media_change(struct ifnet *);
373void	oce_tick(void *);
374void	oce_init(void *);
375void	oce_stop(struct oce_softc *);
376void	oce_watchdog(struct ifnet *);
377void	oce_start(struct ifnet *);
378int	oce_encap(struct oce_softc *, struct mbuf **, int wqidx);
379#ifdef OCE_TSO
380struct mbuf *
381	oce_tso(struct oce_softc *, struct mbuf **);
382#endif
383int 	oce_intr(void *);
384void	oce_intr_wq(void *);
385void	oce_txeof(struct oce_wq *);
386void	oce_intr_rq(void *);
387void	oce_rxeof(struct oce_rq *, struct oce_nic_rx_cqe *);
388void	oce_rxeoc(struct oce_rq *, struct oce_nic_rx_cqe *);
389int 	oce_vtp_valid(struct oce_softc *, struct oce_nic_rx_cqe *);
390int 	oce_port_valid(struct oce_softc *, struct oce_nic_rx_cqe *);
391#ifdef OCE_LRO
392void	oce_flush_lro(struct oce_rq *);
393int 	oce_init_lro(struct oce_softc *);
394void	oce_free_lro(struct oce_softc *);
395#endif
396int	oce_get_buf(struct oce_rq *);
397int	oce_alloc_rx_bufs(struct oce_rq *);
398void	oce_refill_rx(void *);
399void	oce_free_posted_rxbuf(struct oce_rq *);
400void	oce_intr_mq(void *);
401void	oce_link_event(struct oce_softc *,
402	    struct oce_async_cqe_link_state *);
403
404int 	oce_init_queues(struct oce_softc *);
405void	oce_release_queues(struct oce_softc *);
406struct oce_wq *oce_create_wq(struct oce_softc *, struct oce_eq *);
407void	oce_drain_wq(struct oce_wq *);
408void	oce_destroy_wq(struct oce_wq *);
409struct oce_rq *
410	oce_create_rq(struct oce_softc *, struct oce_eq *, int rss);
411void	oce_drain_rq(struct oce_rq *);
412void	oce_destroy_rq(struct oce_rq *);
413struct oce_eq *
414	oce_create_eq(struct oce_softc *);
415static inline void
416	oce_arm_eq(struct oce_eq *, int neqe, int rearm, int clearint);
417void	oce_drain_eq(struct oce_eq *);
418void	oce_destroy_eq(struct oce_eq *);
419struct oce_mq *
420	oce_create_mq(struct oce_softc *, struct oce_eq *);
421void	oce_drain_mq(struct oce_mq *);
422void	oce_destroy_mq(struct oce_mq *);
423struct oce_cq *
424	oce_create_cq(struct oce_softc *, struct oce_eq *, int nitems,
425	    int isize, int eventable, int nodelay, int ncoalesce);
426static inline void
427	oce_arm_cq(struct oce_cq *, int ncqe, int rearm);
428void	oce_destroy_cq(struct oce_cq *);
429
430int	oce_dma_alloc(struct oce_softc *, bus_size_t, struct oce_dma_mem *);
431void	oce_dma_free(struct oce_softc *, struct oce_dma_mem *);
432#define	oce_dma_sync(d, f) \
433	    bus_dmamap_sync((d)->tag, (d)->map, 0, (d)->map->dm_mapsize, f)
434
435struct oce_ring *
436	oce_create_ring(struct oce_softc *, int nitems, int isize, int maxseg);
437void	oce_destroy_ring(struct oce_softc *, struct oce_ring *);
438int	oce_load_ring(struct oce_softc *, struct oce_ring *,
439	    struct oce_pa *, int max_segs);
440static inline void *
441	oce_ring_get(struct oce_ring *);
442static inline void *
443	oce_ring_first(struct oce_ring *);
444static inline void *
445	oce_ring_next(struct oce_ring *);
446struct oce_pkt *
447	oce_pkt_alloc(struct oce_softc *, size_t size, int nsegs,
448	    int maxsegsz);
449void	oce_pkt_free(struct oce_softc *, struct oce_pkt *);
450static inline struct oce_pkt *
451	oce_pkt_get(struct oce_pkt_list *);
452static inline void
453	oce_pkt_put(struct oce_pkt_list *, struct oce_pkt *);
454
455int	oce_init_fw(struct oce_softc *);
456int	oce_mbox_init(struct oce_softc *);
457int	oce_mbox_dispatch(struct oce_softc *);
458int	oce_cmd(struct oce_softc *, int subsys, int opcode, int version,
459	    void *payload, int length);
460void	oce_first_mcc(struct oce_softc *);
461
462int	oce_get_fw_config(struct oce_softc *);
463int	oce_check_native_mode(struct oce_softc *);
464int	oce_create_iface(struct oce_softc *, uint8_t *macaddr);
465int	oce_config_vlan(struct oce_softc *, struct normal_vlan *vtags,
466	    int nvtags, int untagged, int promisc);
467int	oce_set_flow_control(struct oce_softc *, uint64_t);
468int	oce_config_rss(struct oce_softc *, int enable);
469int	oce_update_mcast(struct oce_softc *, uint8_t multi[][ETHER_ADDR_LEN],
470	    int naddr);
471int	oce_set_promisc(struct oce_softc *, int enable);
472int	oce_get_link_status(struct oce_softc *);
473
474void	oce_macaddr_set(struct oce_softc *);
475int	oce_macaddr_get(struct oce_softc *, uint8_t *macaddr);
476int	oce_macaddr_add(struct oce_softc *, uint8_t *macaddr, uint32_t *pmac);
477int	oce_macaddr_del(struct oce_softc *, uint32_t pmac);
478
479int	oce_new_rq(struct oce_softc *, struct oce_rq *);
480int	oce_new_wq(struct oce_softc *, struct oce_wq *);
481int	oce_new_mq(struct oce_softc *, struct oce_mq *);
482int	oce_new_eq(struct oce_softc *, struct oce_eq *);
483int	oce_new_cq(struct oce_softc *, struct oce_cq *);
484
485int	oce_init_stats(struct oce_softc *);
486int	oce_update_stats(struct oce_softc *);
487int	oce_stats_be2(struct oce_softc *, uint64_t *, uint64_t *);
488int	oce_stats_be3(struct oce_softc *, uint64_t *, uint64_t *);
489int	oce_stats_xe(struct oce_softc *, uint64_t *, uint64_t *);
490
491struct pool *oce_pkt_pool;
492
493struct cfdriver oce_cd = {
494	NULL, "oce", DV_IFNET
495};
496
497const struct cfattach oce_ca = {
498	sizeof(struct oce_softc), oce_match, oce_attach, NULL, NULL
499};
500
501const struct pci_matchid oce_devices[] = {
502	{ PCI_VENDOR_SERVERENGINES, PCI_PRODUCT_SERVERENGINES_BE2 },
503	{ PCI_VENDOR_SERVERENGINES, PCI_PRODUCT_SERVERENGINES_BE3 },
504	{ PCI_VENDOR_SERVERENGINES, PCI_PRODUCT_SERVERENGINES_OCBE2 },
505	{ PCI_VENDOR_SERVERENGINES, PCI_PRODUCT_SERVERENGINES_OCBE3 },
506	{ PCI_VENDOR_EMULEX, PCI_PRODUCT_EMULEX_XE201 },
507};
508
509int
510oce_match(struct device *parent, void *match, void *aux)
511{
512	return (pci_matchbyid(aux, oce_devices, nitems(oce_devices)));
513}
514
515void
516oce_attach(struct device *parent, struct device *self, void *aux)
517{
518	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
519	struct oce_softc *sc = (struct oce_softc *)self;
520	const char *intrstr = NULL;
521	pci_intr_handle_t ih;
522
523	switch (PCI_PRODUCT(pa->pa_id)) {
524	case PCI_PRODUCT_SERVERENGINES_BE2:
525	case PCI_PRODUCT_SERVERENGINES_OCBE2:
526		SET(sc->sc_flags, OCE_F_BE2);
527		break;
528	case PCI_PRODUCT_SERVERENGINES_BE3:
529	case PCI_PRODUCT_SERVERENGINES_OCBE3:
530		SET(sc->sc_flags, OCE_F_BE3);
531		break;
532	case PCI_PRODUCT_EMULEX_XE201:
533		SET(sc->sc_flags, OCE_F_XE201);
534		break;
535	}
536
537	sc->sc_dmat = pa->pa_dmat;
538	if (oce_pci_alloc(sc, pa))
539		return;
540
541	sc->sc_tx_ring_size = OCE_TX_RING_SIZE;
542	sc->sc_rx_ring_size = OCE_RX_RING_SIZE;
543
544	/* create the bootstrap mailbox */
545	if (oce_dma_alloc(sc, sizeof(struct oce_bmbx), &sc->sc_mbx)) {
546		printf(": failed to allocate mailbox memory\n");
547		return;
548	}
549	if (oce_dma_alloc(sc, OCE_MAX_PAYLOAD, &sc->sc_pld)) {
550		printf(": failed to allocate payload memory\n");
551		goto fail_1;
552	}
553
554	if (oce_init_fw(sc))
555		goto fail_2;
556
557	if (oce_mbox_init(sc)) {
558		printf(": failed to initialize mailbox\n");
559		goto fail_2;
560	}
561
562	if (oce_get_fw_config(sc)) {
563		printf(": failed to get firmware configuration\n");
564		goto fail_2;
565	}
566
567	if (ISSET(sc->sc_flags, OCE_F_BE3)) {
568		if (oce_check_native_mode(sc))
569			goto fail_2;
570	}
571
572	if (oce_macaddr_get(sc, sc->sc_macaddr)) {
573		printf(": failed to fetch MAC address\n");
574		goto fail_2;
575	}
576	memcpy(sc->sc_ac.ac_enaddr, sc->sc_macaddr, ETHER_ADDR_LEN);
577
578	if (oce_pkt_pool == NULL) {
579		oce_pkt_pool = malloc(sizeof(struct pool), M_DEVBUF, M_NOWAIT);
580		if (oce_pkt_pool == NULL) {
581			printf(": unable to allocate descriptor pool\n");
582			goto fail_2;
583		}
584		pool_init(oce_pkt_pool, sizeof(struct oce_pkt), 0, IPL_NET,
585		    0, "ocepkts", NULL);
586	}
587
588	/* We allocate a single interrupt resource */
589	sc->sc_nintr = 1;
590	if (pci_intr_map_msi(pa, &ih) != 0 &&
591	    pci_intr_map(pa, &ih) != 0) {
592		printf(": couldn't map interrupt\n");
593		goto fail_2;
594	}
595
596	intrstr = pci_intr_string(pa->pa_pc, ih);
597	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, oce_intr, sc,
598	    sc->sc_dev.dv_xname);
599	if (sc->sc_ih == NULL) {
600		printf(": couldn't establish interrupt\n");
601		if (intrstr != NULL)
602			printf(" at %s", intrstr);
603		printf("\n");
604		goto fail_2;
605	}
606	printf(": %s", intrstr);
607
608	if (oce_init_stats(sc))
609		goto fail_3;
610
611	if (oce_init_queues(sc))
612		goto fail_3;
613
614	oce_attach_ifp(sc);
615
616#ifdef OCE_LRO
617	if (oce_init_lro(sc))
618		goto fail_4;
619#endif
620
621	timeout_set(&sc->sc_tick, oce_tick, sc);
622	timeout_set(&sc->sc_rxrefill, oce_refill_rx, sc);
623
624	config_mountroot(self, oce_attachhook);
625
626	printf(", address %s\n", ether_sprintf(sc->sc_ac.ac_enaddr));
627
628	return;
629
630#ifdef OCE_LRO
631fail_4:
632	oce_free_lro(sc);
633	ether_ifdetach(&sc->sc_ac.ac_if);
634	if_detach(&sc->sc_ac.ac_if);
635	oce_release_queues(sc);
636#endif
637fail_3:
638	pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
639fail_2:
640	oce_dma_free(sc, &sc->sc_pld);
641fail_1:
642	oce_dma_free(sc, &sc->sc_mbx);
643}
644
645int
646oce_pci_alloc(struct oce_softc *sc, struct pci_attach_args *pa)
647{
648	pcireg_t memtype, reg;
649
650	/* setup the device config region */
651	if (ISSET(sc->sc_flags, OCE_F_BE2))
652		reg = OCE_BAR_CFG_BE2;
653	else
654		reg = OCE_BAR_CFG;
655
656	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg);
657	if (pci_mapreg_map(pa, reg, memtype, 0, &sc->sc_cfg_iot,
658	    &sc->sc_cfg_ioh, NULL, &sc->sc_cfg_size,
659	    IS_BE(sc) ? 0 : 32768)) {
660		printf(": can't find cfg mem space\n");
661		return (ENXIO);
662	}
663
664	/*
665	 * Read the SLI_INTF register and determine whether we
666	 * can use this port and its features
667	 */
668	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, OCE_INTF_REG_OFFSET);
669	if (OCE_SLI_SIGNATURE(reg) != OCE_INTF_VALID_SIG) {
670		printf(": invalid signature\n");
671		goto fail_1;
672	}
673	if (OCE_SLI_REVISION(reg) != OCE_INTF_SLI_REV4) {
674		printf(": unsupported SLI revision\n");
675		goto fail_1;
676	}
677	if (OCE_SLI_IFTYPE(reg) == OCE_INTF_IF_TYPE_1)
678		SET(sc->sc_flags, OCE_F_MBOX_ENDIAN_RQD);
679	if (OCE_SLI_HINT1(reg) == OCE_INTF_FUNC_RESET_REQD)
680		SET(sc->sc_flags, OCE_F_RESET_RQD);
681
682	/* Lancer has one BAR (CFG) but BE3 has three (CFG, CSR, DB) */
683	if (IS_BE(sc)) {
684		/* set up CSR region */
685		reg = OCE_BAR_CSR;
686		memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg);
687		if (pci_mapreg_map(pa, reg, memtype, 0, &sc->sc_csr_iot,
688		    &sc->sc_csr_ioh, NULL, &sc->sc_csr_size, 0)) {
689			printf(": can't find csr mem space\n");
690			goto fail_1;
691		}
692
693		/* set up DB doorbell region */
694		reg = OCE_BAR_DB;
695		memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg);
696		if (pci_mapreg_map(pa, reg, memtype, 0, &sc->sc_db_iot,
697		    &sc->sc_db_ioh, NULL, &sc->sc_db_size, 0)) {
698			printf(": can't find csr mem space\n");
699			goto fail_2;
700		}
701	} else {
702		sc->sc_csr_iot = sc->sc_db_iot = sc->sc_cfg_iot;
703		sc->sc_csr_ioh = sc->sc_db_ioh = sc->sc_cfg_ioh;
704	}
705
706	return (0);
707
708fail_2:
709	bus_space_unmap(sc->sc_csr_iot, sc->sc_csr_ioh, sc->sc_csr_size);
710fail_1:
711	bus_space_unmap(sc->sc_cfg_iot, sc->sc_cfg_ioh, sc->sc_cfg_size);
712	return (ENXIO);
713}
714
715static inline uint32_t
716oce_read_cfg(struct oce_softc *sc, bus_size_t off)
717{
718	bus_space_barrier(sc->sc_cfg_iot, sc->sc_cfg_ioh, off, 4,
719	    BUS_SPACE_BARRIER_READ);
720	return (bus_space_read_4(sc->sc_cfg_iot, sc->sc_cfg_ioh, off));
721}
722
723static inline uint32_t
724oce_read_csr(struct oce_softc *sc, bus_size_t off)
725{
726	bus_space_barrier(sc->sc_csr_iot, sc->sc_csr_ioh, off, 4,
727	    BUS_SPACE_BARRIER_READ);
728	return (bus_space_read_4(sc->sc_csr_iot, sc->sc_csr_ioh, off));
729}
730
731static inline uint32_t
732oce_read_db(struct oce_softc *sc, bus_size_t off)
733{
734	bus_space_barrier(sc->sc_db_iot, sc->sc_db_ioh, off, 4,
735	    BUS_SPACE_BARRIER_READ);
736	return (bus_space_read_4(sc->sc_db_iot, sc->sc_db_ioh, off));
737}
738
739static inline void
740oce_write_cfg(struct oce_softc *sc, bus_size_t off, uint32_t val)
741{
742	bus_space_write_4(sc->sc_cfg_iot, sc->sc_cfg_ioh, off, val);
743	bus_space_barrier(sc->sc_cfg_iot, sc->sc_cfg_ioh, off, 4,
744	    BUS_SPACE_BARRIER_WRITE);
745}
746
747static inline void
748oce_write_csr(struct oce_softc *sc, bus_size_t off, uint32_t val)
749{
750	bus_space_write_4(sc->sc_csr_iot, sc->sc_csr_ioh, off, val);
751	bus_space_barrier(sc->sc_csr_iot, sc->sc_csr_ioh, off, 4,
752	    BUS_SPACE_BARRIER_WRITE);
753}
754
755static inline void
756oce_write_db(struct oce_softc *sc, bus_size_t off, uint32_t val)
757{
758	bus_space_write_4(sc->sc_db_iot, sc->sc_db_ioh, off, val);
759	bus_space_barrier(sc->sc_db_iot, sc->sc_db_ioh, off, 4,
760	    BUS_SPACE_BARRIER_WRITE);
761}
762
763static inline void
764oce_intr_enable(struct oce_softc *sc)
765{
766	uint32_t reg;
767
768	reg = oce_read_cfg(sc, PCI_INTR_CTRL);
769	oce_write_cfg(sc, PCI_INTR_CTRL, reg | HOSTINTR_MASK);
770}
771
772static inline void
773oce_intr_disable(struct oce_softc *sc)
774{
775	uint32_t reg;
776
777	reg = oce_read_cfg(sc, PCI_INTR_CTRL);
778	oce_write_cfg(sc, PCI_INTR_CTRL, reg & ~HOSTINTR_MASK);
779}
780
781void
782oce_attachhook(struct device *self)
783{
784	struct oce_softc *sc = (struct oce_softc *)self;
785
786	oce_get_link_status(sc);
787
788	oce_arm_cq(sc->sc_mq->cq, 0, TRUE);
789
790	/*
791	 * We need to get MCC async events. So enable intrs and arm
792	 * first EQ, Other EQs will be armed after interface is UP
793	 */
794	oce_intr_enable(sc);
795	oce_arm_eq(sc->sc_eq[0], 0, TRUE, FALSE);
796
797	/*
798	 * Send first mcc cmd and after that we get gracious
799	 * MCC notifications from FW
800	 */
801	oce_first_mcc(sc);
802}
803
804void
805oce_attach_ifp(struct oce_softc *sc)
806{
807	struct ifnet *ifp = &sc->sc_ac.ac_if;
808
809	ifmedia_init(&sc->sc_media, IFM_IMASK, oce_media_change,
810	    oce_media_status);
811	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
812	ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
813
814	strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
815	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
816	ifp->if_ioctl = oce_ioctl;
817	ifp->if_start = oce_start;
818	ifp->if_watchdog = oce_watchdog;
819	ifp->if_hardmtu = OCE_MAX_MTU;
820	ifp->if_softc = sc;
821	ifq_init_maxlen(&ifp->if_snd, sc->sc_tx_ring_size - 1);
822
823	ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_CSUM_IPv4 |
824	    IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
825
826#if NVLAN > 0
827	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
828#endif
829
830#ifdef OCE_TSO
831	ifp->if_capabilities |= IFCAP_TSO;
832	ifp->if_capabilities |= IFCAP_VLAN_HWTSO;
833#endif
834#ifdef OCE_LRO
835	ifp->if_capabilities |= IFCAP_LRO;
836#endif
837
838	if_attach(ifp);
839	ether_ifattach(ifp);
840}
841
842int
843oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
844{
845	struct oce_softc *sc = ifp->if_softc;
846	struct ifreq *ifr = (struct ifreq *)data;
847	int s, error = 0;
848
849	s = splnet();
850
851	switch (command) {
852	case SIOCSIFADDR:
853		ifp->if_flags |= IFF_UP;
854		if (!(ifp->if_flags & IFF_RUNNING))
855			oce_init(sc);
856		break;
857	case SIOCSIFFLAGS:
858		if (ifp->if_flags & IFF_UP) {
859			if (ifp->if_flags & IFF_RUNNING)
860				error = ENETRESET;
861			else
862				oce_init(sc);
863		} else {
864			if (ifp->if_flags & IFF_RUNNING)
865				oce_stop(sc);
866		}
867		break;
868	case SIOCGIFMEDIA:
869	case SIOCSIFMEDIA:
870		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command);
871		break;
872	case SIOCGIFRXR:
873		error = oce_rxrinfo(sc, (struct if_rxrinfo *)ifr->ifr_data);
874		break;
875	default:
876		error = ether_ioctl(ifp, &sc->sc_ac, command, data);
877		break;
878	}
879
880	if (error == ENETRESET) {
881		if (ifp->if_flags & IFF_RUNNING)
882			oce_iff(sc);
883		error = 0;
884	}
885
886	splx(s);
887
888	return (error);
889}
890
891int
892oce_rxrinfo(struct oce_softc *sc, struct if_rxrinfo *ifri)
893{
894	struct if_rxring_info *ifr, ifr1;
895	struct oce_rq *rq;
896	int error, i;
897	u_int n = 0;
898
899	if (sc->sc_nrq > 1) {
900		ifr = mallocarray(sc->sc_nrq, sizeof(*ifr), M_DEVBUF,
901		    M_WAITOK | M_ZERO);
902	} else
903		ifr = &ifr1;
904
905	OCE_RQ_FOREACH(sc, rq, i) {
906		ifr[n].ifr_size = MCLBYTES;
907		snprintf(ifr[n].ifr_name, sizeof(ifr[n].ifr_name), "/%d", i);
908		ifr[n].ifr_info = rq->rxring;
909		n++;
910	}
911
912	error = if_rxr_info_ioctl(ifri, sc->sc_nrq, ifr);
913
914	if (sc->sc_nrq > 1)
915		free(ifr, M_DEVBUF, sc->sc_nrq * sizeof(*ifr));
916	return (error);
917}
918
919
920void
921oce_iff(struct oce_softc *sc)
922{
923	uint8_t multi[OCE_MAX_MC_FILTER_SIZE][ETHER_ADDR_LEN];
924	struct arpcom *ac = &sc->sc_ac;
925	struct ifnet *ifp = &ac->ac_if;
926	struct ether_multi *enm;
927	struct ether_multistep step;
928	int naddr = 0, promisc = 0;
929
930	ifp->if_flags &= ~IFF_ALLMULTI;
931
932	if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0 ||
933	    ac->ac_multicnt >= OCE_MAX_MC_FILTER_SIZE) {
934		ifp->if_flags |= IFF_ALLMULTI;
935		promisc = 1;
936	} else {
937		ETHER_FIRST_MULTI(step, &sc->sc_ac, enm);
938		while (enm != NULL) {
939			memcpy(multi[naddr++], enm->enm_addrlo, ETHER_ADDR_LEN);
940			ETHER_NEXT_MULTI(step, enm);
941		}
942		oce_update_mcast(sc, multi, naddr);
943	}
944
945	oce_set_promisc(sc, promisc);
946}
947
948void
949oce_link_status(struct oce_softc *sc)
950{
951	struct ifnet *ifp = &sc->sc_ac.ac_if;
952	int link_state = LINK_STATE_DOWN;
953
954	ifp->if_baudrate = 0;
955	if (sc->sc_link_up) {
956		link_state = LINK_STATE_FULL_DUPLEX;
957
958		switch (sc->sc_link_speed) {
959		case 1:
960			ifp->if_baudrate = IF_Mbps(10);
961			break;
962		case 2:
963			ifp->if_baudrate = IF_Mbps(100);
964			break;
965		case 3:
966			ifp->if_baudrate = IF_Gbps(1);
967			break;
968		case 4:
969			ifp->if_baudrate = IF_Gbps(10);
970			break;
971		}
972	}
973	if (ifp->if_link_state != link_state) {
974		ifp->if_link_state = link_state;
975		if_link_state_change(ifp);
976	}
977}
978
979void
980oce_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
981{
982	struct oce_softc *sc = ifp->if_softc;
983
984	ifmr->ifm_status = IFM_AVALID;
985	ifmr->ifm_active = IFM_ETHER;
986
987	if (oce_get_link_status(sc) == 0)
988		oce_link_status(sc);
989
990	if (!sc->sc_link_up) {
991		ifmr->ifm_active |= IFM_NONE;
992		return;
993	}
994
995	ifmr->ifm_status |= IFM_ACTIVE;
996
997	switch (sc->sc_link_speed) {
998	case 1: /* 10 Mbps */
999		ifmr->ifm_active |= IFM_10_T | IFM_FDX;
1000		break;
1001	case 2: /* 100 Mbps */
1002		ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
1003		break;
1004	case 3: /* 1 Gbps */
1005		ifmr->ifm_active |= IFM_1000_T | IFM_FDX;
1006		break;
1007	case 4: /* 10 Gbps */
1008		ifmr->ifm_active |= IFM_10G_SR | IFM_FDX;
1009		break;
1010	}
1011
1012	if (sc->sc_fc & IFM_ETH_RXPAUSE)
1013		ifmr->ifm_active |= IFM_FLOW | IFM_ETH_RXPAUSE;
1014	if (sc->sc_fc & IFM_ETH_TXPAUSE)
1015		ifmr->ifm_active |= IFM_FLOW | IFM_ETH_TXPAUSE;
1016}
1017
1018int
1019oce_media_change(struct ifnet *ifp)
1020{
1021	return (0);
1022}
1023
1024void
1025oce_tick(void *arg)
1026{
1027	struct oce_softc *sc = arg;
1028	int s;
1029
1030	s = splnet();
1031
1032	if (oce_update_stats(sc) == 0)
1033		timeout_add_sec(&sc->sc_tick, 1);
1034
1035	splx(s);
1036}
1037
1038void
1039oce_init(void *arg)
1040{
1041	struct oce_softc *sc = arg;
1042	struct ifnet *ifp = &sc->sc_ac.ac_if;
1043	struct oce_eq *eq;
1044	struct oce_rq *rq;
1045	struct oce_wq *wq;
1046	int i;
1047
1048	oce_stop(sc);
1049
1050	DELAY(10);
1051
1052	oce_macaddr_set(sc);
1053
1054	oce_iff(sc);
1055
1056	/* Enable VLAN promiscuous mode */
1057	if (oce_config_vlan(sc, NULL, 0, 1, 1))
1058		goto error;
1059
1060	if (oce_set_flow_control(sc, IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE))
1061		goto error;
1062
1063	OCE_RQ_FOREACH(sc, rq, i) {
1064		rq->mtu = ifp->if_hardmtu + ETHER_HDR_LEN + ETHER_CRC_LEN +
1065		    ETHER_VLAN_ENCAP_LEN;
1066		if (oce_new_rq(sc, rq)) {
1067			printf("%s: failed to create rq\n",
1068			    sc->sc_dev.dv_xname);
1069			goto error;
1070		}
1071		rq->ring->index	 = 0;
1072
1073		/* oce splits jumbos into 2k chunks... */
1074		if_rxr_init(&rq->rxring, 8, rq->nitems);
1075
1076		if (!oce_alloc_rx_bufs(rq)) {
1077			printf("%s: failed to allocate rx buffers\n",
1078			    sc->sc_dev.dv_xname);
1079			goto error;
1080		}
1081	}
1082
1083#ifdef OCE_RSS
1084	/* RSS config */
1085	if (sc->sc_rss_enable) {
1086		if (oce_config_rss(sc, (uint8_t)sc->sc_if_id, 1)) {
1087			printf("%s: failed to configure RSS\n",
1088			    sc->sc_dev.dv_xname);
1089			goto error;
1090		}
1091	}
1092#endif
1093
1094	OCE_RQ_FOREACH(sc, rq, i)
1095		oce_arm_cq(rq->cq, 0, TRUE);
1096
1097	OCE_WQ_FOREACH(sc, wq, i)
1098		oce_arm_cq(wq->cq, 0, TRUE);
1099
1100	oce_arm_cq(sc->sc_mq->cq, 0, TRUE);
1101
1102	OCE_EQ_FOREACH(sc, eq, i)
1103		oce_arm_eq(eq, 0, TRUE, FALSE);
1104
1105	if (oce_get_link_status(sc) == 0)
1106		oce_link_status(sc);
1107
1108	ifp->if_flags |= IFF_RUNNING;
1109	ifq_clr_oactive(&ifp->if_snd);
1110
1111	timeout_add_sec(&sc->sc_tick, 1);
1112
1113	oce_intr_enable(sc);
1114
1115	return;
1116error:
1117	oce_stop(sc);
1118}
1119
1120void
1121oce_stop(struct oce_softc *sc)
1122{
1123	struct mbx_delete_nic_rq cmd;
1124	struct ifnet *ifp = &sc->sc_ac.ac_if;
1125	struct oce_rq *rq;
1126	struct oce_wq *wq;
1127	struct oce_eq *eq;
1128	int i;
1129
1130	timeout_del(&sc->sc_tick);
1131	timeout_del(&sc->sc_rxrefill);
1132
1133	ifp->if_flags &= ~IFF_RUNNING;
1134	ifq_clr_oactive(&ifp->if_snd);
1135
1136	/* Stop intrs and finish any bottom halves pending */
1137	oce_intr_disable(sc);
1138
1139	/* Invalidate any pending cq and eq entries */
1140	OCE_EQ_FOREACH(sc, eq, i)
1141		oce_drain_eq(eq);
1142	OCE_RQ_FOREACH(sc, rq, i) {
1143		/* destroy the work queue in the firmware */
1144		memset(&cmd, 0, sizeof(cmd));
1145		cmd.params.req.rq_id = htole16(rq->id);
1146		oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_DELETE_RQ,
1147		    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
1148		DELAY(1000);
1149		oce_drain_rq(rq);
1150		oce_free_posted_rxbuf(rq);
1151	}
1152	OCE_WQ_FOREACH(sc, wq, i)
1153		oce_drain_wq(wq);
1154}
1155
1156void
1157oce_watchdog(struct ifnet *ifp)
1158{
1159	printf("%s: watchdog timeout -- resetting\n", ifp->if_xname);
1160
1161	oce_init(ifp->if_softc);
1162
1163	ifp->if_oerrors++;
1164}
1165
1166void
1167oce_start(struct ifnet *ifp)
1168{
1169	struct oce_softc *sc = ifp->if_softc;
1170	struct mbuf *m;
1171	int pkts = 0;
1172
1173	if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
1174		return;
1175
1176	for (;;) {
1177		m = ifq_dequeue(&ifp->if_snd);
1178		if (m == NULL)
1179			break;
1180
1181		if (oce_encap(sc, &m, 0)) {
1182			ifq_set_oactive(&ifp->if_snd);
1183			break;
1184		}
1185
1186#if NBPFILTER > 0
1187		if (ifp->if_bpf)
1188			bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT);
1189#endif
1190		pkts++;
1191	}
1192
1193	/* Set a timeout in case the chip goes out to lunch */
1194	if (pkts)
1195		ifp->if_timer = 5;
1196}
1197
1198int
1199oce_encap(struct oce_softc *sc, struct mbuf **mpp, int wqidx)
1200{
1201	struct mbuf *m = *mpp;
1202	struct oce_wq *wq = sc->sc_wq[wqidx];
1203	struct oce_pkt *pkt = NULL;
1204	struct oce_nic_hdr_wqe *nhe;
1205	struct oce_nic_frag_wqe *nfe;
1206	int i, nwqe, err;
1207
1208#ifdef OCE_TSO
1209	if (m->m_pkthdr.csum_flags & CSUM_TSO) {
1210		/* consolidate packet buffers for TSO/LSO segment offload */
1211		m = oce_tso(sc, mpp);
1212		if (m == NULL)
1213			goto error;
1214	}
1215#endif
1216
1217	if ((pkt = oce_pkt_get(&wq->pkt_free)) == NULL)
1218		goto error;
1219
1220	err = bus_dmamap_load_mbuf(sc->sc_dmat, pkt->map, m, BUS_DMA_NOWAIT);
1221	if (err == EFBIG) {
1222		if (m_defrag(m, M_DONTWAIT) ||
1223		    bus_dmamap_load_mbuf(sc->sc_dmat, pkt->map, m,
1224			BUS_DMA_NOWAIT))
1225			goto error;
1226		*mpp = m;
1227	} else if (err != 0)
1228		goto error;
1229
1230	pkt->nsegs = pkt->map->dm_nsegs;
1231
1232	nwqe = pkt->nsegs + 1;
1233	if (IS_BE(sc)) {
1234		/* BE2 and BE3 require even number of WQEs */
1235		if (nwqe & 1)
1236			nwqe++;
1237	}
1238
1239	/* Fail if there's not enough free WQEs */
1240	if (nwqe >= wq->ring->nitems - wq->ring->nused) {
1241		bus_dmamap_unload(sc->sc_dmat, pkt->map);
1242		goto error;
1243	}
1244
1245	bus_dmamap_sync(sc->sc_dmat, pkt->map, 0, pkt->map->dm_mapsize,
1246	    BUS_DMASYNC_PREWRITE);
1247	pkt->mbuf = m;
1248
1249	/* TX work queue entry for the header */
1250	nhe = oce_ring_get(wq->ring);
1251	memset(nhe, 0, sizeof(*nhe));
1252
1253	nhe->u0.s.complete = 1;
1254	nhe->u0.s.event = 1;
1255	nhe->u0.s.crc = 1;
1256	nhe->u0.s.forward = 0;
1257	nhe->u0.s.ipcs = (m->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT) ? 1 : 0;
1258	nhe->u0.s.udpcs = (m->m_pkthdr.csum_flags & M_UDP_CSUM_OUT) ? 1 : 0;
1259	nhe->u0.s.tcpcs = (m->m_pkthdr.csum_flags & M_TCP_CSUM_OUT) ? 1 : 0;
1260	nhe->u0.s.num_wqe = nwqe;
1261	nhe->u0.s.total_length = m->m_pkthdr.len;
1262
1263#if NVLAN > 0
1264	if (m->m_flags & M_VLANTAG) {
1265		nhe->u0.s.vlan = 1; /* Vlan present */
1266		nhe->u0.s.vlan_tag = m->m_pkthdr.ether_vtag;
1267	}
1268#endif
1269
1270#ifdef OCE_TSO
1271	if (m->m_pkthdr.csum_flags & CSUM_TSO) {
1272		if (m->m_pkthdr.tso_segsz) {
1273			nhe->u0.s.lso = 1;
1274			nhe->u0.s.lso_mss  = m->m_pkthdr.tso_segsz;
1275		}
1276		if (!IS_BE(sc))
1277			nhe->u0.s.ipcs = 1;
1278	}
1279#endif
1280
1281	oce_dma_sync(&wq->ring->dma, BUS_DMASYNC_PREREAD |
1282	    BUS_DMASYNC_PREWRITE);
1283
1284	wq->ring->nused++;
1285
1286	/* TX work queue entries for data chunks */
1287	for (i = 0; i < pkt->nsegs; i++) {
1288		nfe = oce_ring_get(wq->ring);
1289		memset(nfe, 0, sizeof(*nfe));
1290		nfe->u0.s.frag_pa_hi = ADDR_HI(pkt->map->dm_segs[i].ds_addr);
1291		nfe->u0.s.frag_pa_lo = ADDR_LO(pkt->map->dm_segs[i].ds_addr);
1292		nfe->u0.s.frag_len = pkt->map->dm_segs[i].ds_len;
1293		wq->ring->nused++;
1294	}
1295	if (nwqe > (pkt->nsegs + 1)) {
1296		nfe = oce_ring_get(wq->ring);
1297		memset(nfe, 0, sizeof(*nfe));
1298		wq->ring->nused++;
1299		pkt->nsegs++;
1300	}
1301
1302	oce_pkt_put(&wq->pkt_list, pkt);
1303
1304	oce_dma_sync(&wq->ring->dma, BUS_DMASYNC_POSTREAD |
1305	    BUS_DMASYNC_POSTWRITE);
1306
1307	oce_write_db(sc, PD_TXULP_DB, wq->id | (nwqe << 16));
1308
1309	return (0);
1310
1311error:
1312	if (pkt)
1313		oce_pkt_put(&wq->pkt_free, pkt);
1314	m_freem(*mpp);
1315	*mpp = NULL;
1316	return (1);
1317}
1318
1319#ifdef OCE_TSO
1320struct mbuf *
1321oce_tso(struct oce_softc *sc, struct mbuf **mpp)
1322{
1323	struct mbuf *m;
1324	struct ip *ip;
1325#ifdef INET6
1326	struct ip6_hdr *ip6;
1327#endif
1328	struct ether_vlan_header *eh;
1329	struct tcphdr *th;
1330	uint16_t etype;
1331	int total_len = 0, ehdrlen = 0;
1332
1333	m = *mpp;
1334
1335	if (M_WRITABLE(m) == 0) {
1336		m = m_dup(*mpp, M_DONTWAIT);
1337		if (!m)
1338			return (NULL);
1339		m_freem(*mpp);
1340		*mpp = m;
1341	}
1342
1343	eh = mtod(m, struct ether_vlan_header *);
1344	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
1345		etype = ntohs(eh->evl_proto);
1346		ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
1347	} else {
1348		etype = ntohs(eh->evl_encap_proto);
1349		ehdrlen = ETHER_HDR_LEN;
1350	}
1351
1352	switch (etype) {
1353	case ETHERTYPE_IP:
1354		ip = (struct ip *)(m->m_data + ehdrlen);
1355		if (ip->ip_p != IPPROTO_TCP)
1356			return (NULL);
1357		th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
1358
1359		total_len = ehdrlen + (ip->ip_hl << 2) + (th->th_off << 2);
1360		break;
1361#ifdef INET6
1362	case ETHERTYPE_IPV6:
1363		ip6 = (struct ip6_hdr *)(m->m_data + ehdrlen);
1364		if (ip6->ip6_nxt != IPPROTO_TCP)
1365			return NULL;
1366		th = (struct tcphdr *)((caddr_t)ip6 + sizeof(struct ip6_hdr));
1367
1368		total_len = ehdrlen + sizeof(struct ip6_hdr) +
1369		    (th->th_off << 2);
1370		break;
1371#endif
1372	default:
1373		return (NULL);
1374	}
1375
1376	m = m_pullup(m, total_len);
1377	if (!m)
1378		return (NULL);
1379	*mpp = m;
1380	return (m);
1381
1382}
1383#endif /* OCE_TSO */
1384
1385int
1386oce_intr(void *arg)
1387{
1388	struct oce_softc *sc = arg;
1389	struct oce_eq *eq = sc->sc_eq[0];
1390	struct oce_eqe *eqe;
1391	struct oce_cq *cq = NULL;
1392	int i, neqe = 0;
1393
1394	oce_dma_sync(&eq->ring->dma, BUS_DMASYNC_POSTREAD);
1395
1396	OCE_RING_FOREACH(eq->ring, eqe, eqe->evnt != 0) {
1397		eqe->evnt = 0;
1398		neqe++;
1399	}
1400
1401	/* Spurious? */
1402	if (!neqe) {
1403		oce_arm_eq(eq, 0, TRUE, FALSE);
1404		return (0);
1405	}
1406
1407	oce_dma_sync(&eq->ring->dma, BUS_DMASYNC_PREWRITE);
1408
1409 	/* Clear EQ entries, but dont arm */
1410	oce_arm_eq(eq, neqe, FALSE, TRUE);
1411
1412	/* Process TX, RX and MCC completion queues */
1413	for (i = 0; i < eq->cq_valid; i++) {
1414		cq = eq->cq[i];
1415		(*cq->cq_intr)(cq->cb_arg);
1416		oce_arm_cq(cq, 0, TRUE);
1417	}
1418
1419	oce_arm_eq(eq, 0, TRUE, FALSE);
1420	return (1);
1421}
1422
1423/* Handle the Completion Queue for transmit */
1424void
1425oce_intr_wq(void *arg)
1426{
1427	struct oce_wq *wq = (struct oce_wq *)arg;
1428	struct oce_cq *cq = wq->cq;
1429	struct oce_nic_tx_cqe *cqe;
1430	struct oce_softc *sc = wq->sc;
1431	struct ifnet *ifp = &sc->sc_ac.ac_if;
1432	int ncqe = 0;
1433
1434	oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_POSTREAD);
1435	OCE_RING_FOREACH(cq->ring, cqe, WQ_CQE_VALID(cqe)) {
1436		oce_txeof(wq);
1437		WQ_CQE_INVALIDATE(cqe);
1438		ncqe++;
1439	}
1440	oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_PREWRITE);
1441
1442	if (ifq_is_oactive(&ifp->if_snd)) {
1443		if (wq->ring->nused < (wq->ring->nitems / 2)) {
1444			ifq_clr_oactive(&ifp->if_snd);
1445			oce_start(ifp);
1446		}
1447	}
1448	if (wq->ring->nused == 0)
1449		ifp->if_timer = 0;
1450
1451	if (ncqe)
1452		oce_arm_cq(cq, ncqe, FALSE);
1453}
1454
1455void
1456oce_txeof(struct oce_wq *wq)
1457{
1458	struct oce_softc *sc = wq->sc;
1459	struct oce_pkt *pkt;
1460	struct mbuf *m;
1461
1462	if ((pkt = oce_pkt_get(&wq->pkt_list)) == NULL) {
1463		printf("%s: missing descriptor in txeof\n",
1464		    sc->sc_dev.dv_xname);
1465		return;
1466	}
1467
1468	wq->ring->nused -= pkt->nsegs + 1;
1469	bus_dmamap_sync(sc->sc_dmat, pkt->map, 0, pkt->map->dm_mapsize,
1470	    BUS_DMASYNC_POSTWRITE);
1471	bus_dmamap_unload(sc->sc_dmat, pkt->map);
1472
1473	m = pkt->mbuf;
1474	m_freem(m);
1475	pkt->mbuf = NULL;
1476	oce_pkt_put(&wq->pkt_free, pkt);
1477}
1478
1479/* Handle the Completion Queue for receive */
1480void
1481oce_intr_rq(void *arg)
1482{
1483	struct oce_rq *rq = (struct oce_rq *)arg;
1484	struct oce_cq *cq = rq->cq;
1485	struct oce_softc *sc = rq->sc;
1486	struct oce_nic_rx_cqe *cqe;
1487	struct ifnet *ifp = &sc->sc_ac.ac_if;
1488	int maxrx, ncqe = 0;
1489
1490	maxrx = IS_XE201(sc) ? 8 : OCE_MAX_RQ_COMPL;
1491
1492	oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_POSTREAD);
1493
1494	OCE_RING_FOREACH(cq->ring, cqe, RQ_CQE_VALID(cqe) && ncqe <= maxrx) {
1495		if (cqe->u0.s.error == 0) {
1496			if (cqe->u0.s.pkt_size == 0)
1497				/* partial DMA workaround for Lancer */
1498				oce_rxeoc(rq, cqe);
1499			else
1500				oce_rxeof(rq, cqe);
1501		} else {
1502			ifp->if_ierrors++;
1503			if (IS_XE201(sc))
1504				/* Lancer A0 no buffer workaround */
1505				oce_rxeoc(rq, cqe);
1506			else
1507				/* Post L3/L4 errors to stack.*/
1508				oce_rxeof(rq, cqe);
1509		}
1510#ifdef OCE_LRO
1511		if (IF_LRO_ENABLED(ifp) && rq->lro_pkts_queued >= 16)
1512			oce_flush_lro(rq);
1513#endif
1514		RQ_CQE_INVALIDATE(cqe);
1515		ncqe++;
1516	}
1517
1518	oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_PREWRITE);
1519
1520#ifdef OCE_LRO
1521	if (IF_LRO_ENABLED(ifp))
1522		oce_flush_lro(rq);
1523#endif
1524
1525	if (ncqe) {
1526		oce_arm_cq(cq, ncqe, FALSE);
1527		if (!oce_alloc_rx_bufs(rq))
1528			timeout_add(&sc->sc_rxrefill, 1);
1529	}
1530}
1531
1532void
1533oce_rxeof(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
1534{
1535	struct oce_softc *sc = rq->sc;
1536	struct oce_pkt *pkt = NULL;
1537	struct ifnet *ifp = &sc->sc_ac.ac_if;
1538	struct mbuf_list ml = MBUF_LIST_INITIALIZER();
1539	struct mbuf *m = NULL, *tail = NULL;
1540	int i, len, frag_len;
1541	uint16_t vtag;
1542
1543	len = cqe->u0.s.pkt_size;
1544
1545	 /* Get vlan_tag value */
1546	if (IS_BE(sc))
1547		vtag = ntohs(cqe->u0.s.vlan_tag);
1548	else
1549		vtag = cqe->u0.s.vlan_tag;
1550
1551	for (i = 0; i < cqe->u0.s.num_fragments; i++) {
1552		if ((pkt = oce_pkt_get(&rq->pkt_list)) == NULL) {
1553			printf("%s: missing descriptor in rxeof\n",
1554			    sc->sc_dev.dv_xname);
1555			goto exit;
1556		}
1557
1558		bus_dmamap_sync(sc->sc_dmat, pkt->map, 0, pkt->map->dm_mapsize,
1559		    BUS_DMASYNC_POSTREAD);
1560		bus_dmamap_unload(sc->sc_dmat, pkt->map);
1561		if_rxr_put(&rq->rxring, 1);
1562
1563		frag_len = (len > rq->fragsize) ? rq->fragsize : len;
1564		pkt->mbuf->m_len = frag_len;
1565
1566		if (tail != NULL) {
1567			/* additional fragments */
1568			pkt->mbuf->m_flags &= ~M_PKTHDR;
1569			tail->m_next = pkt->mbuf;
1570			tail = pkt->mbuf;
1571		} else {
1572			/* first fragment, fill out most of the header */
1573			pkt->mbuf->m_pkthdr.len = len;
1574			pkt->mbuf->m_pkthdr.csum_flags = 0;
1575			if (cqe->u0.s.ip_cksum_pass) {
1576				if (!cqe->u0.s.ip_ver) { /* IPV4 */
1577					pkt->mbuf->m_pkthdr.csum_flags =
1578					    M_IPV4_CSUM_IN_OK;
1579				}
1580			}
1581			if (cqe->u0.s.l4_cksum_pass) {
1582				pkt->mbuf->m_pkthdr.csum_flags |=
1583				    M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK;
1584			}
1585			m = tail = pkt->mbuf;
1586		}
1587		pkt->mbuf = NULL;
1588		oce_pkt_put(&rq->pkt_free, pkt);
1589		len -= frag_len;
1590	}
1591
1592	if (m) {
1593		if (!oce_port_valid(sc, cqe)) {
1594			 m_freem(m);
1595			 goto exit;
1596		}
1597
1598#if NVLAN > 0
1599		/* This determines if vlan tag is valid */
1600		if (oce_vtp_valid(sc, cqe)) {
1601			if (sc->sc_fmode & FNM_FLEX10_MODE) {
1602				/* FLEX10. If QnQ is not set, neglect VLAN */
1603				if (cqe->u0.s.qnq) {
1604					m->m_pkthdr.ether_vtag = vtag;
1605					m->m_flags |= M_VLANTAG;
1606				}
1607			} else if (sc->sc_pvid != (vtag & VLAN_VID_MASK))  {
1608				/*
1609				 * In UMC mode generally pvid will be striped.
1610				 * But in some cases we have seen it comes
1611				 * with pvid. So if pvid == vlan, neglect vlan.
1612				 */
1613				m->m_pkthdr.ether_vtag = vtag;
1614				m->m_flags |= M_VLANTAG;
1615			}
1616		}
1617#endif
1618
1619#ifdef OCE_LRO
1620		/* Try to queue to LRO */
1621		if (IF_LRO_ENABLED(ifp) && !(m->m_flags & M_VLANTAG) &&
1622		    cqe->u0.s.ip_cksum_pass && cqe->u0.s.l4_cksum_pass &&
1623		    !cqe->u0.s.ip_ver && rq->lro.lro_cnt != 0) {
1624
1625			if (tcp_lro_rx(&rq->lro, m, 0) == 0) {
1626				rq->lro_pkts_queued ++;
1627				goto exit;
1628			}
1629			/* If LRO posting fails then try to post to STACK */
1630		}
1631#endif
1632
1633		ml_enqueue(&ml, m);
1634	}
1635exit:
1636	if (ifiq_input(&ifp->if_rcv, &ml))
1637		if_rxr_livelocked(&rq->rxring);
1638}
1639
1640void
1641oce_rxeoc(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
1642{
1643	struct oce_softc *sc = rq->sc;
1644	struct oce_pkt *pkt;
1645	int i, num_frags = cqe->u0.s.num_fragments;
1646
1647	if (IS_XE201(sc) && cqe->u0.s.error) {
1648		/*
1649		 * Lancer A0 workaround:
1650		 * num_frags will be 1 more than actual in case of error
1651		 */
1652		if (num_frags)
1653			num_frags--;
1654	}
1655	for (i = 0; i < num_frags; i++) {
1656		if ((pkt = oce_pkt_get(&rq->pkt_list)) == NULL) {
1657			printf("%s: missing descriptor in rxeoc\n",
1658			    sc->sc_dev.dv_xname);
1659			return;
1660		}
1661		bus_dmamap_sync(sc->sc_dmat, pkt->map, 0, pkt->map->dm_mapsize,
1662		    BUS_DMASYNC_POSTREAD);
1663		bus_dmamap_unload(sc->sc_dmat, pkt->map);
1664		if_rxr_put(&rq->rxring, 1);
1665		m_freem(pkt->mbuf);
1666		oce_pkt_put(&rq->pkt_free, pkt);
1667	}
1668}
1669
1670int
1671oce_vtp_valid(struct oce_softc *sc, struct oce_nic_rx_cqe *cqe)
1672{
1673	struct oce_nic_rx_cqe_v1 *cqe_v1;
1674
1675	if (IS_BE(sc) && ISSET(sc->sc_flags, OCE_F_BE3_NATIVE)) {
1676		cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe;
1677		return (cqe_v1->u0.s.vlan_tag_present);
1678	}
1679	return (cqe->u0.s.vlan_tag_present);
1680}
1681
1682int
1683oce_port_valid(struct oce_softc *sc, struct oce_nic_rx_cqe *cqe)
1684{
1685	struct oce_nic_rx_cqe_v1 *cqe_v1;
1686
1687	if (IS_BE(sc) && ISSET(sc->sc_flags, OCE_F_BE3_NATIVE)) {
1688		cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe;
1689		if (sc->sc_port != cqe_v1->u0.s.port)
1690			return (0);
1691	}
1692	return (1);
1693}
1694
1695#ifdef OCE_LRO
1696void
1697oce_flush_lro(struct oce_rq *rq)
1698{
1699	struct oce_softc *sc = rq->sc;
1700	struct ifnet *ifp = &sc->sc_ac.ac_if;
1701	struct lro_ctrl	*lro = &rq->lro;
1702	struct lro_entry *queued;
1703
1704	if (!IF_LRO_ENABLED(ifp))
1705		return;
1706
1707	while ((queued = SLIST_FIRST(&lro->lro_active)) != NULL) {
1708		SLIST_REMOVE_HEAD(&lro->lro_active, next);
1709		tcp_lro_flush(lro, queued);
1710	}
1711	rq->lro_pkts_queued = 0;
1712}
1713
1714int
1715oce_init_lro(struct oce_softc *sc)
1716{
1717	struct lro_ctrl *lro = NULL;
1718	int i = 0, rc = 0;
1719
1720	for (i = 0; i < sc->sc_nrq; i++) {
1721		lro = &sc->sc_rq[i]->lro;
1722		rc = tcp_lro_init(lro);
1723		if (rc != 0) {
1724			printf("%s: LRO init failed\n",
1725			    sc->sc_dev.dv_xname);
1726			return rc;
1727		}
1728		lro->ifp = &sc->sc_ac.ac_if;
1729	}
1730
1731	return (rc);
1732}
1733
1734void
1735oce_free_lro(struct oce_softc *sc)
1736{
1737	struct lro_ctrl *lro = NULL;
1738	int i = 0;
1739
1740	for (i = 0; i < sc->sc_nrq; i++) {
1741		lro = &sc->sc_rq[i]->lro;
1742		if (lro)
1743			tcp_lro_free(lro);
1744	}
1745}
1746#endif /* OCE_LRO */
1747
1748int
1749oce_get_buf(struct oce_rq *rq)
1750{
1751	struct oce_softc *sc = rq->sc;
1752	struct oce_pkt *pkt;
1753	struct oce_nic_rqe *rqe;
1754
1755	if ((pkt = oce_pkt_get(&rq->pkt_free)) == NULL)
1756		return (0);
1757
1758	pkt->mbuf = MCLGETL(NULL, M_DONTWAIT, MCLBYTES);
1759	if (pkt->mbuf == NULL) {
1760		oce_pkt_put(&rq->pkt_free, pkt);
1761		return (0);
1762	}
1763
1764	pkt->mbuf->m_len = pkt->mbuf->m_pkthdr.len = MCLBYTES;
1765#ifdef __STRICT_ALIGNMENT
1766	m_adj(pkt->mbuf, ETHER_ALIGN);
1767#endif
1768
1769	if (bus_dmamap_load_mbuf(sc->sc_dmat, pkt->map, pkt->mbuf,
1770	    BUS_DMA_NOWAIT)) {
1771		m_freem(pkt->mbuf);
1772		pkt->mbuf = NULL;
1773		oce_pkt_put(&rq->pkt_free, pkt);
1774		return (0);
1775	}
1776
1777	bus_dmamap_sync(sc->sc_dmat, pkt->map, 0, pkt->map->dm_mapsize,
1778	    BUS_DMASYNC_PREREAD);
1779
1780	oce_dma_sync(&rq->ring->dma, BUS_DMASYNC_PREREAD |
1781	    BUS_DMASYNC_PREWRITE);
1782
1783	rqe = oce_ring_get(rq->ring);
1784	rqe->u0.s.frag_pa_hi = ADDR_HI(pkt->map->dm_segs[0].ds_addr);
1785	rqe->u0.s.frag_pa_lo = ADDR_LO(pkt->map->dm_segs[0].ds_addr);
1786
1787	oce_dma_sync(&rq->ring->dma, BUS_DMASYNC_POSTREAD |
1788	    BUS_DMASYNC_POSTWRITE);
1789
1790	oce_pkt_put(&rq->pkt_list, pkt);
1791
1792	return (1);
1793}
1794
1795int
1796oce_alloc_rx_bufs(struct oce_rq *rq)
1797{
1798	struct oce_softc *sc = rq->sc;
1799	int i, nbufs = 0;
1800	u_int slots;
1801
1802	for (slots = if_rxr_get(&rq->rxring, rq->nitems); slots > 0; slots--) {
1803		if (oce_get_buf(rq) == 0)
1804			break;
1805
1806		nbufs++;
1807	}
1808	if_rxr_put(&rq->rxring, slots);
1809
1810	if (!nbufs)
1811		return (0);
1812	for (i = nbufs / OCE_MAX_RQ_POSTS; i > 0; i--) {
1813		oce_write_db(sc, PD_RXULP_DB, rq->id |
1814		    (OCE_MAX_RQ_POSTS << 24));
1815		nbufs -= OCE_MAX_RQ_POSTS;
1816	}
1817	if (nbufs > 0)
1818		oce_write_db(sc, PD_RXULP_DB, rq->id | (nbufs << 24));
1819	return (1);
1820}
1821
1822void
1823oce_refill_rx(void *arg)
1824{
1825	struct oce_softc *sc = arg;
1826	struct oce_rq *rq;
1827	int i, s;
1828
1829	s = splnet();
1830	OCE_RQ_FOREACH(sc, rq, i) {
1831		if (!oce_alloc_rx_bufs(rq))
1832			timeout_add(&sc->sc_rxrefill, 5);
1833	}
1834	splx(s);
1835}
1836
1837/* Handle the Completion Queue for the Mailbox/Async notifications */
1838void
1839oce_intr_mq(void *arg)
1840{
1841	struct oce_mq *mq = (struct oce_mq *)arg;
1842	struct oce_softc *sc = mq->sc;
1843	struct oce_cq *cq = mq->cq;
1844	struct oce_mq_cqe *cqe;
1845	struct oce_async_cqe_link_state *acqe;
1846	struct oce_async_event_grp5_pvid_state *gcqe;
1847	int evtype, optype, ncqe = 0;
1848
1849	oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_POSTREAD);
1850
1851	OCE_RING_FOREACH(cq->ring, cqe, MQ_CQE_VALID(cqe)) {
1852		if (cqe->u0.s.async_event) {
1853			evtype = cqe->u0.s.event_type;
1854			optype = cqe->u0.s.async_type;
1855			if (evtype  == ASYNC_EVENT_CODE_LINK_STATE) {
1856				/* Link status evt */
1857				acqe = (struct oce_async_cqe_link_state *)cqe;
1858				oce_link_event(sc, acqe);
1859			} else if ((evtype == ASYNC_EVENT_GRP5) &&
1860				   (optype == ASYNC_EVENT_PVID_STATE)) {
1861				/* GRP5 PVID */
1862				gcqe =
1863				(struct oce_async_event_grp5_pvid_state *)cqe;
1864				if (gcqe->enabled)
1865					sc->sc_pvid =
1866					    gcqe->tag & VLAN_VID_MASK;
1867				else
1868					sc->sc_pvid = 0;
1869			}
1870		}
1871		MQ_CQE_INVALIDATE(cqe);
1872		ncqe++;
1873	}
1874
1875	oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_PREWRITE);
1876
1877	if (ncqe)
1878		oce_arm_cq(cq, ncqe, FALSE);
1879}
1880
1881void
1882oce_link_event(struct oce_softc *sc, struct oce_async_cqe_link_state *acqe)
1883{
1884	/* Update Link status */
1885	sc->sc_link_up = ((acqe->u0.s.link_status & ~ASYNC_EVENT_LOGICAL) ==
1886	    ASYNC_EVENT_LINK_UP);
1887	/* Update speed */
1888	sc->sc_link_speed = acqe->u0.s.speed;
1889	oce_link_status(sc);
1890}
1891
1892int
1893oce_init_queues(struct oce_softc *sc)
1894{
1895	struct oce_wq *wq;
1896	struct oce_rq *rq;
1897	int i;
1898
1899	sc->sc_nrq = 1;
1900	sc->sc_nwq = 1;
1901
1902	/* Create network interface on card */
1903	if (oce_create_iface(sc, sc->sc_macaddr))
1904		goto error;
1905
1906	/* create all of the event queues */
1907	for (i = 0; i < sc->sc_nintr; i++) {
1908		sc->sc_eq[i] = oce_create_eq(sc);
1909		if (!sc->sc_eq[i])
1910			goto error;
1911	}
1912
1913	/* alloc tx queues */
1914	OCE_WQ_FOREACH(sc, wq, i) {
1915		sc->sc_wq[i] = oce_create_wq(sc, sc->sc_eq[i]);
1916		if (!sc->sc_wq[i])
1917			goto error;
1918	}
1919
1920	/* alloc rx queues */
1921	OCE_RQ_FOREACH(sc, rq, i) {
1922		sc->sc_rq[i] = oce_create_rq(sc, sc->sc_eq[i > 0 ? i - 1 : 0],
1923		    i > 0 ? sc->sc_rss_enable : 0);
1924		if (!sc->sc_rq[i])
1925			goto error;
1926	}
1927
1928	/* alloc mailbox queue */
1929	sc->sc_mq = oce_create_mq(sc, sc->sc_eq[0]);
1930	if (!sc->sc_mq)
1931		goto error;
1932
1933	return (0);
1934error:
1935	oce_release_queues(sc);
1936	return (1);
1937}
1938
1939void
1940oce_release_queues(struct oce_softc *sc)
1941{
1942	struct oce_wq *wq;
1943	struct oce_rq *rq;
1944	struct oce_eq *eq;
1945	int i;
1946
1947	OCE_RQ_FOREACH(sc, rq, i) {
1948		if (rq)
1949			oce_destroy_rq(sc->sc_rq[i]);
1950	}
1951
1952	OCE_WQ_FOREACH(sc, wq, i) {
1953		if (wq)
1954			oce_destroy_wq(sc->sc_wq[i]);
1955	}
1956
1957	if (sc->sc_mq)
1958		oce_destroy_mq(sc->sc_mq);
1959
1960	OCE_EQ_FOREACH(sc, eq, i) {
1961		if (eq)
1962			oce_destroy_eq(sc->sc_eq[i]);
1963	}
1964}
1965
1966/**
1967 * @brief 		Function to create a WQ for NIC Tx
1968 * @param sc 		software handle to the device
1969 * @returns		the pointer to the WQ created or NULL on failure
1970 */
1971struct oce_wq *
1972oce_create_wq(struct oce_softc *sc, struct oce_eq *eq)
1973{
1974	struct oce_wq *wq;
1975	struct oce_cq *cq;
1976	struct oce_pkt *pkt;
1977	int i;
1978
1979	if (sc->sc_tx_ring_size < 256 || sc->sc_tx_ring_size > 2048)
1980		return (NULL);
1981
1982	wq = malloc(sizeof(struct oce_wq), M_DEVBUF, M_NOWAIT | M_ZERO);
1983	if (!wq)
1984		return (NULL);
1985
1986	wq->ring = oce_create_ring(sc, sc->sc_tx_ring_size, NIC_WQE_SIZE, 8);
1987	if (!wq->ring) {
1988		free(wq, M_DEVBUF, 0);
1989		return (NULL);
1990	}
1991
1992	cq = oce_create_cq(sc, eq, CQ_LEN_512, sizeof(struct oce_nic_tx_cqe),
1993	    1, 0, 3);
1994	if (!cq) {
1995		oce_destroy_ring(sc, wq->ring);
1996		free(wq, M_DEVBUF, 0);
1997		return (NULL);
1998	}
1999
2000	wq->id = -1;
2001	wq->sc = sc;
2002
2003	wq->cq = cq;
2004	wq->nitems = sc->sc_tx_ring_size;
2005
2006	SIMPLEQ_INIT(&wq->pkt_free);
2007	SIMPLEQ_INIT(&wq->pkt_list);
2008
2009	for (i = 0; i < sc->sc_tx_ring_size / 2; i++) {
2010		pkt = oce_pkt_alloc(sc, OCE_MAX_TX_SIZE, OCE_MAX_TX_ELEMENTS,
2011		    PAGE_SIZE);
2012		if (pkt == NULL) {
2013			oce_destroy_wq(wq);
2014			return (NULL);
2015		}
2016		oce_pkt_put(&wq->pkt_free, pkt);
2017	}
2018
2019	if (oce_new_wq(sc, wq)) {
2020		oce_destroy_wq(wq);
2021		return (NULL);
2022	}
2023
2024	eq->cq[eq->cq_valid] = cq;
2025	eq->cq_valid++;
2026	cq->cb_arg = wq;
2027	cq->cq_intr = oce_intr_wq;
2028
2029	return (wq);
2030}
2031
2032void
2033oce_drain_wq(struct oce_wq *wq)
2034{
2035	struct oce_cq *cq = wq->cq;
2036	struct oce_nic_tx_cqe *cqe;
2037	int ncqe = 0;
2038
2039	oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_POSTREAD);
2040	OCE_RING_FOREACH(cq->ring, cqe, WQ_CQE_VALID(cqe)) {
2041		WQ_CQE_INVALIDATE(cqe);
2042		ncqe++;
2043	}
2044	oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_PREWRITE);
2045	oce_arm_cq(cq, ncqe, FALSE);
2046}
2047
2048void
2049oce_destroy_wq(struct oce_wq *wq)
2050{
2051	struct mbx_delete_nic_wq cmd;
2052	struct oce_softc *sc = wq->sc;
2053	struct oce_pkt *pkt;
2054
2055	if (wq->id >= 0) {
2056		memset(&cmd, 0, sizeof(cmd));
2057		cmd.params.req.wq_id = htole16(wq->id);
2058		oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_DELETE_WQ, OCE_MBX_VER_V0,
2059		    &cmd, sizeof(cmd));
2060	}
2061	if (wq->cq != NULL)
2062		oce_destroy_cq(wq->cq);
2063	if (wq->ring != NULL)
2064		oce_destroy_ring(sc, wq->ring);
2065	while ((pkt = oce_pkt_get(&wq->pkt_free)) != NULL)
2066		oce_pkt_free(sc, pkt);
2067	free(wq, M_DEVBUF, 0);
2068}
2069
2070/**
2071 * @brief 		function to allocate receive queue resources
2072 * @param sc		software handle to the device
2073 * @param eq		pointer to associated event queue
2074 * @param rss		is-rss-queue flag
2075 * @returns		the pointer to the RQ created or NULL on failure
2076 */
2077struct oce_rq *
2078oce_create_rq(struct oce_softc *sc, struct oce_eq *eq, int rss)
2079{
2080	struct oce_rq *rq;
2081	struct oce_cq *cq;
2082	struct oce_pkt *pkt;
2083	int i;
2084
2085	/* Hardware doesn't support any other value */
2086	if (sc->sc_rx_ring_size != 1024)
2087		return (NULL);
2088
2089	rq = malloc(sizeof(struct oce_rq), M_DEVBUF, M_NOWAIT | M_ZERO);
2090	if (!rq)
2091		return (NULL);
2092
2093	rq->ring = oce_create_ring(sc, sc->sc_rx_ring_size,
2094	    sizeof(struct oce_nic_rqe), 2);
2095	if (!rq->ring) {
2096		free(rq, M_DEVBUF, 0);
2097		return (NULL);
2098	}
2099
2100	cq = oce_create_cq(sc, eq, CQ_LEN_1024, sizeof(struct oce_nic_rx_cqe),
2101	    1, 0, 3);
2102	if (!cq) {
2103		oce_destroy_ring(sc, rq->ring);
2104		free(rq, M_DEVBUF, 0);
2105		return (NULL);
2106	}
2107
2108	rq->id = -1;
2109	rq->sc = sc;
2110
2111	rq->nitems = sc->sc_rx_ring_size;
2112	rq->fragsize = OCE_RX_BUF_SIZE;
2113	rq->rss = rss;
2114
2115	SIMPLEQ_INIT(&rq->pkt_free);
2116	SIMPLEQ_INIT(&rq->pkt_list);
2117
2118	for (i = 0; i < sc->sc_rx_ring_size; i++) {
2119		pkt = oce_pkt_alloc(sc, OCE_RX_BUF_SIZE, 1, OCE_RX_BUF_SIZE);
2120		if (pkt == NULL) {
2121			oce_destroy_rq(rq);
2122			return (NULL);
2123		}
2124		oce_pkt_put(&rq->pkt_free, pkt);
2125	}
2126
2127	rq->cq = cq;
2128	eq->cq[eq->cq_valid] = cq;
2129	eq->cq_valid++;
2130	cq->cb_arg = rq;
2131	cq->cq_intr = oce_intr_rq;
2132
2133	/* RX queue is created in oce_init */
2134
2135	return (rq);
2136}
2137
2138void
2139oce_drain_rq(struct oce_rq *rq)
2140{
2141	struct oce_nic_rx_cqe *cqe;
2142	struct oce_cq *cq = rq->cq;
2143	int ncqe = 0;
2144
2145	oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_POSTREAD);
2146	OCE_RING_FOREACH(cq->ring, cqe, RQ_CQE_VALID(cqe)) {
2147		RQ_CQE_INVALIDATE(cqe);
2148		ncqe++;
2149	}
2150	oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_PREWRITE);
2151	oce_arm_cq(cq, ncqe, FALSE);
2152}
2153
2154void
2155oce_destroy_rq(struct oce_rq *rq)
2156{
2157	struct mbx_delete_nic_rq cmd;
2158	struct oce_softc *sc = rq->sc;
2159	struct oce_pkt *pkt;
2160
2161	if (rq->id >= 0) {
2162		memset(&cmd, 0, sizeof(cmd));
2163		cmd.params.req.rq_id = htole16(rq->id);
2164		oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_DELETE_RQ, OCE_MBX_VER_V0,
2165		    &cmd, sizeof(cmd));
2166	}
2167	if (rq->cq != NULL)
2168		oce_destroy_cq(rq->cq);
2169	if (rq->ring != NULL)
2170		oce_destroy_ring(sc, rq->ring);
2171	while ((pkt = oce_pkt_get(&rq->pkt_free)) != NULL)
2172		oce_pkt_free(sc, pkt);
2173	free(rq, M_DEVBUF, 0);
2174}
2175
2176struct oce_eq *
2177oce_create_eq(struct oce_softc *sc)
2178{
2179	struct oce_eq *eq;
2180
2181	/* allocate an eq */
2182	eq = malloc(sizeof(struct oce_eq), M_DEVBUF, M_NOWAIT | M_ZERO);
2183	if (eq == NULL)
2184		return (NULL);
2185
2186	eq->ring = oce_create_ring(sc, EQ_LEN_1024, EQE_SIZE_4, 8);
2187	if (!eq->ring) {
2188		free(eq, M_DEVBUF, 0);
2189		return (NULL);
2190	}
2191
2192	eq->id = -1;
2193	eq->sc = sc;
2194	eq->nitems = EQ_LEN_1024;	/* length of event queue */
2195	eq->isize = EQE_SIZE_4; 	/* size of a queue item */
2196	eq->delay = OCE_DEFAULT_EQD;	/* event queue delay */
2197
2198	if (oce_new_eq(sc, eq)) {
2199		oce_destroy_ring(sc, eq->ring);
2200		free(eq, M_DEVBUF, 0);
2201		return (NULL);
2202	}
2203
2204	return (eq);
2205}
2206
2207/**
2208 * @brief		Function to arm an EQ so that it can generate events
2209 * @param eq		pointer to event queue structure
2210 * @param neqe		number of EQEs to arm
2211 * @param rearm		rearm bit enable/disable
2212 * @param clearint	bit to clear the interrupt condition because of which
2213 *			EQEs are generated
2214 */
2215static inline void
2216oce_arm_eq(struct oce_eq *eq, int neqe, int rearm, int clearint)
2217{
2218	oce_write_db(eq->sc, PD_EQ_DB, eq->id | PD_EQ_DB_EVENT |
2219	    (clearint << 9) | (neqe << 16) | (rearm << 29));
2220}
2221
2222void
2223oce_drain_eq(struct oce_eq *eq)
2224{
2225	struct oce_eqe *eqe;
2226	int neqe = 0;
2227
2228	oce_dma_sync(&eq->ring->dma, BUS_DMASYNC_POSTREAD);
2229	OCE_RING_FOREACH(eq->ring, eqe, eqe->evnt != 0) {
2230		eqe->evnt = 0;
2231		neqe++;
2232	}
2233	oce_dma_sync(&eq->ring->dma, BUS_DMASYNC_PREWRITE);
2234	oce_arm_eq(eq, neqe, FALSE, TRUE);
2235}
2236
2237void
2238oce_destroy_eq(struct oce_eq *eq)
2239{
2240	struct mbx_destroy_common_eq cmd;
2241	struct oce_softc *sc = eq->sc;
2242
2243	if (eq->id >= 0) {
2244		memset(&cmd, 0, sizeof(cmd));
2245		cmd.params.req.id = htole16(eq->id);
2246		oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_DESTROY_EQ,
2247		    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
2248	}
2249	if (eq->ring != NULL)
2250		oce_destroy_ring(sc, eq->ring);
2251	free(eq, M_DEVBUF, 0);
2252}
2253
2254struct oce_mq *
2255oce_create_mq(struct oce_softc *sc, struct oce_eq *eq)
2256{
2257	struct oce_mq *mq = NULL;
2258	struct oce_cq *cq;
2259
2260	/* allocate the mq */
2261	mq = malloc(sizeof(struct oce_mq), M_DEVBUF, M_NOWAIT | M_ZERO);
2262	if (!mq)
2263		return (NULL);
2264
2265	mq->ring = oce_create_ring(sc, 128, sizeof(struct oce_mbx), 8);
2266	if (!mq->ring) {
2267		free(mq, M_DEVBUF, 0);
2268		return (NULL);
2269	}
2270
2271	cq = oce_create_cq(sc, eq, CQ_LEN_256, sizeof(struct oce_mq_cqe),
2272	    1, 0, 0);
2273	if (!cq) {
2274		oce_destroy_ring(sc, mq->ring);
2275		free(mq, M_DEVBUF, 0);
2276		return (NULL);
2277	}
2278
2279	mq->id = -1;
2280	mq->sc = sc;
2281	mq->cq = cq;
2282
2283	mq->nitems = 128;
2284
2285	if (oce_new_mq(sc, mq)) {
2286		oce_destroy_cq(mq->cq);
2287		oce_destroy_ring(sc, mq->ring);
2288		free(mq, M_DEVBUF, 0);
2289		return (NULL);
2290	}
2291
2292	eq->cq[eq->cq_valid] = cq;
2293	eq->cq_valid++;
2294	mq->cq->eq = eq;
2295	mq->cq->cb_arg = mq;
2296	mq->cq->cq_intr = oce_intr_mq;
2297
2298	return (mq);
2299}
2300
2301void
2302oce_drain_mq(struct oce_mq *mq)
2303{
2304	struct oce_cq *cq = mq->cq;
2305	struct oce_mq_cqe *cqe;
2306	int ncqe = 0;
2307
2308	oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_POSTREAD);
2309	OCE_RING_FOREACH(cq->ring, cqe, MQ_CQE_VALID(cqe)) {
2310		MQ_CQE_INVALIDATE(cqe);
2311		ncqe++;
2312	}
2313	oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_PREWRITE);
2314	oce_arm_cq(cq, ncqe, FALSE);
2315}
2316
2317void
2318oce_destroy_mq(struct oce_mq *mq)
2319{
2320	struct mbx_destroy_common_mq cmd;
2321	struct oce_softc *sc = mq->sc;
2322
2323	if (mq->id >= 0) {
2324		memset(&cmd, 0, sizeof(cmd));
2325		cmd.params.req.id = htole16(mq->id);
2326		oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_DESTROY_MQ,
2327		    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
2328	}
2329	if (mq->ring != NULL)
2330		oce_destroy_ring(sc, mq->ring);
2331	if (mq->cq != NULL)
2332		oce_destroy_cq(mq->cq);
2333	free(mq, M_DEVBUF, 0);
2334}
2335
2336/**
2337 * @brief		Function to create a completion queue
2338 * @param sc		software handle to the device
2339 * @param eq		optional eq to be associated with to the cq
2340 * @param nitems	length of completion queue
2341 * @param isize		size of completion queue items
2342 * @param eventable	event table
2343 * @param nodelay	no delay flag
2344 * @param ncoalesce	no coalescence flag
2345 * @returns 		pointer to the cq created, NULL on failure
2346 */
2347struct oce_cq *
2348oce_create_cq(struct oce_softc *sc, struct oce_eq *eq, int nitems, int isize,
2349    int eventable, int nodelay, int ncoalesce)
2350{
2351	struct oce_cq *cq = NULL;
2352
2353	cq = malloc(sizeof(struct oce_cq), M_DEVBUF, M_NOWAIT | M_ZERO);
2354	if (!cq)
2355		return (NULL);
2356
2357	cq->ring = oce_create_ring(sc, nitems, isize, 4);
2358	if (!cq->ring) {
2359		free(cq, M_DEVBUF, 0);
2360		return (NULL);
2361	}
2362
2363	cq->sc = sc;
2364	cq->eq = eq;
2365	cq->nitems = nitems;
2366	cq->nodelay = nodelay;
2367	cq->ncoalesce = ncoalesce;
2368	cq->eventable = eventable;
2369
2370	if (oce_new_cq(sc, cq)) {
2371		oce_destroy_ring(sc, cq->ring);
2372		free(cq, M_DEVBUF, 0);
2373		return (NULL);
2374	}
2375
2376	sc->sc_cq[sc->sc_ncq++] = cq;
2377
2378	return (cq);
2379}
2380
2381void
2382oce_destroy_cq(struct oce_cq *cq)
2383{
2384	struct mbx_destroy_common_cq cmd;
2385	struct oce_softc *sc = cq->sc;
2386
2387	if (cq->id >= 0) {
2388		memset(&cmd, 0, sizeof(cmd));
2389		cmd.params.req.id = htole16(cq->id);
2390		oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_DESTROY_CQ,
2391		    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
2392	}
2393	if (cq->ring != NULL)
2394		oce_destroy_ring(sc, cq->ring);
2395	free(cq, M_DEVBUF, 0);
2396}
2397
2398/**
2399 * @brief		Function to arm a CQ with CQEs
2400 * @param cq		pointer to the completion queue structure
2401 * @param ncqe		number of CQEs to arm
2402 * @param rearm		rearm bit enable/disable
2403 */
2404static inline void
2405oce_arm_cq(struct oce_cq *cq, int ncqe, int rearm)
2406{
2407	oce_write_db(cq->sc, PD_CQ_DB, cq->id | (ncqe << 16) | (rearm << 29));
2408}
2409
2410void
2411oce_free_posted_rxbuf(struct oce_rq *rq)
2412{
2413	struct oce_softc *sc = rq->sc;
2414	struct oce_pkt *pkt;
2415
2416	while ((pkt = oce_pkt_get(&rq->pkt_list)) != NULL) {
2417		bus_dmamap_sync(sc->sc_dmat, pkt->map, 0, pkt->map->dm_mapsize,
2418		    BUS_DMASYNC_POSTREAD);
2419		bus_dmamap_unload(sc->sc_dmat, pkt->map);
2420		if (pkt->mbuf != NULL) {
2421			m_freem(pkt->mbuf);
2422			pkt->mbuf = NULL;
2423		}
2424		oce_pkt_put(&rq->pkt_free, pkt);
2425		if_rxr_put(&rq->rxring, 1);
2426	}
2427}
2428
2429int
2430oce_dma_alloc(struct oce_softc *sc, bus_size_t size, struct oce_dma_mem *dma)
2431{
2432	int rc;
2433
2434	memset(dma, 0, sizeof(struct oce_dma_mem));
2435
2436	dma->tag = sc->sc_dmat;
2437	rc = bus_dmamap_create(dma->tag, size, 1, size, 0, BUS_DMA_NOWAIT,
2438	    &dma->map);
2439	if (rc != 0) {
2440		printf("%s: failed to allocate DMA handle",
2441		    sc->sc_dev.dv_xname);
2442		goto fail_0;
2443	}
2444
2445	rc = bus_dmamem_alloc(dma->tag, size, PAGE_SIZE, 0, &dma->segs, 1,
2446	    &dma->nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
2447	if (rc != 0) {
2448		printf("%s: failed to allocate DMA memory",
2449		    sc->sc_dev.dv_xname);
2450		goto fail_1;
2451	}
2452
2453	rc = bus_dmamem_map(dma->tag, &dma->segs, dma->nsegs, size,
2454	    &dma->vaddr, BUS_DMA_NOWAIT);
2455	if (rc != 0) {
2456		printf("%s: failed to map DMA memory", sc->sc_dev.dv_xname);
2457		goto fail_2;
2458	}
2459
2460	rc = bus_dmamap_load(dma->tag, dma->map, dma->vaddr, size, NULL,
2461	    BUS_DMA_NOWAIT);
2462	if (rc != 0) {
2463		printf("%s: failed to load DMA memory", sc->sc_dev.dv_xname);
2464		goto fail_3;
2465	}
2466
2467	bus_dmamap_sync(dma->tag, dma->map, 0, dma->map->dm_mapsize,
2468	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2469
2470	dma->paddr = dma->map->dm_segs[0].ds_addr;
2471	dma->size = size;
2472
2473	return (0);
2474
2475fail_3:
2476	bus_dmamem_unmap(dma->tag, dma->vaddr, size);
2477fail_2:
2478	bus_dmamem_free(dma->tag, &dma->segs, dma->nsegs);
2479fail_1:
2480	bus_dmamap_destroy(dma->tag, dma->map);
2481fail_0:
2482	return (rc);
2483}
2484
2485void
2486oce_dma_free(struct oce_softc *sc, struct oce_dma_mem *dma)
2487{
2488	if (dma->tag == NULL)
2489		return;
2490
2491	if (dma->map != NULL) {
2492		oce_dma_sync(dma, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2493		bus_dmamap_unload(dma->tag, dma->map);
2494
2495		if (dma->vaddr != 0) {
2496			bus_dmamem_free(dma->tag, &dma->segs, dma->nsegs);
2497			dma->vaddr = 0;
2498		}
2499
2500		bus_dmamap_destroy(dma->tag, dma->map);
2501		dma->map = NULL;
2502		dma->tag = NULL;
2503	}
2504}
2505
2506struct oce_ring *
2507oce_create_ring(struct oce_softc *sc, int nitems, int isize, int maxsegs)
2508{
2509	struct oce_dma_mem *dma;
2510	struct oce_ring *ring;
2511	bus_size_t size = nitems * isize;
2512	int rc;
2513
2514	if (size > maxsegs * PAGE_SIZE)
2515		return (NULL);
2516
2517	ring = malloc(sizeof(struct oce_ring), M_DEVBUF, M_NOWAIT | M_ZERO);
2518	if (ring == NULL)
2519		return (NULL);
2520
2521	ring->isize = isize;
2522	ring->nitems = nitems;
2523
2524	dma = &ring->dma;
2525	dma->tag = sc->sc_dmat;
2526	rc = bus_dmamap_create(dma->tag, size, maxsegs, PAGE_SIZE, 0,
2527	    BUS_DMA_NOWAIT, &dma->map);
2528	if (rc != 0) {
2529		printf("%s: failed to allocate DMA handle",
2530		    sc->sc_dev.dv_xname);
2531		goto fail_0;
2532	}
2533
2534	rc = bus_dmamem_alloc(dma->tag, size, 0, 0, &dma->segs, maxsegs,
2535	    &dma->nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
2536	if (rc != 0) {
2537		printf("%s: failed to allocate DMA memory",
2538		    sc->sc_dev.dv_xname);
2539		goto fail_1;
2540	}
2541
2542	rc = bus_dmamem_map(dma->tag, &dma->segs, dma->nsegs, size,
2543	    &dma->vaddr, BUS_DMA_NOWAIT);
2544	if (rc != 0) {
2545		printf("%s: failed to map DMA memory", sc->sc_dev.dv_xname);
2546		goto fail_2;
2547	}
2548
2549	bus_dmamap_sync(dma->tag, dma->map, 0, dma->map->dm_mapsize,
2550	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2551
2552	dma->paddr = 0;
2553	dma->size = size;
2554
2555	return (ring);
2556
2557fail_2:
2558	bus_dmamem_free(dma->tag, &dma->segs, dma->nsegs);
2559fail_1:
2560	bus_dmamap_destroy(dma->tag, dma->map);
2561fail_0:
2562	free(ring, M_DEVBUF, 0);
2563	return (NULL);
2564}
2565
2566void
2567oce_destroy_ring(struct oce_softc *sc, struct oce_ring *ring)
2568{
2569	oce_dma_free(sc, &ring->dma);
2570	free(ring, M_DEVBUF, 0);
2571}
2572
2573int
2574oce_load_ring(struct oce_softc *sc, struct oce_ring *ring,
2575    struct oce_pa *pa, int maxsegs)
2576{
2577	struct oce_dma_mem *dma = &ring->dma;
2578	int i;
2579
2580	if (bus_dmamap_load(dma->tag, dma->map, dma->vaddr,
2581	    ring->isize * ring->nitems, NULL, BUS_DMA_NOWAIT)) {
2582		printf("%s: failed to load a ring map\n", sc->sc_dev.dv_xname);
2583		return (0);
2584	}
2585
2586	if (dma->map->dm_nsegs > maxsegs) {
2587		printf("%s: too many segments\n", sc->sc_dev.dv_xname);
2588		return (0);
2589	}
2590
2591	bus_dmamap_sync(dma->tag, dma->map, 0, dma->map->dm_mapsize,
2592	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2593
2594	for (i = 0; i < dma->map->dm_nsegs; i++)
2595		pa[i].addr = dma->map->dm_segs[i].ds_addr;
2596
2597	return (dma->map->dm_nsegs);
2598}
2599
2600static inline void *
2601oce_ring_get(struct oce_ring *ring)
2602{
2603	int index = ring->index;
2604
2605	if (++ring->index == ring->nitems)
2606		ring->index = 0;
2607	return ((void *)(ring->dma.vaddr + index * ring->isize));
2608}
2609
2610static inline void *
2611oce_ring_first(struct oce_ring *ring)
2612{
2613	return ((void *)(ring->dma.vaddr + ring->index * ring->isize));
2614}
2615
2616static inline void *
2617oce_ring_next(struct oce_ring *ring)
2618{
2619	if (++ring->index == ring->nitems)
2620		ring->index = 0;
2621	return ((void *)(ring->dma.vaddr + ring->index * ring->isize));
2622}
2623
2624struct oce_pkt *
2625oce_pkt_alloc(struct oce_softc *sc, size_t size, int nsegs, int maxsegsz)
2626{
2627	struct oce_pkt *pkt;
2628
2629	if ((pkt = pool_get(oce_pkt_pool, PR_NOWAIT | PR_ZERO)) == NULL)
2630		return (NULL);
2631
2632	if (bus_dmamap_create(sc->sc_dmat, size, nsegs, maxsegsz, 0,
2633	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &pkt->map)) {
2634		pool_put(oce_pkt_pool, pkt);
2635		return (NULL);
2636	}
2637
2638	return (pkt);
2639}
2640
2641void
2642oce_pkt_free(struct oce_softc *sc, struct oce_pkt *pkt)
2643{
2644	if (pkt->map) {
2645		bus_dmamap_unload(sc->sc_dmat, pkt->map);
2646		bus_dmamap_destroy(sc->sc_dmat, pkt->map);
2647	}
2648	pool_put(oce_pkt_pool, pkt);
2649}
2650
2651static inline struct oce_pkt *
2652oce_pkt_get(struct oce_pkt_list *lst)
2653{
2654	struct oce_pkt *pkt;
2655
2656	pkt = SIMPLEQ_FIRST(lst);
2657	if (pkt == NULL)
2658		return (NULL);
2659
2660	SIMPLEQ_REMOVE_HEAD(lst, entry);
2661
2662	return (pkt);
2663}
2664
2665static inline void
2666oce_pkt_put(struct oce_pkt_list *lst, struct oce_pkt *pkt)
2667{
2668	SIMPLEQ_INSERT_TAIL(lst, pkt, entry);
2669}
2670
2671/**
2672 * @brief Wait for FW to become ready and reset it
2673 * @param sc		software handle to the device
2674 */
2675int
2676oce_init_fw(struct oce_softc *sc)
2677{
2678	struct ioctl_common_function_reset cmd;
2679	uint32_t reg;
2680	int err = 0, tmo = 60000;
2681
2682	/* read semaphore CSR */
2683	reg = oce_read_csr(sc, MPU_EP_SEMAPHORE(sc));
2684
2685	/* if host is ready then wait for fw ready else send POST */
2686	if ((reg & MPU_EP_SEM_STAGE_MASK) <= POST_STAGE_AWAITING_HOST_RDY) {
2687		reg = (reg & ~MPU_EP_SEM_STAGE_MASK) | POST_STAGE_CHIP_RESET;
2688		oce_write_csr(sc, MPU_EP_SEMAPHORE(sc), reg);
2689	}
2690
2691	/* wait for FW to become ready */
2692	for (;;) {
2693		if (--tmo == 0)
2694			break;
2695
2696		DELAY(1000);
2697
2698		reg = oce_read_csr(sc, MPU_EP_SEMAPHORE(sc));
2699		if (reg & MPU_EP_SEM_ERROR) {
2700			printf(": POST failed: %#x\n", reg);
2701			return (ENXIO);
2702		}
2703		if ((reg & MPU_EP_SEM_STAGE_MASK) == POST_STAGE_ARMFW_READY) {
2704			/* reset FW */
2705			if (ISSET(sc->sc_flags, OCE_F_RESET_RQD)) {
2706				memset(&cmd, 0, sizeof(cmd));
2707				err = oce_cmd(sc, SUBSYS_COMMON,
2708				    OPCODE_COMMON_FUNCTION_RESET,
2709				    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
2710			}
2711			return (err);
2712		}
2713	}
2714
2715	printf(": POST timed out: %#x\n", reg);
2716
2717	return (ENXIO);
2718}
2719
2720static inline int
2721oce_mbox_wait(struct oce_softc *sc)
2722{
2723	int i;
2724
2725	for (i = 0; i < 20000; i++) {
2726		if (oce_read_db(sc, PD_MPU_MBOX_DB) & PD_MPU_MBOX_DB_READY)
2727			return (0);
2728		DELAY(100);
2729	}
2730	return (ETIMEDOUT);
2731}
2732
2733/**
2734 * @brief Mailbox dispatch
2735 * @param sc		software handle to the device
2736 */
2737int
2738oce_mbox_dispatch(struct oce_softc *sc)
2739{
2740	uint32_t pa, reg;
2741	int err;
2742
2743	pa = (uint32_t)((uint64_t)OCE_MEM_DVA(&sc->sc_mbx) >> 34);
2744	reg = PD_MPU_MBOX_DB_HI | (pa << PD_MPU_MBOX_DB_ADDR_SHIFT);
2745
2746	if ((err = oce_mbox_wait(sc)) != 0)
2747		goto out;
2748
2749	oce_write_db(sc, PD_MPU_MBOX_DB, reg);
2750
2751	pa = (uint32_t)((uint64_t)OCE_MEM_DVA(&sc->sc_mbx) >> 4) & 0x3fffffff;
2752	reg = pa << PD_MPU_MBOX_DB_ADDR_SHIFT;
2753
2754	if ((err = oce_mbox_wait(sc)) != 0)
2755		goto out;
2756
2757	oce_write_db(sc, PD_MPU_MBOX_DB, reg);
2758
2759	oce_dma_sync(&sc->sc_mbx, BUS_DMASYNC_POSTWRITE);
2760
2761	if ((err = oce_mbox_wait(sc)) != 0)
2762		goto out;
2763
2764out:
2765	oce_dma_sync(&sc->sc_mbx, BUS_DMASYNC_PREREAD);
2766	return (err);
2767}
2768
2769/**
2770 * @brief Function to initialize the hw with host endian information
2771 * @param sc		software handle to the device
2772 * @returns		0 on success, ETIMEDOUT on failure
2773 */
2774int
2775oce_mbox_init(struct oce_softc *sc)
2776{
2777	struct oce_bmbx *bmbx = OCE_MEM_KVA(&sc->sc_mbx);
2778	uint8_t *ptr = (uint8_t *)&bmbx->mbx;
2779
2780	if (!ISSET(sc->sc_flags, OCE_F_MBOX_ENDIAN_RQD))
2781		return (0);
2782
2783	/* Endian Signature */
2784	*ptr++ = 0xff;
2785	*ptr++ = 0x12;
2786	*ptr++ = 0x34;
2787	*ptr++ = 0xff;
2788	*ptr++ = 0xff;
2789	*ptr++ = 0x56;
2790	*ptr++ = 0x78;
2791	*ptr = 0xff;
2792
2793	return (oce_mbox_dispatch(sc));
2794}
2795
2796int
2797oce_cmd(struct oce_softc *sc, int subsys, int opcode, int version,
2798    void *payload, int length)
2799{
2800	struct oce_bmbx *bmbx = OCE_MEM_KVA(&sc->sc_mbx);
2801	struct oce_mbx *mbx = &bmbx->mbx;
2802	struct mbx_hdr *hdr;
2803	caddr_t epayload = NULL;
2804	int err;
2805
2806	if (length > OCE_MBX_PAYLOAD)
2807		epayload = OCE_MEM_KVA(&sc->sc_pld);
2808	if (length > OCE_MAX_PAYLOAD)
2809		return (EINVAL);
2810
2811	oce_dma_sync(&sc->sc_mbx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2812
2813	memset(mbx, 0, sizeof(struct oce_mbx));
2814
2815	mbx->payload_length = length;
2816
2817	if (epayload) {
2818		mbx->flags = OCE_MBX_F_SGE;
2819		oce_dma_sync(&sc->sc_pld, BUS_DMASYNC_PREREAD);
2820		memcpy(epayload, payload, length);
2821		mbx->pld.sgl[0].addr = OCE_MEM_DVA(&sc->sc_pld);
2822		mbx->pld.sgl[0].length = length;
2823		hdr = (struct mbx_hdr *)epayload;
2824	} else {
2825		mbx->flags = OCE_MBX_F_EMBED;
2826		memcpy(mbx->pld.data, payload, length);
2827		hdr = (struct mbx_hdr *)&mbx->pld.data;
2828	}
2829
2830	hdr->subsys = subsys;
2831	hdr->opcode = opcode;
2832	hdr->version = version;
2833	hdr->length = length - sizeof(*hdr);
2834	if (opcode == OPCODE_COMMON_FUNCTION_RESET)
2835		hdr->timeout = 2 * OCE_MBX_TIMEOUT;
2836	else
2837		hdr->timeout = OCE_MBX_TIMEOUT;
2838
2839	if (epayload)
2840		oce_dma_sync(&sc->sc_pld, BUS_DMASYNC_PREWRITE);
2841
2842	err = oce_mbox_dispatch(sc);
2843	if (err == 0) {
2844		if (epayload) {
2845			oce_dma_sync(&sc->sc_pld, BUS_DMASYNC_POSTWRITE);
2846			memcpy(payload, epayload, length);
2847		} else
2848			memcpy(payload, &mbx->pld.data, length);
2849	} else
2850		printf("%s: mailbox timeout, subsys %d op %d ver %d "
2851		    "%spayload length %d\n", sc->sc_dev.dv_xname, subsys,
2852		    opcode, version, epayload ? "ext " : "",
2853		    length);
2854	return (err);
2855}
2856
2857/**
2858 * @brief	Firmware will send gracious notifications during
2859 *		attach only after sending first mcc command. We
2860 *		use MCC queue only for getting async and mailbox
2861 *		for sending cmds. So to get gracious notifications
2862 *		at least send one dummy command on mcc.
2863 */
2864void
2865oce_first_mcc(struct oce_softc *sc)
2866{
2867	struct oce_mbx *mbx;
2868	struct oce_mq *mq = sc->sc_mq;
2869	struct mbx_hdr *hdr;
2870	struct mbx_get_common_fw_version *cmd;
2871
2872	mbx = oce_ring_get(mq->ring);
2873	memset(mbx, 0, sizeof(struct oce_mbx));
2874
2875	cmd = (struct mbx_get_common_fw_version *)&mbx->pld.data;
2876
2877	hdr = &cmd->hdr;
2878	hdr->subsys = SUBSYS_COMMON;
2879	hdr->opcode = OPCODE_COMMON_GET_FW_VERSION;
2880	hdr->version = OCE_MBX_VER_V0;
2881	hdr->timeout = OCE_MBX_TIMEOUT;
2882	hdr->length = sizeof(*cmd) - sizeof(*hdr);
2883
2884	mbx->flags = OCE_MBX_F_EMBED;
2885	mbx->payload_length = sizeof(*cmd);
2886	oce_dma_sync(&mq->ring->dma, BUS_DMASYNC_PREREAD |
2887	    BUS_DMASYNC_PREWRITE);
2888	oce_write_db(sc, PD_MQ_DB, mq->id | (1 << 16));
2889}
2890
2891int
2892oce_get_fw_config(struct oce_softc *sc)
2893{
2894	struct mbx_common_query_fw_config cmd;
2895	int err;
2896
2897	memset(&cmd, 0, sizeof(cmd));
2898
2899	err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
2900	    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
2901	if (err)
2902		return (err);
2903
2904	sc->sc_port = cmd.params.rsp.port_id;
2905	sc->sc_fmode = cmd.params.rsp.function_mode;
2906
2907	return (0);
2908}
2909
2910int
2911oce_check_native_mode(struct oce_softc *sc)
2912{
2913	struct mbx_common_set_function_cap cmd;
2914	int err;
2915
2916	memset(&cmd, 0, sizeof(cmd));
2917
2918	cmd.params.req.valid_capability_flags = CAP_SW_TIMESTAMPS |
2919	    CAP_BE3_NATIVE_ERX_API;
2920	cmd.params.req.capability_flags = CAP_BE3_NATIVE_ERX_API;
2921
2922	err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_SET_FUNCTIONAL_CAPS,
2923	    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
2924	if (err)
2925		return (err);
2926
2927	if (cmd.params.rsp.capability_flags & CAP_BE3_NATIVE_ERX_API)
2928		SET(sc->sc_flags, OCE_F_BE3_NATIVE);
2929
2930	return (0);
2931}
2932
2933/**
2934 * @brief Function for creating a network interface.
2935 * @param sc		software handle to the device
2936 * @returns		0 on success, error otherwise
2937 */
2938int
2939oce_create_iface(struct oce_softc *sc, uint8_t *macaddr)
2940{
2941	struct mbx_create_common_iface cmd;
2942	uint32_t caps, caps_en;
2943	int err = 0;
2944
2945	/* interface capabilities to give device when creating interface */
2946	caps = MBX_RX_IFACE_BROADCAST | MBX_RX_IFACE_UNTAGGED |
2947	    MBX_RX_IFACE_PROMISC | MBX_RX_IFACE_MCAST_PROMISC |
2948	    MBX_RX_IFACE_RSS;
2949
2950	/* capabilities to enable by default (others set dynamically) */
2951	caps_en = MBX_RX_IFACE_BROADCAST | MBX_RX_IFACE_UNTAGGED;
2952
2953	if (!IS_XE201(sc)) {
2954		/* LANCER A0 workaround */
2955		caps |= MBX_RX_IFACE_PASS_L3L4_ERR;
2956		caps_en |= MBX_RX_IFACE_PASS_L3L4_ERR;
2957	}
2958
2959	/* enable capabilities controlled via driver startup parameters */
2960	if (sc->sc_rss_enable)
2961		caps_en |= MBX_RX_IFACE_RSS;
2962
2963	memset(&cmd, 0, sizeof(cmd));
2964
2965	cmd.params.req.version = 0;
2966	cmd.params.req.cap_flags = htole32(caps);
2967	cmd.params.req.enable_flags = htole32(caps_en);
2968	if (macaddr != NULL) {
2969		memcpy(&cmd.params.req.mac_addr[0], macaddr, ETHER_ADDR_LEN);
2970		cmd.params.req.mac_invalid = 0;
2971	} else
2972		cmd.params.req.mac_invalid = 1;
2973
2974	err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CREATE_IFACE,
2975	    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
2976	if (err)
2977		return (err);
2978
2979	sc->sc_if_id = letoh32(cmd.params.rsp.if_id);
2980
2981	if (macaddr != NULL)
2982		sc->sc_pmac_id = letoh32(cmd.params.rsp.pmac_id);
2983
2984	return (0);
2985}
2986
2987/**
2988 * @brief Function to send the mbx command to configure vlan
2989 * @param sc 		software handle to the device
2990 * @param vtags		array of vlan tags
2991 * @param nvtags	number of elements in array
2992 * @param untagged	boolean TRUE/FLASE
2993 * @param promisc	flag to enable/disable VLAN promiscuous mode
2994 * @returns		0 on success, EIO on failure
2995 */
2996int
2997oce_config_vlan(struct oce_softc *sc, struct normal_vlan *vtags, int nvtags,
2998    int untagged, int promisc)
2999{
3000	struct mbx_common_config_vlan cmd;
3001
3002	memset(&cmd, 0, sizeof(cmd));
3003
3004	cmd.params.req.if_id = sc->sc_if_id;
3005	cmd.params.req.promisc = promisc;
3006	cmd.params.req.untagged = untagged;
3007	cmd.params.req.num_vlans = nvtags;
3008
3009	if (!promisc)
3010		memcpy(cmd.params.req.tags.normal_vlans, vtags,
3011			nvtags * sizeof(struct normal_vlan));
3012
3013	return (oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CONFIG_IFACE_VLAN,
3014	    OCE_MBX_VER_V0, &cmd, sizeof(cmd)));
3015}
3016
3017/**
3018 * @brief Function to set flow control capability in the hardware
3019 * @param sc 		software handle to the device
3020 * @param flags		flow control flags to set
3021 * @returns		0 on success, EIO on failure
3022 */
3023int
3024oce_set_flow_control(struct oce_softc *sc, uint64_t flags)
3025{
3026	struct mbx_common_get_set_flow_control cmd;
3027	int err;
3028
3029	memset(&cmd, 0, sizeof(cmd));
3030
3031	cmd.rx_flow_control = flags & IFM_ETH_RXPAUSE ? 1 : 0;
3032	cmd.tx_flow_control = flags & IFM_ETH_TXPAUSE ? 1 : 0;
3033
3034	err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_SET_FLOW_CONTROL,
3035	    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
3036	if (err)
3037		return (err);
3038
3039	memset(&cmd, 0, sizeof(cmd));
3040
3041	err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_GET_FLOW_CONTROL,
3042	    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
3043	if (err)
3044		return (err);
3045
3046	sc->sc_fc  = cmd.rx_flow_control ? IFM_ETH_RXPAUSE : 0;
3047	sc->sc_fc |= cmd.tx_flow_control ? IFM_ETH_TXPAUSE : 0;
3048
3049	return (0);
3050}
3051
3052#ifdef OCE_RSS
3053/**
3054 * @brief Function to set flow control capability in the hardware
3055 * @param sc 		software handle to the device
3056 * @param enable	0=disable, OCE_RSS_xxx flags otherwise
3057 * @returns		0 on success, EIO on failure
3058 */
3059int
3060oce_config_rss(struct oce_softc *sc, int enable)
3061{
3062	struct mbx_config_nic_rss cmd;
3063	uint8_t *tbl = &cmd.params.req.cputable;
3064	int i, j;
3065
3066	memset(&cmd, 0, sizeof(cmd));
3067
3068	if (enable)
3069		cmd.params.req.enable_rss = RSS_ENABLE_IPV4 | RSS_ENABLE_IPV6 |
3070		    RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_TCP_IPV6;
3071	cmd.params.req.flush = OCE_FLUSH;
3072	cmd.params.req.if_id = htole32(sc->sc_if_id);
3073
3074	arc4random_buf(cmd.params.req.hash, sizeof(cmd.params.req.hash));
3075
3076	/*
3077	 * Initialize the RSS CPU indirection table.
3078	 *
3079	 * The table is used to choose the queue to place incoming packets.
3080	 * Incoming packets are hashed.  The lowest bits in the hash result
3081	 * are used as the index into the CPU indirection table.
3082	 * Each entry in the table contains the RSS CPU-ID returned by the NIC
3083	 * create.  Based on the CPU ID, the receive completion is routed to
3084	 * the corresponding RSS CQs.  (Non-RSS packets are always completed
3085	 * on the default (0) CQ).
3086	 */
3087	for (i = 0, j = 0; j < sc->sc_nrq; j++) {
3088		if (sc->sc_rq[j]->cfg.is_rss_queue)
3089			tbl[i++] = sc->sc_rq[j]->rss_cpuid;
3090	}
3091	if (i > 0)
3092		cmd->params.req.cpu_tbl_sz_log2 = htole16(ilog2(i));
3093	else
3094		return (ENXIO);
3095
3096	return (oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_CONFIG_RSS, OCE_MBX_VER_V0,
3097	    &cmd, sizeof(cmd)));
3098}
3099#endif	/* OCE_RSS */
3100
3101/**
3102 * @brief Function for hardware update multicast filter
3103 * @param sc		software handle to the device
3104 * @param multi		table of multicast addresses
3105 * @param naddr		number of multicast addresses in the table
3106 */
3107int
3108oce_update_mcast(struct oce_softc *sc,
3109    uint8_t multi[][ETHER_ADDR_LEN], int naddr)
3110{
3111	struct mbx_set_common_iface_multicast cmd;
3112
3113	memset(&cmd, 0, sizeof(cmd));
3114
3115	memcpy(&cmd.params.req.mac[0], &multi[0], naddr * ETHER_ADDR_LEN);
3116	cmd.params.req.num_mac = htole16(naddr);
3117	cmd.params.req.if_id = sc->sc_if_id;
3118
3119	return (oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_SET_IFACE_MULTICAST,
3120	    OCE_MBX_VER_V0, &cmd, sizeof(cmd)));
3121}
3122
3123/**
3124 * @brief RXF function to enable/disable device promiscuous mode
3125 * @param sc		software handle to the device
3126 * @param enable	enable/disable flag
3127 * @returns		0 on success, EIO on failure
3128 * @note
3129 *	The OPCODE_NIC_CONFIG_PROMISCUOUS command deprecated for Lancer.
3130 *	This function uses the COMMON_SET_IFACE_RX_FILTER command instead.
3131 */
3132int
3133oce_set_promisc(struct oce_softc *sc, int enable)
3134{
3135	struct mbx_set_common_iface_rx_filter cmd;
3136	struct iface_rx_filter_ctx *req;
3137
3138	memset(&cmd, 0, sizeof(cmd));
3139
3140	req = &cmd.params.req;
3141	req->if_id = sc->sc_if_id;
3142
3143	if (enable)
3144		req->iface_flags = req->iface_flags_mask =
3145		    MBX_RX_IFACE_PROMISC | MBX_RX_IFACE_VLAN_PROMISC;
3146
3147	return (oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_SET_IFACE_RX_FILTER,
3148	    OCE_MBX_VER_V0, &cmd, sizeof(cmd)));
3149}
3150
3151/**
3152 * @brief Function to query the link status from the hardware
3153 * @param sc 		software handle to the device
3154 * @param[out] link	pointer to the structure returning link attributes
3155 * @returns		0 on success, EIO on failure
3156 */
3157int
3158oce_get_link_status(struct oce_softc *sc)
3159{
3160	struct mbx_query_common_link_config cmd;
3161	int err;
3162
3163	memset(&cmd, 0, sizeof(cmd));
3164
3165	err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_QUERY_LINK_CONFIG,
3166	    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
3167	if (err)
3168		return (err);
3169
3170	sc->sc_link_up = (letoh32(cmd.params.rsp.logical_link_status) ==
3171	    NTWK_LOGICAL_LINK_UP);
3172
3173	if (cmd.params.rsp.mac_speed < 5)
3174		sc->sc_link_speed = cmd.params.rsp.mac_speed;
3175	else
3176		sc->sc_link_speed = 0;
3177
3178	return (0);
3179}
3180
3181void
3182oce_macaddr_set(struct oce_softc *sc)
3183{
3184	uint32_t old_pmac_id = sc->sc_pmac_id;
3185	int status = 0;
3186
3187	if (!memcmp(sc->sc_macaddr, sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN))
3188		return;
3189
3190	status = oce_macaddr_add(sc, sc->sc_ac.ac_enaddr, &sc->sc_pmac_id);
3191	if (!status)
3192		status = oce_macaddr_del(sc, old_pmac_id);
3193	else
3194		printf("%s: failed to set MAC address\n", sc->sc_dev.dv_xname);
3195}
3196
3197int
3198oce_macaddr_get(struct oce_softc *sc, uint8_t *macaddr)
3199{
3200	struct mbx_query_common_iface_mac cmd;
3201	int err;
3202
3203	memset(&cmd, 0, sizeof(cmd));
3204
3205	cmd.params.req.type = MAC_ADDRESS_TYPE_NETWORK;
3206	cmd.params.req.permanent = 1;
3207
3208	err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_QUERY_IFACE_MAC,
3209	    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
3210	if (err == 0)
3211		memcpy(macaddr, &cmd.params.rsp.mac.mac_addr[0],
3212		    ETHER_ADDR_LEN);
3213	return (err);
3214}
3215
3216int
3217oce_macaddr_add(struct oce_softc *sc, uint8_t *enaddr, uint32_t *pmac)
3218{
3219	struct mbx_add_common_iface_mac cmd;
3220	int err;
3221
3222	memset(&cmd, 0, sizeof(cmd));
3223
3224	cmd.params.req.if_id = htole16(sc->sc_if_id);
3225	memcpy(cmd.params.req.mac_address, enaddr, ETHER_ADDR_LEN);
3226
3227	err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_ADD_IFACE_MAC,
3228	    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
3229	if (err == 0)
3230		*pmac = letoh32(cmd.params.rsp.pmac_id);
3231	return (err);
3232}
3233
3234int
3235oce_macaddr_del(struct oce_softc *sc, uint32_t pmac)
3236{
3237	struct mbx_del_common_iface_mac cmd;
3238
3239	memset(&cmd, 0, sizeof(cmd));
3240
3241	cmd.params.req.if_id = htole16(sc->sc_if_id);
3242	cmd.params.req.pmac_id = htole32(pmac);
3243
3244	return (oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_DEL_IFACE_MAC,
3245	    OCE_MBX_VER_V0, &cmd, sizeof(cmd)));
3246}
3247
3248int
3249oce_new_rq(struct oce_softc *sc, struct oce_rq *rq)
3250{
3251	struct mbx_create_nic_rq cmd;
3252	int err, npages;
3253
3254	memset(&cmd, 0, sizeof(cmd));
3255
3256	npages = oce_load_ring(sc, rq->ring, &cmd.params.req.pages[0],
3257	    nitems(cmd.params.req.pages));
3258	if (!npages) {
3259		printf("%s: failed to load the rq ring\n", __func__);
3260		return (1);
3261	}
3262
3263	if (IS_XE201(sc)) {
3264		cmd.params.req.frag_size = rq->fragsize / 2048;
3265		cmd.params.req.page_size = 1;
3266	} else
3267		cmd.params.req.frag_size = ilog2(rq->fragsize);
3268	cmd.params.req.num_pages = npages;
3269	cmd.params.req.cq_id = rq->cq->id;
3270	cmd.params.req.if_id = htole32(sc->sc_if_id);
3271	cmd.params.req.max_frame_size = htole16(rq->mtu);
3272	cmd.params.req.is_rss_queue = htole32(rq->rss);
3273
3274	err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_CREATE_RQ,
3275	    IS_XE201(sc) ? OCE_MBX_VER_V1 : OCE_MBX_VER_V0, &cmd,
3276	    sizeof(cmd));
3277	if (err)
3278		return (err);
3279
3280	rq->id = letoh16(cmd.params.rsp.rq_id);
3281	rq->rss_cpuid = cmd.params.rsp.rss_cpuid;
3282
3283	return (0);
3284}
3285
3286int
3287oce_new_wq(struct oce_softc *sc, struct oce_wq *wq)
3288{
3289	struct mbx_create_nic_wq cmd;
3290	int err, npages;
3291
3292	memset(&cmd, 0, sizeof(cmd));
3293
3294	npages = oce_load_ring(sc, wq->ring, &cmd.params.req.pages[0],
3295	    nitems(cmd.params.req.pages));
3296	if (!npages) {
3297		printf("%s: failed to load the wq ring\n", __func__);
3298		return (1);
3299	}
3300
3301	if (IS_XE201(sc))
3302		cmd.params.req.if_id = sc->sc_if_id;
3303	cmd.params.req.nic_wq_type = NIC_WQ_TYPE_STANDARD;
3304	cmd.params.req.num_pages = npages;
3305	cmd.params.req.wq_size = ilog2(wq->nitems) + 1;
3306	cmd.params.req.cq_id = htole16(wq->cq->id);
3307	cmd.params.req.ulp_num = 1;
3308
3309	err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_CREATE_WQ,
3310	    IS_XE201(sc) ? OCE_MBX_VER_V1 : OCE_MBX_VER_V0, &cmd,
3311	    sizeof(cmd));
3312	if (err)
3313		return (err);
3314
3315	wq->id = letoh16(cmd.params.rsp.wq_id);
3316
3317	return (0);
3318}
3319
3320int
3321oce_new_mq(struct oce_softc *sc, struct oce_mq *mq)
3322{
3323	struct mbx_create_common_mq_ex cmd;
3324	union oce_mq_ext_ctx *ctx;
3325	int err, npages;
3326
3327	memset(&cmd, 0, sizeof(cmd));
3328
3329	npages = oce_load_ring(sc, mq->ring, &cmd.params.req.pages[0],
3330	    nitems(cmd.params.req.pages));
3331	if (!npages) {
3332		printf("%s: failed to load the mq ring\n", __func__);
3333		return (-1);
3334	}
3335
3336	ctx = &cmd.params.req.context;
3337	ctx->v0.num_pages = npages;
3338	ctx->v0.cq_id = mq->cq->id;
3339	ctx->v0.ring_size = ilog2(mq->nitems) + 1;
3340	ctx->v0.valid = 1;
3341	/* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
3342	ctx->v0.async_evt_bitmap = 0xffffffff;
3343
3344	err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CREATE_MQ_EXT,
3345	    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
3346	if (err)
3347		return (err);
3348
3349	mq->id = letoh16(cmd.params.rsp.mq_id);
3350
3351	return (0);
3352}
3353
3354int
3355oce_new_eq(struct oce_softc *sc, struct oce_eq *eq)
3356{
3357	struct mbx_create_common_eq cmd;
3358	int err, npages;
3359
3360	memset(&cmd, 0, sizeof(cmd));
3361
3362	npages = oce_load_ring(sc, eq->ring, &cmd.params.req.pages[0],
3363	    nitems(cmd.params.req.pages));
3364	if (!npages) {
3365		printf("%s: failed to load the eq ring\n", __func__);
3366		return (-1);
3367	}
3368
3369	cmd.params.req.ctx.num_pages = htole16(npages);
3370	cmd.params.req.ctx.valid = 1;
3371	cmd.params.req.ctx.size = (eq->isize == 4) ? 0 : 1;
3372	cmd.params.req.ctx.count = ilog2(eq->nitems / 256);
3373	cmd.params.req.ctx.armed = 0;
3374	cmd.params.req.ctx.delay_mult = htole32(eq->delay);
3375
3376	err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CREATE_EQ,
3377	    OCE_MBX_VER_V0, &cmd, sizeof(cmd));
3378	if (err)
3379		return (err);
3380
3381	eq->id = letoh16(cmd.params.rsp.eq_id);
3382
3383	return (0);
3384}
3385
3386int
3387oce_new_cq(struct oce_softc *sc, struct oce_cq *cq)
3388{
3389	struct mbx_create_common_cq cmd;
3390	union oce_cq_ctx *ctx;
3391	int err, npages;
3392
3393	memset(&cmd, 0, sizeof(cmd));
3394
3395	npages = oce_load_ring(sc, cq->ring, &cmd.params.req.pages[0],
3396	    nitems(cmd.params.req.pages));
3397	if (!npages) {
3398		printf("%s: failed to load the cq ring\n", __func__);
3399		return (-1);
3400	}
3401
3402	ctx = &cmd.params.req.cq_ctx;
3403
3404	if (IS_XE201(sc)) {
3405		ctx->v2.num_pages = htole16(npages);
3406		ctx->v2.page_size = 1; /* for 4K */
3407		ctx->v2.eventable = cq->eventable;
3408		ctx->v2.valid = 1;
3409		ctx->v2.count = ilog2(cq->nitems / 256);
3410		ctx->v2.nodelay = cq->nodelay;
3411		ctx->v2.coalesce_wm = cq->ncoalesce;
3412		ctx->v2.armed = 0;
3413		ctx->v2.eq_id = cq->eq->id;
3414		if (ctx->v2.count == 3) {
3415			if (cq->nitems > (4*1024)-1)
3416				ctx->v2.cqe_count = (4*1024)-1;
3417			else
3418				ctx->v2.cqe_count = cq->nitems;
3419		}
3420	} else {
3421		ctx->v0.num_pages = htole16(npages);
3422		ctx->v0.eventable = cq->eventable;
3423		ctx->v0.valid = 1;
3424		ctx->v0.count = ilog2(cq->nitems / 256);
3425		ctx->v0.nodelay = cq->nodelay;
3426		ctx->v0.coalesce_wm = cq->ncoalesce;
3427		ctx->v0.armed = 0;
3428		ctx->v0.eq_id = cq->eq->id;
3429	}
3430
3431	err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CREATE_CQ,
3432	    IS_XE201(sc) ? OCE_MBX_VER_V2 : OCE_MBX_VER_V0, &cmd,
3433	    sizeof(cmd));
3434	if (err)
3435		return (err);
3436
3437	cq->id = letoh16(cmd.params.rsp.cq_id);
3438
3439	return (0);
3440}
3441
3442int
3443oce_init_stats(struct oce_softc *sc)
3444{
3445	union cmd {
3446		struct mbx_get_nic_stats_v0	_be2;
3447		struct mbx_get_nic_stats	_be3;
3448		struct mbx_get_pport_stats	_xe201;
3449	};
3450
3451	sc->sc_statcmd = malloc(sizeof(union cmd), M_DEVBUF, M_ZERO | M_NOWAIT);
3452	if (sc->sc_statcmd == NULL) {
3453		printf("%s: failed to allocate statistics command block\n",
3454		    sc->sc_dev.dv_xname);
3455		return (-1);
3456	}
3457	return (0);
3458}
3459
3460int
3461oce_update_stats(struct oce_softc *sc)
3462{
3463	struct ifnet *ifp = &sc->sc_ac.ac_if;
3464	uint64_t rxe, txe;
3465	int err;
3466
3467	if (ISSET(sc->sc_flags, OCE_F_BE2))
3468		err = oce_stats_be2(sc, &rxe, &txe);
3469	else if (ISSET(sc->sc_flags, OCE_F_BE3))
3470		err = oce_stats_be3(sc, &rxe, &txe);
3471	else
3472		err = oce_stats_xe(sc, &rxe, &txe);
3473	if (err)
3474		return (err);
3475
3476	ifp->if_ierrors += (rxe > sc->sc_rx_errors) ?
3477	    rxe - sc->sc_rx_errors : sc->sc_rx_errors - rxe;
3478	sc->sc_rx_errors = rxe;
3479	ifp->if_oerrors += (txe > sc->sc_tx_errors) ?
3480	    txe - sc->sc_tx_errors : sc->sc_tx_errors - txe;
3481	sc->sc_tx_errors = txe;
3482
3483	return (0);
3484}
3485
3486int
3487oce_stats_be2(struct oce_softc *sc, uint64_t *rxe, uint64_t *txe)
3488{
3489	struct mbx_get_nic_stats_v0 *cmd = sc->sc_statcmd;
3490	struct oce_pmem_stats *ms;
3491	struct oce_rxf_stats_v0 *rs;
3492	struct oce_port_rxf_stats_v0 *ps;
3493	int err;
3494
3495	memset(cmd, 0, sizeof(*cmd));
3496
3497	err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_GET_STATS, OCE_MBX_VER_V0,
3498	    cmd, sizeof(*cmd));
3499	if (err)
3500		return (err);
3501
3502	ms = &cmd->params.rsp.stats.pmem;
3503	rs = &cmd->params.rsp.stats.rxf;
3504	ps = &rs->port[sc->sc_port];
3505
3506	*rxe = ps->rx_crc_errors + ps->rx_in_range_errors +
3507	    ps->rx_frame_too_long + ps->rx_dropped_runt +
3508	    ps->rx_ip_checksum_errs + ps->rx_tcp_checksum_errs +
3509	    ps->rx_udp_checksum_errs + ps->rxpp_fifo_overflow_drop +
3510	    ps->rx_dropped_tcp_length + ps->rx_dropped_too_small +
3511	    ps->rx_dropped_too_short + ps->rx_out_range_errors +
3512	    ps->rx_dropped_header_too_small + ps->rx_input_fifo_overflow_drop +
3513	    ps->rx_alignment_symbol_errors;
3514	if (sc->sc_if_id)
3515		*rxe += rs->port1_jabber_events;
3516	else
3517		*rxe += rs->port0_jabber_events;
3518	*rxe += ms->eth_red_drops;
3519
3520	*txe = 0; /* hardware doesn't provide any extra tx error statistics */
3521
3522	return (0);
3523}
3524
3525int
3526oce_stats_be3(struct oce_softc *sc, uint64_t *rxe, uint64_t *txe)
3527{
3528	struct mbx_get_nic_stats *cmd = sc->sc_statcmd;
3529	struct oce_pmem_stats *ms;
3530	struct oce_rxf_stats_v1 *rs;
3531	struct oce_port_rxf_stats_v1 *ps;
3532	int err;
3533
3534	memset(cmd, 0, sizeof(*cmd));
3535
3536	err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_GET_STATS, OCE_MBX_VER_V1,
3537	    cmd, sizeof(*cmd));
3538	if (err)
3539		return (err);
3540
3541	ms = &cmd->params.rsp.stats.pmem;
3542	rs = &cmd->params.rsp.stats.rxf;
3543	ps = &rs->port[sc->sc_port];
3544
3545	*rxe = ps->rx_crc_errors + ps->rx_in_range_errors +
3546	    ps->rx_frame_too_long + ps->rx_dropped_runt +
3547	    ps->rx_ip_checksum_errs + ps->rx_tcp_checksum_errs +
3548	    ps->rx_udp_checksum_errs + ps->rxpp_fifo_overflow_drop +
3549	    ps->rx_dropped_tcp_length + ps->rx_dropped_too_small +
3550	    ps->rx_dropped_too_short + ps->rx_out_range_errors +
3551	    ps->rx_dropped_header_too_small + ps->rx_input_fifo_overflow_drop +
3552	    ps->rx_alignment_symbol_errors + ps->jabber_events;
3553	*rxe += ms->eth_red_drops;
3554
3555	*txe = 0; /* hardware doesn't provide any extra tx error statistics */
3556
3557	return (0);
3558}
3559
3560int
3561oce_stats_xe(struct oce_softc *sc, uint64_t *rxe, uint64_t *txe)
3562{
3563	struct mbx_get_pport_stats *cmd = sc->sc_statcmd;
3564	struct oce_pport_stats *pps;
3565	int err;
3566
3567	memset(cmd, 0, sizeof(*cmd));
3568
3569	cmd->params.req.reset_stats = 0;
3570	cmd->params.req.port_number = sc->sc_if_id;
3571
3572	err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_GET_PPORT_STATS,
3573	    OCE_MBX_VER_V0, cmd, sizeof(*cmd));
3574	if (err)
3575		return (err);
3576
3577	pps = &cmd->params.rsp.pps;
3578
3579	*rxe = pps->rx_discards + pps->rx_errors + pps->rx_crc_errors +
3580	    pps->rx_alignment_errors + pps->rx_symbol_errors +
3581	    pps->rx_frames_too_long + pps->rx_internal_mac_errors +
3582	    pps->rx_undersize_pkts + pps->rx_oversize_pkts + pps->rx_jabbers +
3583	    pps->rx_control_frames_unknown_opcode + pps->rx_in_range_errors +
3584	    pps->rx_out_of_range_errors + pps->rx_ip_checksum_errors +
3585	    pps->rx_tcp_checksum_errors + pps->rx_udp_checksum_errors +
3586	    pps->rx_fifo_overflow + pps->rx_input_fifo_overflow +
3587	    pps->rx_drops_too_many_frags + pps->rx_drops_mtu;
3588
3589	*txe = pps->tx_discards + pps->tx_errors + pps->tx_internal_mac_errors;
3590
3591	return (0);
3592}
3593