Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/marvell - Fix a bug that a fragmented packet is mark...



details:   https://anonhg.NetBSD.org/src/rev/3da6f17e7adb
branches:  trunk
changeset: 781812:3da6f17e7adb
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Tue Oct 02 15:22:46 2012 +0000

description:
- Fix a bug that a fragmented packet is marked as bad checksum. It causes
  a real bug when HW checksum offload function is used. It was easy to
  reproduce with NFS UDP mount.
- Fix a potential bug that a packet other than TCP and UDP is marked as bad
  checksum.

diffstat:

 sys/dev/marvell/if_mvgbe.c |  36 ++++++++++++++++++++++++------------
 1 files changed, 24 insertions(+), 12 deletions(-)

diffs (75 lines):

diff -r 8ff2b3d69376 -r 3da6f17e7adb sys/dev/marvell/if_mvgbe.c
--- a/sys/dev/marvell/if_mvgbe.c        Tue Oct 02 14:15:04 2012 +0000
+++ b/sys/dev/marvell/if_mvgbe.c        Tue Oct 02 15:22:46 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_mvgbe.c,v 1.20 2012/09/21 00:26:15 msaitoh Exp $    */
+/*     $NetBSD: if_mvgbe.c,v 1.21 2012/10/02 15:22:46 msaitoh Exp $    */
 /*
  * Copyright (c) 2007, 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -25,7 +25,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_mvgbe.c,v 1.20 2012/09/21 00:26:15 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_mvgbe.c,v 1.21 2012/10/02 15:22:46 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -1676,6 +1676,7 @@
        struct mbuf *m;
        bus_dmamap_t dmamap;
        uint32_t rxstat;
+       uint16_t bufsize;
        int idx, cur, total_len;
 
        idx = sc->sc_cdata.mvgbe_rx_prod;
@@ -1715,6 +1716,7 @@
                cdata->mvgbe_rx_chain[idx].mvgbe_mbuf = NULL;
                total_len = cur_rx->bytecnt;
                rxstat = cur_rx->cmdsts;
+               bufsize = cur_rx->bufsize;
 
                cdata->mvgbe_rx_map[idx] = NULL;
 
@@ -1743,20 +1745,30 @@
                        goto sw_csum;
 
                if (rxstat & MVGBE_RX_IP_FRAME_TYPE) {
+                       int flgs = 0;
+
                        /* Check IPv4 header checksum */
                        m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
                        if (!(rxstat & MVGBE_RX_IP_HEADER_OK))
-                               m->m_pkthdr.csum_flags |=
-                                   M_CSUM_IPv4_BAD;
+                               flgs |= M_CSUM_IPv4_BAD;
+
                        /* Check TCPv4/UDPv4 checksum */
-                       if ((rxstat & MVGBE_RX_L4_TYPE_MASK) ==
-                           MVGBE_RX_L4_TYPE_TCP)
-                               m->m_pkthdr.csum_flags |= M_CSUM_TCPv4;
-                       else if ((rxstat & MVGBE_RX_L4_TYPE_MASK) ==
-                           MVGBE_RX_L4_TYPE_UDP)
-                               m->m_pkthdr.csum_flags |= M_CSUM_UDPv4;
-                       if (!(rxstat & MVGBE_RX_L4_CHECKSUM))
-                               m->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD;
+                       if ((bufsize & MVGBE_RX_MAX_FRAME_LEN_ERROR) == 0) {
+                               /* Not fragmented */
+
+                               if ((rxstat & MVGBE_RX_L4_TYPE_MASK) ==
+                                   MVGBE_RX_L4_TYPE_TCP)
+                                       flgs |= M_CSUM_TCPv4;
+                               else if ((rxstat & MVGBE_RX_L4_TYPE_MASK) ==
+                                   MVGBE_RX_L4_TYPE_UDP)
+                                       flgs |= M_CSUM_UDPv4;
+
+                               if (((flgs & (M_CSUM_TCPv4|M_CSUM_UDPv4)) != 0)
+                                   && !(rxstat & MVGBE_RX_L4_CHECKSUM))
+                                       flgs |= M_CSUM_TCP_UDP_BAD;
+                       }
+
+                       m->m_pkthdr.csum_flags = flgs;
                }
 sw_csum:
 



Home | Main Index | Thread Index | Old Index