tech-net archive

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

Re: RTL8169S/8110S not supported on 4.0_STABLE?



bradd%cat.co.za@localhost wrote:

> Can anything be deduced from the fact that the manual as well as the 
> print on the chip itself says that this is an 8111C while dmesg says 
> 8111B?

Realtek uses the same PCI device ID for those chips,
and we use the ID to print device names.
Probably we could use device revision to distingush variants,
but there is no info about it.

> Would the 8111C use the same rtl8169 driver?

Well, we need chip's manual to answer it.
In the sane design, the chip should have a differnt ID
if it requires a completely different driver.
(though minor quirks could be handled in the same driver)

Anyway, could you try the attached (untested) patch?
rgephy part is taken from FreeBSD, and some of values
are taken from RealTek's driver. Other changes (eeprom etc.)
are by my random guess.
---
Izumi Tsutsui



Index: dev/ic/rtl8169.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl8169.c,v
retrieving revision 1.96
diff -u -r1.96 rtl8169.c
--- dev/ic/rtl8169.c    7 Feb 2008 01:21:54 -0000       1.96
+++ dev/ic/rtl8169.c    13 Mar 2008 14:48:33 -0000
@@ -590,7 +590,9 @@
                /* Revision of 8169/8169S/8110s in bits 30..26, 23 */
                hwrev = CSR_READ_4(sc, RTK_TXCFG) & RTK_TXCFG_HWREV;
                /* These rev numbers are taken from Realtek's driver */
