Remove RX checksum offloading support. The chip is too limited, and
authornaddy <naddy@openbsd.org>
Tue, 22 Apr 2014 15:52:05 +0000 (15:52 +0000)
committernaddy <naddy@openbsd.org>
Tue, 22 Apr 2014 15:52:05 +0000 (15:52 +0000)
examining higher protocol layers to adjust the checksum and calculate
the pseudo-header in the driver is too complex to be worthwhile.
ok henning@

sys/arch/sparc/dev/hme.c
sys/dev/ic/gem.c
sys/dev/ic/hme.c

index 353f5a0..c736f51 100644 (file)
@@ -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
        /*
index eefb641..8d3e84c 100644 (file)
@@ -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<<GEM_RX_CONFIG_FIFO_THRS_SHIFT)|
@@ -947,95 +943,6 @@ gem_init_regs(struct gem_softc *sc)
                (sc->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);
index 803008f..bc66d37 100644 (file)
@@ -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)