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 the following, requested by msaitoh in ti...



details:   https://anonhg.NetBSD.org/src/rev/0eed8e866164
branches:  netbsd-8
changeset: 852246:0eed8e866164
user:      martin <martin%NetBSD.org@localhost>
date:      Thu Jan 31 06:43:48 2019 +0000

description:
Pull up the following, requested by msaitoh in ticket #1179:

        sys/dev/pci/if_wm.c                     1.603-1.605,1.607-1.611,
                                                1.613,1.615,1.618-1.620
                                                via patch
        sys/dev/pci/if_wmreg.h                  1.110-1.111
        sys/dev/pci/if_wmvar.h                  1.40-1.42
        sys/dev/mii/inbmphyreg.h                1.13-1.15

- Add some code for suspend/resume:
  - Rename wm_smbustopci() to wm_init_phy_workarounds_pchlan(). It will
    also called when resume.
  - Call wm_phy_resetisblocked() after PHY reset in
    wm_init_phy_workarounds_pchlan() to wait for the PHY to quiesce to
    an accessible state.
  - Add new wm_resume_workarounds_pchlan() function and use it in
    wm_resume(). This workaround is only for PCH2 and newer.
  - Don't call wm_disable_aspm() neither in wm_attach() nor in
    wm_resume() but in wm_reset().
  - Do some initialization in wm_resume() when IFF_UP is NOT set.
  - Don't continue when it failed to acquire semaphore in
    wm_ulp_disable().
- Print CLSEM workaround bit correctly.
- Fix availability detection of WoL on some chips.
- Print the WUS (WakeUp Status) register bits when resume.
- Don't setup WoL on non-WoL capable port.
- Setup PHY wakeup feature on PCH and newer. Tested on Thinkpad X220.
- Remove an extra register read in
  wm_kmrn_lock_loss_workaround_ich8lan().
- Don't leave the MDICNFG register modified when the Power Management
  capability offset can't get.
- Reduce indent level of wm_linkintr_gmii(). No functional change.
- 80003's SERDES is not the same as 82575's but the same as legacy
  devices. Use the old methods on 80003.
- Use __nothing for null DPRINTF().
- Rename functions. Add comment.

diffstat:

 sys/dev/mii/inbmphyreg.h |   53 ++-
 sys/dev/pci/if_wm.c      |  999 +++++++++++++++++++++++++++++++++-------------
 sys/dev/pci/if_wmreg.h   |   41 +-
 sys/dev/pci/if_wmvar.h   |   24 +-
 4 files changed, 807 insertions(+), 310 deletions(-)

diffs (truncated from 1744 to 300 lines):

diff -r 767c1f55d846 -r 0eed8e866164 sys/dev/mii/inbmphyreg.h
--- a/sys/dev/mii/inbmphyreg.h  Thu Jan 31 06:02:50 2019 +0000
+++ b/sys/dev/mii/inbmphyreg.h  Thu Jan 31 06:43:48 2019 +0000
@@ -1,6 +1,6 @@
-/*     $NetBSD: inbmphyreg.h,v 1.9.8.3 2018/12/04 11:21:32 martin Exp $        */
+/*     $NetBSD: inbmphyreg.h,v 1.9.8.4 2019/01/31 06:43:48 martin Exp $        */
 /*******************************************************************************
-Copyright (c) 2001-2005, Intel Corporation 
+Copyright (c) 2001-2015, Intel Corporation 
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without 
@@ -39,12 +39,16 @@
 #define        _DEV_MII_INBMPHYREG_H_
 
 /* Bits...
- * 15-5: page
- * 4-0: register offset
+ * 31-16: register offset (high)
+ * 15-5:  page
+ * 4-0:   register offset (low)
  */
-#define BME1000_PAGE_SHIFT        5
+#define BME1000_PAGE_SHIFT     5
+#define BM_PHY_UPPER_SHIFT     21
 #define BME1000_REG(page, reg)    \
-        (((page) << BME1000_PAGE_SHIFT) | ((reg) & MII_ADDRMASK))
+        (((reg) & MII_ADDRMASK) |                      \
+           (((page) & 0xffff) << BME1000_PAGE_SHIFT) | \
+           (((reg) & ~MII_ADDRMASK) << (BM_PHY_UPPER_SHIFT - BME1000_PAGE_SHIFT)))
 
 #define BME1000_MAX_MULTI_PAGE_REG     0xf   /* Registers equal on all pages */
 
