Source-Changes-HG archive

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

[src/trunk]: src/sys/dev - Call wm_kmrn_lock_loss_workaround_ich8lan() before...



details:   https://anonhg.NetBSD.org/src/rev/86b1ae21976b
branches:  trunk
changeset: 825406:86b1ae21976b
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Thu Jul 13 08:22:20 2017 +0000

description:
- Call wm_kmrn_lock_loss_workaround_ich8lan() before any PHY access in
  wm_linkintr_gmii().
- Register access in wm_kmrn_lock_loss_workaround_ich8lan() now works
  correctly. Enable this function.
- Configure the LCD with the extended configuration region in NVM if it's
  required.
- Add debug printf.

diffstat:

 sys/dev/mii/inbmphyreg.h |    4 +-
 sys/dev/pci/if_wm.c      |  138 ++++++++++++++++++++++++++++++++++++++++------
 sys/dev/pci/if_wmreg.h   |   16 +++-
 3 files changed, 132 insertions(+), 26 deletions(-)

diffs (283 lines):

diff -r 9c8af8a2df75 -r 86b1ae21976b sys/dev/mii/inbmphyreg.h
--- a/sys/dev/mii/inbmphyreg.h  Thu Jul 13 08:04:56 2017 +0000
+++ b/sys/dev/mii/inbmphyreg.h  Thu Jul 13 08:22:20 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: inbmphyreg.h,v 1.9 2016/11/16 08:56:17 msaitoh Exp $   */
+/*     $NetBSD: inbmphyreg.h,v 1.10 2017/07/13 08:22:20 msaitoh Exp $  */
 /*******************************************************************************
 Copyright (c) 2001-2005, Intel Corporation 
 All rights reserved.
@@ -91,6 +91,8 @@
 #define HV_OEM_BITS_A1KDIS     (1 << 6)
 #define HV_OEM_BITS_ANEGNOW    (1 << 10)
 
+#define HV_LED_CONFIG          BME1000_REG(0, 30)
+
 #define        HV_KMRN_MODE_CTRL       BME1000_REG(BM_PORT_CTRL_PAGE, 16)
 #define        HV_KMRN_MDIO_SLOW       0x0400
 
diff -r 9c8af8a2df75 -r 86b1ae21976b sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Thu Jul 13 08:04:56 2017 +0000
+++ b/sys/dev/pci/if_wm.c       Thu Jul 13 08:22:20 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wm.c,v 1.522 2017/07/13 08:04:56 msaitoh Exp $      */
+/*     $NetBSD: if_wm.c,v 1.523 2017/07/13 08:22:21 msaitoh Exp $      */
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -83,7 +83,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.522 2017/07/13 08:04:56 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.523 2017/07/13 08:22:21 msaitoh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -679,6 +679,7 @@
 static void    wm_lan_init_done(struct wm_softc *);
 static void    wm_get_cfg_done(struct wm_softc *);
 static void    wm_phy_post_reset(struct wm_softc *);
+static void    wm_init_lcd_from_nvm(struct wm_softc *);
 static void    wm_initialize_hardware_bits(struct wm_softc *);
 static uint32_t        wm_rxpbs_adjust_82580(uint32_t);
 static void    wm_reset_phy(struct wm_softc *);
@@ -3692,14 +3693,102 @@
                    BM_PORT_GEN_CFG, reg);
        }
 
-       /*
-        * XXX Configure the LCD with th extended configuration region
-        * in NVM
-        */
+       /* Configure the LCD with the extended configuration region in NVM */
+       wm_init_lcd_from_nvm(sc);
 
        /* Configure the LCD with the OEM bits in NVM */
 }
 