-               if (       hwrev == RTK_HWREV_8100E_SPIN2) {
+               if (       hwrev == RTK_HWREV_8168C) {
+                       sc->sc_rev = 16;
+               } else if (hwrev == RTK_HWREV_8100E_SPIN2) {
                        sc->sc_rev = 15;
                } else if (hwrev == RTK_HWREV_8100E) {
                        sc->sc_rev = 14;
@@ -1748,6 +1750,13 @@
 
        DELAY(10000);
 
+       if (sc->sc_rev == 16) {
+               /* magic values for 8168C from Realtek driver */
+               CSR_WRITE_4(sc, RTK_CSIDR, 0x27000000);
+               CSR_WRITE_4(sc, RTK_CSIAR, 0x800087C0);
+
+               CSR_WRITE_1(sc, 0xD1, 0x38);
+       }
        /*
         * Init our MAC address.  Even though the chipset
         * documentation doesn't mention it, we need to enter "Config
@@ -1865,13 +1874,20 @@
                 * For 8169 gigE NICs, set the max allowed RX packet
                 * size so we can receive jumbo frames.
                 */
-               CSR_WRITE_2(sc, RTK_MAXRXPKTLEN, 16383);
+               if (sc->sc_rev != 16)
+                       CSR_WRITE_2(sc, RTK_MAXRXPKTLEN, 16383);
+               else
+                       CSR_WRITE_2(sc, RTK_MAXRXPKTLEN, 0x05EF);
        }
 
        if (sc->re_testmode)
                return 0;
 
-       CSR_WRITE_1(sc, RTK_CFG1, RTK_CFG1_DRVLOAD);
+       if (sc->sc_rev != 16)
+               CSR_WRITE_1(sc, RTK_CFG1, RTK_CFG1_DRVLOAD);
+       else
+               /* from Realtek driver for 8168C */
+               CSR_WRITE_1(sc, RTK_CFG1, 0);
 
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
Index: dev/ic/rtl81x9.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl81x9.c,v
retrieving revision 1.81
diff -u -r1.81 rtl81x9.c
--- dev/ic/rtl81x9.c    19 Jan 2008 22:10:17 -0000      1.81
+++ dev/ic/rtl81x9.c    13 Mar 2008 14:48:33 -0000
@@ -165,7 +165,7 @@
        CSR_WRITE_1(sc, RTK_EECMD,                      \
                CSR_READ_1(sc, RTK_EECMD) & ~(x))
 
-#define EE_DELAY()     DELAY(100)
+#define EE_DELAY()     DELAY(150)
 
 #define ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN)
 
@@ -209,6 +209,7 @@
        CSR_WRITE_1(sc, RTK_EECMD, RTK_EEMODE_PROGRAM);
        EE_DELAY();
        EE_SET(RTK_EE_SEL);
+       EE_DELAY();
 
        /*
         * Send address of word we want to read.
Index: dev/ic/rtl81x9reg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl81x9reg.h,v
retrieving revision 1.29
diff -u -r1.29 rtl81x9reg.h
--- dev/ic/rtl81x9reg.h 6 Feb 2008 22:51:02 -0000       1.29
+++ dev/ic/rtl81x9reg.h 13 Mar 2008 14:48:34 -0000
@@ -88,6 +88,9 @@
                                        /* 005F reserved */
 #define RTK_TXSTAT_ALL 0x0060          /* TX status of all descriptors */
 
+#define RTK_CSIDR      0x0064          
+#define RTK_CSIAR      0x0068          
+
 /* Direct PHY access registers only available on 8139 */
 #define RTK_BMCR       0x0062          /* PHY basic mode control */
 #define RTK_BMSR       0x0064          /* PHY basic mode status */
@@ -161,6 +164,7 @@
 #define RTK_HWREV_8168_SPIN2   0x38000000
 #define RTK_HWREV_8168_SPIN3   0x38400000
 #define RTK_HWREV_8100E_SPIN2  0x38800000
+#define RTK_HWREV_8168C                0x3C000000
 #define RTK_HWREV_8139         0x60000000
 #define RTK_HWREV_8139A                0x70000000
 #define RTK_HWREV_8139AG       0x70800000
Index: dev/mii/rgephy.c
===================================================================
RCS file: /cvsroot/src/sys/dev/mii/rgephy.c,v
retrieving revision 1.18
diff -u -r1.18 rgephy.c
--- dev/mii/rgephy.c    26 Jan 2008 14:24:14 -0000      1.18
+++ dev/mii/rgephy.c    13 Mar 2008 14:48:36 -0000
@@ -118,7 +118,6 @@
        sc->mii_phy = ma->mii_phyno;
        sc->mii_pdata = mii;
        sc->mii_flags = mii->mii_flags;
-       sc->mii_anegticks = MII_ANEGTICKS;
 
        sc->mii_funcs = &rgephy_funcs;
 
@@ -288,9 +287,19 @@
                 * need to restart the autonegotiation process.  Read
                 * the BMSR twice in case it's latched.
                 */
-               reg = PHY_READ(sc, RTK_GMEDIASTAT);
-               if ((reg & RTK_GMEDIASTAT_LINK) != 0)
-                       break;
+               if (sc->mii_mpd_model >= 2) {
+                       /* RTL8211B(L) */
+                       reg = PHY_READ(sc, RGEPHY_MII_SSR);
+                       if (reg & RGEPHY_SSR_LINK) {
+                               sc->mii_ticks = 0;
+                               break;
+               } else {
+                       reg = PHY_READ(sc, RTK_GMEDIASTAT);
+                       if ((reg & RTK_GMEDIASTAT_LINK) != 0)
+                               sc->mii_ticks = 0;
+                               break;
+                       }
+               }
 
                /*
                 * Only retry autonegotiation every 5 seconds.
@@ -326,14 +335,23 @@
 rgephy_status(struct mii_softc *sc)
 {
        struct mii_data *mii = sc->mii_pdata;
-       int bmsr, bmcr;
+       int gstat, bmsr, bmcr;
+       uint16_t ssr;
 
        mii->mii_media_status = IFM_AVALID;
        mii->mii_media_active = IFM_ETHER;
 
-       if ((PHY_READ(sc, RTK_GMEDIASTAT) & RTK_GMEDIASTAT_LINK) != 0)
-               mii->mii_media_status |= IFM_ACTIVE;
+       if (sc->mii_mpd_model>= 2) {
+               ssr = PHY_READ(sc, RGEPHY_MII_SSR);
+               if (ssr & RGEPHY_SSR_LINK)
+                       mii->mii_media_status |= IFM_ACTIVE;
+       } else {
+               gstat = PHY_READ(sc, RTK_GMEDIASTAT);
+               if ((gstat & RTK_GMEDIASTAT_LINK) != 0)
+                       mii->mii_media_status |= IFM_ACTIVE;
+       }
 
+       (void)PHY_READ(sc, RGEPHY_MII_BMSR);
        bmsr = PHY_READ(sc, RGEPHY_MII_BMSR);
        bmcr = PHY_READ(sc, RGEPHY_MII_BMCR);
 
@@ -354,17 +372,39 @@
                }
        }
 
-       bmsr = PHY_READ(sc, RTK_GMEDIASTAT);
-       if ((bmsr & RTK_GMEDIASTAT_1000MBPS) != 0)
-               mii->mii_media_active |= IFM_1000_T;
-       else if ((bmsr & RTK_GMEDIASTAT_100MBPS) != 0)
-               mii->mii_media_active |= IFM_100_TX;
-       else if ((bmsr & RTK_GMEDIASTAT_10MBPS) != 0)
-               mii->mii_media_active |= IFM_10_T;
-       else
-               mii->mii_media_active |= IFM_NONE;
-       if ((bmsr & RTK_GMEDIASTAT_FDX) != 0)
-               mii->mii_media_active |= IFM_FDX;
+       if (sc->mii_mpd_model >= 2) {
+               ssr = PHY_READ(sc, RGEPHY_MII_SSR);
+               switch (ssr & RGEPHY_SSR_SPD_MASK) {
+               case RGEPHY_SSR_S1000:
+                       mii->mii_media_active |= IFM_1000_T;
+                       break;
+               case RGEPHY_SSR_S100:
+                       mii->mii_media_active |= IFM_100_TX;
+                       break;
+               case RGEPHY_SSR_S10:
+                       mii->mii_media_active |= IFM_10_T;
+                       break;
+               default:
+                       mii->mii_media_active |= IFM_NONE;
+                       break;
+               }
+               if (ssr & RGEPHY_SSR_FDX)
+                       mii->mii_media_active |= IFM_FDX;
+               else
+                       mii->mii_media_active |= IFM_HDX;
+       } else {
+               gstat = PHY_READ(sc, RTK_GMEDIASTAT);
+               if ((gstat & RTK_GMEDIASTAT_1000MBPS) != 0)
+                       mii->mii_media_active |= IFM_1000_T;
+               else if ((gstat & RTK_GMEDIASTAT_100MBPS) != 0)
+                       mii->mii_media_active |= IFM_100_TX;
+               else if ((gstat & RTK_GMEDIASTAT_10MBPS) != 0)
+                       mii->mii_media_active |= IFM_10_T;
+               else
+                       mii->mii_media_active |= IFM_NONE;
+               if ((gstat & RTK_GMEDIASTAT_FDX) != 0)
+                       mii->mii_media_active |= IFM_FDX;
+       }
 }
 
 
@@ -394,8 +434,10 @@
        uint32_t bmsr;
        int i;
 
-       PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN);
-       DELAY(1000);
+       if (sc->mii_mpd_model < 2) {
+               PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN);
+               DELAY(1000);
+       }
 
        for (i = 0; i < 15000; i++) {
                bmsr = PHY_READ(sc, RGEPHY_MII_BMSR);
Index: dev/mii/rgephyreg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/mii/rgephyreg.h,v
retrieving revision 1.2
diff -u -r1.2 rgephyreg.h
--- dev/mii/rgephyreg.h 29 Nov 2006 14:01:53 -0000      1.2
+++ dev/mii/rgephyreg.h 13 Mar 2008 14:48:36 -0000
@@ -137,6 +137,17 @@
 #define RGEPHY_EXTSTS_T_FD_CAP 0x2000  /* 1000base-T FD capable */
 #define RGEPHY_EXTSTS_T_HD_CAP 0x1000  /* 1000base-T HD capable */
 
-
+/* RTL8211B(L) */
+#define RGEPHY_MII_SSR         0x11    /* PHY Specific status register */
+#define        RGEPHY_SSR_S1000        0x8000  /* 1000Mbps */
+#define        RGEPHY_SSR_S100         0x4000  /* 100Mbps */
+#define        RGEPHY_SSR_S10          0x0000  /* 10Mbps */
+#define        RGEPHY_SSR_SPD_MASK     0xc000
+#define        RGEPHY_SSR_FDX          0x2000  /* full duplex */
+#define        RGEPHY_SSR_PAGE_RECEIVED        0x1000  /* new page received */
+#define        RGEPHY_SSR_SPD_DPLX_RESOLVED    0x0800  /* speed/duplex 
resolved */
+#define        RGEPHY_SSR_LINK         0x0400  /* link up */
+#define        RGEPHY_SSR_MDI_XOVER    0x0040  /* MDI crossover */
+#define        RGEPHY_SSR_JABBER       0x0001  /* Jabber */
 
 #endif /* _DEV_MII_RGEPHYREG_H_ */


Home | Main Index | Thread Index | Old Index