@@ -52,7 +56,7 @@
        ((uint16_t)(((offset) >> BME1000_PAGE_SHIFT) & 0xffff))
 #define        BM_PHY_REG_NUM(offset)                          \
        ((uint16_t)((offset) & MII_ADDRMASK)            \
-       | (((offset) >> (21 - BME1000_PAGE_SHIFT)) & ~MII_ADDRMASK))
+       | (((offset) >> (BM_PHY_UPPER_SHIFT - BME1000_PAGE_SHIFT)) & ~MII_ADDRMASK))
 
 /* BME1000 Specific Registers */
 #define BME1000_PHY_SPEC_CTRL  BME1000_REG(0, 16) /* PHY Specific Control */
@@ -126,6 +130,20 @@
 #define        IGP3_KMRN_DIAG          BME1000_REG(770, 19)
 #define        IGP3_KMRN_DIAG_PCS_LOCK_LOSS    (1 << 1)
 
+#define        I217_LPI_GPIO_CTRL      BME1000_REG(772, 18)
+#define        I217_LPI_GPIO_CTRL_AUTO_EN_LPI  __BIT(11)
+
+#define        I82579_LPI_CTRL         BME1000_REG(772, 20)
+#define        I82579_LPI_CTRL_ENABLE  __BITS(14, 13)
+#define        I82579_LPI_CTRL_EN_100  __BIT(13)
+#define        I82579_LPI_CTRL_EN_1000 __BIT(14)
+
+#define        I217_MEMPWR             BME1000_REG(772, 26)
+#define        I217_MEMPWR_DISABLE_SMB_RELEASE         0x0010
+
+#define        I217_CFGREG             BME1000_REG(772, 29)
+#define I217_CGFREG_ENABLE_MTA_RESET   0x0002
+
 #define HV_MUX_DATA_CTRL       BME1000_REG(776, 16)
 #define HV_MUX_DATA_CTRL_FORCE_SPEED   (1 << 2)
 #define HV_MUX_DATA_CTRL_GEN_TO_MAC    (1 << 10)
@@ -142,6 +160,16 @@
 #define I218_ULP_CONFIG1_DIS_SMB_PERST __BIT(12)
 
 #define        BM_WUC_PAGE             800
+
+#define        BM_RCTL                 BME1000_REG(BM_WUC_PAGE, 0)
+#define BM_RCTL_UPE            0x0001 /* Unicast Promiscuous Mode */
+#define BM_RCTL_MPE            0x0002 /* Multicast Promiscuous Mode */
+#define BM_RCTL_MO_SHIFT       3      /* Multicast Offset Shift */
+#define BM_RCTL_MO_MASK                (3 << 3) /* Multicast Offset Mask */
+#define BM_RCTL_BAM            0x0020 /* Broadcast Accept Mode */
+#define BM_RCTL_PMCF           0x0040 /* Pass MAC Control Frames */
+#define BM_RCTL_RFCE           0x0080 /* Rx Flow Control Enable */
+
 #define        BM_WUC                  BME1000_REG(BM_WUC_PAGE, 1)
 #define        BM_WUC_ADDRESS_OPCODE   0x11
 #define        BM_WUC_DATA_OPCODE      0x12
@@ -151,4 +179,15 @@
 #define        BM_WUC_HOST_WU_BIT      (1 << 4)
 #define        BM_WUC_ME_WU_BIT        (1 << 5)
 
+#define        BM_WUFC                 BME1000_REG(BM_WUC_PAGE, 2)
+
+#define        I217_PROXY_CTRL         BME1000_REG(BM_WUC_PAGE, 70)
+#define I217_PROXY_CTRL_AUTO_DISABLE   0x0080
+
+#define BM_RAR_L(_i)           (BME1000_REG(BM_WUC_PAGE, 16 + ((_i) << 2)))
+#define BM_RAR_M(_i)           (BME1000_REG(BM_WUC_PAGE, 17 + ((_i) << 2)))
+#define BM_RAR_H(_i)           (BME1000_REG(BM_WUC_PAGE, 18 + ((_i) << 2)))
+#define BM_RAR_CTRL(_i)                (BME1000_REG(BM_WUC_PAGE, 19 + ((_i) << 2)))
+#define BM_MTA(_i)             (BME1000_REG(BM_WUC_PAGE, 128 + ((_i) << 1)))
+
 #endif /* _DEV_MII_INBMPHYREG_H_ */
