Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci - Change to use 2500Base-KX correctly on C2000(I...



details:   https://anonhg.NetBSD.org/src/rev/1745c490e11c
branches:  trunk
changeset: 349516:1745c490e11c
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Tue Dec 13 10:01:44 2016 +0000

description:
- Change to use 2500Base-KX correctly on C2000(I354). It worked, but the
output of ifconfig and if_baudrate was not good. Tested by nils@:
  - The STATUS_TBIMODE bit in the STATUS register is deleted since 82575,
    so check for 82575 and newer first and then check for old devices.
  - Check the 2P5_SKU and 2P5_SKU_OVER bit for KX.
  - Set IFM_2500_SX instead of IFM_1000_SX for 2.5G.
- Check SERDES's speed directly from the PCS layer (PCS_LSTS register) for old
  devices.
- Style fix.

diffstat:

 sys/dev/pci/if_wm.c    |  206 +++++++++++++++++++++++++++---------------------
 sys/dev/pci/if_wmreg.h |   10 +-
 2 files changed, 122 insertions(+), 94 deletions(-)

diffs (295 lines):

diff -r 1066c9d25165 -r 1745c490e11c sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Tue Dec 13 09:51:34 2016 +0000
+++ b/sys/dev/pci/if_wm.c       Tue Dec 13 10:01:44 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wm.c,v 1.456 2016/12/08 01:12:01 ozaki-r Exp $      */
+/*     $NetBSD: if_wm.c,v 1.457 2016/12/13 10:01:44 msaitoh Exp $      */
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -84,7 +84,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.456 2016/12/08 01:12:01 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.457 2016/12/13 10:01:44 msaitoh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -2411,6 +2411,76 @@
            || sc->sc_type == WM_T_82574 || sc->sc_type == WM_T_82583) {
                /* STATUS_TBIMODE reserved/reused, can't rely on it */
                wm_gmii_mediainit(sc, wmp->wmp_product);
+       } else if ((sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576)
+           || (sc->sc_type ==WM_T_82580) || (sc->sc_type ==WM_T_I350)
+           || (sc->sc_type ==WM_T_I354) || (sc->sc_type ==WM_T_I210)
+           || (sc->sc_type ==WM_T_I211)) {
+               reg = CSR_READ(sc, WMREG_CTRL_EXT);
+               link_mode = reg & CTRL_EXT_LINK_MODE_MASK;
+               switch (link_mode) {
+               case CTRL_EXT_LINK_MODE_1000KX:
+                       aprint_verbose_dev(sc->sc_dev, "1000KX\n");
+                       sc->sc_mediatype = WM_MEDIATYPE_SERDES;
+                       break;
+               case CTRL_EXT_LINK_MODE_SGMII:
+                       if (wm_sgmii_uses_mdio(sc)) {
+                               aprint_verbose_dev(sc->sc_dev,
+                                   "SGMII(MDIO)\n");
+                               sc->sc_flags |= WM_F_SGMII;
+                               sc->sc_mediatype = WM_MEDIATYPE_COPPER;
+                               break;
+                       }
+                       aprint_verbose_dev(sc->sc_dev, "SGMII(I2C)\n");
+                       /*FALLTHROUGH*/
+               case CTRL_EXT_LINK_MODE_PCIE_SERDES:
+                       sc->sc_mediatype = wm_sfp_get_media_type(sc);
+                       if (sc->sc_mediatype == WM_MEDIATYPE_UNKNOWN) {
+                               if (link_mode
+                                   == CTRL_EXT_LINK_MODE_SGMII) {
+                                       sc->sc_mediatype = WM_MEDIATYPE_COPPER;
+                                       sc->sc_flags |= WM_F_SGMII;
+                               } else {
+                                       sc->sc_mediatype = WM_MEDIATYPE_SERDES;
+                                       aprint_verbose_dev(sc->sc_dev,
+                                           "SERDES\n");
+                               }
+                               break;
+                       }
+                       if (sc->sc_mediatype == WM_MEDIATYPE_SERDES)
+                               aprint_verbose_dev(sc->sc_dev, "SERDES\n");
+
+                       /* Change current link mode setting */
+                       reg &= ~CTRL_EXT_LINK_MODE_MASK;
+                       switch (sc->sc_mediatype) {
+                       case WM_MEDIATYPE_COPPER:
+                               reg |= CTRL_EXT_LINK_MODE_SGMII;
+                               break;
+                       case WM_MEDIATYPE_SERDES:
+                               reg |= CTRL_EXT_LINK_MODE_PCIE_SERDES;
+                               break;
+                       default:
+                               break;
+                       }
+                       CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
+                       break;
+               case CTRL_EXT_LINK_MODE_GMII:
+               default:
+                       aprint_verbose_dev(sc->sc_dev, "Copper\n");
+                       sc->sc_mediatype = WM_MEDIATYPE_COPPER;
+                       break;
+               }
+
+               reg &= ~CTRL_EXT_I2C_ENA;
+               if ((sc->sc_flags & WM_F_SGMII) != 0)
+                       reg |= CTRL_EXT_I2C_ENA;
+               else
+                       reg &= ~CTRL_EXT_I2C_ENA;
+               CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
+
+               if (sc->sc_mediatype == WM_MEDIATYPE_COPPER)
+                       wm_gmii_mediainit(sc, wmp->wmp_product);
+               else
+                       wm_tbi_mediainit(sc);
        } else if (sc->sc_type < WM_T_82543 ||
            (CSR_READ(sc, WMREG_STATUS) & STATUS_TBIMODE) != 0) {
                if (sc->sc_mediatype == WM_MEDIATYPE_COPPER) {
@@ -2420,91 +2490,12 @@
                }
                wm_tbi_mediainit(sc);
        } else {
-               switch (sc->sc_type) {
-               case WM_T_82575:
-               case WM_T_82576:
-               case WM_T_82580:
-               case WM_T_I350:
-               case WM_T_I354:
-               case WM_T_I210:
-               case WM_T_I211:
-                       reg = CSR_READ(sc, WMREG_CTRL_EXT);
-                       link_mode = reg & CTRL_EXT_LINK_MODE_MASK;
-                       switch (link_mode) {
-                       case CTRL_EXT_LINK_MODE_1000KX:
-                               aprint_verbose_dev(sc->sc_dev, "1000KX\n");
-                               sc->sc_mediatype = WM_MEDIATYPE_SERDES;
-                               break;
-                       case CTRL_EXT_LINK_MODE_SGMII:
-                               if (wm_sgmii_uses_mdio(sc)) {
-                                       aprint_verbose_dev(sc->sc_dev,
-                                           "SGMII(MDIO)\n");
-                                       sc->sc_flags |= WM_F_SGMII;
-                                       sc->sc_mediatype = WM_MEDIATYPE_COPPER;
-                                       break;
-                               }
-                               aprint_verbose_dev(sc->sc_dev, "SGMII(I2C)\n");
-                               /*FALLTHROUGH*/
-                       case CTRL_EXT_LINK_MODE_PCIE_SERDES:
-                               sc->sc_mediatype = wm_sfp_get_media_type(sc);
-                               if (sc->sc_mediatype == WM_MEDIATYPE_UNKNOWN) {
-                                       if (link_mode
-                                           == CTRL_EXT_LINK_MODE_SGMII) {
-                                               sc->sc_mediatype
-                                                   = WM_MEDIATYPE_COPPER;
-                                               sc->sc_flags |= WM_F_SGMII;
-                                       } else {
-                                               sc->sc_mediatype
-                                                   = WM_MEDIATYPE_SERDES;
-                                               aprint_verbose_dev(sc->sc_dev,
-                                                   "SERDES\n");
-                                       }
-                                       break;
-                               }
-                               if (sc->sc_mediatype == WM_MEDIATYPE_SERDES)
-                                       aprint_verbose_dev(sc->sc_dev,
-                                           "SERDES\n");
-
-                               /* Change current link mode setting */
-                               reg &= ~CTRL_EXT_LINK_MODE_MASK;
-                               switch (sc->sc_mediatype) {
-                               case WM_MEDIATYPE_COPPER:
-                                       reg |= CTRL_EXT_LINK_MODE_SGMII;
-                                       break;
-                               case WM_MEDIATYPE_SERDES:
-                                       reg |= CTRL_EXT_LINK_MODE_PCIE_SERDES;
-                                       break;
-                               default:
-                                       break;
-                               }
-                               CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
-                               break;
-                       case CTRL_EXT_LINK_MODE_GMII:
-                       default:
-                               aprint_verbose_dev(sc->sc_dev, "Copper\n");
-                               sc->sc_mediatype = WM_MEDIATYPE_COPPER;
-                               break;
-                       }
-
-                       reg &= ~CTRL_EXT_I2C_ENA;
-                       if ((sc->sc_flags & WM_F_SGMII) != 0)
-                               reg |= CTRL_EXT_I2C_ENA;
-                       else
-                               reg &= ~CTRL_EXT_I2C_ENA;
-                       CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
-
-                       if (sc->sc_mediatype == WM_MEDIATYPE_COPPER)
-                               wm_gmii_mediainit(sc, wmp->wmp_product);
-                       else
-                               wm_tbi_mediainit(sc);
-                       break;
-               default:
-                       if (sc->sc_mediatype == WM_MEDIATYPE_FIBER)
-                               aprint_error_dev(sc->sc_dev,
-                                   "WARNING: TBIMODE clear on 1000BASE-X product!\n");
+               if (sc->sc_mediatype == WM_MEDIATYPE_FIBER) {
+                       aprint_error_dev(sc->sc_dev,
+                           "WARNING: TBIMODE clear on 1000BASE-X product!\n");
                        sc->sc_mediatype = WM_MEDIATYPE_COPPER;
-                       wm_gmii_mediainit(sc, wmp->wmp_product);
-               }
+               }
+               wm_gmii_mediainit(sc, wmp->wmp_product);
        }
 
        ifp = &sc->sc_ethercom.ec_if;
