xref: /freebsd/sys/dev/bnxt/bnxt_en/bnxt_txrx.c (revision 35b53f8c989f62286aad075ef2e97bba358144f8)
1*35b53f8cSChandrakanth patil /*-
2*35b53f8cSChandrakanth patil  * Broadcom NetXtreme-C/E network driver.
3*35b53f8cSChandrakanth patil  *
4*35b53f8cSChandrakanth patil  * Copyright (c) 2016 Broadcom, All Rights Reserved.
5*35b53f8cSChandrakanth patil  * The term Broadcom refers to Broadcom Limited and/or its subsidiaries
6*35b53f8cSChandrakanth patil  *
7*35b53f8cSChandrakanth patil  * Redistribution and use in source and binary forms, with or without
8*35b53f8cSChandrakanth patil  * modification, are permitted provided that the following conditions
9*35b53f8cSChandrakanth patil  * are met:
10*35b53f8cSChandrakanth patil  * 1. Redistributions of source code must retain the above copyright
11*35b53f8cSChandrakanth patil  *    notice, this list of conditions and the following disclaimer.
12*35b53f8cSChandrakanth patil  * 2. Redistributions in binary form must reproduce the above copyright
13*35b53f8cSChandrakanth patil  *    notice, this list of conditions and the following disclaimer in the
14*35b53f8cSChandrakanth patil  *    documentation and/or other materials provided with the distribution.
15*35b53f8cSChandrakanth patil  *
16*35b53f8cSChandrakanth patil  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
17*35b53f8cSChandrakanth patil  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*35b53f8cSChandrakanth patil  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*35b53f8cSChandrakanth patil  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20*35b53f8cSChandrakanth patil  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*35b53f8cSChandrakanth patil  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*35b53f8cSChandrakanth patil  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*35b53f8cSChandrakanth patil  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*35b53f8cSChandrakanth patil  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*35b53f8cSChandrakanth patil  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26*35b53f8cSChandrakanth patil  * THE POSSIBILITY OF SUCH DAMAGE.
27*35b53f8cSChandrakanth patil  */
28*35b53f8cSChandrakanth patil 
29*35b53f8cSChandrakanth patil #include <sys/types.h>
30*35b53f8cSChandrakanth patil #include <sys/socket.h>
31*35b53f8cSChandrakanth patil #include <sys/endian.h>
32*35b53f8cSChandrakanth patil #include <net/if.h>
33*35b53f8cSChandrakanth patil #include <net/if_var.h>
34*35b53f8cSChandrakanth patil #include <net/ethernet.h>
35*35b53f8cSChandrakanth patil #include <net/iflib.h>
36*35b53f8cSChandrakanth patil 
37*35b53f8cSChandrakanth patil #include "opt_inet.h"
38*35b53f8cSChandrakanth patil #include "opt_inet6.h"
39*35b53f8cSChandrakanth patil #include "opt_rss.h"
40*35b53f8cSChandrakanth patil 
41*35b53f8cSChandrakanth patil #include "bnxt.h"
42*35b53f8cSChandrakanth patil 
43*35b53f8cSChandrakanth patil /*
44*35b53f8cSChandrakanth patil  * Function prototypes
45*35b53f8cSChandrakanth patil  */
46*35b53f8cSChandrakanth patil 
47*35b53f8cSChandrakanth patil static int bnxt_isc_txd_encap(void *sc, if_pkt_info_t pi);
48*35b53f8cSChandrakanth patil static void bnxt_isc_txd_flush(void *sc, uint16_t txqid, qidx_t pidx);
49*35b53f8cSChandrakanth patil static int bnxt_isc_txd_credits_update(void *sc, uint16_t txqid, bool clear);
50*35b53f8cSChandrakanth patil 
51*35b53f8cSChandrakanth patil static void bnxt_isc_rxd_refill(void *sc, if_rxd_update_t iru);
52*35b53f8cSChandrakanth patil 
53*35b53f8cSChandrakanth patil /*				uint16_t rxqid, uint8_t flid,
54*35b53f8cSChandrakanth patil     uint32_t pidx, uint64_t *paddrs, caddr_t *vaddrs, uint16_t count,
55*35b53f8cSChandrakanth patil     uint16_t buf_size);
56*35b53f8cSChandrakanth patil */
57*35b53f8cSChandrakanth patil static void bnxt_isc_rxd_flush(void *sc, uint16_t rxqid, uint8_t flid,
58*35b53f8cSChandrakanth patil     qidx_t pidx);
59*35b53f8cSChandrakanth patil static int bnxt_isc_rxd_available(void *sc, uint16_t rxqid, qidx_t idx,
60*35b53f8cSChandrakanth patil     qidx_t budget);
61*35b53f8cSChandrakanth patil static int bnxt_isc_rxd_pkt_get(void *sc, if_rxd_info_t ri);
62*35b53f8cSChandrakanth patil 
63*35b53f8cSChandrakanth patil static int bnxt_intr(void *sc);
64*35b53f8cSChandrakanth patil 
65*35b53f8cSChandrakanth patil struct if_txrx bnxt_txrx  = {
66*35b53f8cSChandrakanth patil 	.ift_txd_encap = bnxt_isc_txd_encap,
67*35b53f8cSChandrakanth patil 	.ift_txd_flush = bnxt_isc_txd_flush,
68*35b53f8cSChandrakanth patil 	.ift_txd_credits_update = bnxt_isc_txd_credits_update,
69*35b53f8cSChandrakanth patil 	.ift_rxd_available = bnxt_isc_rxd_available,
70*35b53f8cSChandrakanth patil 	.ift_rxd_pkt_get = bnxt_isc_rxd_pkt_get,
71*35b53f8cSChandrakanth patil 	.ift_rxd_refill = bnxt_isc_rxd_refill,
72*35b53f8cSChandrakanth patil 	.ift_rxd_flush = bnxt_isc_rxd_flush,
73*35b53f8cSChandrakanth patil 	.ift_legacy_intr = bnxt_intr
74*35b53f8cSChandrakanth patil };
75*35b53f8cSChandrakanth patil 
76*35b53f8cSChandrakanth patil /*
77*35b53f8cSChandrakanth patil  * Device Dependent Packet Transmit and Receive Functions
78*35b53f8cSChandrakanth patil  */
79*35b53f8cSChandrakanth patil 
80*35b53f8cSChandrakanth patil static const uint16_t bnxt_tx_lhint[] = {
81*35b53f8cSChandrakanth patil 	TX_BD_SHORT_FLAGS_LHINT_LT512,
82*35b53f8cSChandrakanth patil 	TX_BD_SHORT_FLAGS_LHINT_LT1K,
83*35b53f8cSChandrakanth patil 	TX_BD_SHORT_FLAGS_LHINT_LT2K,
84*35b53f8cSChandrakanth patil 	TX_BD_SHORT_FLAGS_LHINT_LT2K,
85*35b53f8cSChandrakanth patil 	TX_BD_SHORT_FLAGS_LHINT_GTE2K,
86*35b53f8cSChandrakanth patil };
87*35b53f8cSChandrakanth patil 
88*35b53f8cSChandrakanth patil static int
bnxt_isc_txd_encap(void * sc,if_pkt_info_t pi)89*35b53f8cSChandrakanth patil bnxt_isc_txd_encap(void *sc, if_pkt_info_t pi)
90*35b53f8cSChandrakanth patil {
91*35b53f8cSChandrakanth patil 	struct bnxt_softc *softc = (struct bnxt_softc *)sc;
92*35b53f8cSChandrakanth patil 	struct bnxt_ring *txr = &softc->tx_rings[pi->ipi_qsidx];
93*35b53f8cSChandrakanth patil 	struct tx_bd_long *tbd;
94*35b53f8cSChandrakanth patil 	struct tx_bd_long_hi *tbdh;
95*35b53f8cSChandrakanth patil 	bool need_hi = false;
96*35b53f8cSChandrakanth patil 	uint16_t flags_type;
97*35b53f8cSChandrakanth patil 	uint16_t lflags;
98*35b53f8cSChandrakanth patil 	uint32_t cfa_meta;
99*35b53f8cSChandrakanth patil 	int seg = 0;
100*35b53f8cSChandrakanth patil 
101*35b53f8cSChandrakanth patil 	/* If we have offloads enabled, we need to use two BDs. */
102*35b53f8cSChandrakanth patil 	if ((pi->ipi_csum_flags & (CSUM_OFFLOAD | CSUM_TSO | CSUM_IP)) ||
103*35b53f8cSChandrakanth patil 	    pi->ipi_mflags & M_VLANTAG)
104*35b53f8cSChandrakanth patil 		need_hi = true;
105*35b53f8cSChandrakanth patil 
106*35b53f8cSChandrakanth patil 	/* TODO: Devices before Cu+B1 need to not mix long and short BDs */
107*35b53f8cSChandrakanth patil 	need_hi = true;
108*35b53f8cSChandrakanth patil 
109*35b53f8cSChandrakanth patil 	pi->ipi_new_pidx = pi->ipi_pidx;
110*35b53f8cSChandrakanth patil 	tbd = &((struct tx_bd_long *)txr->vaddr)[pi->ipi_new_pidx];
111*35b53f8cSChandrakanth patil 	pi->ipi_ndescs = 0;
112*35b53f8cSChandrakanth patil 	/* No need to byte-swap the opaque value */
113*35b53f8cSChandrakanth patil 	tbd->opaque = ((pi->ipi_nsegs + need_hi) << 24) | pi->ipi_new_pidx;
114*35b53f8cSChandrakanth patil 	tbd->len = htole16(pi->ipi_segs[seg].ds_len);
115*35b53f8cSChandrakanth patil 	tbd->addr = htole64(pi->ipi_segs[seg++].ds_addr);
116*35b53f8cSChandrakanth patil 	flags_type = ((pi->ipi_nsegs + need_hi) <<
117*35b53f8cSChandrakanth patil 	    TX_BD_SHORT_FLAGS_BD_CNT_SFT) & TX_BD_SHORT_FLAGS_BD_CNT_MASK;
118*35b53f8cSChandrakanth patil 	if (pi->ipi_len >= 2048)
119*35b53f8cSChandrakanth patil 		flags_type |= TX_BD_SHORT_FLAGS_LHINT_GTE2K;
120*35b53f8cSChandrakanth patil 	else
121*35b53f8cSChandrakanth patil 		flags_type |= bnxt_tx_lhint[pi->ipi_len >> 9];
122*35b53f8cSChandrakanth patil 
123*35b53f8cSChandrakanth patil 	if (need_hi) {
124*35b53f8cSChandrakanth patil 		flags_type |= TX_BD_LONG_TYPE_TX_BD_LONG;
125*35b53f8cSChandrakanth patil 
126*35b53f8cSChandrakanth patil 		pi->ipi_new_pidx = RING_NEXT(txr, pi->ipi_new_pidx);
127*35b53f8cSChandrakanth patil 		tbdh = &((struct tx_bd_long_hi *)txr->vaddr)[pi->ipi_new_pidx];
128*35b53f8cSChandrakanth patil 		tbdh->kid_or_ts_high_mss = htole16(pi->ipi_tso_segsz);
129*35b53f8cSChandrakanth patil 		tbdh->kid_or_ts_low_hdr_size = htole16((pi->ipi_ehdrlen + pi->ipi_ip_hlen +
130*35b53f8cSChandrakanth patil 		    pi->ipi_tcp_hlen) >> 1);
131*35b53f8cSChandrakanth patil 		tbdh->cfa_action = 0;
132*35b53f8cSChandrakanth patil 		lflags = 0;
133*35b53f8cSChandrakanth patil 		cfa_meta = 0;
134*35b53f8cSChandrakanth patil 		if (pi->ipi_mflags & M_VLANTAG) {
135*35b53f8cSChandrakanth patil 			/* TODO: Do we need to byte-swap the vtag here? */
136*35b53f8cSChandrakanth patil 			cfa_meta = TX_BD_LONG_CFA_META_KEY_VLAN_TAG |
137*35b53f8cSChandrakanth patil 			    pi->ipi_vtag;
138*35b53f8cSChandrakanth patil 			cfa_meta |= TX_BD_LONG_CFA_META_VLAN_TPID_TPID8100;
139*35b53f8cSChandrakanth patil 		}
140*35b53f8cSChandrakanth patil 		tbdh->cfa_meta = htole32(cfa_meta);
141*35b53f8cSChandrakanth patil 		if (pi->ipi_csum_flags & CSUM_TSO) {
142*35b53f8cSChandrakanth patil 			lflags |= TX_BD_LONG_LFLAGS_LSO |
143*35b53f8cSChandrakanth patil 			    TX_BD_LONG_LFLAGS_T_IPID;
144*35b53f8cSChandrakanth patil 		}
145*35b53f8cSChandrakanth patil 		else if(pi->ipi_csum_flags & CSUM_OFFLOAD) {
146*35b53f8cSChandrakanth patil 			lflags |= TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM |
147*35b53f8cSChandrakanth patil 			    TX_BD_LONG_LFLAGS_IP_CHKSUM;
148*35b53f8cSChandrakanth patil 		}
149*35b53f8cSChandrakanth patil 		else if(pi->ipi_csum_flags & CSUM_IP) {
150*35b53f8cSChandrakanth patil 			lflags |= TX_BD_LONG_LFLAGS_IP_CHKSUM;
151*35b53f8cSChandrakanth patil 		}
152*35b53f8cSChandrakanth patil 		tbdh->lflags = htole16(lflags);
153*35b53f8cSChandrakanth patil 	}
154*35b53f8cSChandrakanth patil 	else {
155*35b53f8cSChandrakanth patil 		flags_type |= TX_BD_SHORT_TYPE_TX_BD_SHORT;
156*35b53f8cSChandrakanth patil 	}
157*35b53f8cSChandrakanth patil 
158*35b53f8cSChandrakanth patil 	for (; seg < pi->ipi_nsegs; seg++) {
159*35b53f8cSChandrakanth patil 		tbd->flags_type = htole16(flags_type);
160*35b53f8cSChandrakanth patil 		pi->ipi_new_pidx = RING_NEXT(txr, pi->ipi_new_pidx);
161*35b53f8cSChandrakanth patil 		tbd = &((struct tx_bd_long *)txr->vaddr)[pi->ipi_new_pidx];
162*35b53f8cSChandrakanth patil 		tbd->len = htole16(pi->ipi_segs[seg].ds_len);
163*35b53f8cSChandrakanth patil 		tbd->addr = htole64(pi->ipi_segs[seg].ds_addr);
164*35b53f8cSChandrakanth patil 		flags_type = TX_BD_SHORT_TYPE_TX_BD_SHORT;
165*35b53f8cSChandrakanth patil 	}
166*35b53f8cSChandrakanth patil 	flags_type |= TX_BD_SHORT_FLAGS_PACKET_END;
167*35b53f8cSChandrakanth patil 	tbd->flags_type = htole16(flags_type);
168*35b53f8cSChandrakanth patil 	pi->ipi_new_pidx = RING_NEXT(txr, pi->ipi_new_pidx);
169*35b53f8cSChandrakanth patil 
170*35b53f8cSChandrakanth patil 	return 0;
171*35b53f8cSChandrakanth patil }
172*35b53f8cSChandrakanth patil 
173*35b53f8cSChandrakanth patil static void
bnxt_isc_txd_flush(void * sc,uint16_t txqid,qidx_t pidx)174*35b53f8cSChandrakanth patil bnxt_isc_txd_flush(void *sc, uint16_t txqid, qidx_t pidx)
175*35b53f8cSChandrakanth patil {
176*35b53f8cSChandrakanth patil 	struct bnxt_softc *softc = (struct bnxt_softc *)sc;
177*35b53f8cSChandrakanth patil 	struct bnxt_ring *tx_ring = &softc->tx_rings[txqid];
178*35b53f8cSChandrakanth patil 
179*35b53f8cSChandrakanth patil 	/* pidx is what we last set ipi_new_pidx to */
180*35b53f8cSChandrakanth patil 	softc->db_ops.bnxt_db_tx(tx_ring, pidx);
181*35b53f8cSChandrakanth patil 	return;
182*35b53f8cSChandrakanth patil }
183*35b53f8cSChandrakanth patil 
184*35b53f8cSChandrakanth patil static int
bnxt_isc_txd_credits_update(void * sc,uint16_t txqid,bool clear)185*35b53f8cSChandrakanth patil bnxt_isc_txd_credits_update(void *sc, uint16_t txqid, bool clear)
186*35b53f8cSChandrakanth patil {
187*35b53f8cSChandrakanth patil 	struct bnxt_softc *softc = (struct bnxt_softc *)sc;
188*35b53f8cSChandrakanth patil 	struct bnxt_cp_ring *cpr = &softc->tx_cp_rings[txqid];
189*35b53f8cSChandrakanth patil 	struct tx_cmpl *cmpl = (struct tx_cmpl *)cpr->ring.vaddr;
190*35b53f8cSChandrakanth patil 	int avail = 0;
191*35b53f8cSChandrakanth patil 	uint32_t cons = cpr->cons;
192*35b53f8cSChandrakanth patil 	bool v_bit = cpr->v_bit;
193*35b53f8cSChandrakanth patil 	bool last_v_bit;
194*35b53f8cSChandrakanth patil 	uint32_t last_cons;
195*35b53f8cSChandrakanth patil 	uint16_t type;
196*35b53f8cSChandrakanth patil 	uint16_t err;
197*35b53f8cSChandrakanth patil 
198*35b53f8cSChandrakanth patil 	for (;;) {
199*35b53f8cSChandrakanth patil 		last_cons = cons;
200*35b53f8cSChandrakanth patil 		last_v_bit = v_bit;
201*35b53f8cSChandrakanth patil 		NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
202*35b53f8cSChandrakanth patil 		CMPL_PREFETCH_NEXT(cpr, cons);
203*35b53f8cSChandrakanth patil 
204*35b53f8cSChandrakanth patil 		if (!CMP_VALID(&cmpl[cons], v_bit))
205*35b53f8cSChandrakanth patil 			goto done;
206*35b53f8cSChandrakanth patil 
207*35b53f8cSChandrakanth patil 		type = cmpl[cons].flags_type & TX_CMPL_TYPE_MASK;
208*35b53f8cSChandrakanth patil 		switch (type) {
209*35b53f8cSChandrakanth patil 		case TX_CMPL_TYPE_TX_L2:
210*35b53f8cSChandrakanth patil 			err = (le16toh(cmpl[cons].errors_v) &
211*35b53f8cSChandrakanth patil 			    TX_CMPL_ERRORS_BUFFER_ERROR_MASK) >>
212*35b53f8cSChandrakanth patil 			    TX_CMPL_ERRORS_BUFFER_ERROR_SFT;
213*35b53f8cSChandrakanth patil 			if (err)
214*35b53f8cSChandrakanth patil 				device_printf(softc->dev,
215*35b53f8cSChandrakanth patil 				    "TX completion error %u\n", err);
216*35b53f8cSChandrakanth patil 			/* No need to byte-swap the opaque value */
217*35b53f8cSChandrakanth patil 			avail += cmpl[cons].opaque >> 24;
218*35b53f8cSChandrakanth patil 			/*
219*35b53f8cSChandrakanth patil 			 * If we're not clearing, iflib only cares if there's
220*35b53f8cSChandrakanth patil 			 * at least one buffer.  Don't scan the whole ring in
221*35b53f8cSChandrakanth patil 			 * this case.
222*35b53f8cSChandrakanth patil 			 */
223*35b53f8cSChandrakanth patil 			if (!clear)
224*35b53f8cSChandrakanth patil 				goto done;
225*35b53f8cSChandrakanth patil 			break;
226*35b53f8cSChandrakanth patil 		default:
227*35b53f8cSChandrakanth patil 			if (type & 1) {
228*35b53f8cSChandrakanth patil 				NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
229*35b53f8cSChandrakanth patil 				if (!CMP_VALID(&cmpl[cons], v_bit))
230*35b53f8cSChandrakanth patil 					goto done;
231*35b53f8cSChandrakanth patil 			}
232*35b53f8cSChandrakanth patil 			device_printf(softc->dev,
233*35b53f8cSChandrakanth patil 			    "Unhandled TX completion type %u\n", type);
234*35b53f8cSChandrakanth patil 			break;
235*35b53f8cSChandrakanth patil 		}
236*35b53f8cSChandrakanth patil 	}
237*35b53f8cSChandrakanth patil done:
238*35b53f8cSChandrakanth patil 
239*35b53f8cSChandrakanth patil 	if (clear && avail) {
240*35b53f8cSChandrakanth patil 		cpr->cons = last_cons;
241*35b53f8cSChandrakanth patil 		cpr->v_bit = last_v_bit;
242*35b53f8cSChandrakanth patil 		softc->db_ops.bnxt_db_tx_cq(cpr, 0);
243*35b53f8cSChandrakanth patil 	}
244*35b53f8cSChandrakanth patil 
245*35b53f8cSChandrakanth patil 	return avail;
246*35b53f8cSChandrakanth patil }
247*35b53f8cSChandrakanth patil 
248*35b53f8cSChandrakanth patil static void
bnxt_isc_rxd_refill(void * sc,if_rxd_update_t iru)249*35b53f8cSChandrakanth patil bnxt_isc_rxd_refill(void *sc, if_rxd_update_t iru)
250*35b53f8cSChandrakanth patil {
251*35b53f8cSChandrakanth patil 	struct bnxt_softc *softc = (struct bnxt_softc *)sc;
252*35b53f8cSChandrakanth patil 	struct bnxt_ring *rx_ring;
253*35b53f8cSChandrakanth patil 	struct rx_prod_pkt_bd *rxbd;
254*35b53f8cSChandrakanth patil 	uint16_t type;
255*35b53f8cSChandrakanth patil 	uint16_t i;
256*35b53f8cSChandrakanth patil 	uint16_t rxqid;
257*35b53f8cSChandrakanth patil 	uint16_t count;
258*35b53f8cSChandrakanth patil 	uint32_t pidx;
259*35b53f8cSChandrakanth patil 	uint8_t flid;
260*35b53f8cSChandrakanth patil 	uint64_t *paddrs;
261*35b53f8cSChandrakanth patil 	qidx_t	*frag_idxs;
262*35b53f8cSChandrakanth patil 
263*35b53f8cSChandrakanth patil 	rxqid = iru->iru_qsidx;
264*35b53f8cSChandrakanth patil 	count = iru->iru_count;
265*35b53f8cSChandrakanth patil 	pidx = iru->iru_pidx;
266*35b53f8cSChandrakanth patil 	flid = iru->iru_flidx;
267*35b53f8cSChandrakanth patil 	paddrs = iru->iru_paddrs;
268*35b53f8cSChandrakanth patil 	frag_idxs = iru->iru_idxs;
269*35b53f8cSChandrakanth patil 
270*35b53f8cSChandrakanth patil 	if (flid == 0) {
271*35b53f8cSChandrakanth patil 		rx_ring = &softc->rx_rings[rxqid];
272*35b53f8cSChandrakanth patil 		type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT;
273*35b53f8cSChandrakanth patil 	}
274*35b53f8cSChandrakanth patil 	else {
275*35b53f8cSChandrakanth patil 		rx_ring = &softc->ag_rings[rxqid];
276*35b53f8cSChandrakanth patil 		type = RX_PROD_AGG_BD_TYPE_RX_PROD_AGG;
277*35b53f8cSChandrakanth patil 	}
278*35b53f8cSChandrakanth patil 	rxbd = (void *)rx_ring->vaddr;
279*35b53f8cSChandrakanth patil 
280*35b53f8cSChandrakanth patil 	for (i=0; i<count; i++) {
281*35b53f8cSChandrakanth patil 		rxbd[pidx].flags_type = htole16(type);
282*35b53f8cSChandrakanth patil 		rxbd[pidx].len = htole16(softc->rx_buf_size);
283*35b53f8cSChandrakanth patil 		/* No need to byte-swap the opaque value */
284*35b53f8cSChandrakanth patil 		rxbd[pidx].opaque = (((rxqid & 0xff) << 24) | (flid << 16)
285*35b53f8cSChandrakanth patil 		    | (frag_idxs[i]));
286*35b53f8cSChandrakanth patil 		rxbd[pidx].addr = htole64(paddrs[i]);
287*35b53f8cSChandrakanth patil 		if (++pidx == rx_ring->ring_size)
288*35b53f8cSChandrakanth patil 			pidx = 0;
289*35b53f8cSChandrakanth patil 	}
290*35b53f8cSChandrakanth patil 	return;
291*35b53f8cSChandrakanth patil }
292*35b53f8cSChandrakanth patil 
293*35b53f8cSChandrakanth patil static void
bnxt_isc_rxd_flush(void * sc,uint16_t rxqid,uint8_t flid,qidx_t pidx)294*35b53f8cSChandrakanth patil bnxt_isc_rxd_flush(void *sc, uint16_t rxqid, uint8_t flid,
295*35b53f8cSChandrakanth patil     qidx_t pidx)
296*35b53f8cSChandrakanth patil {
297*35b53f8cSChandrakanth patil 	struct bnxt_softc *softc = (struct bnxt_softc *)sc;
298*35b53f8cSChandrakanth patil 	struct bnxt_ring *rx_ring;
299*35b53f8cSChandrakanth patil 
300*35b53f8cSChandrakanth patil 	if (flid == 0)
301*35b53f8cSChandrakanth patil 		rx_ring = &softc->rx_rings[rxqid];
302*35b53f8cSChandrakanth patil 	else
303*35b53f8cSChandrakanth patil 		rx_ring = &softc->ag_rings[rxqid];
304*35b53f8cSChandrakanth patil 
305*35b53f8cSChandrakanth patil 	/*
306*35b53f8cSChandrakanth patil 	 * We *must* update the completion ring before updating the RX ring
307*35b53f8cSChandrakanth patil 	 * or we will overrun the completion ring and the device will wedge for
308*35b53f8cSChandrakanth patil 	 * RX.
309*35b53f8cSChandrakanth patil 	 */
310*35b53f8cSChandrakanth patil 	softc->db_ops.bnxt_db_rx_cq(&softc->rx_cp_rings[rxqid], 0);
311*35b53f8cSChandrakanth patil 	softc->db_ops.bnxt_db_rx(rx_ring, pidx);
312*35b53f8cSChandrakanth patil 	return;
313*35b53f8cSChandrakanth patil }
314*35b53f8cSChandrakanth patil 
315*35b53f8cSChandrakanth patil static int
bnxt_isc_rxd_available(void * sc,uint16_t rxqid,qidx_t idx,qidx_t budget)316*35b53f8cSChandrakanth patil bnxt_isc_rxd_available(void *sc, uint16_t rxqid, qidx_t idx, qidx_t budget)
317*35b53f8cSChandrakanth patil {
318*35b53f8cSChandrakanth patil 	struct bnxt_softc *softc = (struct bnxt_softc *)sc;
319*35b53f8cSChandrakanth patil 	struct bnxt_cp_ring *cpr = &softc->rx_cp_rings[rxqid];
320*35b53f8cSChandrakanth patil 	struct rx_pkt_cmpl *rcp;
321*35b53f8cSChandrakanth patil 	struct rx_tpa_end_cmpl *rtpae;
322*35b53f8cSChandrakanth patil 	struct cmpl_base *cmp = (struct cmpl_base *)cpr->ring.vaddr;
323*35b53f8cSChandrakanth patil 	int avail = 0;
324*35b53f8cSChandrakanth patil 	uint32_t cons = cpr->cons;
325*35b53f8cSChandrakanth patil 	bool v_bit = cpr->v_bit;
326*35b53f8cSChandrakanth patil 	uint8_t ags;
327*35b53f8cSChandrakanth patil 	int i;
328*35b53f8cSChandrakanth patil 	uint16_t type;
329*35b53f8cSChandrakanth patil 
330*35b53f8cSChandrakanth patil 	for (;;) {
331*35b53f8cSChandrakanth patil 		NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
332*35b53f8cSChandrakanth patil 		CMPL_PREFETCH_NEXT(cpr, cons);
333*35b53f8cSChandrakanth patil 
334*35b53f8cSChandrakanth patil 		if (!CMP_VALID(&cmp[cons], v_bit))
335*35b53f8cSChandrakanth patil 			goto cmpl_invalid;
336*35b53f8cSChandrakanth patil 
337*35b53f8cSChandrakanth patil 		type = le16toh(cmp[cons].type) & CMPL_BASE_TYPE_MASK;
338*35b53f8cSChandrakanth patil 		switch (type) {
339*35b53f8cSChandrakanth patil 		case CMPL_BASE_TYPE_RX_L2:
340*35b53f8cSChandrakanth patil 			rcp = (void *)&cmp[cons];
341*35b53f8cSChandrakanth patil 			ags = (rcp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK) >>
342*35b53f8cSChandrakanth patil 			    RX_PKT_CMPL_AGG_BUFS_SFT;
343*35b53f8cSChandrakanth patil 			NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
344*35b53f8cSChandrakanth patil 			CMPL_PREFETCH_NEXT(cpr, cons);
345*35b53f8cSChandrakanth patil 
346*35b53f8cSChandrakanth patil 			if (!CMP_VALID(&cmp[cons], v_bit))
347*35b53f8cSChandrakanth patil 				goto cmpl_invalid;
348*35b53f8cSChandrakanth patil 
349*35b53f8cSChandrakanth patil 			/* Now account for all the AG completions */
350*35b53f8cSChandrakanth patil 			for (i=0; i<ags; i++) {
351*35b53f8cSChandrakanth patil 				NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
352*35b53f8cSChandrakanth patil 				CMPL_PREFETCH_NEXT(cpr, cons);
353*35b53f8cSChandrakanth patil 				if (!CMP_VALID(&cmp[cons], v_bit))
354*35b53f8cSChandrakanth patil 					goto cmpl_invalid;
355*35b53f8cSChandrakanth patil 			}
356*35b53f8cSChandrakanth patil 			avail++;
357*35b53f8cSChandrakanth patil 			break;
358*35b53f8cSChandrakanth patil 		case CMPL_BASE_TYPE_RX_TPA_END:
359*35b53f8cSChandrakanth patil 			rtpae = (void *)&cmp[cons];
360*35b53f8cSChandrakanth patil 			ags = (rtpae->agg_bufs_v1 &
361*35b53f8cSChandrakanth patil 			    RX_TPA_END_CMPL_AGG_BUFS_MASK) >>
362*35b53f8cSChandrakanth patil 			    RX_TPA_END_CMPL_AGG_BUFS_SFT;
363*35b53f8cSChandrakanth patil 			NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
364*35b53f8cSChandrakanth patil 			CMPL_PREFETCH_NEXT(cpr, cons);
365*35b53f8cSChandrakanth patil 
366*35b53f8cSChandrakanth patil 			if (!CMP_VALID(&cmp[cons], v_bit))
367*35b53f8cSChandrakanth patil 				goto cmpl_invalid;
368*35b53f8cSChandrakanth patil 			/* Now account for all the AG completions */
369*35b53f8cSChandrakanth patil 			for (i=0; i<ags; i++) {
370*35b53f8cSChandrakanth patil 				NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
371*35b53f8cSChandrakanth patil 				CMPL_PREFETCH_NEXT(cpr, cons);
372*35b53f8cSChandrakanth patil 				if (!CMP_VALID(&cmp[cons], v_bit))
373*35b53f8cSChandrakanth patil 					goto cmpl_invalid;
374*35b53f8cSChandrakanth patil 			}
375*35b53f8cSChandrakanth patil 			avail++;
376*35b53f8cSChandrakanth patil 			break;
377*35b53f8cSChandrakanth patil 		case CMPL_BASE_TYPE_RX_TPA_START:
378*35b53f8cSChandrakanth patil 			NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
379*35b53f8cSChandrakanth patil 			CMPL_PREFETCH_NEXT(cpr, cons);
380*35b53f8cSChandrakanth patil 
381*35b53f8cSChandrakanth patil 			if (!CMP_VALID(&cmp[cons], v_bit))
382*35b53f8cSChandrakanth patil 				goto cmpl_invalid;
383*35b53f8cSChandrakanth patil 			break;
384*35b53f8cSChandrakanth patil 		case CMPL_BASE_TYPE_RX_AGG:
385*35b53f8cSChandrakanth patil 			break;
386*35b53f8cSChandrakanth patil 		default:
387*35b53f8cSChandrakanth patil 			device_printf(softc->dev,
388*35b53f8cSChandrakanth patil 			    "Unhandled completion type %d on RXQ %d\n",
389*35b53f8cSChandrakanth patil 			    type, rxqid);
390*35b53f8cSChandrakanth patil 
391*35b53f8cSChandrakanth patil 			/* Odd completion types use two completions */
392*35b53f8cSChandrakanth patil 			if (type & 1) {
393*35b53f8cSChandrakanth patil 				NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
394*35b53f8cSChandrakanth patil 				CMPL_PREFETCH_NEXT(cpr, cons);
395*35b53f8cSChandrakanth patil 
396*35b53f8cSChandrakanth patil 				if (!CMP_VALID(&cmp[cons], v_bit))
397*35b53f8cSChandrakanth patil 					goto cmpl_invalid;
398*35b53f8cSChandrakanth patil 			}
399*35b53f8cSChandrakanth patil 			break;
400*35b53f8cSChandrakanth patil 		}
401*35b53f8cSChandrakanth patil 		if (avail > budget)
402*35b53f8cSChandrakanth patil 			break;
403*35b53f8cSChandrakanth patil 	}
404*35b53f8cSChandrakanth patil cmpl_invalid:
405*35b53f8cSChandrakanth patil 
406*35b53f8cSChandrakanth patil 	return avail;
407*35b53f8cSChandrakanth patil }
408*35b53f8cSChandrakanth patil 
409*35b53f8cSChandrakanth patil static void
bnxt_set_rsstype(if_rxd_info_t ri,uint8_t rss_hash_type)410*35b53f8cSChandrakanth patil bnxt_set_rsstype(if_rxd_info_t ri, uint8_t rss_hash_type)
411*35b53f8cSChandrakanth patil {
412*35b53f8cSChandrakanth patil 	uint8_t rss_profile_id;
413*35b53f8cSChandrakanth patil 
414*35b53f8cSChandrakanth patil 	rss_profile_id = BNXT_GET_RSS_PROFILE_ID(rss_hash_type);
415*35b53f8cSChandrakanth patil 	switch (rss_profile_id) {
416*35b53f8cSChandrakanth patil 	case BNXT_RSS_HASH_TYPE_TCPV4:
417*35b53f8cSChandrakanth patil 		ri->iri_rsstype = M_HASHTYPE_RSS_TCP_IPV4;
418*35b53f8cSChandrakanth patil 		break;
419*35b53f8cSChandrakanth patil 	case BNXT_RSS_HASH_TYPE_UDPV4:
420*35b53f8cSChandrakanth patil 		ri->iri_rsstype = M_HASHTYPE_RSS_UDP_IPV4;
421*35b53f8cSChandrakanth patil 		break;
422*35b53f8cSChandrakanth patil 	case BNXT_RSS_HASH_TYPE_IPV4:
423*35b53f8cSChandrakanth patil 		ri->iri_rsstype = M_HASHTYPE_RSS_IPV4;
424*35b53f8cSChandrakanth patil 		break;
425*35b53f8cSChandrakanth patil 	case BNXT_RSS_HASH_TYPE_TCPV6:
426*35b53f8cSChandrakanth patil 		ri->iri_rsstype = M_HASHTYPE_RSS_TCP_IPV6;
427*35b53f8cSChandrakanth patil 		break;
428*35b53f8cSChandrakanth patil 	case BNXT_RSS_HASH_TYPE_UDPV6:
429*35b53f8cSChandrakanth patil 		ri->iri_rsstype = M_HASHTYPE_RSS_UDP_IPV6;
430*35b53f8cSChandrakanth patil 		break;
431*35b53f8cSChandrakanth patil 	case BNXT_RSS_HASH_TYPE_IPV6:
432*35b53f8cSChandrakanth patil 		ri->iri_rsstype = M_HASHTYPE_RSS_IPV6;
433*35b53f8cSChandrakanth patil 		break;
434*35b53f8cSChandrakanth patil 	default:
435*35b53f8cSChandrakanth patil 		ri->iri_rsstype = M_HASHTYPE_OPAQUE_HASH;
436*35b53f8cSChandrakanth patil 		break;
437*35b53f8cSChandrakanth patil 	}
438*35b53f8cSChandrakanth patil }
439*35b53f8cSChandrakanth patil 
440*35b53f8cSChandrakanth patil static int
bnxt_pkt_get_l2(struct bnxt_softc * softc,if_rxd_info_t ri,struct bnxt_cp_ring * cpr,uint16_t flags_type)441*35b53f8cSChandrakanth patil bnxt_pkt_get_l2(struct bnxt_softc *softc, if_rxd_info_t ri,
442*35b53f8cSChandrakanth patil     struct bnxt_cp_ring *cpr, uint16_t flags_type)
443*35b53f8cSChandrakanth patil {
444*35b53f8cSChandrakanth patil 	struct rx_pkt_cmpl *rcp;
445*35b53f8cSChandrakanth patil 	struct rx_pkt_cmpl_hi *rcph;
446*35b53f8cSChandrakanth patil 	struct rx_abuf_cmpl *acp;
447*35b53f8cSChandrakanth patil 	uint32_t flags2;
448*35b53f8cSChandrakanth patil 	uint32_t errors;
449*35b53f8cSChandrakanth patil 	uint8_t	ags;
450*35b53f8cSChandrakanth patil 	int i;
451*35b53f8cSChandrakanth patil 
452*35b53f8cSChandrakanth patil 	rcp = &((struct rx_pkt_cmpl *)cpr->ring.vaddr)[cpr->cons];
453*35b53f8cSChandrakanth patil 
454*35b53f8cSChandrakanth patil 	/* Extract from the first 16-byte BD */
455*35b53f8cSChandrakanth patil 	if (flags_type & RX_PKT_CMPL_FLAGS_RSS_VALID) {
456*35b53f8cSChandrakanth patil 		ri->iri_flowid = le32toh(rcp->rss_hash);
457*35b53f8cSChandrakanth patil 		bnxt_set_rsstype(ri, rcp->rss_hash_type);
458*35b53f8cSChandrakanth patil 	}
459*35b53f8cSChandrakanth patil 	else {
460*35b53f8cSChandrakanth patil 		ri->iri_rsstype = M_HASHTYPE_NONE;
461*35b53f8cSChandrakanth patil 	}
462*35b53f8cSChandrakanth patil 	ags = (rcp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK) >>
463*35b53f8cSChandrakanth patil 	    RX_PKT_CMPL_AGG_BUFS_SFT;
464*35b53f8cSChandrakanth patil 	ri->iri_nfrags = ags + 1;
465*35b53f8cSChandrakanth patil 	/* No need to byte-swap the opaque value */
466*35b53f8cSChandrakanth patil 	ri->iri_frags[0].irf_flid = (rcp->opaque >> 16) & 0xff;
467*35b53f8cSChandrakanth patil 	ri->iri_frags[0].irf_idx = rcp->opaque & 0xffff;
468*35b53f8cSChandrakanth patil 	ri->iri_frags[0].irf_len = le16toh(rcp->len);
469*35b53f8cSChandrakanth patil 	ri->iri_len = le16toh(rcp->len);
470*35b53f8cSChandrakanth patil 
471*35b53f8cSChandrakanth patil 	/* Now the second 16-byte BD */
472*35b53f8cSChandrakanth patil 	NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit);
473*35b53f8cSChandrakanth patil 	ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx);
474*35b53f8cSChandrakanth patil 	rcph = &((struct rx_pkt_cmpl_hi *)cpr->ring.vaddr)[cpr->cons];
475*35b53f8cSChandrakanth patil 
476*35b53f8cSChandrakanth patil 	flags2 = le32toh(rcph->flags2);
477*35b53f8cSChandrakanth patil 	errors = le16toh(rcph->errors_v2);
478*35b53f8cSChandrakanth patil 	if ((flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_MASK) ==
479*35b53f8cSChandrakanth patil 	    RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) {
480*35b53f8cSChandrakanth patil 		ri->iri_flags |= M_VLANTAG;
481*35b53f8cSChandrakanth patil 		/* TODO: Should this be the entire 16-bits? */
482*35b53f8cSChandrakanth patil 		ri->iri_vtag = le32toh(rcph->metadata) &
483*35b53f8cSChandrakanth patil 		    (RX_PKT_CMPL_METADATA_VID_MASK | RX_PKT_CMPL_METADATA_DE |
484*35b53f8cSChandrakanth patil 		    RX_PKT_CMPL_METADATA_PRI_MASK);
485*35b53f8cSChandrakanth patil 	}
486*35b53f8cSChandrakanth patil 	if (flags2 & RX_PKT_CMPL_FLAGS2_IP_CS_CALC) {
487*35b53f8cSChandrakanth patil 		ri->iri_csum_flags |= CSUM_IP_CHECKED;
488*35b53f8cSChandrakanth patil 		if (!(errors & RX_PKT_CMPL_ERRORS_IP_CS_ERROR))
489*35b53f8cSChandrakanth patil 			ri->iri_csum_flags |= CSUM_IP_VALID;
490*35b53f8cSChandrakanth patil 	}
491*35b53f8cSChandrakanth patil 	if (flags2 & (RX_PKT_CMPL_FLAGS2_L4_CS_CALC |
492*35b53f8cSChandrakanth patil 		      RX_PKT_CMPL_FLAGS2_T_L4_CS_CALC)) {
493*35b53f8cSChandrakanth patil 		ri->iri_csum_flags |= CSUM_L4_CALC;
494*35b53f8cSChandrakanth patil 		if (!(errors & (RX_PKT_CMPL_ERRORS_L4_CS_ERROR |
495*35b53f8cSChandrakanth patil 				RX_PKT_CMPL_ERRORS_T_L4_CS_ERROR))) {
496*35b53f8cSChandrakanth patil 			ri->iri_csum_flags |= CSUM_L4_VALID;
497*35b53f8cSChandrakanth patil 			ri->iri_csum_data = 0xffff;
498*35b53f8cSChandrakanth patil 		}
499*35b53f8cSChandrakanth patil 	}
500*35b53f8cSChandrakanth patil 
501*35b53f8cSChandrakanth patil 	/* And finally the ag ring stuff. */
502*35b53f8cSChandrakanth patil 	for (i=1; i < ri->iri_nfrags; i++) {
503*35b53f8cSChandrakanth patil 		NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit);
504*35b53f8cSChandrakanth patil 		ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx);
505*35b53f8cSChandrakanth patil 		acp = &((struct rx_abuf_cmpl *)cpr->ring.vaddr)[cpr->cons];
506*35b53f8cSChandrakanth patil 
507*35b53f8cSChandrakanth patil 		/* No need to byte-swap the opaque value */
508*35b53f8cSChandrakanth patil 		ri->iri_frags[i].irf_flid = (acp->opaque >> 16 & 0xff);
509*35b53f8cSChandrakanth patil 		ri->iri_frags[i].irf_idx = acp->opaque & 0xffff;
510*35b53f8cSChandrakanth patil 		ri->iri_frags[i].irf_len = le16toh(acp->len);
511*35b53f8cSChandrakanth patil 		ri->iri_len += le16toh(acp->len);
512*35b53f8cSChandrakanth patil 	}
513*35b53f8cSChandrakanth patil 
514*35b53f8cSChandrakanth patil 	return 0;
515*35b53f8cSChandrakanth patil }
516*35b53f8cSChandrakanth patil 
517*35b53f8cSChandrakanth patil static int
bnxt_pkt_get_tpa(struct bnxt_softc * softc,if_rxd_info_t ri,struct bnxt_cp_ring * cpr,uint16_t flags_type)518*35b53f8cSChandrakanth patil bnxt_pkt_get_tpa(struct bnxt_softc *softc, if_rxd_info_t ri,
519*35b53f8cSChandrakanth patil     struct bnxt_cp_ring *cpr, uint16_t flags_type)
520*35b53f8cSChandrakanth patil {
521*35b53f8cSChandrakanth patil 	struct rx_tpa_end_cmpl *agend =
522*35b53f8cSChandrakanth patil 	    &((struct rx_tpa_end_cmpl *)cpr->ring.vaddr)[cpr->cons];
523*35b53f8cSChandrakanth patil 	struct rx_abuf_cmpl *acp;
524*35b53f8cSChandrakanth patil 	struct bnxt_full_tpa_start *tpas;
525*35b53f8cSChandrakanth patil 	uint32_t flags2;
526*35b53f8cSChandrakanth patil 	uint8_t	ags;
527*35b53f8cSChandrakanth patil 	uint8_t agg_id;
528*35b53f8cSChandrakanth patil 	int i;
529*35b53f8cSChandrakanth patil 
530*35b53f8cSChandrakanth patil 	/* Get the agg_id */
531*35b53f8cSChandrakanth patil 	agg_id = (agend->agg_id & RX_TPA_END_CMPL_AGG_ID_MASK) >>
532*35b53f8cSChandrakanth patil 	    RX_TPA_END_CMPL_AGG_ID_SFT;
533*35b53f8cSChandrakanth patil 	tpas = &(softc->rx_rings[ri->iri_qsidx].tpa_start[agg_id]);
534*35b53f8cSChandrakanth patil 
535*35b53f8cSChandrakanth patil 	/* Extract from the first 16-byte BD */
536*35b53f8cSChandrakanth patil 	if (le16toh(tpas->low.flags_type) & RX_TPA_START_CMPL_FLAGS_RSS_VALID) {
537*35b53f8cSChandrakanth patil 		ri->iri_flowid = le32toh(tpas->low.rss_hash);
538*35b53f8cSChandrakanth patil 		bnxt_set_rsstype(ri, tpas->low.rss_hash_type);
539*35b53f8cSChandrakanth patil 	}
540*35b53f8cSChandrakanth patil 	else {
541*35b53f8cSChandrakanth patil 		ri->iri_rsstype = M_HASHTYPE_NONE;
542*35b53f8cSChandrakanth patil 	}
543*35b53f8cSChandrakanth patil 	ags = (agend->agg_bufs_v1 & RX_TPA_END_CMPL_AGG_BUFS_MASK) >>
544*35b53f8cSChandrakanth patil 	    RX_TPA_END_CMPL_AGG_BUFS_SFT;
545*35b53f8cSChandrakanth patil 	ri->iri_nfrags = ags + 1;
546*35b53f8cSChandrakanth patil 	/* No need to byte-swap the opaque value */
547*35b53f8cSChandrakanth patil 	ri->iri_frags[0].irf_flid = ((tpas->low.opaque >> 16) & 0xff);
548*35b53f8cSChandrakanth patil 	ri->iri_frags[0].irf_idx = (tpas->low.opaque & 0xffff);
549*35b53f8cSChandrakanth patil 	ri->iri_frags[0].irf_len = le16toh(tpas->low.len);
550*35b53f8cSChandrakanth patil 	ri->iri_len = le16toh(tpas->low.len);
551*35b53f8cSChandrakanth patil 
552*35b53f8cSChandrakanth patil 	/* Now the second 16-byte BD */
553*35b53f8cSChandrakanth patil 	NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit);
554*35b53f8cSChandrakanth patil 	ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx);
555*35b53f8cSChandrakanth patil 
556*35b53f8cSChandrakanth patil 	flags2 = le32toh(tpas->high.flags2);
557*35b53f8cSChandrakanth patil 	if ((flags2 & RX_TPA_START_CMPL_FLAGS2_META_FORMAT_MASK) ==
558*35b53f8cSChandrakanth patil 	    RX_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN) {
559*35b53f8cSChandrakanth patil 		ri->iri_flags |= M_VLANTAG;
560*35b53f8cSChandrakanth patil 		/* TODO: Should this be the entire 16-bits? */
561*35b53f8cSChandrakanth patil 		ri->iri_vtag = le32toh(tpas->high.metadata) &
562*35b53f8cSChandrakanth patil 		    (RX_TPA_START_CMPL_METADATA_VID_MASK |
563*35b53f8cSChandrakanth patil 		    RX_TPA_START_CMPL_METADATA_DE |
564*35b53f8cSChandrakanth patil 		    RX_TPA_START_CMPL_METADATA_PRI_MASK);
565*35b53f8cSChandrakanth patil 	}
566*35b53f8cSChandrakanth patil 	if (flags2 & RX_TPA_START_CMPL_FLAGS2_IP_CS_CALC) {
567*35b53f8cSChandrakanth patil 		ri->iri_csum_flags |= CSUM_IP_CHECKED;
568*35b53f8cSChandrakanth patil 		ri->iri_csum_flags |= CSUM_IP_VALID;
569*35b53f8cSChandrakanth patil 	}
570*35b53f8cSChandrakanth patil 	if (flags2 & RX_TPA_START_CMPL_FLAGS2_L4_CS_CALC) {
571*35b53f8cSChandrakanth patil 		ri->iri_csum_flags |= CSUM_L4_CALC;
572*35b53f8cSChandrakanth patil 		ri->iri_csum_flags |= CSUM_L4_VALID;
573*35b53f8cSChandrakanth patil 		ri->iri_csum_data = 0xffff;
574*35b53f8cSChandrakanth patil 	}
575*35b53f8cSChandrakanth patil 
576*35b53f8cSChandrakanth patil 	/* Now the ag ring stuff. */
577*35b53f8cSChandrakanth patil 	for (i=1; i < ri->iri_nfrags; i++) {
578*35b53f8cSChandrakanth patil 		NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit);
579*35b53f8cSChandrakanth patil 		ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx);
580*35b53f8cSChandrakanth patil 		acp = &((struct rx_abuf_cmpl *)cpr->ring.vaddr)[cpr->cons];
581*35b53f8cSChandrakanth patil 
582*35b53f8cSChandrakanth patil 		/* No need to byte-swap the opaque value */
583*35b53f8cSChandrakanth patil 		ri->iri_frags[i].irf_flid = ((acp->opaque >> 16) & 0xff);
584*35b53f8cSChandrakanth patil 		ri->iri_frags[i].irf_idx = (acp->opaque & 0xffff);
585*35b53f8cSChandrakanth patil 		ri->iri_frags[i].irf_len = le16toh(acp->len);
586*35b53f8cSChandrakanth patil 		ri->iri_len += le16toh(acp->len);
587*35b53f8cSChandrakanth patil 	}
588*35b53f8cSChandrakanth patil 
589*35b53f8cSChandrakanth patil 	/* And finally, the empty BD at the end... */
590*35b53f8cSChandrakanth patil 	ri->iri_nfrags++;
591*35b53f8cSChandrakanth patil 	/* No need to byte-swap the opaque value */
592*35b53f8cSChandrakanth patil 	ri->iri_frags[i].irf_flid = ((agend->opaque >> 16) & 0xff);
593*35b53f8cSChandrakanth patil 	ri->iri_frags[i].irf_idx = (agend->opaque & 0xffff);
594*35b53f8cSChandrakanth patil 	ri->iri_frags[i].irf_len = le16toh(agend->len);
595*35b53f8cSChandrakanth patil 	ri->iri_len += le16toh(agend->len);
596*35b53f8cSChandrakanth patil 
597*35b53f8cSChandrakanth patil 	return 0;
598*35b53f8cSChandrakanth patil }
599*35b53f8cSChandrakanth patil 
600*35b53f8cSChandrakanth patil /* If we return anything but zero, iflib will assert... */
601*35b53f8cSChandrakanth patil static int
bnxt_isc_rxd_pkt_get(void * sc,if_rxd_info_t ri)602*35b53f8cSChandrakanth patil bnxt_isc_rxd_pkt_get(void *sc, if_rxd_info_t ri)
603*35b53f8cSChandrakanth patil {
604*35b53f8cSChandrakanth patil 	struct bnxt_softc *softc = (struct bnxt_softc *)sc;
605*35b53f8cSChandrakanth patil 	struct bnxt_cp_ring *cpr = &softc->rx_cp_rings[ri->iri_qsidx];
606*35b53f8cSChandrakanth patil 	struct cmpl_base *cmp_q = (struct cmpl_base *)cpr->ring.vaddr;
607*35b53f8cSChandrakanth patil 	struct cmpl_base *cmp;
608*35b53f8cSChandrakanth patil 	struct rx_tpa_start_cmpl *rtpa;
609*35b53f8cSChandrakanth patil 	uint16_t flags_type;
610*35b53f8cSChandrakanth patil 	uint16_t type;
611*35b53f8cSChandrakanth patil 	uint8_t agg_id;
612*35b53f8cSChandrakanth patil 
613*35b53f8cSChandrakanth patil 	for (;;) {
614*35b53f8cSChandrakanth patil 		NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit);
615*35b53f8cSChandrakanth patil 		ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx);
616*35b53f8cSChandrakanth patil 		CMPL_PREFETCH_NEXT(cpr, cpr->cons);
617*35b53f8cSChandrakanth patil 		cmp = &((struct cmpl_base *)cpr->ring.vaddr)[cpr->cons];
618*35b53f8cSChandrakanth patil 
619*35b53f8cSChandrakanth patil 		flags_type = le16toh(cmp->type);
620*35b53f8cSChandrakanth patil 		type = flags_type & CMPL_BASE_TYPE_MASK;
621*35b53f8cSChandrakanth patil 
622*35b53f8cSChandrakanth patil 		switch (type) {
623*35b53f8cSChandrakanth patil 		case CMPL_BASE_TYPE_RX_L2:
624*35b53f8cSChandrakanth patil 			return bnxt_pkt_get_l2(softc, ri, cpr, flags_type);
625*35b53f8cSChandrakanth patil 		case CMPL_BASE_TYPE_RX_TPA_END:
626*35b53f8cSChandrakanth patil 			return bnxt_pkt_get_tpa(softc, ri, cpr, flags_type);
627*35b53f8cSChandrakanth patil 		case CMPL_BASE_TYPE_RX_TPA_START:
628*35b53f8cSChandrakanth patil 			rtpa = (void *)&cmp_q[cpr->cons];
629*35b53f8cSChandrakanth patil 			agg_id = (rtpa->agg_id &
630*35b53f8cSChandrakanth patil 			    RX_TPA_START_CMPL_AGG_ID_MASK) >>
631*35b53f8cSChandrakanth patil 			    RX_TPA_START_CMPL_AGG_ID_SFT;
632*35b53f8cSChandrakanth patil 			softc->rx_rings[ri->iri_qsidx].tpa_start[agg_id].low = *rtpa;
633*35b53f8cSChandrakanth patil 
634*35b53f8cSChandrakanth patil 			NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit);
635*35b53f8cSChandrakanth patil 			ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx);
636*35b53f8cSChandrakanth patil 			CMPL_PREFETCH_NEXT(cpr, cpr->cons);
637*35b53f8cSChandrakanth patil 
638*35b53f8cSChandrakanth patil 			softc->rx_rings[ri->iri_qsidx].tpa_start[agg_id].high =
639*35b53f8cSChandrakanth patil 			    ((struct rx_tpa_start_cmpl_hi *)cmp_q)[cpr->cons];
640*35b53f8cSChandrakanth patil 			break;
641*35b53f8cSChandrakanth patil 		default:
642*35b53f8cSChandrakanth patil 			device_printf(softc->dev,
643*35b53f8cSChandrakanth patil 			    "Unhandled completion type %d on RXQ %d get\n",
644*35b53f8cSChandrakanth patil 			    type, ri->iri_qsidx);
645*35b53f8cSChandrakanth patil 			if (type & 1) {
646*35b53f8cSChandrakanth patil 				NEXT_CP_CONS_V(&cpr->ring, cpr->cons,
647*35b53f8cSChandrakanth patil 				    cpr->v_bit);
648*35b53f8cSChandrakanth patil 				ri->iri_cidx = RING_NEXT(&cpr->ring,
649*35b53f8cSChandrakanth patil 				    ri->iri_cidx);
650*35b53f8cSChandrakanth patil 				CMPL_PREFETCH_NEXT(cpr, cpr->cons);
651*35b53f8cSChandrakanth patil 			}
652*35b53f8cSChandrakanth patil 			break;
653*35b53f8cSChandrakanth patil 		}
654*35b53f8cSChandrakanth patil 	}
655*35b53f8cSChandrakanth patil 
656*35b53f8cSChandrakanth patil 	return 0;
657*35b53f8cSChandrakanth patil }
658*35b53f8cSChandrakanth patil 
659*35b53f8cSChandrakanth patil static int
bnxt_intr(void * sc)660*35b53f8cSChandrakanth patil bnxt_intr(void *sc)
661*35b53f8cSChandrakanth patil {
662*35b53f8cSChandrakanth patil 	struct bnxt_softc *softc = (struct bnxt_softc *)sc;
663*35b53f8cSChandrakanth patil 
664*35b53f8cSChandrakanth patil 	device_printf(softc->dev, "STUB: %s @ %s:%d\n", __func__, __FILE__, __LINE__);
665*35b53f8cSChandrakanth patil 	return ENOSYS;
666*35b53f8cSChandrakanth patil }
667