+void
+wm_init_lcd_from_nvm(struct wm_softc *sc)
+{
+       uint32_t extcnfctr, sw_cfg_mask, cnf_size, word_addr, i, reg;
+       uint16_t phy_page = 0;
+
+       switch (sc->sc_type) {
+       case WM_T_ICH8:
+               if (sc->sc_phytype != WMPHY_IGP_3)
+                       return;
+
+               if ((sc->sc_pcidevid == PCI_PRODUCT_INTEL_82801H_AMT)
+                   || (sc->sc_pcidevid == PCI_PRODUCT_INTEL_82801H_LAN)) {
+                       sw_cfg_mask = FEXTNVM_SW_CONFIG;
+                       break;
+               }
+               /* FALLTHROUGH */
+       case WM_T_PCH:
+       case WM_T_PCH2:
+       case WM_T_PCH_LPT:
+       case WM_T_PCH_SPT:
+               sw_cfg_mask = FEXTNVM_SW_CONFIG_ICH8M;
+               break;
+       default:
+               return;
+       }
+
+       sc->phy.acquire(sc);
+
+       reg = CSR_READ(sc, WMREG_FEXTNVM);
+       if ((reg & sw_cfg_mask) == 0)
+               goto release;
+
+       /*
+        * Make sure HW does not configure LCD from PHY extended configuration
+        * before SW configuration
+        */
+       extcnfctr = CSR_READ(sc, WMREG_EXTCNFCTR);
+       if ((sc->sc_type < WM_T_PCH2)
+           && ((extcnfctr & EXTCNFCTR_PCIE_WRITE_ENABLE) != 0))
+               goto release;
+
+       /* word_addr is in DWORD */
+       word_addr = __SHIFTOUT(extcnfctr, EXTCNFCTR_EXT_CNF_POINTER) << 1;
+       
+       reg = CSR_READ(sc, WMREG_EXTCNFSIZE);
+       cnf_size = __SHIFTOUT(reg, EXTCNFSIZE_LENGTH);
+
+       if (((sc->sc_type == WM_T_PCH)
+               && ((extcnfctr & EXTCNFCTR_OEM_WRITE_ENABLE) == 0))
+           || (sc->sc_type > WM_T_PCH)) {
+               /*
+                * HW configures the SMBus address and LEDs when the OEM and
+                * LCD Write Enable bits are set in the NVM. When both NVM bits
+                * are cleared, SW will configure them instead.
+                */
+               device_printf(sc->sc_dev, "%s: need write_smbus()\n",
+                   __func__);
+
+               reg = CSR_READ(sc, WMREG_LEDCTL);
+               wm_gmii_hv_writereg_locked(sc->sc_dev, 1, HV_LED_CONFIG, reg);
+       }
+
+       /* Configure LCD from extended configuration region. */
+       for (i = 0; i < cnf_size; i++) {
+               uint16_t reg_data, reg_addr;
+
+               if (wm_nvm_read(sc, (word_addr + i * 2), 1, &reg_data) != 0)
+                       goto release;
+
+               if (wm_nvm_read(sc, (word_addr + i * 2 + 1), 1, &reg_addr) !=0)
+                       goto release;
+
+               if (reg_addr == MII_IGPHY_PAGE_SELECT)
+                       phy_page = reg_data;
+
+               reg_addr &= IGPHY_MAXREGADDR;
+               reg_addr |= phy_page;
+
+               sc->phy.release(sc); /* XXX */
+               sc->sc_mii.mii_writereg(sc->sc_dev, 1, reg_addr, reg_data);
+               sc->phy.acquire(sc); /* XXX */
+       }
+
+release:       
+       sc->phy.release(sc);
+       return;
+}
+    
+
 /* Init hardware bits */
 void
 wm_initialize_hardware_bits(struct wm_softc *sc)
@@ -8286,9 +8375,21 @@
                uint32_t reg;
                uint32_t status = CSR_READ(sc, WMREG_STATUS);
 
+               if ((status & STATUS_LU) != 0) {
+                       DPRINTF(WM_DEBUG_LINK, ("%s: LINK: LSC -> up %s\n",
+                               device_xname(sc->sc_dev),
+                               (status & STATUS_FD) ? "FDX" : "HDX"));
+               } else {
+                       DPRINTF(WM_DEBUG_LINK, ("%s: LINK: LSC -> down\n",
+                               device_xname(sc->sc_dev)));
+               }
                if ((sc->sc_type == WM_T_ICH8) && ((status & STATUS_LU) == 0))
                        wm_gig_downshift_workaround_ich8lan(sc);
 
+               if ((sc->sc_type == WM_T_ICH8)
+                   && (sc->sc_phytype == WMPHY_IGP_3)) {
+                       wm_kmrn_lock_loss_workaround_ich8lan(sc);
+               }
                DPRINTF(WM_DEBUG_LINK, ("%s: LINK: LSC -> mii_pollstat\n",
                        device_xname(sc->sc_dev)));
                mii_pollstat(&sc->sc_mii);
@@ -8327,9 +8428,6 @@
                                        sc->sc_ctrl |= CTRL_FD;
                                CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
                        }
-               } else if ((sc->sc_type == WM_T_ICH8)
-                   && (sc->sc_phytype == WMPHY_IGP_3)) {
-                       wm_kmrn_lock_loss_workaround_ich8lan(sc);
                } else if (sc->sc_type == WM_T_PCH) {
                        wm_k1_gig_workaround_hv(sc,
                            ((sc->sc_mii.mii_media_status & IFM_ACTIVE) != 0));
@@ -13512,31 +13610,32 @@
 static void
 wm_kmrn_lock_loss_workaround_ich8lan(struct wm_softc *sc)
 {
-#if 0
-       int miistatus, active, i;
+       struct mii_data *mii = &sc->sc_mii;
+       uint32_t status = CSR_READ(sc, WMREG_STATUS);
+       int i;
        int reg;
 
-       miistatus = sc->sc_mii.mii_media_status;
+       DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+               device_xname(sc->sc_dev), __func__));
 
        /* If the link is not up, do nothing */
