Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci - Fix availability detection of WoL on some chip...
details: https://anonhg.NetBSD.org/src/rev/0a48adf163cd
branches: trunk
changeset: 446676:0a48adf163cd
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Fri Dec 14 09:47:40 2018 +0000
description:
- Fix availability detection of WoL on some chips. This change has no effect
other than dmesg because WM_F_WOL is currently not used to change the behavior:
- For ICH/PCH, check the capability not from NVM but from the WUC register.
Check the value before clearing the register.
- 82580 and newer have per-port NVM block, so read the area correctly.
Note that 82580, I350 and I354 may have PCI function 2 and 3.
- Some devices can't detect WoL capability neither from NVM nor from WUC.
Use PCI device ID and the function number.
- Print the WUS (WakeUp Status) register bits when resume.
diffstat:
sys/dev/pci/if_wm.c | 84 ++++++++++++++++++++++++++++++++++++++++++++-----
sys/dev/pci/if_wmreg.h | 39 ++++++++++++++++++----
2 files changed, 106 insertions(+), 17 deletions(-)
diffs (194 lines):
diff -r c066f12890a8 -r 0a48adf163cd sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Fri Dec 14 09:21:32 2018 +0000
+++ b/sys/dev/pci/if_wm.c Fri Dec 14 09:47:40 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.603 2018/12/12 08:49:33 msaitoh Exp $ */
+/* $NetBSD: if_wm.c,v 1.604 2018/12/14 09:47:40 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.603 2018/12/12 08:49:33 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.604 2018/12/14 09:47:40 msaitoh Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -2379,6 +2379,22 @@
*/
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);
+ break;
+ default:
+ break;
+ }
/* Reset the chip to a known state. */
wm_reset(sc);
@@ -2480,16 +2496,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:
@@ -2498,9 +2520,12 @@
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);
+ /* 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;
}
@@ -2508,6 +2533,42 @@
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;
+ break;
+ }
+
if ((sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576)) {
/* Check NVM for autonegotiation */
if (wm_nvm_read(sc, NVM_OFF_COMPAT, 1, &nvmword) == 0) {
@@ -2977,6 +3038,11 @@
{
struct wm_softc *sc = device_private(self);
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+ char buf[256];
+
+ snprintb(buf, sizeof(buf), WUS_FLAGS, CSR_READ(sc, WMREG_WUS));
+ device_printf(sc->sc_dev, "wakeup status %s\n", buf);
+ CSR_WRITE(sc, WMREG_WUS, 0xffffffff); /* W1C */
if (sc->sc_type >= WM_T_PCH2)
wm_resume_workarounds_pchlan(sc);
diff -r c066f12890a8 -r 0a48adf163cd sys/dev/pci/if_wmreg.h
--- a/sys/dev/pci/if_wmreg.h Fri Dec 14 09:21:32 2018 +0000
+++ b/sys/dev/pci/if_wmreg.h Fri Dec 14 09:47:40 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wmreg.h,v 1.109 2018/11/19 06:38:58 msaitoh Exp $ */
+/* $NetBSD: if_wmreg.h,v 1.110 2018/12/14 09:47:40 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -1195,15 +1195,38 @@
#define WMREG_WUC 0x5800 /* Wakeup Control */
#define WUC_APME 0x00000001 /* APM Enable */
#define WUC_PME_EN 0x00000002 /* PME Enable */
+#define WUC_PME_STATUS 0x00000004 /* PME Status */
+#define WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */
+#define WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */
#define WMREG_WUFC 0x5808 /* Wakeup Filter Control */
-#define WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
-#define WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
-#define WUFC_MC 0x00000008 /* Directed Multicast Wakeup En */
-#define WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
-#define WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup En */
-#define WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup En */
-#define WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup En */
+#define WUFC_LNKC __BIT(0) /* Link Status Change Wakeup Enable */
+#define WUFC_MAG __BIT(1) /* Magic Packet Wakeup Enable */
+#define WUFC_EX __BIT(2) /* Directed Exact Wakeup Enable */
+#define WUFC_MC __BIT(3) /* Directed Multicast Wakeup En */
+#define WUFC_BC __BIT(4) /* Broadcast Wakeup Enable */
+#define WUFC_ARPDIR __BIT(5) /* ARP Request Packet Wakeup En */
+#define WUFC_IPV4 __BIT(6) /* Directed IPv4 Packet Wakeup En */
+#define WUFC_IPV6 __BIT(7) /* Directed IPv6 Packet Wakeup En */
+#define WUFC_NS __BIT(9) /* NS Wakeup En */
+#define WUFC_NSDIR __BIT(10) /* NS Directed En */
+#define WUFC_ARP __BIT(11) /* ARP request En */
+#define WUFC_FLEX_HQ __BIT(14) /* Flex Filters Host Queueing En */
+#define WUFC_NOTCO __BIT(15) /* ? */
+#define WUFC_FLX __BITS(23, 16) /* Flexible Filter [0-7] En */
+#define WUFC_FLXACT __BITS(27, 24) /* Flexible Filter [0-3] Action */
+#define WUFC_FW_RST_WK __BIT(31) /* Wake on Firmware Reset Assert En */
+
+#define WMREG_WUS 0x5810 /* Wakeup Status (R/W1C) */
+ /* Bit 30-24 and 15-12 are reserved */
+#define WUS_MNG __BIT(8) /* Manageability event */
+#define WUS_FLAGS "\20" \
+ "\1LINKC" "\2MAG" "\3EX" "\4MC" \
+ "\5BC" "\6ARPDIR" "\7IPV4" "\10IPV6" \
+ "\11MNG" "\12NS" "\13NSDIR" "\14ARP" \
+ "\21FLX0" "\22FLX1" "\23FLX2" "\24FLX3" \
+ "\25FLX4" "\26FLX5" "\27FLX6" "\30FLX7" \
+ "\40FW_RST_WK"
#define WMREG_MRQC 0x5818 /* Multiple Receive Queues Command */
#define MRQC_DISABLE_RSS 0x00000000
Home |
Main Index |
Thread Index |
Old Index