tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

hme(4) hardware RX checksum



In hme.c:hme_get(), m_pkthdr.csum_flags is always cleared after
a goto label, so hardware RX checksum on hme(4) seems unused at all.
(no one has checked hwcsum stats by options TCP_CSUM_COUNTERS etc?)

There is also a wrong pointer arith in VLAN case.

Is it okay to commit this fix?

---
Index: hme.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/hme.c,v
retrieving revision 1.68
diff -u -r1.68 hme.c
--- hme.c       16 Dec 2008 22:35:31 -0000      1.68
+++ hme.c       6 Mar 2009 14:53:52 -0000
@@ -703,6 +703,9 @@
        struct mbuf *m, *m0, *newm;
        char *bp;
        int len, totlen;
+#ifdef INET
+       int csum_flags;
+#endif
 
        totlen = HME_XD_DECODE_RSIZE(flags);
        MGETHDR(m0, M_DONTWAIT, MT_DATA);
@@ -747,6 +750,7 @@
 
 #ifdef INET
        /* hardware checksum */
+       csum_flags = 0;
        if (ifp->if_csum_flags_rx & (M_CSUM_TCPv4 | M_CSUM_UDPv4)) {
                struct ether_header *eh;
                struct ip *ip;
@@ -758,8 +762,8 @@
                if (sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_MTU) {
                        pktlen = m0->m_pkthdr.len - ETHER_HDR_LEN -
                                ETHER_VLAN_ENCAP_LEN;
-                       eh = (struct ether_header *) mtod(m0, void *) +
-                               ETHER_VLAN_ENCAP_LEN;
+                       eh = (struct ether_header *)(mtod(m0, uint8_t *) +
+                               ETHER_VLAN_ENCAP_LEN);
                } else {
                        pktlen = m0->m_pkthdr.len - ETHER_HDR_LEN;
                        eh = mtod(m0, struct ether_header *);
@@ -790,7 +794,7 @@
                                goto swcsum;
                        if (pktlen < (hlen + sizeof(struct tcphdr)))
                                goto swcsum;
-                       m0->m_pkthdr.csum_flags = M_CSUM_TCPv4;
+                       csum_flags = M_CSUM_TCPv4;
                        break;
                case IPPROTO_UDP:
                        if (! (ifp->if_csum_flags_rx & M_CSUM_UDPv4))
@@ -801,7 +805,7 @@
                        /* no checksum */
                        if (uh->uh_sum == 0)
                                goto swcsum;
-                       m0->m_pkthdr.csum_flags = M_CSUM_UDPv4;
+                       csum_flags = M_CSUM_UDPv4;
                        break;
                default:
                        goto swcsum;
@@ -835,10 +839,10 @@
                                        (m0->m_pkthdr.csum_data & 0xffff);
                }
 
-               m0->m_pkthdr.csum_flags |= M_CSUM_DATA | M_CSUM_NO_PSEUDOHDR;
+               csum_flags |= M_CSUM_DATA | M_CSUM_NO_PSEUDOHDR;
        }
 swcsum:
-               m0->m_pkthdr.csum_flags = 0;
+       m0->m_pkthdr.csum_flags = csum_flags;
 #endif
 
        return (m0);

---
Izumi Tsutsui


Home | Main Index | Thread Index | Old Index