Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/e1000/em_txrx.c
Show First 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | |||||
static int em_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri); | static int em_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri); | ||||
static void lem_isc_rxd_refill(void *arg, if_rxd_update_t iru); | static void lem_isc_rxd_refill(void *arg, if_rxd_update_t iru); | ||||
static int lem_isc_rxd_available(void *arg, uint16_t rxqid, qidx_t idx, | 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 em_receive_checksum(uint16_t, uint8_t, if_rxd_info_t); | ||||
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 = { | ||||
.ift_txd_encap = em_isc_txd_encap, | .ift_txd_encap = em_isc_txd_encap, | ||||
.ift_txd_flush = em_isc_txd_flush, | .ift_txd_flush = em_isc_txd_flush, | ||||
.ift_txd_credits_update = em_isc_txd_credits_update, | .ift_txd_credits_update = em_isc_txd_credits_update, | ||||
.ift_rxd_available = em_isc_rxd_available, | .ift_rxd_available = em_isc_rxd_available, | ||||
▲ Show 20 Lines • Show All 566 Lines • ▼ Show 20 Lines | do { | ||||
rxd->status = 0; | rxd->status = 0; | ||||
if (++cidx == scctx->isc_nrxd[0]) | if (++cidx == scctx->isc_nrxd[0]) | ||||
cidx = 0; | cidx = 0; | ||||
i++; | i++; | ||||
} while (!eop); | } while (!eop); | ||||
/* XXX add a faster way to look this up */ | /* XXX add a faster way to look this up */ | ||||
if (adapter->hw.mac.type >= e1000_82543 && !(status & E1000_RXD_STAT_IXSM)) | if (adapter->hw.mac.type >= e1000_82543) | ||||
lem_receive_checksum(status, errors, ri); | em_receive_checksum(status, errors, ri); | ||||
if (status & E1000_RXD_STAT_VP) { | if (status & E1000_RXD_STAT_VP) { | ||||
ri->iri_vtag = le16toh(rxd->special); | ri->iri_vtag = le16toh(rxd->special); | ||||
ri->iri_flags |= M_VLANTAG; | ri->iri_flags |= M_VLANTAG; | ||||
} | } | ||||
ri->iri_nfrags = i; | ri->iri_nfrags = i; | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | do { | ||||
/* Zero out the receive descriptors status. */ | /* Zero out the receive descriptors status. */ | ||||
rxd->wb.upper.status_error &= htole32(~0xFF); | rxd->wb.upper.status_error &= htole32(~0xFF); | ||||
if (++cidx == scctx->isc_nrxd[0]) | if (++cidx == scctx->isc_nrxd[0]) | ||||
cidx = 0; | cidx = 0; | ||||
i++; | i++; | ||||
} while (!eop); | } while (!eop); | ||||
/* XXX add a faster way to look this up */ | em_receive_checksum(staterr, staterr >> 24, ri); | ||||
if (adapter->hw.mac.type >= e1000_82543) | |||||
em_receive_checksum(staterr, ri); | |||||
if (staterr & E1000_RXD_STAT_VP) { | if (staterr & E1000_RXD_STAT_VP) { | ||||
vtag = le16toh(rxd->wb.upper.vlan); | vtag = le16toh(rxd->wb.upper.vlan); | ||||
} | } | ||||
ri->iri_vtag = vtag; | ri->iri_vtag = vtag; | ||||
if (vtag) | if (vtag) | ||||
ri->iri_flags |= M_VLANTAG; | ri->iri_flags |= M_VLANTAG; | ||||
ri->iri_flowid = le32toh(rxd->wb.lower.hi_dword.rss); | ri->iri_flowid = le32toh(rxd->wb.lower.hi_dword.rss); | ||||
ri->iri_rsstype = em_determine_rsstype(pkt_info); | ri->iri_rsstype = em_determine_rsstype(pkt_info); | ||||
ri->iri_nfrags = i; | ri->iri_nfrags = i; | ||||
return (0); | return (0); | ||||
} | } | ||||
/********************************************************************* | /********************************************************************* | ||||
* | * | ||||
* Verify that the hardware indicated that the checksum is valid. | * Verify that the hardware indicated that the checksum is valid. | ||||
* Inform the stack about the status of checksum so that stack | * Inform the stack about the status of checksum so that stack | ||||
* doesn't spend time verifying the checksum. | * doesn't spend time verifying the checksum. | ||||
* | * | ||||
*********************************************************************/ | *********************************************************************/ | ||||
static void | static void | ||||
lem_receive_checksum(int status, int errors, if_rxd_info_t ri) | em_receive_checksum(uint16_t status, uint8_t errors, if_rxd_info_t ri) | ||||
{ | { | ||||
/* Did it pass? */ | if (__predict_false(status & E1000_RXD_STAT_IXSM)) | ||||
if (status & E1000_RXD_STAT_IPCS && !(errors & E1000_RXD_ERR_IPE)) | return; | ||||
/* If there is a layer 3 or 4 error we are done */ | |||||
if (__predict_false(errors & (E1000_RXD_ERR_IPE | E1000_RXD_ERR_TCPE))) | |||||
karels: Isn't this test redundant? | |||||
Done Inline ActionsYes, thanks! kbowling: Yes, thanks! | |||||
Not Done Inline Actionsfwiw, the comment might have been worth keeping. karels: fwiw, the comment might have been worth keeping. | |||||
Not Done Inline ActionsYeah, seems like it emaste: Yeah, seems like it | |||||
Not Done Inline ActionsI'm indifferent to it, I'd want to go add it back to igb and igc if it stays here. @grehan thoughts? kbowling: I'm indifferent to it, I'd want to go add it back to igb and igc if it stays here. @grehan… | |||||
return; | |||||
/* IP Checksum Good */ | |||||
if (status & E1000_RXD_STAT_IPCS) | |||||
ri->iri_csum_flags = (CSUM_IP_CHECKED|CSUM_IP_VALID); | ri->iri_csum_flags = (CSUM_IP_CHECKED | CSUM_IP_VALID); | ||||
if (status & E1000_RXD_STAT_TCPCS) { | /* Valid L4E checksum */ | ||||
/* Did it pass? */ | if (__predict_true(status & | ||||
if (!(errors & E1000_RXD_ERR_TCPE)) { | (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))) { | ||||
ri->iri_csum_flags |= | ri->iri_csum_flags |= CSUM_DATA_VALID | CSUM_PSEUDO_HDR; | ||||
(CSUM_DATA_VALID | CSUM_PSEUDO_HDR); | |||||
ri->iri_csum_data = htons(0xffff); | ri->iri_csum_data = htons(0xffff); | ||||
} | } | ||||
} | } | ||||
} | |||||
/******************************************************************** | /******************************************************************** | ||||
* | * | ||||
* Parse the packet type to determine the appropriate hash | * Parse the packet type to determine the appropriate hash | ||||
* | * | ||||
******************************************************************/ | ******************************************************************/ | ||||
static int | static int | ||||
em_determine_rsstype(u32 pkt_info) | em_determine_rsstype(u32 pkt_info) | ||||
{ | { | ||||
switch (pkt_info & E1000_RXDADV_RSSTYPE_MASK) { | switch (pkt_info & E1000_RXDADV_RSSTYPE_MASK) { | ||||
case E1000_RXDADV_RSSTYPE_IPV4_TCP: | case E1000_RXDADV_RSSTYPE_IPV4_TCP: | ||||
return M_HASHTYPE_RSS_TCP_IPV4; | return M_HASHTYPE_RSS_TCP_IPV4; | ||||
case E1000_RXDADV_RSSTYPE_IPV4: | case E1000_RXDADV_RSSTYPE_IPV4: | ||||
return M_HASHTYPE_RSS_IPV4; | return M_HASHTYPE_RSS_IPV4; | ||||
case E1000_RXDADV_RSSTYPE_IPV6_TCP: | case E1000_RXDADV_RSSTYPE_IPV6_TCP: | ||||
return M_HASHTYPE_RSS_TCP_IPV6; | return M_HASHTYPE_RSS_TCP_IPV6; | ||||
case E1000_RXDADV_RSSTYPE_IPV6_EX: | case E1000_RXDADV_RSSTYPE_IPV6_EX: | ||||
return M_HASHTYPE_RSS_IPV6_EX; | return M_HASHTYPE_RSS_IPV6_EX; | ||||
case E1000_RXDADV_RSSTYPE_IPV6: | case E1000_RXDADV_RSSTYPE_IPV6: | ||||
return M_HASHTYPE_RSS_IPV6; | return M_HASHTYPE_RSS_IPV6; | ||||
case E1000_RXDADV_RSSTYPE_IPV6_TCP_EX: | case E1000_RXDADV_RSSTYPE_IPV6_TCP_EX: | ||||
return M_HASHTYPE_RSS_TCP_IPV6_EX; | return M_HASHTYPE_RSS_TCP_IPV6_EX; | ||||
default: | default: | ||||
return M_HASHTYPE_OPAQUE; | return M_HASHTYPE_OPAQUE; | ||||
} | |||||
} | |||||
static void | |||||
em_receive_checksum(uint32_t status, if_rxd_info_t ri) | |||||
{ | |||||
ri->iri_csum_flags = 0; | |||||
/* Ignore Checksum bit is set */ | |||||
if (status & E1000_RXD_STAT_IXSM) | |||||
return; | |||||
/* If the IP checksum exists and there is no IP Checksum error */ | |||||
if ((status & (E1000_RXD_STAT_IPCS | E1000_RXDEXT_STATERR_IPE)) == | |||||
E1000_RXD_STAT_IPCS) { | |||||
ri->iri_csum_flags = (CSUM_IP_CHECKED | CSUM_IP_VALID); | |||||
} | |||||
/* TCP or UDP checksum */ | |||||
if ((status & (E1000_RXD_STAT_TCPCS | E1000_RXDEXT_STATERR_TCPE)) == | |||||
E1000_RXD_STAT_TCPCS) { | |||||
ri->iri_csum_flags |= (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); | |||||
ri->iri_csum_data = htons(0xffff); | |||||
} | |||||
if (status & E1000_RXD_STAT_UDPCS) { | |||||
ri->iri_csum_flags |= (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); | |||||
ri->iri_csum_data = htons(0xffff); | |||||
} | } | ||||
} | } |
Isn't this test redundant?