Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev - Don't setup WoL on non-WoL capable port.
details: https://anonhg.NetBSD.org/src/rev/269dc8989e52
branches: trunk
changeset: 446808:269dc8989e52
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Thu Dec 20 09:32:12 2018 +0000
description:
- Don't setup WoL on non-WoL capable port.
- Setup PHY wakeup feature on PCH and newer. Tested on Thinkpad X220.
diffstat:
sys/dev/mii/inbmphyreg.h | 21 ++-
sys/dev/pci/if_wm.c | 426 ++++++++++++++++++++++++++++++++++++----------
sys/dev/pci/if_wmreg.h | 4 +-
sys/dev/pci/if_wmvar.h | 6 +-
4 files changed, 358 insertions(+), 99 deletions(-)
diffs (truncated from 705 to 300 lines):
diff -r d57f9872fa6c -r 269dc8989e52 sys/dev/mii/inbmphyreg.h
--- a/sys/dev/mii/inbmphyreg.h Thu Dec 20 09:17:04 2018 +0000
+++ b/sys/dev/mii/inbmphyreg.h Thu Dec 20 09:32:12 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: inbmphyreg.h,v 1.14 2018/12/13 05:22:44 msaitoh Exp $ */
+/* $NetBSD: inbmphyreg.h,v 1.15 2018/12/20 09:32:12 msaitoh Exp $ */
/*******************************************************************************
Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
@@ -160,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
@@ -169,6 +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 d57f9872fa6c -r 269dc8989e52 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Thu Dec 20 09:17:04 2018 +0000
+++ b/sys/dev/pci/if_wm.c Thu Dec 20 09:32:12 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.609 2018/12/20 08:59:22 msaitoh Exp $ */
+/* $NetBSD: if_wm.c,v 1.610 2018/12/20 09:32:13 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.609 2018/12/20 08:59:22 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.610 2018/12/20 09:32:13 msaitoh Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -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 *);
@@ -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);
@@ -954,7 +958,7 @@
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 *);
@@ -972,6 +976,7 @@
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_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);
@@ -3566,6 +3571,50 @@
}
/*
+ *
+ *
+ */
+static int
+wm_rar_count(struct wm_softc *sc)
+{
+ int size;
+
+ switch (sc->sc_type) {
+ case WM_T_ICH8:
+ size = WM_RAL_TABSIZE_ICH8 -1;
+ break;
+ case WM_T_ICH9:
+ case WM_T_ICH10:
+ case WM_T_PCH:
+ size = WM_RAL_TABSIZE_ICH8;
+ break;
+ case WM_T_PCH2:
+ size = WM_RAL_TABSIZE_PCH2;
+ break;
+ case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
+ case WM_T_PCH_CNP:
+ size = WM_RAL_TABSIZE_PCH_LPT;
+ break;
+ case WM_T_82575:
+ size = WM_RAL_TABSIZE_82575;
+ break;
+ case WM_T_82576:
+ case WM_T_82580:
+ size = WM_RAL_TABSIZE_82576;
+ break;
+ case WM_T_I350:
+ case WM_T_I354:
+ size = WM_RAL_TABSIZE_I350;
+ break;
+ default:
+ size = WM_RAL_TABSIZE;
+ }
+
+ return size;
+}
+
+/*
* wm_set_filter:
*
* Set up the receive filter.
@@ -3602,24 +3651,7 @@
* Set the station address in the first RAL slot, and
* clear the remaining slots.
*/
- if (sc->sc_type == WM_T_ICH8)
- size = WM_RAL_TABSIZE_ICH8 -1;
- else if ((sc->sc_type == WM_T_ICH9) || (sc->sc_type == WM_T_ICH10)
- || (sc->sc_type == WM_T_PCH))
- size = WM_RAL_TABSIZE_ICH8;
- else if (sc->sc_type == WM_T_PCH2)
- size = WM_RAL_TABSIZE_PCH2;
- else if ((sc->sc_type == WM_T_PCH_LPT) || (sc->sc_type == WM_T_PCH_SPT)
- || (sc->sc_type == WM_T_PCH_CNP))
- size = WM_RAL_TABSIZE_PCH_LPT;
- else if (sc->sc_type == WM_T_82575)
- size = WM_RAL_TABSIZE_82575;
- else if ((sc->sc_type == WM_T_82576) || (sc->sc_type == WM_T_82580))
- size = WM_RAL_TABSIZE_82576;
- else if ((sc->sc_type == WM_T_I350) || (sc->sc_type == WM_T_I354))
- size = WM_RAL_TABSIZE_I350;
- else
- size = WM_RAL_TABSIZE;
+ size = wm_rar_count(sc);
wm_set_ral(sc, CLLADDR(ifp->if_sadl), 0);
if ((sc->sc_type == WM_T_PCH_LPT) || (sc->sc_type == WM_T_PCH_SPT)
@@ -6050,7 +6082,7 @@
*/
sc->sc_mchash_type = 0;
sc->sc_rctl = RCTL_EN | RCTL_LBM_NONE | RCTL_RDMTS_1_2 | RCTL_DPF
- | RCTL_MO(sc->sc_mchash_type);
+ | __SHIFTIN(sc->sc_mchash_type, RCTL_MO);
/*
* 82574 use one buffer extended Rx descriptor.
@@ -10288,7 +10320,8 @@
uint32_t mdic = 0;
int i, rv;
- if (reg > MII_ADDRMASK) {
+ if ((sc->sc_phytype != WMPHY_82579) && (sc->sc_phytype != WMPHY_I217)
+ && (reg > MII_ADDRMASK)) {
device_printf(dev, "%s: PHYTYPE = %d, addr 0x%x > 0x1f\n",
__func__, sc->sc_phytype, reg);
reg &= MII_ADDRMASK;
@@ -10342,7 +10375,8 @@
uint32_t mdic = 0;
int i;
- if (reg > MII_ADDRMASK) {
+ if ((sc->sc_phytype != WMPHY_82579) && (sc->sc_phytype != WMPHY_I217)
+ && (reg > MII_ADDRMASK)) {
device_printf(dev, "%s: PHYTYPE = %d, addr 0x%x > 0x1f\n",
__func__, sc->sc_phytype, reg);
reg &= MII_ADDRMASK;
@@ -10602,7 +10636,7 @@
|| (reg == 31)) ? 1 : phy;
/* Page 800 works differently than the rest so it has its own func */
if (page == BM_WUC_PAGE) {
- wm_access_phy_wakeup_reg_bm(dev, reg, &val, 1);
+ wm_access_phy_wakeup_reg_bm(dev, reg, &val, true, false);
rv = val;
goto release;
}
@@ -10650,7 +10684,7 @@
uint16_t tmp;
tmp = val;
- wm_access_phy_wakeup_reg_bm(dev, reg, &tmp, 0);
+ wm_access_phy_wakeup_reg_bm(dev, reg, &tmp, false, false);
goto release;
}
@@ -10670,39 +10704,139 @@
sc->phy.release(sc);
}
-static void
-wm_access_phy_wakeup_reg_bm(device_t dev, int offset, int16_t *val, int rd)
+/*
+ * wm_enable_phy_wakeup_reg_access_bm - enable access to BM wakeup registers
+ * @dev: pointer to the HW structure
+ * @phy_reg: pointer to store original contents of BM_WUC_ENABLE_REG
+ *
+ * Assumes semaphore already acquired and phy_reg points to a valid memory
+ * address to store contents of the BM_WUC_ENABLE_REG register.
+ */
+static int
+wm_enable_phy_wakeup_reg_access_bm(device_t dev, uint16_t *phy_regp)
+{
+ uint16_t temp;
+
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(dev), __func__));
+
+ if (!phy_regp)
+ return -1;
+
+ /* All page select, port ctrl and wakeup registers use phy address 1 */
+
+ /* Select Port Control Registers page */
+ wm_gmii_mdic_writereg(dev, 1, MII_IGPHY_PAGE_SELECT,
+ BM_PORT_CTRL_PAGE << IGP3_PAGE_SHIFT);
+
+ /* Read WUCE and save it */
+ *phy_regp = wm_gmii_mdic_readreg(dev, 1, BM_WUC_ENABLE_REG);
+
+ /* Enable both PHY wakeup mode and Wakeup register page writes.
+ * Prevent a power state change by disabling ME and Host PHY wakeup.
+ */
+ temp = *phy_regp;
+ temp |= BM_WUC_ENABLE_BIT;
+ temp &= ~(BM_WUC_ME_WU_BIT | BM_WUC_HOST_WU_BIT);
+
+ wm_gmii_mdic_writereg(dev, 1, BM_WUC_ENABLE_REG, temp);
+
+ /* Select Host Wakeup Registers page - caller now able to write
+ * registers on the Wakeup registers page
+ */
+ wm_gmii_mdic_writereg(dev, 1, MII_IGPHY_PAGE_SELECT,
+ BM_WUC_PAGE << IGP3_PAGE_SHIFT);
+
+ return 0;
+}
+
+/*
+ * wm_disable_phy_wakeup_reg_access_bm - disable access to BM wakeup regs
+ * @dev: pointer to the HW structure
+ * @phy_reg: pointer to original contents of BM_WUC_ENABLE_REG
+ *
+ * Restore BM_WUC_ENABLE_REG to its original value.
+ *
+ * Assumes semaphore already acquired and *phy_reg is the contents of the
+ * BM_WUC_ENABLE_REG before register(s) on BM_WUC_PAGE were accessed by
+ * caller.
+ */
+static int
+wm_disable_phy_wakeup_reg_access_bm(device_t dev, uint16_t *phy_regp)
+{
+
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(dev), __func__));
+
+ if (!phy_regp)
+ return -1;
+
+ /* Select Port Control Registers page */
+ wm_gmii_mdic_writereg(dev, 1, MII_IGPHY_PAGE_SELECT,
+ BM_PORT_CTRL_PAGE << IGP3_PAGE_SHIFT);
+
+ /* Restore 769.17 to its original value */
+ wm_gmii_mdic_writereg(dev, 1, BM_WUC_ENABLE_REG, *phy_regp);
Home |
Main Index |
Thread Index |
Old Index