Source-Changes-HG archive

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

[src/netbsd-8]: src/sys/dev Pull up following revision(s) (requested by msait...



details:   https://anonhg.NetBSD.org/src/rev/e50a21625af5
branches:  netbsd-8
changeset: 446403:e50a21625af5
user:      martin <martin%NetBSD.org@localhost>
date:      Tue Dec 04 11:21:32 2018 +0000

description:
Pull up following revision(s) (requested by msaitoh in ticket #1117):

        sys/dev/pci/if_wmreg.h: revision 1.109
        sys/dev/pci/if_wm.c: revision 1.597
        sys/dev/pci/if_wm.c: revision 1.598
        sys/dev/mii/inbmphyreg.h: revision 1.12
        sys/dev/pci/if_wm.c: revision 1.600
        sys/dev/pci/if_wm.c: revision 1.601
        sys/dev/pci/if_wm.c: revision 1.602

- Add new wm_gmii_{hv,i82544}_{read,write}reg_locked() and use them in
   wm_gmii_{hv,i82544}_{read,write}reg(). *_locked() functions are not
   mii(4) API functions, so it's not required to keep the mii API. Change
   the PHY register type from int to uint16_t. It also change the usage of
   return value. It returns zero on success and non-zero on error.
- Check the return value of *_locked() function and treat it.
- Use *writereg_locked() function to reduce race condition in
   wm_init_lcd_from_nvm().
- Add comment.
- Control TX/RX descriptor snooping control bits on ICH8 and newer.
   Only on ICH8, No-snoop bits are opposite polarity. On my Thinkpad X61,
   the default value of this bits are all zero, so this commit changes
   the snoop function enable on the machine. I tested with some other
   PCH machines and those bits are all zero (enable snoop by default),
   so this commit won't affect to some machines.
- Disable relax ordering on 82546GB(Device ID 0x1099 and 0x10b5) or >= ICH8.
   Same as other OSes.
- Add wm_oem_bits_config_ich8lan() to control LPLU and GbE setting base on
   the NVM's info.
- Modify wm_enable_wakeup() to reduce difference against FreeBSD and Linux.
   This modification affects to ICH8 and newer devices. I217 Rapid Start
   Technology support have not written yet (it's TODO).
- Add wm_k1_workaround_lv() from FreeBSD. It's PCH2 specific:
     Workaround to set the K1 beacon duration for 82579 parts in 10Mbps.
     Disable K1 for 1000 and 100 speeds.
- Make wm_link_stall_workaround_hv() and move an 82578 specific code into it.
   Don't apply the workaround if BMCR_LOOP bit is set. Same as FreeBSD.
- Add comment. Modify comment.
  Fix comment. No functional change.

diffstat:

 sys/dev/mii/inbmphyreg.h |   17 +-
 sys/dev/pci/if_wm.c      |  554 +++++++++++++++++++++++++++++++++++++---------
 sys/dev/pci/if_wmreg.h   |    8 +-
 3 files changed, 460 insertions(+), 119 deletions(-)

diffs (truncated from 1028 to 300 lines):

diff -r 977b8768acd9 -r e50a21625af5 sys/dev/mii/inbmphyreg.h
--- a/sys/dev/mii/inbmphyreg.h  Tue Dec 04 11:16:33 2018 +0000
+++ b/sys/dev/mii/inbmphyreg.h  Tue Dec 04 11:21:32 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: inbmphyreg.h,v 1.9.8.2 2018/11/08 12:09:18 martin Exp $        */
+/*     $NetBSD: inbmphyreg.h,v 1.9.8.3 2018/12/04 11:21:32 martin Exp $        */
 /*******************************************************************************
 Copyright (c) 2001-2005, Intel Corporation 
 All rights reserved.
@@ -74,6 +74,13 @@
 #define BME1000_PSCR_DOWNSHIFT_COUNTER_MASK     0x7000
 #define BME1000_PSCR_DOWNSHIFT_COUNTER_SHIFT    12
 
+/* BM PHY Copper Specific Status */
+#define BM_CS_STATUS           BME1000_REG(0, 17)
+#define BM_CS_STATUS_LINK_UP   0x0400
+#define BM_CS_STATUS_RESOLVED  0x0800
+#define BM_CS_STATUS_SPEED_MASK        0xC000
+#define BM_CS_STATUS_SPEED_1000        0x8000
+
 #define BME1000_PHY_PAGE_SELECT        BME1000_REG(0, 22) /* Page Select */
 
 #define BME1000_BIAS_SETTING   29
@@ -91,6 +98,14 @@
 #define HV_OEM_BITS_A1KDIS     (1 << 6)
 #define HV_OEM_BITS_ANEGNOW    (1 << 10)
 
+/* 82577 Mobile Phy Status Register */
+#define HV_M_STATUS            BME1000_REG(0, 26)
+#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000
+#define HV_M_STATUS_SPEED_MASK 0x0300
+#define HV_M_STATUS_SPEED_1000 0x0200
+#define HV_M_STATUS_SPEED_100  0x0100
+#define HV_M_STATUS_LINK_UP    0x0040
+
 #define HV_LED_CONFIG          BME1000_REG(0, 30)
 
 #define        HV_KMRN_MODE_CTRL       BME1000_REG(BM_PORT_CTRL_PAGE, 16)
diff -r 977b8768acd9 -r e50a21625af5 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Tue Dec 04 11:16:33 2018 +0000
+++ b/sys/dev/pci/if_wm.c       Tue Dec 04 11:21:32 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wm.c,v 1.508.4.26 2018/11/26 17:24:51 snj Exp $     */
+/*     $NetBSD: if_wm.c,v 1.508.4.27 2018/12/04 11:21:32 martin 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.508.4.26 2018/11/26 17:24:51 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.508.4.27 2018/12/04 11:21:32 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -463,6 +463,8 @@
 struct wm_phyop {
        int (*acquire)(struct wm_softc *);
        void (*release)(struct wm_softc *);
+       int (*readreg_locked)(device_t, int, int, uint16_t *);
+       int (*writereg_locked)(device_t, int, int, uint16_t);
        int reset_delay_us;
 };
 
@@ -716,8 +718,9 @@
 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_write_smbus_addr(struct wm_softc *);
+static int     wm_write_smbus_addr(struct wm_softc *);
 static void    wm_init_lcd_from_nvm(struct wm_softc *);
+static int     wm_oem_bits_config_ich8lan(struct wm_softc *, bool);
 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 *);
@@ -819,16 +822,18 @@
 static int     wm_gmii_mdic_readreg(device_t, int, int);
 static void    wm_gmii_mdic_writereg(device_t, int, int, int);
 static int     wm_gmii_i82544_readreg(device_t, int, int);
+static int     wm_gmii_i82544_readreg_locked(device_t, int, int, uint16_t *);
 static void    wm_gmii_i82544_writereg(device_t, int, int, int);
+static int     wm_gmii_i82544_writereg_locked(device_t, int, int, uint16_t);
 static int     wm_gmii_i80003_readreg(device_t, int, int);
 static void    wm_gmii_i80003_writereg(device_t, int, int, int);
 static int     wm_gmii_bm_readreg(device_t, int, int);
 static void    wm_gmii_bm_writereg(device_t, int, int, int);
 static void    wm_access_phy_wakeup_reg_bm(device_t, int, int16_t *, int);
 static int     wm_gmii_hv_readreg(device_t, int, int);
-static int     wm_gmii_hv_readreg_locked(device_t, int, int);
+static int     wm_gmii_hv_readreg_locked(device_t, int, int, uint16_t *);
 static void    wm_gmii_hv_writereg(device_t, int, int, int);
-static void    wm_gmii_hv_writereg_locked(device_t, int, int, int);
+static int     wm_gmii_hv_writereg_locked(device_t, int, int, uint16_t);
 static int     wm_gmii_82580_readreg(device_t, int, int);
 static void    wm_gmii_82580_writereg(device_t, int, int, int);
 static int     wm_gmii_gs40g_readreg(device_t, int, int);
@@ -948,9 +953,10 @@
 static void    wm_init_manageability(struct wm_softc *);
 static void    wm_release_manageability(struct wm_softc *);
 static void    wm_get_wakeup(struct wm_softc *);
-static void    wm_ulp_disable(struct wm_softc *);
+static int     wm_ulp_disable(struct wm_softc *);
 static void    wm_enable_phy_wakeup(struct wm_softc *);
 static void    wm_igp3_phy_powerdown_workaround_ich8lan(struct wm_softc *);
+static void    wm_suspend_workarounds_ich8lan(struct wm_softc *);
 static void    wm_enable_wakeup(struct wm_softc *);
 static void    wm_disable_aspm(struct wm_softc *);
 /* LPLU (Low Power Link Up) */
@@ -968,6 +974,8 @@
 static void    wm_lv_phy_workaround_ich8lan(struct wm_softc *);
 static int     wm_k1_workaround_lpt_lp(struct wm_softc *, bool);
 static int     wm_k1_gig_workaround_hv(struct wm_softc *, int);
+static int     wm_k1_workaround_lv(struct wm_softc *);
+static int     wm_link_stall_workaround_hv(struct wm_softc *);
 static void    wm_set_mdio_slow_mode_hv(struct wm_softc *);
 static void    wm_configure_k1_ich8lan(struct wm_softc *, int);
 static void    wm_reset_init_script_82575(struct wm_softc *);
@@ -3826,6 +3834,7 @@
                else
                        wm_get_auto_rd_done(sc);
 
+               /* Clear PHY Reset Asserted bit */
                reg = CSR_READ(sc, WMREG_STATUS);
                if ((reg & STATUS_PHYRA) != 0)
                        CSR_WRITE(sc, WMREG_STATUS, reg & ~STATUS_PHYRA);
@@ -3873,7 +3882,8 @@
        /* Configure the LCD with the extended configuration region in NVM */
        wm_init_lcd_from_nvm(sc);
 
-       /* XXX Configure the LCD with the OEM bits in NVM */
+       /* Configure the LCD with the OEM bits in NVM */
+       wm_oem_bits_config_ich8lan(sc, true);
 
        if (sc->sc_type == WM_T_PCH2) {
                /* Ungate automatic PHY configuration on non-managed 82579 */
@@ -3886,19 +3896,23 @@
 }
 
 /* Only for PCH and newer */
-static void
+static int
 wm_write_smbus_addr(struct wm_softc *sc)
 {
        uint32_t strap, freq;
-       uint32_t phy_data;
+       uint16_t phy_data;
+       int rv;
 
        DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
                device_xname(sc->sc_dev), __func__));
+       KASSERT(CSR_READ(sc, WMREG_EXTCNFCTR) & EXTCNFCTR_MDIO_SW_OWNERSHIP);
 
        strap = CSR_READ(sc, WMREG_STRAP);
        freq = __SHIFTOUT(strap, STRAP_FREQ);
 
-       phy_data = wm_gmii_hv_readreg_locked(sc->sc_dev, 2, HV_SMB_ADDR);
+       rv = wm_gmii_hv_readreg_locked(sc->sc_dev, 2, HV_SMB_ADDR, &phy_data);
+       if (rv != 0)
+               return -1;
 
        phy_data &= ~HV_SMB_ADDR_ADDR;
        phy_data |= __SHIFTOUT(strap, STRAP_SMBUSADDR);
@@ -3920,7 +3934,8 @@
                }
        }
 
