Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Add some workarounds which use EMI register or EEE r...
details: https://anonhg.NetBSD.org/src/rev/5bd077b9622f
branches: trunk
changeset: 996397:5bd077b9622f
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Thu Jan 31 05:20:49 2019 +0000
description:
Add some workarounds which use EMI register or EEE related:
- PCH only: Add workaround for link disconnects on a busy hub in half duplex.
- PCH and PCH2 only: Set MSE higher to enable link to stay up when noise is
high.
- PCH2 only: Drop link after 5 times MSE threshold was reached.
- PCH2 only: Set EEE LPI Update Timer to 200usec.
- For PCH2 and newer: When connected at 10Mbps half-duplex, some parts are
excessively aggressive resulting in many collisions. To avoid this, increase
the IPG and reduce Rx latency in the PHY.
- For I21[789] and if EEE is enabled: Disable LPLU if both link partners
support 100BaseT EEE and 100Full is advertised on both ends of the link, and
enable Auto Enable LPI since there will be no driver to enable LPI while in
Sx.
diffstat:
sys/dev/mii/inbmphyreg.h | 16 ++-
sys/dev/pci/if_wm.c | 235 ++++++++++++++++++++++++++++++++++++++++++----
sys/dev/pci/if_wmreg.h | 5 +-
3 files changed, 228 insertions(+), 28 deletions(-)
diffs (truncated from 475 to 300 lines):
diff -r 569436b2ba62 -r 5bd077b9622f sys/dev/mii/inbmphyreg.h
--- a/sys/dev/mii/inbmphyreg.h Thu Jan 31 03:25:29 2019 +0000
+++ b/sys/dev/mii/inbmphyreg.h Thu Jan 31 05:20:49 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: inbmphyreg.h,v 1.16 2019/01/07 01:43:22 msaitoh Exp $ */
+/* $NetBSD: inbmphyreg.h,v 1.17 2019/01/31 05:20:49 msaitoh Exp $ */
/*******************************************************************************
Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
@@ -81,15 +81,21 @@
/* Extended Management Interface (EMI) Registers */
#define I82579_EMI_ADDR 0x10
#define I82579_EMI_DATA 0x11
+#define I82579_LPI_UPDATE_TIMER 0x4805 /* in 40ns units + 40 ns base value */
+#define I82579_MSE_THRESHOLD 0x084F /* 82579 Mean Square Error Threshold */
+#define I82577_MSE_THRESHOLD 0x0887 /* 82577 Mean Square Error Threshold */
+#define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */
#define I82579_EEE_ADVERTISEMENT 0x040e /* IEEE MMD Register 7.60 */
#define I82579_EEE_LP_ABILITY 0x040f /* IEEE MMD Register 7.61 */
#define I82579_EEE_PCS_STATUS 0x182e
+#define I82579_RX_CONFIG 0x3412 /* Receive configuration */
#define I82579_LPI_PLL_SHUT 0x4412
-#define I82579_LPI_PLL_SHUT_100 __BIT(2) /* 100M LPI PLL Shut Enable */
+#define I82579_LPI_PLL_SHUT_100 __BIT(2) /* 100M LPI PLL Shut Enable */
#define I217_EEE_PCS_STATUS 0x9401 /* IEEE MMD Register 3.1 */
#define I217_EEE_CAPABILITY 0x8000 /* IEEE MMD Register 3.20 */
#define I217_EEE_ADVERTISEMENT 0x8001 /* IEEE MMD Register 7.60 */
#define I217_EEE_LP_ABILITY 0x8002 /* IEEE MMD Register 7.61 */
+#define I217_RX_CONFIG 0xb20c /* Receive configuration */
/* BM PHY Copper Specific Status */
#define BM_CS_STATUS BME1000_REG(0, 17)
@@ -134,6 +140,7 @@
#define CV_SMB_CTRL_FORCE_SMBUS __BIT(0)
#define HV_PM_CTRL BME1000_REG(770, 17)
+#define HV_PM_CTRL_K1_CLK_REQ __BIT(9)
#define HV_PM_CTRL_K1_ENA __BIT(14)
#define I217_INBAND_CTRL BME1000_REG(770, 18)
@@ -154,6 +161,9 @@
#define I217_MEMPWR BME1000_REG(772, 26)
#define I217_MEMPWR_DISABLE_SMB_RELEASE 0x0010
+#define I217_PLL_CLOCK_GATE_REG BME1000_REG(772, 28)
+#define I217_PLL_CLOCK_GATE_MASK 0x07FF
+
#define I217_CFGREG BME1000_REG(772, 29)
#define I217_CGFREG_ENABLE_MTA_RESET 0x0002
@@ -161,6 +171,8 @@
#define HV_MUX_DATA_CTRL_FORCE_SPEED (1 << 2)
#define HV_MUX_DATA_CTRL_GEN_TO_MAC (1 << 10)
+#define I219_UNKNOWN1 BME1000_REG(776, 20)
+
#define I218_ULP_CONFIG1 BME1000_REG(779, 16)
#define I218_ULP_CONFIG1_START __BIT(0)
#define I218_ULP_CONFIG1_IND __BIT(2)
diff -r 569436b2ba62 -r 5bd077b9622f sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Thu Jan 31 03:25:29 2019 +0000
+++ b/sys/dev/pci/if_wm.c Thu Jan 31 05:20:49 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.620 2019/01/25 08:04:07 msaitoh Exp $ */
+/* $NetBSD: if_wm.c,v 1.621 2019/01/31 05:20:49 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.620 2019/01/25 08:04:07 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.621 2019/01/31 05:20:49 msaitoh Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -4008,6 +4008,7 @@
int
wm_phy_post_reset(struct wm_softc *sc)
{
+ device_t dev = sc->sc_dev;
uint16_t reg;
int rv = 0;
@@ -4017,7 +4018,7 @@
if (wm_phy_resetisblocked(sc)) {
/* XXX */
- device_printf(sc->sc_dev, "PHY is blocked\n");
+ device_printf(dev, "PHY is blocked\n");
return -1;
}
@@ -4034,9 +4035,9 @@
/* Clear the host wakeup bit after lcd reset */
if (sc->sc_type >= WM_T_PCH) {
- wm_gmii_hv_readreg(sc->sc_dev, 2, BM_PORT_GEN_CFG, ®);
+ wm_gmii_hv_readreg(dev, 2, BM_PORT_GEN_CFG, ®);
reg &= ~BM_WUC_HOST_WU_BIT;
- wm_gmii_hv_writereg(sc->sc_dev, 2, BM_PORT_GEN_CFG, reg);
+ wm_gmii_hv_writereg(dev, 2, BM_PORT_GEN_CFG, reg);
}
/* Configure the LCD with the extended configuration region in NVM */
@@ -4052,7 +4053,13 @@
delay(10 * 1000);
wm_gate_hw_phy_config_ich8lan(sc, false);
}
- /* XXX Set EEE LPI Update Timer to 200usec */
+ /* Set EEE LPI Update Timer to 200usec */
+ rv = sc->phy.acquire(sc);
+ if (rv)
+ return rv;
+ rv = wm_write_emi_reg_locked(dev,
+ I82579_LPI_UPDATE_TIMER, 0x1387);
+ sc->phy.release(sc);
}
return rv;
@@ -8953,19 +8960,21 @@
static void
wm_linkintr_gmii(struct wm_softc *sc, uint32_t icr)
{
+ device_t dev = sc->sc_dev;
uint32_t status, reg;
bool link;
+ int rv;
KASSERT(WM_CORE_LOCKED(sc));
- DPRINTF(WM_DEBUG_LINK, ("%s: %s:\n", device_xname(sc->sc_dev),
+ DPRINTF(WM_DEBUG_LINK, ("%s: %s:\n", device_xname(dev),
__func__));
if ((icr & ICR_LSC) == 0) {
if (icr & ICR_RXSEQ)
DPRINTF(WM_DEBUG_LINK,
("%s: LINK Receive sequence error\n",
- device_xname(sc->sc_dev)));
+ device_xname(dev)));
return;
}
@@ -8974,11 +8983,11 @@
link = status & STATUS_LU;
if (link)
DPRINTF(WM_DEBUG_LINK, ("%s: LINK: LSC -> up %s\n",
- device_xname(sc->sc_dev),
+ device_xname(dev),
(status & STATUS_FD) ? "FDX" : "HDX"));
else
DPRINTF(WM_DEBUG_LINK, ("%s: LINK: LSC -> down\n",
- device_xname(sc->sc_dev)));
+ device_xname(dev)));
if ((sc->sc_type == WM_T_ICH8) && (link == false))
wm_gig_downshift_workaround_ich8lan(sc);
@@ -8987,7 +8996,7 @@
wm_kmrn_lock_loss_workaround_ich8lan(sc);
}
DPRINTF(WM_DEBUG_LINK, ("%s: LINK: LSC -> mii_pollstat\n",
- device_xname(sc->sc_dev)));
+ device_xname(dev)));
mii_pollstat(&sc->sc_mii);
if (sc->sc_type == WM_T_82543) {
int miistatus, active;
@@ -9030,6 +9039,117 @@
}
/*
+ * When connected at 10Mbps half-duplex, some parts are excessively
+ * aggressive resulting in many collisions. To avoid this, increase
+ * the IPG and reduce Rx latency in the PHY.
+ */
+ if ((sc->sc_type >= WM_T_PCH2) && (sc->sc_type <= WM_T_PCH_CNP)
+ && link) {
+ uint32_t tipg_reg;
+ uint32_t speed = __SHIFTOUT(status, STATUS_SPEED);
+ bool fdx;
+ uint16_t emi_addr, emi_val;
+
+ tipg_reg = CSR_READ(sc, WMREG_TIPG);
+ tipg_reg &= ~TIPG_IPGT_MASK;
+ fdx = status & STATUS_FD;
+
+ if (!fdx && (speed == STATUS_SPEED_10)) {
+ tipg_reg |= 0xff;
+ /* Reduce Rx latency in analog PHY */
+ emi_val = 0;
+ } else if ((sc->sc_type >= WM_T_PCH_SPT) &&
+ fdx && speed != STATUS_SPEED_1000) {
+ tipg_reg |= 0xc;
+ emi_val = 1;
+ } else {
+ /* Roll back the default values */
+ tipg_reg |= 0x08;
+ emi_val = 1;
+ }
+
+ CSR_WRITE(sc, WMREG_TIPG, tipg_reg);
+
+ rv = sc->phy.acquire(sc);
+ if (rv)
+ return;
+
+ if (sc->sc_type == WM_T_PCH2)
+ emi_addr = I82579_RX_CONFIG;
+ else
+ emi_addr = I217_RX_CONFIG;
+ rv = wm_write_emi_reg_locked(dev, emi_addr, emi_val);
+
+ if (sc->sc_type >= WM_T_PCH_LPT) {
+ uint16_t phy_reg;
+
+ sc->phy.readreg_locked(dev, 2,
+ I217_PLL_CLOCK_GATE_REG, &phy_reg);
+ phy_reg &= ~I217_PLL_CLOCK_GATE_MASK;
+ if (speed == STATUS_SPEED_100
+ || speed == STATUS_SPEED_10)
+ phy_reg |= 0x3e8;
+ else
+ phy_reg |= 0xfa;
+ sc->phy.writereg_locked(dev, 2,
+ I217_PLL_CLOCK_GATE_REG, phy_reg);
+
+ if (speed == STATUS_SPEED_1000) {
+ sc->phy.readreg_locked(dev, 2,
+ HV_PM_CTRL, &phy_reg);
+
+ phy_reg |= HV_PM_CTRL_K1_CLK_REQ;
+
+ sc->phy.writereg_locked(dev, 2,
+ HV_PM_CTRL, phy_reg);
+ }
+ }
+ sc->phy.release(sc);
+
+ if (rv)
+ return;
+
+ if (sc->sc_type >= WM_T_PCH_SPT) {
+ uint16_t data, ptr_gap;
+
+ if (speed == STATUS_SPEED_1000) {
+ rv = sc->phy.acquire(sc);
+ if (rv)
+ return;
+
+ rv = sc->phy.readreg_locked(dev, 2,
+ I219_UNKNOWN1, &data);
+ if (rv) {
+ sc->phy.release(sc);
+ return;
+ }
+
+ ptr_gap = (data & (0x3ff << 2)) >> 2;
+ if (ptr_gap < 0x18) {
+ data &= ~(0x3ff << 2);
+ data |= (0x18 << 2);
+ rv = sc->phy.writereg_locked(dev,
+ 2, I219_UNKNOWN1, data);
+ }
+ sc->phy.release(sc);
+ if (rv)
+ return;
+ } else {
+ rv = sc->phy.acquire(sc);
+ if (rv)
+ return;
+
+ rv = sc->phy.writereg_locked(dev, 2,
+ I219_UNKNOWN1, 0xc023);
+ sc->phy.release(sc);
+ if (rv)
+ return;
+
+ }
+ }
+ }
+
+ /*
* I217 Packet Loss issue:
* ensure that FEXTNVM4 Beacon Duration is set correctly
* on power up.
@@ -14695,11 +14815,16 @@
static void
wm_suspend_workarounds_ich8lan(struct wm_softc *sc)
{
+ device_t dev = sc->sc_dev;
+ struct ethercom *ec = &sc->sc_ethercom;
uint32_t phy_ctrl;
+ int rv;
phy_ctrl = CSR_READ(sc, WMREG_PHY_CTRL);
phy_ctrl |= PHY_CTRL_GBE_DIS;
+ KASSERT((sc->sc_type >= WM_T_ICH8) && (sc->sc_type <= WM_T_PCH_CNP));
+
Home |
Main Index |
Thread Index |
Old Index