Current-Users archive

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

Re: 5.0_RC3 messed up RTL8111DL onboard NIC



tomsbsd%googlemail.com@localhost wrote:

> But not all is well. I can't get it to recognize/switch to Gigabit
> speed, neither automatically nor manually. And what's worse, this
> stays so even when rebooting into Windows. Only a cold-start (as in
> powerless until the standby voltage drops off) cures this again.

Hmm, could you try this random patch for netbsd-5 (from FreeBSD)?
(apply after reverting previous one)

Pre-compiled ones are here:
http://www.ceres.dti.ne.jp/~tsutsui/netbsd/netbsd-amd64-5.0_RC3-20090413.gz
http://www.ceres.dti.ne.jp/~tsutsui/netbsd/netbsd-i386-5.0_RC3-20090413.gz

---
Index: sys/dev/ic/rtl8169.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl8169.c,v
retrieving revision 1.105.4.2
diff -u -r1.105.4.2 rtl8169.c
--- sys/dev/ic/rtl8169.c        26 Mar 2009 17:36:03 -0000      1.105.4.2
+++ sys/dev/ic/rtl8169.c        13 Apr 2009 13:54:31 -0000
@@ -589,6 +589,7 @@
                        break;
                case RTK_HWREV_8101E:
                        sc->sc_rev = 11;
+                       sc->sc_quirk |= RTKQ_NOJUMBO;
                        break;
                case RTK_HWREV_8168_SPIN1:
                        sc->sc_rev = 21;
@@ -598,30 +599,58 @@
                        break;
                case RTK_HWREV_8168_SPIN3:
                        sc->sc_rev = 23;
+                       sc->sc_quirk |= RTKQ_MACSTAT;
                        break;
                case RTK_HWREV_8168C:
                case RTK_HWREV_8168C_SPIN2:
+               case RTK_HWREV_8168CP:
+               case RTK_HWREV_8168D:
                        sc->sc_rev = 24;
+                       sc->sc_quirk |= RTKQ_DESCV2 | RTKQ_NOEECMD |
+                           RTKQ_MACSTAT | RTKQ_CMDSTOP;
+                       /*
+                        * From FreeBSD driver:
+                        * 
+                        * These (8168/8111) controllers support jumbo frame
+                        * but it seems that enabling it requires touching
+                        * additional magic registers. Depending on MAC
+                        * revisions some controllers need to disable
+                        * checksum offload. So disable jumbo frame until
+                        * I have better idea what it really requires to
+                        * make it support.
+                        * RTL8168C/CP : supports up to 6KB jumbo frame.
+                        * RTL8111C/CP : supports up to 9KB jumbo frame.
+                        */
+                       sc->sc_quirk |= RTKQ_NOJUMBO;
                        break;
                case RTK_HWREV_8102E:
                case RTK_HWREV_8102EL:
+               case RTK_HWREV_8102EL_SPIN2:
                        sc->sc_rev = 25;
+                       sc->sc_quirk |= RTKQ_DESCV2 | RTKQ_NOEECMD |
+                           RTKQ_MACSTAT | RTKQ_CMDSTOP | RTKQ_NOJUMBO;
                        break;
                case RTK_HWREV_8100E:
                case RTK_HWREV_8100E_SPIN2:
                        /* XXX not in the Realtek driver */
                        sc->sc_rev = 0;
+                       sc->sc_quirk |= RTKQ_NOJUMBO;
                        break;
                default:
                        aprint_normal_dev(sc->sc_dev,
                            "Unknown revision (0x%08x)\n", hwrev);
                        sc->sc_rev = 0;