-       wm_gmii_hv_writereg_locked(sc->sc_dev, 2, HV_SMB_ADDR, phy_data);
+       return wm_gmii_hv_writereg_locked(sc->sc_dev, 2, HV_SMB_ADDR,
+           phy_data);
 }
 
 void
@@ -4012,9 +4027,8 @@
                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 */
+               KASSERT(sc->phy.writereg_locked != NULL);
+               sc->phy.writereg_locked(sc->sc_dev, 1, reg_addr, reg_data);
        }
 
 release:       
@@ -4022,6 +4036,72 @@
        return;
 }
     
+/*
+ *  wm_oem_bits_config_ich8lan - SW-based LCD Configuration
+ *  @sc:       pointer to the HW structure
+ *  @d0_state: boolean if entering d0 or d3 device state
+ *
+ *  SW will configure Gbe Disable and LPLU based on the NVM. The four bits are
+ *  collectively called OEM bits.  The OEM Write Enable bit and SW Config bit
+ *  in NVM determines whether HW should configure LPLU and Gbe Disable.
+ */
+int
+wm_oem_bits_config_ich8lan(struct wm_softc *sc, bool d0_state)
+{
+       uint32_t mac_reg;
+       uint16_t oem_reg;
+       int rv;
+
+       if (sc->sc_type < WM_T_PCH)
+               return 0;
+
+       rv = sc->phy.acquire(sc);
+       if (rv != 0)
+               return rv;
+
+       if (sc->sc_type == WM_T_PCH) {
+               mac_reg = CSR_READ(sc, WMREG_EXTCNFCTR);
+               if ((mac_reg & EXTCNFCTR_OEM_WRITE_ENABLE) != 0)
+                       goto release;
+       }
+
+       mac_reg = CSR_READ(sc, WMREG_FEXTNVM);
+       if ((mac_reg & FEXTNVM_SW_CONFIG_ICH8M) == 0)
+               goto release;
+
+       mac_reg = CSR_READ(sc, WMREG_PHY_CTRL);
+       
+       rv = wm_gmii_hv_readreg_locked(sc->sc_dev, 1, HV_OEM_BITS, &oem_reg);
+       if (rv != 0)
+               goto release;
+       oem_reg &= ~(HV_OEM_BITS_A1KDIS | HV_OEM_BITS_LPLU);
+
+       if (d0_state) {
+               if ((mac_reg & PHY_CTRL_GBE_DIS) != 0)
+                       oem_reg |= HV_OEM_BITS_A1KDIS;
+               if ((mac_reg & PHY_CTRL_D0A_LPLU) != 0)
+                       oem_reg |= HV_OEM_BITS_LPLU;
+       } else {
+               if ((mac_reg & (PHY_CTRL_GBE_DIS | PHY_CTRL_NOND0A_GBE_DIS))
+                   != 0)
+                       oem_reg |= HV_OEM_BITS_A1KDIS;
+               if ((mac_reg & (PHY_CTRL_D0A_LPLU | PHY_CTRL_NOND0A_LPLU))
+                   != 0)
+                       oem_reg |= HV_OEM_BITS_LPLU;
+       }
+
+       /* Set Restart auto-neg to activate the bits */
+       if ((d0_state || (sc->sc_type != WM_T_PCH))
+           && (wm_phy_resetisblocked(sc) == false))
+               oem_reg |= HV_OEM_BITS_ANEGNOW;
+
+       rv = wm_gmii_hv_writereg_locked(sc->sc_dev, 1, HV_OEM_BITS, oem_reg);
+
+release:
+       sc->phy.release(sc);
+
+       return rv;
+}
 
 /* Init hardware bits */
 void
