Corrections to the RX checksum code, make sure its disabled as

well as enabled when necessary. And simplify the checksum routine
itself, adding UDP bit to the test. Thanks to Kevin Lo for pointing
out the problems and code suggestions.
This commit is contained in:
Jack F Vogel 2013-04-15 17:01:42 +00:00
parent c072011223
commit 386c110e3c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=249509

View File

@ -4322,11 +4322,12 @@ em_initialize_receive_unit(struct adapter *adapter)
E1000_WRITE_REG(hw, E1000_RFCTL, E1000_RFCTL_ACK_DIS);
}
if (ifp->if_capenable & IFCAP_RXCSUM) {
rxcsum = E1000_READ_REG(hw, E1000_RXCSUM);
rxcsum |= (E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL);
E1000_WRITE_REG(hw, E1000_RXCSUM, rxcsum);
}
rxcsum = E1000_READ_REG(hw, E1000_RXCSUM);
if (ifp->if_capenable & IFCAP_RXCSUM)
rxcsum |= E1000_RXCSUM_TUOFL;
else
rxcsum &= ~E1000_RXCSUM_TUOFL;
E1000_WRITE_REG(hw, E1000_RXCSUM, rxcsum);
/*
** XXX TEMPORARY WORKAROUND: on some systems with 82573
@ -4644,31 +4645,23 @@ em_fixup_rx(struct rx_ring *rxr)
static void
em_receive_checksum(struct e1000_rx_desc *rx_desc, struct mbuf *mp)
{
mp->m_pkthdr.csum_flags = 0;
/* Ignore Checksum bit is set */
if (rx_desc->status & E1000_RXD_STAT_IXSM) {
mp->m_pkthdr.csum_flags = 0;
if (rx_desc->status & E1000_RXD_STAT_IXSM)
return;
}
if (rx_desc->status & E1000_RXD_STAT_IPCS) {
/* Did it pass? */
if (!(rx_desc->errors & E1000_RXD_ERR_IPE)) {
/* IP Checksum Good */
mp->m_pkthdr.csum_flags = CSUM_IP_CHECKED;
mp->m_pkthdr.csum_flags |= CSUM_IP_VALID;
if (rx_desc->errors & (E1000_RXD_ERR_TCPE | E1000_RXD_ERR_IPE))
return;
} else {
mp->m_pkthdr.csum_flags = 0;
}
}
/* IP Checksum Good? */
if (rx_desc->status & E1000_RXD_STAT_IPCS)
mp->m_pkthdr.csum_flags = (CSUM_IP_CHECKED | CSUM_IP_VALID);
if (rx_desc->status & E1000_RXD_STAT_TCPCS) {
/* Did it pass? */
if (!(rx_desc->errors & E1000_RXD_ERR_TCPE)) {
mp->m_pkthdr.csum_flags |=
(CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
mp->m_pkthdr.csum_data = htons(0xffff);
}
/* TCP or UDP checksum */
if (rx_desc->status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)) {
mp->m_pkthdr.csum_flags |= (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
mp->m_pkthdr.csum_data = htons(0xffff);
}
}