+                       /* assume the latest features */
+                       sc->sc_quirk |= RTKQ_DESCV2 | RTKQ_NOEECMD;
+                       sc->sc_quirk |= RTKQ_NOJUMBO;
                }
 
                /* Set RX length mask */
                sc->re_rxlenmask = RE_RDESC_STAT_GFRAGLEN;
                sc->re_ldata.re_tx_desc_cnt = RE_TX_DESC_CNT_8169;
        } else {
+               sc->sc_quirk |= RTKQ_NOJUMBO;
+
                /* Set RX length mask */
                sc->re_rxlenmask = RE_RDESC_STAT_FRAGLEN;
                sc->re_ldata.re_tx_desc_cnt = RE_TX_DESC_CNT_8139;
@@ -630,7 +659,7 @@
        /* Reset the adapter. */
        re_reset(sc);
 
-       if (sc->sc_rev == 24 || sc->sc_rev == 25) {
+       if ((sc->sc_quirk & RTKQ_NOEECMD) != 0) {
                /*
                 * Get station address from ID registers.
                 */
@@ -792,6 +821,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 +1276,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_RDESC_VLANCTL_IPV4) != 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 +1493,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 +1509,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 +1554,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 +1583,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;
 
                /*
@@ -1664,6 +1721,7 @@
        const uint8_t *enaddr;
        uint32_t rxcfg = 0;
        uint32_t reg;
+       uint16_t cfg;
        int error;
 
        if ((error = re_enable(sc)) != 0)
@@ -1681,32 +1739,27 @@
         * RX checksum offload. We must configure the C+ register
         * before all others.
         */
-       reg = 0;
-
-       /*
-        * XXX: Realtek docs say bits 0 and 1 are reserved, for 8169S/8110S.
-        * FreeBSD  drivers set these bits anyway (for 8139C+?).
-        * So far, it works.
-        */
+       cfg = RE_CPLUSCMD_PCI_MRW;
 
        /*
         * XXX: For old 8169 set bit 14.
         *      For 8169S/8110S and above, do not set bit 14.
         */
        if ((sc->sc_quirk & RTKQ_8169NONS) != 0)
-               reg |= (0x1 << 14) | RTK_CPLUSCMD_PCI_MRW;;
+               cfg |= (0x1 << 14);
 
-       if (1)  {/* not for 8169S ? */
-               reg |=
-                   RTK_CPLUSCMD_VLANSTRIP |
-                   (ifp->if_capenable &
-                   (IFCAP_CSUM_IPv4_Rx | IFCAP_CSUM_TCPv4_Rx |
-                    IFCAP_CSUM_UDPv4_Rx) ?
-                   RTK_CPLUSCMD_RXCSUM_ENB : 0);
-       }
+       if ((ifp->if_capenable & ETHERCAP_VLAN_HWTAGGING) != 0)
+               cfg |= RE_CPLUSCMD_VLANSTRIP;
+       if ((ifp->if_capenable & (IFCAP_CSUM_IPv4_Rx |
+            IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx)) != 0)
+               cfg |= RE_CPLUSCMD_RXCSUM_ENB;
+       if ((sc->sc_quirk & RTKQ_MACSTAT) != 0) {
+               cfg |= RE_CPLUSCMD_MACSTAT_DIS;
+               cfg |= RE_CPLUSCMD_TXENB;
+       } else
+               cfg |= RE_CPLUSCMD_RXENB | RE_CPLUSCMD_TXENB;
 
-       CSR_WRITE_2(sc, RTK_CPLUS_CMD,
-           reg | RTK_CPLUSCMD_RXENB | RTK_CPLUSCMD_TXENB);
+       CSR_WRITE_2(sc, RTK_CPLUS_CMD, cfg);
 
        /* XXX: from Realtek-supplied Linux driver. Wholly undocumented. */
        if ((sc->sc_quirk & RTKQ_8139CPLUS) == 0)
@@ -1859,14 +1912,9 @@
        switch (command) {
        case SIOCSIFMTU:
                /*
-                * According to FreeBSD, 8102E/8102EL use a different DMA
-                * descriptor format. 8168C/8111C requires touching additional
-                * magic registers. Depending on MAC revisions some controllers
-                * need to disable checksum offload.
-                *
-                * Disable jumbo frames for those parts.
+                * Disable jumbo frames if it's not supported.
                 */
-               if ((sc->sc_rev == 24 || sc->sc_rev == 25) &&
+               if ((sc->sc_quirk & RTKQ_NOJUMBO) != 0 &&
                    ifr->ifr_mtu > ETHERMTU) {
                        error = EINVAL;
                        break;
@@ -1931,8 +1979,14 @@
 
        mii_down(&sc->mii);
 
-       CSR_WRITE_1(sc, RTK_COMMAND, 0x00);
+       if ((sc->sc_quirk & RTKQ_CMDSTOP) != 0)
+               CSR_WRITE_1(sc, RTK_COMMAND, RTK_CMD_STOPREQ | RTK_CMD_TX_ENB |
+                   RTK_CMD_RX_ENB);
+       else
+               CSR_WRITE_1(sc, RTK_COMMAND, 0x00);
+       DELAY(1000);
        CSR_WRITE_2(sc, RTK_IMR, 0x0000);
+       CSR_WRITE_2(sc, RTK_ISR, 0xFFFF);
 
        if (sc->re_head != NULL) {
                m_freem(sc->re_head);
Index: sys/dev/ic/rtl81x9reg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl81x9reg.h,v
retrieving revision 1.32.4.1
diff -u -r1.32.4.1 rtl81x9reg.h
--- sys/dev/ic/rtl81x9reg.h     26 Mar 2009 17:36:03 -0000      1.32.4.1
+++ sys/dev/ic/rtl81x9reg.h     13 Apr 2009 13:54:31 -0000
@@ -158,6 +158,8 @@
 #define RTK_HWREV_8169_8110SB  0x10000000
 #define RTK_HWREV_8169_8110SC  0x18000000
 #define RTK_HWREV_8102EL       0x24800000
+#define RTK_HWREV_8102EL_SPIN2 0x24C00000
+#define RTK_HWREV_8168D                0x28000000
 #define RTK_HWREV_8168_SPIN1   0x30000000
 #define RTK_HWREV_8100E                0x30800000
 #define RTK_HWREV_8101E                0x34000000
@@ -167,6 +169,7 @@
 #define RTK_HWREV_8100E_SPIN2  0x38800000
 #define RTK_HWREV_8168C                0x3C000000
 #define RTK_HWREV_8168C_SPIN2  0x3C400000
+#define RTK_HWREV_8168CP       0x3C800000
 #define RTK_HWREV_8139         0x60000000
 #define RTK_HWREV_8139A                0x70000000
 #define RTK_HWREV_8139AG       0x70800000
@@ -306,6 +309,7 @@
 #define RTK_CMD_TX_ENB         0x0004
 #define RTK_CMD_RX_ENB         0x0008
 #define RTK_CMD_RESET          0x0010
+#define RTK_CMD_STOPREQ                0x0080
 
 /*
  * EEPROM control register
@@ -400,12 +404,21 @@
 
 /* C+ mode command register */
 
-#define RTK_CPLUSCMD_TXENB     0x0001  /* enable C+ transmit mode */
-#define RTK_CPLUSCMD_RXENB     0x0002  /* enable C+ receive mode */
-#define RTK_CPLUSCMD_PCI_MRW   0x0008  /* enable PCI multi-read/write */
-#define RTK_CPLUSCMD_PCI_DAC   0x0010  /* PCI dual-address cycle only */
-#define RTK_CPLUSCMD_RXCSUM_ENB        0x0020  /* enable RX checksum offload */
-#define RTK_CPLUSCMD_VLANSTRIP 0x0040  /* enable VLAN tag stripping */
+#define RE_CPLUSCMD_TXENB      0x0001  /* enable C+ transmit mode */
+#define RE_CPLUSCMD_RXENB      0x0002  /* enable C+ receive mode */
+#define RE_CPLUSCMD_PCI_MRW    0x0008  /* enable PCI multi-read/write */
+#define RE_CPLUSCMD_PCI_DAC    0x0010  /* PCI dual-address cycle only */
+#define RE_CPLUSCMD_RXCSUM_ENB 0x0020  /* enable RX checksum offload */
+#define RE_CPLUSCMD_VLANSTRIP  0x0040  /* enable VLAN tag stripping */
+#define RE_CPLUSCMD_MACSTAT_DIS        0x0080  /* 8168B/C/CP */
+#define RE_CPLUSCMD_ASF                0x0100  /* 8168C/CP */
+#define RE_CPLUSCMD_DBG_SEL    0x0200  /* 8168C/CP */
+#define RE_CPLUSCMD_FORCE_TXFC 0x0400  /* 8168C/CP */
+#define RE_CPLUSCMD_FORCE_RXFC 0x0800  /* 8168C/CP */
+#define RE_CPLUSCMD_FORCE_HDPX 0x1000  /* 8168C/CP */
+#define RE_CPLUSCMD_NORMAL_MODE        0x2000  /* 8168C/CP */
+#define RE_CPLUSCMD_DBG_ENB    0x4000  /* 8168C/CP */
+#define RE_CPLUSCMD_BIST_ENB   0x8000  /* 8168C/CP */
 
 /* C+ early transmit threshold */
 
@@ -475,6 +488,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
@@ -521,6 +537,8 @@
 #define RE_RDESC_VLANCTL_TAG   0x00010000      /* VLAN tag available
                                                   (re_vlandata valid)*/
 #define RE_RDESC_VLANCTL_DATA  0x0000FFFF      /* TAG data */
+#define RE_RDESC_VLANCTL_IPV6  0x80000000      /* DESCV2 IPV6 packet */
+#define RE_RDESC_VLANCTL_IPV4  0x40000000      /* DESCV2 IPV4 packet */
 
 #define RE_PROTOID_NONIP       0x00000000
 #define RE_PROTOID_TCPIP       0x00010000
Index: sys/dev/ic/rtl81x9var.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl81x9var.h,v
retrieving revision 1.41.12.1
diff -u -r1.41.12.1 rtl81x9var.h
--- sys/dev/ic/rtl81x9var.h     24 Mar 2009 20:38:38 -0000      1.41.12.1
+++ sys/dev/ic/rtl81x9var.h     13 Apr 2009 13:54:31 -0000
@@ -189,6 +189,11 @@
 #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 */
+#define RTKQ_NOJUMBO           0x00000040      /* no jumbo MTU support */
+#define RTKQ_NOEECMD           0x00000080      /* unusable EEPROM command */
+#define RTKQ_MACSTAT           0x00000100      /* set MACSTAT_DIS on init */
+#define RTKQ_CMDSTOP           0x00000200      /* set STOPREQ on stop */
 
        bus_dma_tag_t           sc_dmat;
 
---
Izumi Tsutsui


Home | Main Index | Thread Index | Old Index