From: naddy Date: Tue, 22 Apr 2014 15:52:05 +0000 (+0000) Subject: Remove RX checksum offloading support. The chip is too limited, and X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=e535ad4641e1fb13a307139fefe55e31998e15f4;p=openbsd Remove RX checksum offloading support. The chip is too limited, and examining higher protocol layers to adjust the checksum and calculate the pseudo-header in the driver is too complex to be worthwhile. ok henning@ --- diff --git a/sys/arch/sparc/dev/hme.c b/sys/arch/sparc/dev/hme.c index 353f5a05b8e..c736f518c35 100644 --- a/sys/arch/sparc/dev/hme.c +++ b/sys/arch/sparc/dev/hme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hme.c,v 1.64 2013/09/05 20:55:58 bluhm Exp $ */ +/* $OpenBSD: hme.c,v 1.65 2014/04/22 15:52:05 naddy Exp $ */ /* * Copyright (c) 1998 Jason L. Wright (jason@thought.net) @@ -103,9 +103,6 @@ int hme_tint(struct hme_softc *); int hme_mint(struct hme_softc *, u_int32_t); int hme_eint(struct hme_softc *, u_int32_t); -/* TCP/UDP checksum offload support */ -void hme_rxcksum(struct mbuf *, u_int32_t); - void hme_reset_rx(struct hme_softc *); void hme_reset_tx(struct hme_softc *); @@ -494,7 +491,7 @@ void hmeinit(sc) struct hme_softc *sc; { - u_int32_t c, n; + u_int32_t c; struct ifnet *ifp = &sc->sc_arpcom.ac_if; struct hme_tcvr *tcvr = sc->sc_tcvr; struct hme_cr *cr = sc->sc_cr; @@ -553,10 +550,6 @@ hmeinit(sc) txr->cfg |= TXR_CFG_DMAENABLE; c = RXR_CFG_DMAENABLE | (HME_RX_OFFSET << 3); - /* RX TCP/UDP cksum offset */ - n = (ETHER_HDR_LEN + sizeof(struct ip)) / 2; - n = (n << RXR_CFG_CSUM_SHIFT) & RXR_CFG_CSUMSTART; - c |= n; #if HME_RX_RING_SIZE == 32 c |= RXR_CFG_RINGSIZE32; #elif HME_RX_RING_SIZE == 64 @@ -709,101 +702,6 @@ hme_tint(sc) return (1); } -/* - * XXX layering violation - * - * If we can have additional csum data member in 'struct pkthdr' for - * these incomplete checksum offload capable hardware, things would be - * much simpler. That member variable will carry partial checksum - * data and it may be evaluated in TCP/UDP input handler after - * computing pseudo header checksumming. - */ -void -hme_rxcksum(struct mbuf *m, u_int32_t flags) -{ - struct ether_header *eh; - struct ip *ip; - struct udphdr *uh; - int32_t hlen, len, pktlen; - u_int16_t cksum, *opts; - u_int32_t temp32; - union pseudoh { - struct hdr { - u_int16_t len; - u_int8_t ttl; - u_int8_t proto; - u_int32_t src; - u_int32_t dst; - } h; - u_int16_t w[6]; - } ph; - - pktlen = m->m_pkthdr.len; - if (pktlen < sizeof(struct ether_header)) - return; - eh = mtod(m, struct ether_header *); - if (eh->ether_type != htons(ETHERTYPE_IP)) - return; - ip = (struct ip *)(eh + 1); - if (ip->ip_v != IPVERSION) - return; - - hlen = ip->ip_hl << 2; - pktlen -= sizeof(struct ether_header); - if (hlen < sizeof(struct ip)) - return; - if (ntohs(ip->ip_len) < hlen) - return; - if (ntohs(ip->ip_len) != pktlen) - return; - if (ip->ip_off & htons(IP_MF | IP_OFFMASK)) - return; /* can't handle fragmented packet */ - - switch (ip->ip_p) { - case IPPROTO_TCP: - if (pktlen < (hlen + sizeof(struct tcphdr))) - return; - break; - case IPPROTO_UDP: - if (pktlen < (hlen + sizeof(struct udphdr))) - return; - uh = (struct udphdr *)((caddr_t)ip + hlen); - if (uh->uh_sum == 0) - return; /* no checksum */ - break; - default: - return; - } - - cksum = htons(~(flags & HME_RXD_CSUM)); - /* cksum fixup for IP options */ - len = hlen - sizeof(struct ip); - if (len > 0) { - opts = (u_int16_t *)(ip + 1); - for (; len > 0; len -= sizeof(u_int16_t), opts++) { - temp32 = cksum - *opts; - temp32 = (temp32 >> 16) + (temp32 & 65535); - cksum = temp32 & 65535; - } - } - /* cksum fixup for pseudo-header, replace with in_cksum_phdr()? */ - ph.h.len = htons(ntohs(ip->ip_len) - hlen); - ph.h.ttl = 0; - ph.h.proto = ip->ip_p; - ph.h.src = ip->ip_src.s_addr; - ph.h.dst = ip->ip_dst.s_addr; - temp32 = cksum; - opts = &ph.w[0]; - temp32 += opts[0] + opts[1] + opts[2] + opts[3] + opts[4] + opts[5]; - temp32 = (temp32 >> 16) + (temp32 & 65535); - temp32 += (temp32 >> 16); - cksum = ~temp32; - if (cksum == 0) { - m->m_pkthdr.csum_flags |= - M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK; - } -} - int hme_rint(sc) struct hme_softc *sc; @@ -944,7 +842,6 @@ hme_read(sc, idx, len, flags) } ifp->if_ipackets++; - hme_rxcksum(m, flags); #if NBPFILTER > 0 /* diff --git a/sys/dev/ic/gem.c b/sys/dev/ic/gem.c index eefb6410649..8d3e84cdb55 100644 --- a/sys/dev/ic/gem.c +++ b/sys/dev/ic/gem.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gem.c,v 1.102 2014/03/14 11:04:24 dlg Exp $ */ +/* $OpenBSD: gem.c,v 1.103 2014/04/22 15:52:05 naddy Exp $ */ /* $NetBSD: gem.c,v 1.1 2001/09/16 00:11:43 eeh Exp $ */ /* @@ -120,7 +120,6 @@ int gem_eint(struct gem_softc *, u_int); int gem_rint(struct gem_softc *); int gem_tint(struct gem_softc *, u_int32_t); int gem_pint(struct gem_softc *); -void gem_rxcksum(struct mbuf *, u_int64_t); #ifdef GEM_DEBUG #define DPRINTF(sc, x) if ((sc)->sc_arpcom.ac_if.if_flags & IFF_DEBUG) \ @@ -811,9 +810,6 @@ gem_init(struct ifnet *ifp) /* Encode Receive Descriptor ring size: four possible values */ v = gem_ringsize(GEM_NRXDESC /*XXX*/); - /* RX TCP/UDP checksum offset */ - v |= ((ETHER_HDR_LEN + sizeof(struct ip)) << - GEM_RX_CONFIG_CXM_START_SHFT); /* Enable DMA */ bus_space_write_4(t, h, GEM_RX_CONFIG, v|(GEM_THRSH_1024<sc_arpcom.ac_enaddr[0]<<8) | sc->sc_arpcom.ac_enaddr[1]); } -/* - * RX TCP/UDP checksum - */ -void -gem_rxcksum(struct mbuf *m, u_int64_t rxstat) -{ - struct ether_header *eh; - struct ip *ip; - struct udphdr *uh; - int32_t hlen, len, pktlen; - u_int16_t cksum, *opts; - u_int32_t temp32; - union pseudoh { - struct hdr { - u_int16_t len; - u_int8_t ttl; - u_int8_t proto; - u_int32_t src; - u_int32_t dst; - } h; - u_int16_t w[6]; - } ph; - - pktlen = m->m_pkthdr.len; - if (pktlen < sizeof(struct ether_header)) - return; - eh = mtod(m, struct ether_header *); - if (eh->ether_type != htons(ETHERTYPE_IP)) - return; - ip = (struct ip *)(eh + 1); - if (ip->ip_v != IPVERSION) - return; - - hlen = ip->ip_hl << 2; - pktlen -= sizeof(struct ether_header); - if (hlen < sizeof(struct ip)) - return; - if (ntohs(ip->ip_len) < hlen) - return; - if (ntohs(ip->ip_len) != pktlen) - return; - if (ip->ip_off & htons(IP_MF | IP_OFFMASK)) - return; /* can't handle fragmented packet */ - - switch (ip->ip_p) { - case IPPROTO_TCP: - if (pktlen < (hlen + sizeof(struct tcphdr))) - return; - break; - case IPPROTO_UDP: - if (pktlen < (hlen + sizeof(struct udphdr))) - return; - uh = (struct udphdr *)((caddr_t)ip + hlen); - if (uh->uh_sum == 0) - return; /* no checksum */ - break; - default: - return; - } - - cksum = htons(~(rxstat & GEM_RD_CHECKSUM)); - /* cksum fixup for IP options */ - len = hlen - sizeof(struct ip); - if (len > 0) { - opts = (u_int16_t *)(ip + 1); - for (; len > 0; len -= sizeof(u_int16_t), opts++) { - temp32 = cksum - *opts; - temp32 = (temp32 >> 16) + (temp32 & 65535); - cksum = temp32 & 65535; - } - } - - ph.h.len = htons(ntohs(ip->ip_len) - hlen); - ph.h.ttl = 0; - ph.h.proto = ip->ip_p; - ph.h.src = ip->ip_src.s_addr; - ph.h.dst = ip->ip_dst.s_addr; - temp32 = cksum; - opts = &ph.w[0]; - temp32 += opts[0] + opts[1] + opts[2] + opts[3] + opts[4] + opts[5]; - temp32 = (temp32 >> 16) + (temp32 & 65535); - temp32 += (temp32 >> 16); - cksum = ~temp32; - if (cksum == 0) { - m->m_pkthdr.csum_flags |= - M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK; - } -} - /* * Receive interrupt. */ @@ -1101,8 +1008,6 @@ gem_rint(struct gem_softc *sc) m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = len; - gem_rxcksum(m, rxstat); - #if NBPFILTER > 0 if (ifp->if_bpf) bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN); diff --git a/sys/dev/ic/hme.c b/sys/dev/ic/hme.c index 803008f5610..bc66d37194d 100644 --- a/sys/dev/ic/hme.c +++ b/sys/dev/ic/hme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hme.c,v 1.63 2013/08/07 01:06:29 bluhm Exp $ */ +/* $OpenBSD: hme.c,v 1.64 2014/04/22 15:52:05 naddy Exp $ */ /* $NetBSD: hme.c,v 1.21 2001/07/07 15:59:37 thorpej Exp $ */ /*- @@ -105,8 +105,6 @@ void hme_mediastatus(struct ifnet *, struct ifmediareq *); int hme_eint(struct hme_softc *, u_int); int hme_rint(struct hme_softc *); int hme_tint(struct hme_softc *); -/* TCP/UDP checksum offload support */ -void hme_rxcksum(struct mbuf *, u_int32_t); void hme_config(sc) @@ -516,7 +514,7 @@ hme_init(sc) bus_space_handle_t erx = sc->sc_erx; bus_space_handle_t mac = sc->sc_mac; u_int8_t *ea; - u_int32_t v, n; + u_int32_t v; /* * Initialization sequence. The numbered steps below correspond @@ -625,10 +623,6 @@ hme_init(sc) #endif /* Enable DMA */ v |= HME_ERX_CFG_DMAENABLE | (HME_RX_OFFSET << 3); - /* RX TCP/UDP cksum offset */ - n = (ETHER_HDR_LEN + sizeof(struct ip)) / 2; - n = (n << HME_ERX_CFG_CSUM_SHIFT) & HME_ERX_CFG_CSUMSTART; - v |= n; bus_space_write_4(t, erx, HME_ERXI_CFG, v); /* step 11. XIF Configuration */ @@ -830,101 +824,6 @@ hme_tint(sc) return (1); } -/* - * XXX layering violation - * - * If we can have additional csum data member in 'struct pkthdr' for - * these incomplete checksum offload capable hardware, things would be - * much simpler. That member variable will carry partial checksum - * data and it may be evaluated in TCP/UDP input handler after - * computing pseudo header checksumming. - */ -void -hme_rxcksum(struct mbuf *m, u_int32_t flags) -{ - struct ether_header *eh; - struct ip *ip; - struct udphdr *uh; - int32_t hlen, len, pktlen; - u_int16_t cksum, *opts; - u_int32_t temp32; - union pseudoh { - struct hdr { - u_int16_t len; - u_int8_t ttl; - u_int8_t proto; - u_int32_t src; - u_int32_t dst; - } h; - u_int16_t w[6]; - } ph; - - pktlen = m->m_pkthdr.len; - if (pktlen < sizeof(struct ether_header)) - return; - eh = mtod(m, struct ether_header *); - if (eh->ether_type != htons(ETHERTYPE_IP)) - return; - ip = (struct ip *)(eh + 1); - if (ip->ip_v != IPVERSION) - return; - - hlen = ip->ip_hl << 2; - pktlen -= sizeof(struct ether_header); - if (hlen < sizeof(struct ip)) - return; - if (ntohs(ip->ip_len) < hlen) - return; - if (ntohs(ip->ip_len) != pktlen) - return; - if (ip->ip_off & htons(IP_MF | IP_OFFMASK)) - return; /* can't handle fragmented packet */ - - switch (ip->ip_p) { - case IPPROTO_TCP: - if (pktlen < (hlen + sizeof(struct tcphdr))) - return; - break; - case IPPROTO_UDP: - if (pktlen < (hlen + sizeof(struct udphdr))) - return; - uh = (struct udphdr *)((caddr_t)ip + hlen); - if (uh->uh_sum == 0) - return; /* no checksum */ - break; - default: - return; - } - - cksum = htons(~(flags & HME_XD_RXCKSUM)); - /* cksum fixup for IP options */ - len = hlen - sizeof(struct ip); - if (len > 0) { - opts = (u_int16_t *)(ip + 1); - for (; len > 0; len -= sizeof(u_int16_t), opts++) { - temp32 = cksum - *opts; - temp32 = (temp32 >> 16) + (temp32 & 65535); - cksum = temp32 & 65535; - } - } - /* cksum fixup for pseudo-header, replace with in_cksum_phdr()? */ - ph.h.len = htons(ntohs(ip->ip_len) - hlen); - ph.h.ttl = 0; - ph.h.proto = ip->ip_p; - ph.h.src = ip->ip_src.s_addr; - ph.h.dst = ip->ip_dst.s_addr; - temp32 = cksum; - opts = &ph.w[0]; - temp32 += opts[0] + opts[1] + opts[2] + opts[3] + opts[4] + opts[5]; - temp32 = (temp32 >> 16) + (temp32 & 65535); - temp32 += (temp32 >> 16); - cksum = ~temp32; - if (cksum == 0) { - m->m_pkthdr.csum_flags |= - M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK; - } -} - /* * Receive interrupt. */ @@ -975,7 +874,6 @@ hme_rint(sc) m->m_pkthdr.len = m->m_len = len; ifp->if_ipackets++; - hme_rxcksum(m, flags); #if NBPFILTER > 0 if (ifp->if_bpf)