diff options
author | alc <alc@FreeBSD.org> | 2001-09-23 05:13:12 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2001-09-23 05:13:12 +0000 |
commit | abcc2b1f151377677787c46b3fa3f902543685fb (patch) | |
tree | 3988c51c31c8da5325193cf8336c900e6ca8bbf2 /sys/pci | |
parent | ff0ca8acbc3b62ae1fdace42bffebb93178a0b3d (diff) | |
download | FreeBSD-src-abcc2b1f151377677787c46b3fa3f902543685fb.zip FreeBSD-src-abcc2b1f151377677787c46b3fa3f902543685fb.tar.gz |
Implement TCP/IP checksum off-loading on receive. Announce
rxcsum capabilities.
Reviewed by: wpaul
Diffstat (limited to 'sys/pci')
-rw-r--r-- | sys/pci/if_xl.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/sys/pci/if_xl.c b/sys/pci/if_xl.c index dca74ee..82c6cbe 100644 --- a/sys/pci/if_xl.c +++ b/sys/pci/if_xl.c @@ -1462,14 +1462,16 @@ static int xl_attach(dev) ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = xl_ioctl; ifp->if_output = ether_output; - if (sc->xl_type == XL_TYPE_905B) + if (sc->xl_type == XL_TYPE_905B) { ifp->if_start = xl_start_90xB; - else + ifp->if_capabilities = IFCAP_RXCSUM; + } else ifp->if_start = xl_start; ifp->if_watchdog = xl_watchdog; ifp->if_init = xl_init; ifp->if_baudrate = 10000000; ifp->if_snd.ifq_maxlen = XL_TX_LIST_CNT - 1; + ifp->if_capenable = ifp->if_capabilities; /* * Now we have to see what sort of media we have. @@ -1831,7 +1833,7 @@ static void xl_rxeof(sc) struct ifnet *ifp; struct xl_chain_onefrag *cur_rx; int total_len = 0; - u_int16_t rxstat; + u_int32_t rxstat; ifp = &sc->arpcom.ac_if; @@ -1890,6 +1892,22 @@ again: /* Remove header from mbuf and pass it on. */ m_adj(m, sizeof(struct ether_header)); + + if (sc->xl_type == XL_TYPE_905B) { + /* Do IP checksum checking. */ + if (rxstat & XL_RXSTAT_IPCKOK) + m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED; + if (!(rxstat & XL_RXSTAT_IPCKERR)) + m->m_pkthdr.csum_flags |= CSUM_IP_VALID; + if ((rxstat & XL_RXSTAT_TCPCOK && + !(rxstat & XL_RXSTAT_TCPCKERR)) || + (rxstat & XL_RXSTAT_UDPCKOK && + !(rxstat & XL_RXSTAT_UDPCKERR))) { + m->m_pkthdr.csum_flags |= + CSUM_DATA_VALID|CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xffff; + } + } ether_input(ifp, eh, m); } |