-       if ((miistatus & IFM_ACTIVE) == 0)
+       if ((status & STATUS_LU) == 0)
                return;
 
-       active = sc->sc_mii.mii_media_active;
-
        /* Nothing to do if the link is other than 1Gbps */
-       if (IFM_SUBTYPE(active) != IFM_1000_T)
+       if (__SHIFTOUT(status, STATUS_SPEED) != STATUS_SPEED_1000)
                return;
 
+       reg = CSR_READ(sc, WMREG_PHY_CTRL);
        for (i = 0; i < 10; i++) {
                /* read twice */
-               reg = wm_gmii_i80003_readreg(sc->sc_dev, 1, IGP3_KMRN_DIAG);
-               reg = wm_gmii_i80003_readreg(sc->sc_dev, 1, IGP3_KMRN_DIAG);
+               reg = mii->mii_readreg(sc->sc_dev, 1, IGP3_KMRN_DIAG);
+               reg = mii->mii_readreg(sc->sc_dev, 1, IGP3_KMRN_DIAG);
                if ((reg & IGP3_KMRN_DIAG_PCS_LOCK_LOSS) == 0)
                        goto out;       /* GOOD! */
 
                /* Reset the PHY */
-               wm_gmii_reset(sc);
+               wm_reset_phy(sc);
                delay(5*1000);
        }
 
@@ -13553,7 +13652,6 @@
 
 out:
        return;
-#endif
 }
 
 /* WOL from S5 stops working */
diff -r 9c8af8a2df75 -r 86b1ae21976b sys/dev/pci/if_wmreg.h
--- a/sys/dev/pci/if_wmreg.h    Thu Jul 13 08:04:56 2017 +0000
+++ b/sys/dev/pci/if_wmreg.h    Thu Jul 13 08:22:20 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wmreg.h,v 1.101 2017/07/12 08:15:31 msaitoh Exp $   */
+/*     $NetBSD: if_wmreg.h,v 1.102 2017/07/13 08:22:21 msaitoh Exp $   */
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -589,6 +589,10 @@
 #define        WMREG_FCAL      0x0028  /* Flow Control Address Low */
 #define        FCAL_CONST      0x00c28001      /* Flow Control MAC addr low */
 
+#define        WMREG_FEXTNVM   0x0028  /* Future Extended NVM register */
+#define        FEXTNVM_SW_CONFIG       __BIT(1)
+#define        FEXTNVM_SW_CONFIG_ICH8M __BIT(27)
+
 #define        WMREG_FCAH      0x002c  /* Flow Control Address High */
 #define        FCAH_CONST      0x00000100      /* Flow Control MAC addr high */
 
@@ -940,6 +944,8 @@
 #define        WMREG_AIT       0x0458  /* Adaptive IFS Throttle */
 #define        WMREG_VFTA      0x0600
 
+#define        WMREG_LEDCTL    0x0e00  /* LED Control - RW */
+
 #define        WMREG_MDICNFG   0x0e04  /* MDC/MDIO Configuration Register */
 #define MDICNFG_PHY_SHIFT      21
 #define MDICNFG_PHY_MASK       __BITS(25, 21)
@@ -972,15 +978,15 @@
 
 #define WMREG_EXTCNFCTR        0x0f00  /* Extended Configuration Control */
 #define EXTCNFCTR_PCIE_WRITE_ENABLE    0x00000001
-#define EXTCNFCTR_PHY_WRITE_ENABLE     0x00000002
-#define EXTCNFCTR_D_UD_ENABLE          0x00000004
-#define EXTCNFCTR_D_UD_LATENCY         0x00000008
-#define EXTCNFCTR_D_UD_OWNER           0x00000010
+#define EXTCNFCTR_OEM_WRITE_ENABLE     0x00000008
 #define EXTCNFCTR_MDIO_SW_OWNERSHIP    0x00000020
 #define EXTCNFCTR_MDIO_HW_OWNERSHIP    0x00000040
 #define EXTCNFCTR_GATE_PHY_CFG         0x00000080
 #define EXTCNFCTR_EXT_CNF_POINTER      0x0FFF0000
 
+#define WMREG_EXTCNFSIZE 0x0f08  /* Extended Configuration Size */
+#define EXTCNFSIZE_LENGTH      __BITS(23, 16)
+
 #define        WMREG_PHY_CTRL  0x0f10  /* PHY control */
 #define        PHY_CTRL_SPD_EN         (1 << 0)
 #define        PHY_CTRL_D0A_LPLU       (1 << 1)



Home | Main Index | Thread Index | Old Index