diff -r 767c1f55d846 -r 0eed8e866164 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Thu Jan 31 06:02:50 2019 +0000
+++ b/sys/dev/pci/if_wm.c       Thu Jan 31 06:43:48 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wm.c,v 1.508.4.28 2018/12/18 18:24:09 martin Exp $  */
+/*     $NetBSD: if_wm.c,v 1.508.4.29 2019/01/31 06:43:48 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.28 2018/12/18 18:24:09 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.508.4.29 2019/01/31 06:43:48 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -159,7 +159,7 @@
 
 #define        DPRINTF(x, y)   if (wm_debug & (x)) printf y
 #else
-#define        DPRINTF(x, y)   /* nothing */
+#define        DPRINTF(x, y)   __nothing
 #endif /* WM_DEBUG */
 
 #ifdef NET_MPSAFE
@@ -710,6 +710,7 @@
 static int     wm_read_mac_addr(struct wm_softc *, uint8_t *);
 static void    wm_set_ral(struct wm_softc *, const uint8_t *, int);
 static uint32_t        wm_mchash(struct wm_softc *, const uint8_t *);
+static int     wm_rar_count(struct wm_softc *);
 static void    wm_set_filter(struct wm_softc *);
 /* Reset and init related */
 static void    wm_set_vlan(struct wm_softc *);
@@ -723,7 +724,7 @@
 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 *);
+static int     wm_reset_phy(struct wm_softc *);
 static void    wm_flush_desc_rings(struct wm_softc *);
 static void    wm_reset(struct wm_softc *);
 static int     wm_add_rxbuf(struct wm_rxqueue *, int);
@@ -829,7 +830,10 @@
 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_enable_phy_wakeup_reg_access_bm(device_t, uint16_t *);
+static int     wm_disable_phy_wakeup_reg_access_bm(device_t, uint16_t *);
+static int     wm_access_phy_wakeup_reg_bm(device_t, int, int16_t *, int,
+       bool);
 static int     wm_gmii_hv_readreg(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);
@@ -949,14 +953,15 @@
 static void    wm_get_hw_control(struct wm_softc *);
 static void    wm_release_hw_control(struct wm_softc *);
 static void    wm_gate_hw_phy_config_ich8lan(struct wm_softc *, bool);
-static void    wm_smbustopci(struct wm_softc *);
+static int     wm_init_phy_workarounds_pchlan(struct wm_softc *);
 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 int     wm_ulp_disable(struct wm_softc *);
-static void    wm_enable_phy_wakeup(struct wm_softc *);
+static int     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 int     wm_resume_workarounds_pchlan(struct wm_softc *);
 static void    wm_enable_wakeup(struct wm_softc *);
 static void    wm_disable_aspm(struct wm_softc *);
 /* LPLU (Low Power Link Up) */
@@ -970,8 +975,9 @@
  */
 static void    wm_kmrn_lock_loss_workaround_ich8lan(struct wm_softc *);
 static void    wm_gig_downshift_workaround_ich8lan(struct wm_softc *);
-static void    wm_hv_phy_workaround_ich8lan(struct wm_softc *);
-static void    wm_lv_phy_workaround_ich8lan(struct wm_softc *);
+static void    wm_hv_phy_workarounds_ich8lan(struct wm_softc *);
+static void    wm_copy_rx_addrs_to_phy_ich8lan(struct wm_softc *);
+static void    wm_lv_phy_workarounds_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 *);
@@ -2099,9 +2105,6 @@
                    (sc->sc_flags & WM_F_PCIX) ? "PCIX" : "PCI");
        }
 
-       /* Disable ASPM L0s and/or L1 for workaround */
-       wm_disable_aspm(sc);
-
        /* clear interesting stat counters */
        CSR_READ(sc, WMREG_COLC);
        CSR_READ(sc, WMREG_RXERRC);
@@ -2381,6 +2384,25 @@
         */
        wm_gmii_setup_phytype(sc, 0, 0);
 
