Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/e1000/em_txrx.c
Show First 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | static int lem_isc_rxd_available(void *arg, uint16_t rxqid, qidx_t idx, | ||||
qidx_t budget); | qidx_t budget); | ||||
static int lem_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri); | static int lem_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri); | ||||
static void lem_receive_checksum(int status, int errors, if_rxd_info_t ri); | static void lem_receive_checksum(int status, int errors, if_rxd_info_t ri); | ||||
static void em_receive_checksum(uint32_t status, if_rxd_info_t ri); | static void em_receive_checksum(uint32_t status, if_rxd_info_t ri); | ||||
static int em_determine_rsstype(u32 pkt_info); | static int em_determine_rsstype(u32 pkt_info); | ||||
extern int em_intr(void *arg); | extern int em_intr(void *arg); | ||||
struct if_txrx em_txrx = { | struct if_txrx em_txrx = { | ||||
em_isc_txd_encap, | em_isc_txd_encap, | ||||
em_isc_txd_flush, | em_isc_txd_flush, | ||||
em_isc_txd_credits_update, | em_isc_txd_credits_update, | ||||
em_isc_rxd_available, | em_isc_rxd_available, | ||||
em_isc_rxd_pkt_get, | em_isc_rxd_pkt_get, | ||||
em_isc_rxd_refill, | em_isc_rxd_refill, | ||||
em_isc_rxd_flush, | em_isc_rxd_flush, | ||||
em_intr | em_intr, | ||||
}; | }; | ||||
struct if_txrx lem_txrx = { | struct if_txrx lem_txrx = { | ||||
em_isc_txd_encap, | em_isc_txd_encap, | ||||
em_isc_txd_flush, | em_isc_txd_flush, | ||||
em_isc_txd_credits_update, | em_isc_txd_credits_update, | ||||
lem_isc_rxd_available, | lem_isc_rxd_available, | ||||
lem_isc_rxd_pkt_get, | lem_isc_rxd_pkt_get, | ||||
lem_isc_rxd_refill, | lem_isc_rxd_refill, | ||||
em_isc_rxd_flush, | em_isc_rxd_flush, | ||||
em_intr | em_intr, | ||||
}; | }; | ||||
extern if_shared_ctx_t em_sctx; | extern if_shared_ctx_t em_sctx; | ||||
void | void | ||||
em_dump_rs(struct adapter *adapter) | em_dump_rs(struct adapter *adapter) | ||||
{ | { | ||||
if_softc_ctx_t scctx = adapter->shared; | if_softc_ctx_t scctx = adapter->shared; | ||||
▲ Show 20 Lines • Show All 421 Lines • ▼ Show 20 Lines | em_isc_rxd_refill(void *arg, if_rxd_update_t iru) | ||||
paddrs = iru->iru_paddrs; | paddrs = iru->iru_paddrs; | ||||
pidx = iru->iru_pidx; | pidx = iru->iru_pidx; | ||||
count = iru->iru_count; | count = iru->iru_count; | ||||
for (i = 0, next_pidx = pidx; i < count; i++) { | for (i = 0, next_pidx = pidx; i < count; i++) { | ||||
rxd = &rxr->rx_base[next_pidx]; | rxd = &rxr->rx_base[next_pidx]; | ||||
rxd->read.buffer_addr = htole64(paddrs[i]); | rxd->read.buffer_addr = htole64(paddrs[i]); | ||||
/* DD bits must be cleared */ | /* Zero out rx desc status */ | ||||
rxd->wb.upper.status_error = 0; | rxd->wb.upper.status_error &= htole32(~0xFF); | ||||
cramerj_intel.com: Why? Is the compiler not doing what we would expect? | |||||
Not Done Inline ActionsIn the old driver, that was part of this commit: https://svnweb.freebsd.org/base/head/sys/dev/e1000/if_em.c?revision=293331&view=markup Apparently only the low 8 bits of the status_error word need to be zeroed. shurd: In the old driver, that was part of this commit:
https://svnweb.freebsd. | |||||
if (++next_pidx == scctx->isc_nrxd[0]) | if (++next_pidx == scctx->isc_nrxd[0]) | ||||
next_pidx = 0; | next_pidx = 0; | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
em_isc_rxd_flush(void *arg, uint16_t rxqid, uint8_t flid __unused, qidx_t pidx) | em_isc_rxd_flush(void *arg, uint16_t rxqid, uint8_t flid __unused, qidx_t pidx) | ||||
Show All 10 Lines | |||||
{ | { | ||||
struct adapter *sc = arg; | struct adapter *sc = arg; | ||||
if_softc_ctx_t scctx = sc->shared; | if_softc_ctx_t scctx = sc->shared; | ||||
struct em_rx_queue *que = &sc->rx_queues[rxqid]; | struct em_rx_queue *que = &sc->rx_queues[rxqid]; | ||||
struct rx_ring *rxr = &que->rxr; | struct rx_ring *rxr = &que->rxr; | ||||
struct e1000_rx_desc *rxd; | struct e1000_rx_desc *rxd; | ||||
u32 staterr = 0; | u32 staterr = 0; | ||||
int cnt, i; | int cnt, i; | ||||
budget = min(budget, scctx->isc_nrxd[0]); | |||||
if (budget == 1) { | for (cnt = 0, i = idx; cnt <= budget;) { | ||||
rxd = (struct e1000_rx_desc *)&rxr->rx_base[idx]; | |||||
staterr = rxd->status; | |||||
return (staterr & E1000_RXD_STAT_DD); | |||||
} | |||||
for (cnt = 0, i = idx; cnt < scctx->isc_nrxd[0] && cnt <= budget;) { | |||||
rxd = (struct e1000_rx_desc *)&rxr->rx_base[i]; | rxd = (struct e1000_rx_desc *)&rxr->rx_base[i]; | ||||
staterr = rxd->status; | staterr = rxd->status; | ||||
if ((staterr & E1000_RXD_STAT_DD) == 0) | if ((staterr & E1000_RXD_STAT_DD) == 0) | ||||
break; | break; | ||||
if (++i == scctx->isc_nrxd[0]) | if (++i == scctx->isc_nrxd[0]) | ||||
i = 0; | i = 0; | ||||
if (staterr & E1000_RXD_STAT_EOP) | if (staterr & E1000_RXD_STAT_EOP) | ||||
cnt++; | cnt++; | ||||
} | } | ||||
MPASS(cnt <= scctx->isc_nrxd[0]); | |||||
return (cnt); | return (cnt); | ||||
} | } | ||||
static int | static int | ||||
em_isc_rxd_available(void *arg, uint16_t rxqid, qidx_t idx, qidx_t budget) | em_isc_rxd_available(void *arg, uint16_t rxqid, qidx_t idx, qidx_t budget) | ||||
{ | { | ||||
struct adapter *sc = arg; | struct adapter *sc = arg; | ||||
if_softc_ctx_t scctx = sc->shared; | if_softc_ctx_t scctx = sc->shared; | ||||
struct em_rx_queue *que = &sc->rx_queues[rxqid]; | struct em_rx_queue *que = &sc->rx_queues[rxqid]; | ||||
struct rx_ring *rxr = &que->rxr; | struct rx_ring *rxr = &que->rxr; | ||||
union e1000_rx_desc_extended *rxd; | union e1000_rx_desc_extended *rxd; | ||||
u32 staterr = 0; | u32 staterr = 0; | ||||
int cnt, i; | int cnt, i; | ||||
budget = min(budget, scctx->isc_nrxd[0]); | |||||
if (budget == 1) { | for (cnt = 0, i = idx; cnt <= budget;) { | ||||
rxd = &rxr->rx_base[idx]; | |||||
staterr = le32toh(rxd->wb.upper.status_error); | |||||
return (staterr & E1000_RXD_STAT_DD); | |||||
} | |||||
for (cnt = 0, i = idx; cnt < scctx->isc_nrxd[0] && cnt <= budget;) { | |||||
rxd = &rxr->rx_base[i]; | rxd = &rxr->rx_base[i]; | ||||
staterr = le32toh(rxd->wb.upper.status_error); | staterr = le32toh(rxd->wb.upper.status_error); | ||||
if ((staterr & E1000_RXD_STAT_DD) == 0) | if ((staterr & E1000_RXD_STAT_DD) == 0) | ||||
break; | break; | ||||
if (++i == scctx->isc_nrxd[0]) { | if (++i == scctx->isc_nrxd[0]) { | ||||
i = 0; | i = 0; | ||||
} | } | ||||
if (staterr & E1000_RXD_STAT_EOP) | if (staterr & E1000_RXD_STAT_EOP) | ||||
cnt++; | cnt++; | ||||
} | } | ||||
MPASS(cnt <= scctx->isc_nrxd[0]); | |||||
return (cnt); | return (cnt); | ||||
} | } | ||||
static int | static int | ||||
lem_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri) | lem_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri) | ||||
{ | { | ||||
struct adapter *adapter = arg; | struct adapter *adapter = arg; | ||||
if_softc_ctx_t scctx = adapter->shared; | if_softc_ctx_t scctx = adapter->shared; | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | em_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri) | ||||
cidx = ri->iri_cidx; | cidx = ri->iri_cidx; | ||||
do { | do { | ||||
rxd = &rxr->rx_base[cidx]; | rxd = &rxr->rx_base[cidx]; | ||||
staterr = le32toh(rxd->wb.upper.status_error); | staterr = le32toh(rxd->wb.upper.status_error); | ||||
pkt_info = le32toh(rxd->wb.lower.mrq); | pkt_info = le32toh(rxd->wb.lower.mrq); | ||||
/* Error Checking then decrement count */ | /* Error Checking then decrement count */ | ||||
MPASS ((staterr & E1000_RXD_STAT_DD) != 0); | KASSERT(staterr & E1000_RXD_STAT_DD, | ||||
("cidx=%d i=%d iri_len=%d", cidx, i, ri->iri_len)); | |||||
len = le16toh(rxd->wb.upper.length); | len = le16toh(rxd->wb.upper.length); | ||||
ri->iri_len += len; | ri->iri_len += len; | ||||
eop = (staterr & E1000_RXD_STAT_EOP) != 0; | eop = (staterr & E1000_RXD_STAT_EOP) != 0; | ||||
/* Make sure bad packets are discarded */ | /* Make sure bad packets are discarded */ | ||||
if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) { | if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) { | ||||
▲ Show 20 Lines • Show All 110 Lines • Show Last 20 Lines |
Why? Is the compiler not doing what we would expect?