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