+       /* Check for WM_F_WOL on some chips before wm_reset() */
+       switch (sc->sc_type) {
+       case WM_T_ICH8:
+       case WM_T_ICH9:
+       case WM_T_ICH10:
+       case WM_T_PCH:
+       case WM_T_PCH2:
+       case WM_T_PCH_LPT:
+       case WM_T_PCH_SPT:
+       case WM_T_PCH_CNP:
+               apme_mask = WUC_APME;
+               eeprom_data = CSR_READ(sc, WMREG_WUC);
+               if ((eeprom_data & apme_mask) != 0)
+                       sc->sc_flags |= WM_F_WOL;
+               break;
+       default:
+               break;
+       }
+
        /* Reset the chip to a known state. */
        wm_reset(sc);
 
@@ -2482,16 +2504,22 @@
        case WM_T_82574:
        case WM_T_82583:
        case WM_T_80003:
-       default:
+       case WM_T_82575:
+       case WM_T_82576:
                apme_mask = NVM_CFG3_APME;
                wm_nvm_read(sc, (sc->sc_funcid == 1) ? NVM_OFF_CFG3_PORTB
                    : NVM_OFF_CFG3_PORTA, 1, &eeprom_data);
                break;
-       case WM_T_82575:
-       case WM_T_82576:
        case WM_T_82580:
        case WM_T_I350:
-       case WM_T_I354: /* XXX ok? */
+       case WM_T_I354:
+       case WM_T_I210:
+       case WM_T_I211:
+               apme_mask = NVM_CFG3_APME;
+               wm_nvm_read(sc,
+                   NVM_OFF_LAN_FUNC_82580(sc->sc_funcid) + NVM_OFF_CFG3_PORTA,
+                   1, &eeprom_data);
+               break;
        case WM_T_ICH8:
        case WM_T_ICH9:
        case WM_T_ICH10:
@@ -2500,16 +2528,54 @@
        case WM_T_PCH_LPT:
        case WM_T_PCH_SPT:
        case WM_T_PCH_CNP:
-               /* XXX The funcid should be checked on some devices */
-               apme_mask = WUC_APME;
-               eeprom_data = CSR_READ(sc, WMREG_WUC);
-               break;
-       }
-
+               /* Already checked before wm_reset () */
+               apme_mask = eeprom_data = 0;
+               break;
+       default: /* XXX 82540 */
+               apme_mask = NVM_CFG3_APME;
+               wm_nvm_read(sc, NVM_OFF_CFG3_PORTA, 1, &eeprom_data);
+               break;
+       }
        /* Check for WM_F_WOL flag after the setting of the EEPROM stuff */
        if ((eeprom_data & apme_mask) != 0)
                sc->sc_flags |= WM_F_WOL;
 
+       /*
+        * We have the eeprom settings, now apply the special cases
+        * where the eeprom may be wrong or the board won't support
+        * wake on lan on a particular port
+        */
+       switch (sc->sc_pcidevid) {
+       case PCI_PRODUCT_INTEL_82546GB_PCIE:
+               sc->sc_flags &= ~WM_F_WOL;
+               break;
+       case PCI_PRODUCT_INTEL_82546EB_FIBER:
+       case PCI_PRODUCT_INTEL_82546GB_FIBER:
+               /* Wake events only supported on port A for dual fiber
+                * regardless of eeprom setting */
+               if (sc->sc_funcid == 1)
+                       sc->sc_flags &= ~WM_F_WOL;
+               break;
+       case PCI_PRODUCT_INTEL_82546GB_QUAD_COPPER_KSP3:
+               /* if quad port adapter, disable WoL on all but port A */
+               if (sc->sc_funcid != 0)
+                       sc->sc_flags &= ~WM_F_WOL;
+               break;
+       case PCI_PRODUCT_INTEL_82571EB_FIBER:
+               /* Wake events only supported on port A for dual fiber
+                * regardless of eeprom setting */
+               if (sc->sc_funcid == 1)
+                       sc->sc_flags &= ~WM_F_WOL;
+               break;
+       case PCI_PRODUCT_INTEL_82571EB_QUAD_COPPER:
+       case PCI_PRODUCT_INTEL_82571EB_QUAD_FIBER:
+       case PCI_PRODUCT_INTEL_82571GB_QUAD_COPPER:
+               /* if quad port adapter, disable WoL on all but port A */
+               if (sc->sc_funcid != 0)
+                       sc->sc_flags &= ~WM_F_WOL;



Home | Main Index | Thread Index | Old Index