NetBSD-Bugs archive

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

Re: kern/40955: re(4) fails to work with hardware checksumming enabled



The following reply was made to PR kern/40955; it has been noted by GNATS.

From: Izumi Tsutsui <tsutsui%ceres.dti.ne.jp@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: kern-bug-people%NetBSD.org@localhost, gnats-admin%NetBSD.org@localhost, 
netbsd-bugs%NetBSD.org@localhost,
        tsutsui%ceres.dti.ne.jp@localhost
Subject: Re: kern/40955: re(4) fails to work with hardware checksumming enabled
Date: Fri, 20 Mar 2009 17:12:18 +0900

 > >Synopsis:       re(4) fails to work with hardware checksumming enabled
  :
 > re0 at pci1 dev 0 function 0: RealTek 8100E/8101E/8102E/8102EL PCIe 
 > 10/100BaseTX (rev. 0x02)
 
 Could you try this patch (from FreeBSD) for -current?
 
 If you'd like to try it on netbsd-5, you also have to apply
 the previous another fix first: 
 http://mail-index.NetBSD.org/source-changes/2009/03/20/msg218651.html
 
http://cvsweb.de.NetBSD.org/cgi-bin/cvsweb.cgi/src/sys/dev/ic/rtl8169.c.diff?r1=1.107;r2=1.108
 