@@ -5482,6 +5562,27 @@
        if (sc->sc_flags & WM_F_HAS_MII)
                wm_gmii_reset(sc);
 
+       if (sc->sc_type >= WM_T_ICH8) {
+               reg = CSR_READ(sc, WMREG_GCR);
+               /*
+                * ICH8 No-snoop bits are opposite polarity. Set to snoop by
+                * default after reset.
+                */
+               if (sc->sc_type == WM_T_ICH8)
+                       reg |= GCR_NO_SNOOP_ALL;
+               else
+                       reg &= ~GCR_NO_SNOOP_ALL;
+               CSR_WRITE(sc, WMREG_GCR, reg);
+       }
+       if ((sc->sc_type >= WM_T_ICH8)
+           || (sc->sc_pcidevid == PCI_PRODUCT_INTEL_82546GB_QUAD_COPPER)
+           || (sc->sc_pcidevid == PCI_PRODUCT_INTEL_82546GB_QUAD_COPPER_KSP3)) {
+
+               reg = CSR_READ(sc, WMREG_CTRL_EXT);
+               reg |= CTRL_EXT_RO_DIS;
+               CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
+       }
+
        /* Calculate (E)ITR value */
        if ((sc->sc_flags & WM_F_NEWQUEUE) != 0 && sc->sc_type != WM_T_82575) {
                /*
@@ -8751,23 +8852,6 @@
                            ((sc->sc_mii.mii_media_status & IFM_ACTIVE) != 0));
                }
 
-               if ((sc->sc_phytype == WMPHY_82578)
-                   && (IFM_SUBTYPE(sc->sc_mii.mii_media_active)
-                       == IFM_1000_T)) {
-
-                       if ((sc->sc_mii.mii_media_status & IFM_ACTIVE) != 0) {
-                               delay(200*1000); /* XXX too big */
-
-                               /* Link stall fix for link up */
-                               wm_gmii_hv_writereg(sc->sc_dev, 1,
-                                   HV_MUX_DATA_CTRL,



Home | Main Index | Thread Index | Old Index