Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Sync wm_smbustopci() with Linux and FreeBSD. This ch...
details: https://anonhg.NetBSD.org/src/rev/96202cf81b89
branches: trunk
changeset: 348930:96202cf81b89
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Wed Nov 16 08:56:17 2016 +0000
description:
Sync wm_smbustopci() with Linux and FreeBSD. This change effects PCH and
newer devices.
diffstat:
sys/dev/mii/inbmphyreg.h | 19 ++-
sys/dev/pci/if_wm.c | 312 +++++++++++++++++++++++++++++++++++++++++++---
sys/dev/pci/if_wmreg.h | 18 ++-
3 files changed, 324 insertions(+), 25 deletions(-)
diffs (truncated from 515 to 300 lines):
diff -r 36eb1296e965 -r 96202cf81b89 sys/dev/mii/inbmphyreg.h
--- a/sys/dev/mii/inbmphyreg.h Wed Nov 16 08:14:39 2016 +0000
+++ b/sys/dev/mii/inbmphyreg.h Wed Nov 16 08:56:17 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: inbmphyreg.h,v 1.8 2016/11/08 10:37:39 msaitoh Exp $ */
+/* $NetBSD: inbmphyreg.h,v 1.9 2016/11/16 08:56:17 msaitoh Exp $ */
/*******************************************************************************
Copyright (c) 2001-2005, Intel Corporation
All rights reserved.
@@ -96,6 +96,12 @@
#define BM_PORT_GEN_CFG BME1000_REG(BM_PORT_CTRL_PAGE, 17)
+#define CV_SMB_CTRL BME1000_REG(BM_PORT_CTRL_PAGE, 23)
+#define CV_SMB_CTRL_FORCE_SMBUS __BIT(0)
+
+#define HV_PM_CTRL BME1000_REG(770, 17)
+#define HV_PM_CTRL_K1_ENA __BIT(14)
+
#define IGP3_KMRN_DIAG BME1000_REG(770, 19)
#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS (1 << 1)
@@ -103,6 +109,17 @@
#define HV_MUX_DATA_CTRL_FORCE_SPEED (1 << 2)
#define HV_MUX_DATA_CTRL_GEN_TO_MAC (1 << 10)
+#define I218_ULP_CONFIG1 BME1000_REG(779, 16)
+#define I218_ULP_CONFIG1_START __BIT(0)
+#define I218_ULP_CONFIG1_IND __BIT(2)
+#define I218_ULP_CONFIG1_STICKY_ULP __BIT(4)
+#define I218_ULP_CONFIG1_INBAND_EXIT __BIT(5)
+#define I218_ULP_CONFIG1_WOL_HOST __BIT(6)
+#define I218_ULP_CONFIG1_RESET_TO_SMBUS __BIT(8)
+#define I218_ULP_CONFIG1_EN_ULP_LANPHYPC __BIT(10)
+#define I218_ULP_CONFIG1_DIS_CLR_STICKY_ON_PERST __BIT(11)
+#define I218_ULP_CONFIG1_DIS_SMB_PERST __BIT(12)
+
#define BM_WUC_PAGE 800
#define BM_WUC BME1000_REG(BM_WUC_PAGE, 1)
#define BM_WUC_ADDRESS_OPCODE 0x11
diff -r 36eb1296e965 -r 96202cf81b89 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Wed Nov 16 08:14:39 2016 +0000
+++ b/sys/dev/pci/if_wm.c Wed Nov 16 08:56:17 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.446 2016/11/16 08:14:39 msaitoh Exp $ */
+/* $NetBSD: if_wm.c,v 1.447 2016/11/16 08:56:17 msaitoh Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -84,7 +84,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.446 2016/11/16 08:14:39 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.447 2016/11/16 08:56:17 msaitoh Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -396,6 +396,7 @@
struct wm_phyop {
int (*acquire)(struct wm_softc *);
void (*release)(struct wm_softc *);
+ int reset_delay_us;
};
/*
@@ -637,6 +638,7 @@
static void wm_get_cfg_done(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 *);
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);
@@ -840,6 +842,7 @@
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 void wm_enable_phy_wakeup(struct wm_softc *);
static void wm_igp3_phy_powerdown_workaround_ich8lan(struct wm_softc *);
static void wm_enable_wakeup(struct wm_softc *);
@@ -862,6 +865,8 @@
static void wm_configure_k1_ich8lan(struct wm_softc *, int);
static void wm_reset_init_script_82575(struct wm_softc *);
static void wm_reset_mdicnfg_82580(struct wm_softc *);
+static bool wm_phy_is_accessible_pchlan(struct wm_softc *);
+static void wm_toggle_lanphypc_pch_lpt(struct wm_softc *);
static int wm_platform_pm_pch_lpt(struct wm_softc *, bool);
static void wm_pll_workaround_i210(struct wm_softc *);
@@ -1630,6 +1635,7 @@
/* Set default function pointers */
sc->phy.acquire = wm_get_null;
sc->phy.release = wm_put_null;
+ sc->phy.reset_delay_us = (sc->sc_type >= WM_T_82571) ? 100 : 10000;
if (sc->sc_type < WM_T_82543) {
if (sc->sc_rev < 2) {
@@ -3727,6 +3733,40 @@
return rv;
}
+/*
+ * wm_reset_phy:
+ *
+ * generic PHY reset function.
+ * Same as e1000_phy_hw_reset_generic()
+ */
+static void
+wm_reset_phy(struct wm_softc *sc)
+{
+ uint32_t reg;
+
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
+ if (wm_phy_resetisblocked(sc))
+ return;
+
+ sc->phy.acquire(sc);
+
+ reg = CSR_READ(sc, WMREG_CTRL);
+ CSR_WRITE(sc, WMREG_CTRL, reg | CTRL_PHY_RESET);
+ CSR_WRITE_FLUSH(sc);
+
+ delay(sc->phy.reset_delay_us);
+
+ CSR_WRITE(sc, WMREG_CTRL, reg);
+ CSR_WRITE_FLUSH(sc);
+
+ delay(150);
+
+ sc->phy.release(sc);
+
+ wm_get_cfg_done(sc);
+}
+
static void
wm_flush_desc_rings(struct wm_softc *sc)
{
@@ -11902,6 +11942,7 @@
wm_smbustopci(struct wm_softc *sc)
{
uint32_t fwsm, reg;
+ int rv = 0;
DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
device_xname(sc->sc_dev), __func__));
@@ -11909,46 +11950,82 @@
/* Gate automatic PHY configuration by hardware on non-managed 82579 */
wm_gate_hw_phy_config_ich8lan(sc, true);
+ /* Disable ULP */
+ wm_ulp_disable(sc);
+
/* Acquire PHY semaphore */
sc->phy.acquire(sc);
fwsm = CSR_READ(sc, WMREG_FWSM);
- if (((fwsm & FWSM_FW_VALID) == 0)
- && ((wm_phy_resetisblocked(sc) == false))) {
- if (sc->sc_type >= WM_T_PCH_LPT) {
- reg = CSR_READ(sc, WMREG_CTRL_EXT);
- reg |= CTRL_EXT_FORCE_SMBUS;
- CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
- CSR_WRITE_FLUSH(sc);
- delay(50*1000);
- }
-
- /* Toggle LANPHYPC */
- sc->sc_ctrl |= CTRL_LANPHYPC_OVERRIDE;
- sc->sc_ctrl &= ~CTRL_LANPHYPC_VALUE;
- CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
+ switch (sc->sc_type) {
+ case WM_T_PCH_LPT:
+ case WM_T_PCH_SPT:
+ if (wm_phy_is_accessible_pchlan(sc))
+ break;
+
+ reg = CSR_READ(sc, WMREG_CTRL_EXT);
+ reg |= CTRL_EXT_FORCE_SMBUS;
+ CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
+#if 0
+ /* XXX Isn't this required??? */
CSR_WRITE_FLUSH(sc);
- delay(1000);
- sc->sc_ctrl &= ~CTRL_LANPHYPC_OVERRIDE;
- CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
- CSR_WRITE_FLUSH(sc);
- delay(50*1000);
+#endif
+ delay(50 * 1000);
+ /* FALLTHROUGH */
+ case WM_T_PCH2:
+ if (wm_phy_is_accessible_pchlan(sc) == true)
+ break;
+ /* FALLTHROUGH */
+ case WM_T_PCH:
+ if ((sc->sc_type == WM_T_PCH))
+ if ((fwsm & FWSM_FW_VALID) != 0)
+ break;
+
+ if (wm_phy_resetisblocked(sc) == true) {
+ printf("XXX reset is blocked(3)\n");
+ break;
+ }
+
+ wm_toggle_lanphypc_pch_lpt(sc);
if (sc->sc_type >= WM_T_PCH_LPT) {
+ if (wm_phy_is_accessible_pchlan(sc) == true)
+ break;
+
reg = CSR_READ(sc, WMREG_CTRL_EXT);
reg &= ~CTRL_EXT_FORCE_SMBUS;
CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
- }
+
+ if (wm_phy_is_accessible_pchlan(sc) == true)
+ break;
+ rv = -1;
+ }
+ break;
+ default:
+ break;
}
/* Release semaphore */
sc->phy.release(sc);
+ if (rv == 0) {
+ if (wm_phy_resetisblocked(sc)) {
+ printf("XXX reset is blocked(4)\n");
+ goto out;
+ }
+ wm_reset_phy(sc);
+ if (wm_phy_resetisblocked(sc))
+ printf("XXX reset is blocked(4)\n");
+ }
+
+out:
/*
* Ungate automatic PHY configuration by hardware on non-managed 82579
*/
- if ((sc->sc_type == WM_T_PCH2) && ((fwsm & FWSM_FW_VALID) == 0))
+ if ((sc->sc_type == WM_T_PCH2) && ((fwsm & FWSM_FW_VALID) == 0)) {
+ delay(10*1000);
wm_gate_hw_phy_config_ich8lan(sc, false);
+ }
}
static void
@@ -12051,6 +12128,102 @@
*/
}
+/*
+ * Unconfigure Ultra Low Power mode.
+ * Only for I217 and newer (see below).
+ */
+static void
+wm_ulp_disable(struct wm_softc *sc)
+{
+ uint32_t reg;
+ int i = 0;
+
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
+ /* Exclude old devices */
+ if ((sc->sc_type < WM_T_PCH_LPT)
+ || (sc->sc_pcidevid == PCI_PRODUCT_INTEL_I217_LM)
+ || (sc->sc_pcidevid == PCI_PRODUCT_INTEL_I217_V)
+ || (sc->sc_pcidevid == PCI_PRODUCT_INTEL_I218_LM2)
+ || (sc->sc_pcidevid == PCI_PRODUCT_INTEL_I218_V2))
+ return;
+
+ if ((CSR_READ(sc, WMREG_FWSM) & FWSM_FW_VALID) != 0) {
+ /* Request ME un-configure ULP mode in the PHY */
+ reg = CSR_READ(sc, WMREG_H2ME);
+ reg &= ~H2ME_ULP;
+ reg |= H2ME_ENFORCE_SETTINGS;
+ CSR_WRITE(sc, WMREG_H2ME, reg);
+
+ /* Poll up to 300msec for ME to clear ULP_CFG_DONE. */
+ while ((CSR_READ(sc, WMREG_FWSM) & FWSM_ULP_CFG_DONE) != 0) {
+ if (i++ == 30) {
+ printf("%s timed out\n", __func__);
+ return;
+ }
+ delay(10 * 1000);
+ }
+ reg = CSR_READ(sc, WMREG_H2ME);
+ reg &= ~H2ME_ENFORCE_SETTINGS;
+ CSR_WRITE(sc, WMREG_H2ME, reg);
+
+ return;
+ }
+
+ /* Acquire semaphore */
+ sc->phy.acquire(sc);
Home |
Main Index |
Thread Index |
Old Index