@@ -9677,8 +9668,17 @@
 
        aprint_normal_dev(sc->sc_dev, "");
 
-       /* Only 82545 is LX */
-       if (sc->sc_type == WM_T_82545) {
+       if (sc->sc_type == WM_T_I354) {
+               uint32_t status;
+
+               status = CSR_READ(sc, WMREG_STATUS);
+               if (((status & STATUS_2P5_SKU) != 0)
+                   && ((status & STATUS_2P5_SKU_OVER) == 0)) {
+                       ADD("2500baseKX-FDX", IFM_2500_SX | IFM_FDX,ANAR_X_FD);
+               } else
+                       ADD("1000baseSX-FDX", IFM_1000_SX | IFM_FDX,ANAR_X_FD);
+       } else if (sc->sc_type == WM_T_82545) {
+               /* Only 82545 is LX (XXX except SFP) */
                ADD("1000baseLX", IFM_1000_LX, ANAR_X_HD);
                ADD("1000baseLX-FDX", IFM_1000_LX | IFM_FDX, ANAR_X_FD);
        } else {
@@ -10087,7 +10087,32 @@
 
        sc->sc_tbi_linkup = 1;
        ifmr->ifm_status |= IFM_ACTIVE;
-       ifmr->ifm_active |= IFM_1000_SX; /* XXX */
+       if (sc->sc_type == WM_T_I354) {
+               uint32_t status;
+
+               status = CSR_READ(sc, WMREG_STATUS);
+               if (((status & STATUS_2P5_SKU) != 0)
+                   && ((status & STATUS_2P5_SKU_OVER) == 0)) {
+                       ifmr->ifm_active |= IFM_2500_SX; /* XXX KX */
+               } else
+                       ifmr->ifm_active |= IFM_1000_SX; /* XXX KX */
+       } else {
+               switch (__SHIFTOUT(reg, PCS_LSTS_SPEED)) {
+               case PCS_LSTS_SPEED_10:
+                       ifmr->ifm_active |= IFM_10_T; /* XXX */
+                       break;
+               case PCS_LSTS_SPEED_100:
+                       ifmr->ifm_active |= IFM_100_FX; /* XXX */
+                       break;
+               case PCS_LSTS_SPEED_1000:
+                       ifmr->ifm_active |= IFM_1000_SX; /* XXX */
+                       break;
+               default:
+                       device_printf(sc->sc_dev, "Unknown speed\n");
+                       ifmr->ifm_active |= IFM_1000_SX; /* XXX */
+                       break;
+               }
+       }
        if ((reg & PCS_LSTS_FDX) != 0)
                ifmr->ifm_active |= IFM_FDX;
        else
@@ -10120,7 +10145,6 @@
                    && (pcs_lpab & TXCW_ASYM_PAUSE)) {
                        mii->mii_media_active |= IFM_FLOW
                            | IFM_ETH_RXPAUSE;
-               } else {
                }
        }
        ifmr->ifm_active = (ifmr->ifm_active & ~IFM_ETH_FMASK)