http://cvsweb.de.NetBSD.org/cgi-bin/cvsweb.cgi/src/sys/dev/ic/rtl81x9var.h.diff?r1=1.41;r2=1.42
 
 You can also check RX csum status by a kernel configured with
 "options INET_CSUM_COUNTERS,TCP_CSUM_COUNTERS,UDP_CSUM_COUNTER"
 and commands like "vmstat -ev|grep csum" .
 
 ---
 Index: rtl8169.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/ic/rtl8169.c,v
 retrieving revision 1.108
 diff -u -r1.108 rtl8169.c
 --- rtl8169.c  20 Mar 2009 06:31:31 -0000      1.108
 +++ rtl8169.c  20 Mar 2009 07:43:21 -0000
 @@ -606,6 +606,7 @@
                case RTK_HWREV_8102E:
                case RTK_HWREV_8102EL:
                        sc->sc_rev = 25;
 +                      sc->sc_quirk |= RTKQ_DESCV2;
                        break;
                case RTK_HWREV_8100E:
                case RTK_HWREV_8100E_SPIN2:
 @@ -792,6 +793,15 @@
            IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx |
            IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx |
            IFCAP_TSOv4;
 +
 +      /*
 +       * XXX
 +       * Still have no idea how to make TSO work on 8168C, 8168CP,
 +       * 8102E, 8111C and 8111CP.
 +       */
 +      if ((sc->sc_quirk & RTKQ_DESCV2) != 0)
 +              ifp->if_capabilities &= ~IFCAP_TSOv4;
 +
        ifp->if_watchdog = re_watchdog;
        ifp->if_init = re_init;
        ifp->if_snd.ifq_maxlen = RE_IFQ_MAXLEN;
 @@ -1238,7 +1248,9 @@
                /* Do RX checksumming */
  
                /* Check IP header checksum */
 -              if (rxstat & RE_RDESC_STAT_PROTOID) {
 +              if ((rxstat & RE_RDESC_STAT_PROTOID) != 0 &&
 +                  ((sc->sc_quirk & RTKQ_DESCV2) == 0 ||
 +                   (rxvlan & RE_PROTOID_IP) != 0)) {
                        m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
                        if (rxstat & RE_RDESC_STAT_IPSUMBAD)
                                m->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD;
 @@ -1453,6 +1465,7 @@
                 * chip. I'm not sure if this is a requirement or a bug.)
                 */
  
 +              vlanctl = 0;
                if ((m->m_pkthdr.csum_flags & M_CSUM_TSOv4) != 0) {
                        uint32_t segsz = m->m_pkthdr.segsz;
  
 @@ -1468,12 +1481,28 @@
                        if ((m->m_pkthdr.csum_flags &
                            (M_CSUM_IPv4 | M_CSUM_TCPv4 | M_CSUM_UDPv4))
                            != 0) {
 -                              re_flags |= RE_TDESC_CMD_IPCSUM;
 -                              if (m->m_pkthdr.csum_flags & M_CSUM_TCPv4) {
 -                                      re_flags |= RE_TDESC_CMD_TCPCSUM;
 -                              } else if (m->m_pkthdr.csum_flags &
 -                                  M_CSUM_UDPv4) {
 -                                      re_flags |= RE_TDESC_CMD_UDPCSUM;
 +                              if ((sc->sc_quirk & RTKQ_DESCV2) == 0) {
 +                                      re_flags |= RE_TDESC_CMD_IPCSUM;
 +                                      if (m->m_pkthdr.csum_flags &
 +                                          M_CSUM_TCPv4) {
 +                                              re_flags |=
 +                                                  RE_TDESC_CMD_TCPCSUM;
 +                                      } else if (m->m_pkthdr.csum_flags &
 +                                          M_CSUM_UDPv4) {
 +                                              re_flags |=
 +                                                  RE_TDESC_CMD_UDPCSUM;
 +                                      }
 +                              } else {
 +                                      vlanctl |= RE_TDESC_VLANCTL_IPCSUM;
 +                                      if (m->m_pkthdr.csum_flags &
 +                                          M_CSUM_TCPv4) {
 +                                              vlanctl |=
 +                                                  RE_TDESC_VLANCTL_TCPCSUM;
 +                                      } else if (m->m_pkthdr.csum_flags &
 +                                          M_CSUM_UDPv4) {
 +                                              vlanctl |=
 +                                                  RE_TDESC_VLANCTL_UDPCSUM;
 +                                      }
                                }
                        }
                }
 @@ -1497,7 +1526,8 @@
                nsegs = map->dm_nsegs;
                pad = false;
                if (__predict_false(m->m_pkthdr.len <= RE_IP4CSUMTX_PADLEN &&
 -                  (re_flags & RE_TDESC_CMD_IPCSUM) != 0)) {
 +                  (re_flags & RE_TDESC_CMD_IPCSUM) != 0 &&
 +                  (sc->sc_quirk & RTKQ_DESCV2) == 0)) {
                        pad = true;
                        nsegs++;
                }
 @@ -1525,9 +1555,8 @@
                 * appear in all descriptors of a multi-descriptor
                 * transmission attempt.
                 */
 -              vlanctl = 0;
                if ((mtag = VLAN_OUTPUT_TAG(&sc->ethercom, m)) != NULL)
 -                      vlanctl = bswap16(VLAN_TAG_VALUE(mtag)) |
 +                      vlanctl |= bswap16(VLAN_TAG_VALUE(mtag)) |
                            RE_TDESC_VLANCTL_TAG;
  
                /*
 Index: rtl81x9reg.h
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/ic/rtl81x9reg.h,v
 retrieving revision 1.33
 diff -u -r1.33 rtl81x9reg.h
 --- rtl81x9reg.h       8 Dec 2008 03:24:08 -0000       1.33
 +++ rtl81x9reg.h       20 Mar 2009 07:43:22 -0000
 @@ -475,6 +475,9 @@
  
  #define RE_TDESC_VLANCTL_TAG  0x00020000      /* Insert VLAN tag */
  #define RE_TDESC_VLANCTL_DATA 0x0000FFFF      /* TAG data */
 +#define RE_TDESC_VLANCTL_UDPCSUM 0x80000000   /* DESCV2 UDP cksum enable */
 +#define RE_TDESC_VLANCTL_TCPCSUM 0x40000000   /* DESCV2 TCP cksum enable */
 +#define RE_TDESC_VLANCTL_IPCSUM       0x20000000      /* DESCV2 IP hdr cksum 
enable */
  
  /*
   * Error bits are valid only on the last descriptor of a frame
 Index: rtl81x9var.h
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/ic/rtl81x9var.h,v
 retrieving revision 1.42
 diff -u -r1.42 rtl81x9var.h
 --- rtl81x9var.h       20 Mar 2009 06:31:31 -0000      1.42
 +++ rtl81x9var.h       20 Mar 2009 07:43:22 -0000
 @@ -189,6 +189,7 @@
  #define RTKQ_8169NONS         0x00000004      /* old non-single 8169 */
  #define RTKQ_PCIE             0x00000008      /* PCIe variants */
  #define RTKQ_MACLDPS          0x00000010      /* has LDPS register */
 +#define RTKQ_DESCV2           0x00000020      /* has V2 TX/RX descriptor */
  
        bus_dma_tag_t           sc_dmat;
  
 
 ---
 Izumi Tsutsui
 


Home | Main Index | Thread Index | Old Index