Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/bnxt/bnxt_txrx.c
Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
#include "bnxt.h" | #include "bnxt.h" | ||||
/* | /* | ||||
* Function prototypes | * Function prototypes | ||||
*/ | */ | ||||
static int bnxt_isc_txd_encap(void *sc, if_pkt_info_t pi); | static int bnxt_isc_txd_encap(void *sc, if_pkt_info_t pi); | ||||
static void bnxt_isc_txd_flush(void *sc, uint16_t txqid, uint32_t pidx); | static void bnxt_isc_txd_flush(void *sc, uint16_t txqid, qidx_t pidx); | ||||
static int bnxt_isc_txd_credits_update(void *sc, uint16_t txqid, uint32_t cidx, | static int bnxt_isc_txd_credits_update(void *sc, uint16_t txqid, bool clear); | ||||
bool clear); | |||||
static void bnxt_isc_rxd_refill(void *sc, uint16_t rxqid, uint8_t flid, | static void bnxt_isc_rxd_refill(void *sc, if_rxd_update_t iru); | ||||
/* uint16_t rxqid, uint8_t flid, | |||||
uint32_t pidx, uint64_t *paddrs, caddr_t *vaddrs, uint16_t count, | uint32_t pidx, uint64_t *paddrs, caddr_t *vaddrs, uint16_t count, | ||||
uint16_t buf_size); | uint16_t buf_size); | ||||
*/ | |||||
static void bnxt_isc_rxd_flush(void *sc, uint16_t rxqid, uint8_t flid, | static void bnxt_isc_rxd_flush(void *sc, uint16_t rxqid, uint8_t flid, | ||||
uint32_t pidx); | qidx_t pidx); | ||||
static int bnxt_isc_rxd_available(void *sc, uint16_t rxqid, uint32_t idx, | static int bnxt_isc_rxd_available(void *sc, uint16_t rxqid, qidx_t idx, | ||||
int budget); | qidx_t budget); | ||||
static int bnxt_isc_rxd_pkt_get(void *sc, if_rxd_info_t ri); | static int bnxt_isc_rxd_pkt_get(void *sc, if_rxd_info_t ri); | ||||
static int bnxt_intr(void *sc); | static int bnxt_intr(void *sc); | ||||
struct if_txrx bnxt_txrx = { | struct if_txrx bnxt_txrx = { | ||||
bnxt_isc_txd_encap, | bnxt_isc_txd_encap, | ||||
bnxt_isc_txd_flush, | bnxt_isc_txd_flush, | ||||
bnxt_isc_txd_credits_update, | bnxt_isc_txd_credits_update, | ||||
▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | bnxt_isc_txd_encap(void *sc, if_pkt_info_t pi) | ||||
flags_type |= TX_BD_SHORT_FLAGS_PACKET_END; | flags_type |= TX_BD_SHORT_FLAGS_PACKET_END; | ||||
tbd->flags_type = htole16(flags_type); | tbd->flags_type = htole16(flags_type); | ||||
pi->ipi_new_pidx = RING_NEXT(txr, pi->ipi_new_pidx); | pi->ipi_new_pidx = RING_NEXT(txr, pi->ipi_new_pidx); | ||||
return 0; | return 0; | ||||
} | } | ||||
static void | static void | ||||
bnxt_isc_txd_flush(void *sc, uint16_t txqid, uint32_t pidx) | bnxt_isc_txd_flush(void *sc, uint16_t txqid, qidx_t pidx) | ||||
{ | { | ||||
struct bnxt_softc *softc = (struct bnxt_softc *)sc; | struct bnxt_softc *softc = (struct bnxt_softc *)sc; | ||||
struct bnxt_ring *tx_ring = &softc->tx_rings[txqid]; | struct bnxt_ring *tx_ring = &softc->tx_rings[txqid]; | ||||
/* pidx is what we last set ipi_new_pidx to */ | /* pidx is what we last set ipi_new_pidx to */ | ||||
BNXT_TX_DB(tx_ring, pidx); | BNXT_TX_DB(tx_ring, pidx); | ||||
/* TODO: Cumulus+ doesn't need the double doorbell */ | /* TODO: Cumulus+ doesn't need the double doorbell */ | ||||
BNXT_TX_DB(tx_ring, pidx); | BNXT_TX_DB(tx_ring, pidx); | ||||
return; | return; | ||||
} | } | ||||
static int | static int | ||||
bnxt_isc_txd_credits_update(void *sc, uint16_t txqid, uint32_t idx, bool clear) | bnxt_isc_txd_credits_update(void *sc, uint16_t txqid, bool clear) | ||||
{ | { | ||||
struct bnxt_softc *softc = (struct bnxt_softc *)sc; | struct bnxt_softc *softc = (struct bnxt_softc *)sc; | ||||
struct bnxt_cp_ring *cpr = &softc->tx_cp_rings[txqid]; | struct bnxt_cp_ring *cpr = &softc->tx_cp_rings[txqid]; | ||||
struct tx_cmpl *cmpl = (struct tx_cmpl *)cpr->ring.vaddr; | struct tx_cmpl *cmpl = (struct tx_cmpl *)cpr->ring.vaddr; | ||||
int avail = 0; | int avail = 0; | ||||
uint32_t cons = cpr->cons; | uint32_t cons = cpr->cons; | ||||
bool v_bit = cpr->v_bit; | bool v_bit = cpr->v_bit; | ||||
bool last_v_bit; | bool last_v_bit; | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | if (clear && avail) { | ||||
cpr->v_bit = last_v_bit; | cpr->v_bit = last_v_bit; | ||||
BNXT_CP_IDX_DISABLE_DB(&cpr->ring, cpr->cons); | BNXT_CP_IDX_DISABLE_DB(&cpr->ring, cpr->cons); | ||||
} | } | ||||
return avail; | return avail; | ||||
} | } | ||||
static void | static void | ||||
bnxt_isc_rxd_refill(void *sc, uint16_t rxqid, uint8_t flid, | bnxt_isc_rxd_refill(void *sc, if_rxd_update_t iru) | ||||
uint32_t pidx, uint64_t *paddrs, | |||||
caddr_t *vaddrs, uint16_t count, uint16_t len) | |||||
{ | { | ||||
struct bnxt_softc *softc = (struct bnxt_softc *)sc; | struct bnxt_softc *softc = (struct bnxt_softc *)sc; | ||||
struct bnxt_ring *rx_ring; | struct bnxt_ring *rx_ring; | ||||
struct rx_prod_pkt_bd *rxbd; | struct rx_prod_pkt_bd *rxbd; | ||||
uint16_t type; | uint16_t type; | ||||
uint16_t i; | uint16_t i; | ||||
uint16_t rxqid; | |||||
uint16_t count, len; | |||||
uint32_t pidx; | |||||
uint8_t flid; | |||||
uint64_t *paddrs; | |||||
caddr_t *vaddrs; | |||||
qidx_t *frag_idxs; | |||||
rxqid = iru->iru_qsidx; | |||||
count = iru->iru_count; | |||||
len = iru->iru_buf_size; | |||||
pidx = iru->iru_pidx; | |||||
flid = iru->iru_flidx; | |||||
vaddrs = iru->iru_vaddrs; | |||||
paddrs = iru->iru_paddrs; | |||||
frag_idxs = iru->iru_idxs; | |||||
if (flid == 0) { | if (flid == 0) { | ||||
rx_ring = &softc->rx_rings[rxqid]; | rx_ring = &softc->rx_rings[rxqid]; | ||||
type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT; | type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT; | ||||
} | } | ||||
else { | else { | ||||
rx_ring = &softc->ag_rings[rxqid]; | rx_ring = &softc->ag_rings[rxqid]; | ||||
type = RX_PROD_AGG_BD_TYPE_RX_PROD_AGG; | type = RX_PROD_AGG_BD_TYPE_RX_PROD_AGG; | ||||
} | } | ||||
rxbd = (void *)rx_ring->vaddr; | rxbd = (void *)rx_ring->vaddr; | ||||
for (i=0; i<count; i++) { | for (i=0; i<count; i++) { | ||||
rxbd[pidx].flags_type = htole16(type); | rxbd[pidx].flags_type = htole16(type); | ||||
rxbd[pidx].len = htole16(len); | rxbd[pidx].len = htole16(len); | ||||
/* No need to byte-swap the opaque value */ | /* No need to byte-swap the opaque value */ | ||||
rxbd[pidx].opaque = ((rxqid & 0xff) << 24) | (flid << 16) | rxbd[pidx].opaque = (((rxqid & 0xff) << 24) | (flid << 16) | ||||
| pidx; | | (frag_idxs[i])); | ||||
rxbd[pidx].addr = htole64(paddrs[i]); | rxbd[pidx].addr = htole64(paddrs[i]); | ||||
if (++pidx == rx_ring->ring_size) | if (++pidx == rx_ring->ring_size) | ||||
pidx = 0; | pidx = 0; | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
static void | static void | ||||
bnxt_isc_rxd_flush(void *sc, uint16_t rxqid, uint8_t flid, | bnxt_isc_rxd_flush(void *sc, uint16_t rxqid, uint8_t flid, | ||||
uint32_t pidx) | qidx_t pidx) | ||||
{ | { | ||||
struct bnxt_softc *softc = (struct bnxt_softc *)sc; | struct bnxt_softc *softc = (struct bnxt_softc *)sc; | ||||
struct bnxt_ring *rx_ring; | struct bnxt_ring *rx_ring; | ||||
if (flid == 0) | if (flid == 0) | ||||
rx_ring = &softc->rx_rings[rxqid]; | rx_ring = &softc->rx_rings[rxqid]; | ||||
else | else | ||||
rx_ring = &softc->ag_rings[rxqid]; | rx_ring = &softc->ag_rings[rxqid]; | ||||
Show All 9 Lines | bnxt_isc_rxd_flush(void *sc, uint16_t rxqid, uint8_t flid, | ||||
/* We're given the last filled RX buffer here, not the next empty one */ | /* We're given the last filled RX buffer here, not the next empty one */ | ||||
BNXT_RX_DB(rx_ring, RING_NEXT(rx_ring, pidx)); | BNXT_RX_DB(rx_ring, RING_NEXT(rx_ring, pidx)); | ||||
/* TODO: Cumulus+ doesn't need the double doorbell */ | /* TODO: Cumulus+ doesn't need the double doorbell */ | ||||
BNXT_RX_DB(rx_ring, RING_NEXT(rx_ring, pidx)); | BNXT_RX_DB(rx_ring, RING_NEXT(rx_ring, pidx)); | ||||
return; | return; | ||||
} | } | ||||
static int | static int | ||||
bnxt_isc_rxd_available(void *sc, uint16_t rxqid, uint32_t idx, int budget) | bnxt_isc_rxd_available(void *sc, uint16_t rxqid, qidx_t idx, qidx_t budget) | ||||
{ | { | ||||
struct bnxt_softc *softc = (struct bnxt_softc *)sc; | struct bnxt_softc *softc = (struct bnxt_softc *)sc; | ||||
struct bnxt_cp_ring *cpr = &softc->rx_cp_rings[rxqid]; | struct bnxt_cp_ring *cpr = &softc->rx_cp_rings[rxqid]; | ||||
struct rx_pkt_cmpl *rcp; | struct rx_pkt_cmpl *rcp; | ||||
struct rx_tpa_start_cmpl *rtpa; | |||||
struct rx_tpa_end_cmpl *rtpae; | struct rx_tpa_end_cmpl *rtpae; | ||||
struct cmpl_base *cmp = (struct cmpl_base *)cpr->ring.vaddr; | struct cmpl_base *cmp = (struct cmpl_base *)cpr->ring.vaddr; | ||||
int avail = 0; | int avail = 0; | ||||
uint32_t cons = cpr->cons; | uint32_t cons = cpr->cons; | ||||
bool v_bit = cpr->v_bit; | bool v_bit = cpr->v_bit; | ||||
uint8_t ags; | uint8_t ags; | ||||
int i; | int i; | ||||
uint16_t type; | uint16_t type; | ||||
uint8_t agg_id; | |||||
for (;;) { | for (;;) { | ||||
NEXT_CP_CONS_V(&cpr->ring, cons, v_bit); | NEXT_CP_CONS_V(&cpr->ring, cons, v_bit); | ||||
CMPL_PREFETCH_NEXT(cpr, cons); | CMPL_PREFETCH_NEXT(cpr, cons); | ||||
if (!CMP_VALID(&cmp[cons], v_bit)) | if (!CMP_VALID(&cmp[cons], v_bit)) | ||||
goto cmpl_invalid; | goto cmpl_invalid; | ||||
Show All 33 Lines | case CMPL_BASE_TYPE_RX_TPA_END: | ||||
NEXT_CP_CONS_V(&cpr->ring, cons, v_bit); | NEXT_CP_CONS_V(&cpr->ring, cons, v_bit); | ||||
CMPL_PREFETCH_NEXT(cpr, cons); | CMPL_PREFETCH_NEXT(cpr, cons); | ||||
if (!CMP_VALID(&cmp[cons], v_bit)) | if (!CMP_VALID(&cmp[cons], v_bit)) | ||||
goto cmpl_invalid; | goto cmpl_invalid; | ||||
} | } | ||||
avail++; | avail++; | ||||
break; | break; | ||||
case CMPL_BASE_TYPE_RX_TPA_START: | case CMPL_BASE_TYPE_RX_TPA_START: | ||||
rtpa = (void *)&cmp[cons]; | |||||
agg_id = (rtpa->agg_id & | |||||
RX_TPA_START_CMPL_AGG_ID_MASK) >> | |||||
RX_TPA_START_CMPL_AGG_ID_SFT; | |||||
softc->tpa_start[agg_id].low = *rtpa; | |||||
NEXT_CP_CONS_V(&cpr->ring, cons, v_bit); | NEXT_CP_CONS_V(&cpr->ring, cons, v_bit); | ||||
CMPL_PREFETCH_NEXT(cpr, cons); | CMPL_PREFETCH_NEXT(cpr, cons); | ||||
if (!CMP_VALID(&cmp[cons], v_bit)) | if (!CMP_VALID(&cmp[cons], v_bit)) | ||||
goto cmpl_invalid; | goto cmpl_invalid; | ||||
softc->tpa_start[agg_id].high = | |||||
((struct rx_tpa_start_cmpl_hi *)cmp)[cons]; | |||||
break; | break; | ||||
case CMPL_BASE_TYPE_RX_AGG: | case CMPL_BASE_TYPE_RX_AGG: | ||||
break; | break; | ||||
default: | default: | ||||
device_printf(softc->dev, | device_printf(softc->dev, | ||||
"Unhandled completion type %d on RXQ %d\n", | "Unhandled completion type %d on RXQ %d\n", | ||||
type, rxqid); | type, rxqid); | ||||
Show All 10 Lines | for (;;) { | ||||
if (avail > budget) | if (avail > budget) | ||||
break; | break; | ||||
} | } | ||||
cmpl_invalid: | cmpl_invalid: | ||||
return avail; | return avail; | ||||
} | } | ||||
static void | |||||
bnxt_set_rsstype(if_rxd_info_t ri, uint8_t rss_hash_type) | |||||
{ | |||||
uint8_t rss_profile_id; | |||||
rss_profile_id = BNXT_GET_RSS_PROFILE_ID(rss_hash_type); | |||||
switch (rss_profile_id) { | |||||
case BNXT_RSS_HASH_TYPE_TCPV4: | |||||
ri->iri_rsstype = M_HASHTYPE_RSS_TCP_IPV4; | |||||
break; | |||||
case BNXT_RSS_HASH_TYPE_UDPV4: | |||||
ri->iri_rsstype = M_HASHTYPE_RSS_UDP_IPV4; | |||||
break; | |||||
case BNXT_RSS_HASH_TYPE_IPV4: | |||||
ri->iri_rsstype = M_HASHTYPE_RSS_IPV4; | |||||
break; | |||||
case BNXT_RSS_HASH_TYPE_TCPV6: | |||||
ri->iri_rsstype = M_HASHTYPE_RSS_TCP_IPV6; | |||||
break; | |||||
case BNXT_RSS_HASH_TYPE_UDPV6: | |||||
ri->iri_rsstype = M_HASHTYPE_RSS_UDP_IPV6; | |||||
break; | |||||
case BNXT_RSS_HASH_TYPE_IPV6: | |||||
ri->iri_rsstype = M_HASHTYPE_RSS_IPV6; | |||||
break; | |||||
default: | |||||
ri->iri_rsstype = M_HASHTYPE_OPAQUE_HASH; | |||||
break; | |||||
} | |||||
} | |||||
static int | static int | ||||
bnxt_pkt_get_l2(struct bnxt_softc *softc, if_rxd_info_t ri, | bnxt_pkt_get_l2(struct bnxt_softc *softc, if_rxd_info_t ri, | ||||
struct bnxt_cp_ring *cpr, uint16_t flags_type) | struct bnxt_cp_ring *cpr, uint16_t flags_type) | ||||
{ | { | ||||
struct rx_pkt_cmpl *rcp; | struct rx_pkt_cmpl *rcp; | ||||
struct rx_pkt_cmpl_hi *rcph; | struct rx_pkt_cmpl_hi *rcph; | ||||
struct rx_abuf_cmpl *acp; | struct rx_abuf_cmpl *acp; | ||||
uint32_t flags2; | uint32_t flags2; | ||||
uint32_t errors; | uint32_t errors; | ||||
uint8_t ags; | uint8_t ags; | ||||
int i; | int i; | ||||
rcp = &((struct rx_pkt_cmpl *)cpr->ring.vaddr)[cpr->cons]; | rcp = &((struct rx_pkt_cmpl *)cpr->ring.vaddr)[cpr->cons]; | ||||
/* Extract from the first 16-byte BD */ | /* Extract from the first 16-byte BD */ | ||||
if (flags_type & RX_PKT_CMPL_FLAGS_RSS_VALID) { | if (flags_type & RX_PKT_CMPL_FLAGS_RSS_VALID) { | ||||
ri->iri_flowid = le32toh(rcp->rss_hash); | ri->iri_flowid = le32toh(rcp->rss_hash); | ||||
/* | bnxt_set_rsstype(ri, rcp->rss_hash_type); | ||||
* TODO: Extract something useful from rcp->rss_hash_type | |||||
* (undocumented) | |||||
* May be documented in the "LSI ES" | |||||
* also check the firmware code. | |||||
*/ | |||||
ri->iri_rsstype = M_HASHTYPE_OPAQUE; | |||||
} | } | ||||
else { | else { | ||||
ri->iri_rsstype = M_HASHTYPE_NONE; | ri->iri_rsstype = M_HASHTYPE_NONE; | ||||
} | } | ||||
ags = (rcp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK) >> | ags = (rcp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK) >> | ||||
RX_PKT_CMPL_AGG_BUFS_SFT; | RX_PKT_CMPL_AGG_BUFS_SFT; | ||||
ri->iri_nfrags = ags + 1; | ri->iri_nfrags = ags + 1; | ||||
/* No need to byte-swap the opaque value */ | /* No need to byte-swap the opaque value */ | ||||
Show All 17 Lines | ri->iri_vtag = le32toh(rcph->metadata) & | ||||
(RX_PKT_CMPL_METADATA_VID_MASK | RX_PKT_CMPL_METADATA_DE | | (RX_PKT_CMPL_METADATA_VID_MASK | RX_PKT_CMPL_METADATA_DE | | ||||
RX_PKT_CMPL_METADATA_PRI_MASK); | RX_PKT_CMPL_METADATA_PRI_MASK); | ||||
} | } | ||||
if (flags2 & RX_PKT_CMPL_FLAGS2_IP_CS_CALC) { | if (flags2 & RX_PKT_CMPL_FLAGS2_IP_CS_CALC) { | ||||
ri->iri_csum_flags |= CSUM_IP_CHECKED; | ri->iri_csum_flags |= CSUM_IP_CHECKED; | ||||
if (!(errors & RX_PKT_CMPL_ERRORS_IP_CS_ERROR)) | if (!(errors & RX_PKT_CMPL_ERRORS_IP_CS_ERROR)) | ||||
ri->iri_csum_flags |= CSUM_IP_VALID; | ri->iri_csum_flags |= CSUM_IP_VALID; | ||||
} | } | ||||
if (flags2 & RX_PKT_CMPL_FLAGS2_L4_CS_CALC) { | if (flags2 & (RX_PKT_CMPL_FLAGS2_L4_CS_CALC | | ||||
RX_PKT_CMPL_FLAGS2_T_L4_CS_CALC)) { | |||||
ri->iri_csum_flags |= CSUM_L4_CALC; | ri->iri_csum_flags |= CSUM_L4_CALC; | ||||
if (!(errors & RX_PKT_CMPL_ERRORS_L4_CS_ERROR)) { | if (!(errors & (RX_PKT_CMPL_ERRORS_L4_CS_ERROR | | ||||
RX_PKT_CMPL_ERRORS_T_L4_CS_ERROR))) { | |||||
ri->iri_csum_flags |= CSUM_L4_VALID; | ri->iri_csum_flags |= CSUM_L4_VALID; | ||||
ri->iri_csum_data = 0xffff; | ri->iri_csum_data = 0xffff; | ||||
} | } | ||||
} | } | ||||
/* And finally the ag ring stuff. */ | /* And finally the ag ring stuff. */ | ||||
for (i=1; i < ri->iri_nfrags; i++) { | for (i=1; i < ri->iri_nfrags; i++) { | ||||
NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit); | NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit); | ||||
Show All 22 Lines | bnxt_pkt_get_tpa(struct bnxt_softc *softc, if_rxd_info_t ri, | ||||
uint32_t flags2; | uint32_t flags2; | ||||
uint8_t ags; | uint8_t ags; | ||||
uint8_t agg_id; | uint8_t agg_id; | ||||
int i; | int i; | ||||
/* Get the agg_id */ | /* Get the agg_id */ | ||||
agg_id = (agend->agg_id & RX_TPA_END_CMPL_AGG_ID_MASK) >> | agg_id = (agend->agg_id & RX_TPA_END_CMPL_AGG_ID_MASK) >> | ||||
RX_TPA_END_CMPL_AGG_ID_SFT; | RX_TPA_END_CMPL_AGG_ID_SFT; | ||||
tpas = &softc->tpa_start[agg_id]; | tpas = &(softc->rx_rings[ri->iri_qsidx].tpa_start[agg_id]); | ||||
/* Extract from the first 16-byte BD */ | /* Extract from the first 16-byte BD */ | ||||
if (le16toh(tpas->low.flags_type) & RX_TPA_START_CMPL_FLAGS_RSS_VALID) { | if (le16toh(tpas->low.flags_type) & RX_TPA_START_CMPL_FLAGS_RSS_VALID) { | ||||
ri->iri_flowid = le32toh(tpas->low.rss_hash); | ri->iri_flowid = le32toh(tpas->low.rss_hash); | ||||
/* | bnxt_set_rsstype(ri, tpas->low.rss_hash_type); | ||||
* TODO: Extract something useful from tpas->low.rss_hash_type | |||||
* (undocumented) | |||||
* May be documented in the "LSI ES" | |||||
* also check the firmware code. | |||||
*/ | |||||
ri->iri_rsstype = M_HASHTYPE_OPAQUE; | |||||
} | } | ||||
else { | else { | ||||
ri->iri_rsstype = M_HASHTYPE_NONE; | ri->iri_rsstype = M_HASHTYPE_NONE; | ||||
} | } | ||||
ags = (agend->agg_bufs_v1 & RX_TPA_END_CMPL_AGG_BUFS_MASK) >> | ags = (agend->agg_bufs_v1 & RX_TPA_END_CMPL_AGG_BUFS_MASK) >> | ||||
RX_TPA_END_CMPL_AGG_BUFS_SFT; | RX_TPA_END_CMPL_AGG_BUFS_SFT; | ||||
ri->iri_nfrags = ags + 1; | ri->iri_nfrags = ags + 1; | ||||
/* No need to byte-swap the opaque value */ | /* No need to byte-swap the opaque value */ | ||||
ri->iri_frags[0].irf_flid = (tpas->low.opaque >> 16) & 0xff; | ri->iri_frags[0].irf_flid = ((tpas->low.opaque >> 16) & 0xff); | ||||
ri->iri_frags[0].irf_idx = tpas->low.opaque & 0xffff; | ri->iri_frags[0].irf_idx = (tpas->low.opaque & 0xffff); | ||||
ri->iri_frags[0].irf_len = le16toh(tpas->low.len); | ri->iri_frags[0].irf_len = le16toh(tpas->low.len); | ||||
ri->iri_len = le16toh(tpas->low.len); | ri->iri_len = le16toh(tpas->low.len); | ||||
/* Now the second 16-byte BD */ | /* Now the second 16-byte BD */ | ||||
NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit); | NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit); | ||||
ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx); | ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx); | ||||
agendh = &((struct rx_tpa_end_cmpl_hi *)cpr->ring.vaddr)[cpr->cons]; | agendh = &((struct rx_tpa_end_cmpl_hi *)cpr->ring.vaddr)[cpr->cons]; | ||||
Show All 19 Lines | bnxt_pkt_get_tpa(struct bnxt_softc *softc, if_rxd_info_t ri, | ||||
/* Now the ag ring stuff. */ | /* Now the ag ring stuff. */ | ||||
for (i=1; i < ri->iri_nfrags; i++) { | for (i=1; i < ri->iri_nfrags; i++) { | ||||
NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit); | NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit); | ||||
ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx); | ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx); | ||||
acp = &((struct rx_abuf_cmpl *)cpr->ring.vaddr)[cpr->cons]; | acp = &((struct rx_abuf_cmpl *)cpr->ring.vaddr)[cpr->cons]; | ||||
/* No need to byte-swap the opaque value */ | /* No need to byte-swap the opaque value */ | ||||
ri->iri_frags[i].irf_flid = (acp->opaque >> 16) & 0xff; | ri->iri_frags[i].irf_flid = ((acp->opaque >> 16) & 0xff); | ||||
ri->iri_frags[i].irf_idx = acp->opaque & 0xffff; | ri->iri_frags[i].irf_idx = (acp->opaque & 0xffff); | ||||
ri->iri_frags[i].irf_len = le16toh(acp->len); | ri->iri_frags[i].irf_len = le16toh(acp->len); | ||||
ri->iri_len += le16toh(acp->len); | ri->iri_len += le16toh(acp->len); | ||||
} | } | ||||
/* And finally, the empty BD at the end... */ | /* And finally, the empty BD at the end... */ | ||||
ri->iri_nfrags++; | ri->iri_nfrags++; | ||||
/* No need to byte-swap the opaque value */ | /* No need to byte-swap the opaque value */ | ||||
ri->iri_frags[i].irf_flid = (agend->opaque >> 16) % 0xff; | ri->iri_frags[i].irf_flid = ((agend->opaque >> 16) & 0xff); | ||||
ri->iri_frags[i].irf_idx = agend->opaque & 0xffff; | ri->iri_frags[i].irf_idx = (agend->opaque & 0xffff); | ||||
ri->iri_frags[i].irf_len = le16toh(agend->len); | ri->iri_frags[i].irf_len = le16toh(agend->len); | ||||
ri->iri_len += le16toh(agend->len); | ri->iri_len += le16toh(agend->len); | ||||
return 0; | return 0; | ||||
} | } | ||||
/* If we return anything but zero, iflib will assert... */ | /* If we return anything but zero, iflib will assert... */ | ||||
static int | static int | ||||
bnxt_isc_rxd_pkt_get(void *sc, if_rxd_info_t ri) | bnxt_isc_rxd_pkt_get(void *sc, if_rxd_info_t ri) | ||||
{ | { | ||||
struct bnxt_softc *softc = (struct bnxt_softc *)sc; | struct bnxt_softc *softc = (struct bnxt_softc *)sc; | ||||
struct bnxt_cp_ring *cpr = &softc->rx_cp_rings[ri->iri_qsidx]; | struct bnxt_cp_ring *cpr = &softc->rx_cp_rings[ri->iri_qsidx]; | ||||
struct cmpl_base *cmp_q = (struct cmpl_base *)cpr->ring.vaddr; | |||||
struct cmpl_base *cmp; | struct cmpl_base *cmp; | ||||
struct rx_tpa_start_cmpl *rtpa; | |||||
uint16_t flags_type; | uint16_t flags_type; | ||||
uint16_t type; | uint16_t type; | ||||
uint8_t agg_id; | |||||
for (;;) { | for (;;) { | ||||
NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit); | NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit); | ||||
ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx); | ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx); | ||||
CMPL_PREFETCH_NEXT(cpr, cpr->cons); | CMPL_PREFETCH_NEXT(cpr, cpr->cons); | ||||
cmp = &((struct cmpl_base *)cpr->ring.vaddr)[cpr->cons]; | cmp = &((struct cmpl_base *)cpr->ring.vaddr)[cpr->cons]; | ||||
flags_type = le16toh(cmp->type); | flags_type = le16toh(cmp->type); | ||||
type = flags_type & CMPL_BASE_TYPE_MASK; | type = flags_type & CMPL_BASE_TYPE_MASK; | ||||
switch (type) { | switch (type) { | ||||
case CMPL_BASE_TYPE_RX_L2: | case CMPL_BASE_TYPE_RX_L2: | ||||
return bnxt_pkt_get_l2(softc, ri, cpr, flags_type); | return bnxt_pkt_get_l2(softc, ri, cpr, flags_type); | ||||
case CMPL_BASE_TYPE_RX_TPA_END: | case CMPL_BASE_TYPE_RX_TPA_END: | ||||
return bnxt_pkt_get_tpa(softc, ri, cpr, flags_type); | return bnxt_pkt_get_tpa(softc, ri, cpr, flags_type); | ||||
case CMPL_BASE_TYPE_RX_TPA_START: | case CMPL_BASE_TYPE_RX_TPA_START: | ||||
rtpa = (void *)&cmp_q[cpr->cons]; | |||||
agg_id = (rtpa->agg_id & | |||||
RX_TPA_START_CMPL_AGG_ID_MASK) >> | |||||
RX_TPA_START_CMPL_AGG_ID_SFT; | |||||
softc->rx_rings[ri->iri_qsidx].tpa_start[agg_id].low = *rtpa; | |||||
NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit); | NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit); | ||||
ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx); | ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx); | ||||
CMPL_PREFETCH_NEXT(cpr, cpr->cons); | CMPL_PREFETCH_NEXT(cpr, cpr->cons); | ||||
softc->rx_rings[ri->iri_qsidx].tpa_start[agg_id].high = | |||||
((struct rx_tpa_start_cmpl_hi *)cmp_q)[cpr->cons]; | |||||
break; | break; | ||||
default: | default: | ||||
device_printf(softc->dev, | device_printf(softc->dev, | ||||
"Unhandled completion type %d on RXQ %d get\n", | "Unhandled completion type %d on RXQ %d get\n", | ||||
type, ri->iri_qsidx); | type, ri->iri_qsidx); | ||||
if (type & 1) { | if (type & 1) { | ||||
NEXT_CP_CONS_V(&cpr->ring, cpr->cons, | NEXT_CP_CONS_V(&cpr->ring, cpr->cons, | ||||
cpr->v_bit); | cpr->v_bit); | ||||
Show All 19 Lines |