@@ -10161,7 +10185,7 @@
        } else {
                mii->mii_media_status |= IFM_NONE;
                sc->sc_tbi_linkup = 0;
-                   /* If the timer expired, retry autonegotiation */
+               /* If the timer expired, retry autonegotiation */
                if ((IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO)
                    && (++sc->sc_tbi_serdes_ticks
                        >= sc->sc_tbi_serdes_anegticks)) {
diff -r 1066c9d25165 -r 1745c490e11c sys/dev/pci/if_wmreg.h
--- a/sys/dev/pci/if_wmreg.h    Tue Dec 13 09:51:34 2016 +0000
+++ b/sys/dev/pci/if_wmreg.h    Tue Dec 13 10:01:44 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wmreg.h,v 1.93 2016/11/16 08:56:17 msaitoh Exp $    */
+/*     $NetBSD: if_wmreg.h,v 1.94 2016/12/13 10:01:44 msaitoh Exp $    */
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -267,7 +267,9 @@
 #define        STATUS_PHYRA    (1U << 10)      /* PHY Reset Asserted (PCH) */
 #define        STATUS_PCI66    (1U << 11)      /* 66MHz bus (Livengood) */
 #define        STATUS_BUS64    (1U << 12)      /* 64-bit bus (Livengood) */
+#define        STATUS_2P5_SKU  __BIT(12)       /* Value of the 2.5GBE SKU strap */
 #define        STATUS_PCIX_MODE (1U << 13)     /* PCIX mode (Cordova) */
+#define        STATUS_2P5_SKU_OVER __BIT(13)   /* Value of the 2.5GBE SKU override */
 #define        STATUS_PCIXSPD(x) ((x) << 14)   /* PCIX speed indication (Cordova) */
 #define        STATUS_PCIXSPD_50_66   STATUS_PCIXSPD(0)
 #define        STATUS_PCIXSPD_66_100  STATUS_PCIXSPD(1)
@@ -915,8 +917,10 @@
 
 #define        WMREG_PCS_LSTS  0x420c  /* PCS Link Status */
 #define PCS_LSTS_LINKOK        __BIT(0)
-#define PCS_LSTS_SPEED_100  __BIT(1)
-#define PCS_LSTS_SPEED_1000 __BIT(2)
+#define PCS_LSTS_SPEED __BITS(2, 1)
+#define PCS_LSTS_SPEED_10      0
+#define PCS_LSTS_SPEED_100     1
+#define PCS_LSTS_SPEED_1000    2
 #define PCS_LSTS_FDX   __BIT(3)
 #define PCS_LSTS_AN_COMP __BIT(16)
 



Home | Main Index | Thread Index | Old Index