Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Add three workarounds for PCH_{LPT, SPT}.
details: https://anonhg.NetBSD.org/src/rev/10614c324ffd
branches: trunk
changeset: 348928:10614c324ffd
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Wed Nov 16 07:24:52 2016 +0000
description:
Add three workarounds for PCH_{LPT,SPT}.
diffstat:
sys/dev/pci/if_wm.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++-
sys/dev/pci/if_wmreg.h | 32 ++++++++++-
2 files changed, 153 insertions(+), 7 deletions(-)
diffs (258 lines):
diff -r 5f37971afa33 -r 10614c324ffd sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Wed Nov 16 07:13:01 2016 +0000
+++ b/sys/dev/pci/if_wm.c Wed Nov 16 07:24:52 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.444 2016/11/14 05:38:39 msaitoh Exp $ */
+/* $NetBSD: if_wm.c,v 1.445 2016/11/16 07:24:52 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.444 2016/11/14 05:38:39 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.445 2016/11/16 07:24:52 msaitoh Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -862,6 +862,7 @@
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 int wm_platform_pm_pch_lpt(struct wm_softc *, bool);
static void wm_pll_workaround_i210(struct wm_softc *);
CFATTACH_DECL3_NEW(wm, sizeof(struct wm_softc),
@@ -7507,6 +7508,7 @@
__func__));
if (icr & ICR_LSC) {
+ uint32_t reg;
uint32_t status = CSR_READ(sc, WMREG_STATUS);
if ((sc->sc_type == WM_T_ICH8) && ((status & STATUS_LU) == 0))
@@ -7575,6 +7577,44 @@
HV_MUX_DATA_CTRL_GEN_TO_MAC);
}
}
+ /*
+ * I217 Packet Loss issue:
+ * ensure that FEXTNVM4 Beacon Duration is set correctly
+ * on power up.
+ * Set the Beacon Duration for I217 to 8 usec
+ */
+ if ((sc->sc_type == WM_T_PCH_LPT)
+ || (sc->sc_type == WM_T_PCH_SPT)) {
+ reg = CSR_READ(sc, WMREG_FEXTNVM4);
+ reg &= ~FEXTNVM4_BEACON_DURATION;
+ reg |= FEXTNVM4_BEACON_DURATION_8US;
+ CSR_WRITE(sc, WMREG_FEXTNVM4, reg);
+ }
+
+ /* XXX Work-around I218 hang issue */
+ /* e1000_k1_workaround_lpt_lp() */
+
+ if ((sc->sc_type == WM_T_PCH_LPT)
+ || (sc->sc_type == WM_T_PCH_SPT)) {
+ /*
+ * Set platform power management values for Latency
+ * Tolerance Reporting (LTR)
+ */
+ wm_platform_pm_pch_lpt(sc,
+ ((sc->sc_mii.mii_media_status & IFM_ACTIVE)
+ != 0));
+ }
+
+ /* FEXTNVM6 K1-off workaround */
+ if (sc->sc_type == WM_T_PCH_SPT) {
+ reg = CSR_READ(sc, WMREG_FEXTNVM6);
+ if (CSR_READ(sc, WMREG_PCIEANACFG)
+ & FEXTNVM6_K1_OFF_ENABLE)
+ reg |= FEXTNVM6_K1_OFF_ENABLE;
+ else
+ reg &= ~FEXTNVM6_K1_OFF_ENABLE;
+ CSR_WRITE(sc, WMREG_FEXTNVM6, reg);
+ }
} else if (icr & ICR_RXSEQ) {
DPRINTF(WM_DEBUG_LINK, ("%s: LINK Receive sequence error\n",
device_xname(sc->sc_dev)));
@@ -12525,6 +12565,90 @@
CSR_WRITE(sc, WMREG_MDICNFG, reg);
}
+static int
+wm_platform_pm_pch_lpt(struct wm_softc *sc, bool link)
+{
+ uint32_t reg = __SHIFTIN(link, LTRV_NONSNOOP_REQ)
+ | __SHIFTIN(link, LTRV_SNOOP_REQ) | LTRV_SEND;
+ uint32_t rxa;
+ uint16_t scale = 0, lat_enc = 0;
+ int64_t lat_ns, value;
+
+ DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
+
+ if (link) {
+ pcireg_t preg;
+ uint16_t max_snoop, max_nosnoop, max_ltr_enc;
+
+ rxa = CSR_READ(sc, WMREG_PBA) & PBA_RXA_MASK;
+
+ /*
+ * Determine the maximum latency tolerated by the device.
+ *
+ * Per the PCIe spec, the tolerated latencies are encoded as
+ * a 3-bit encoded scale (only 0-5 are valid) multiplied by
+ * a 10-bit value (0-1023) to provide a range from 1 ns to
+ * 2^25*(2^10-1) ns. The scale is encoded as 0=2^0ns,
+ * 1=2^5ns, 2=2^10ns,...5=2^25ns.
+ */
+ lat_ns = ((int64_t)rxa * 1024 -
+ (2 * (int64_t)sc->sc_ethercom.ec_if.if_mtu)) * 8 * 1000;
+ if (lat_ns < 0)
+ lat_ns = 0;
+ else {
+ uint32_t status;
+ uint16_t speed;
+
+ status = CSR_READ(sc, WMREG_STATUS);
+ switch (__SHIFTOUT(status, STATUS_SPEED)) {
+ case STATUS_SPEED_10:
+ speed = 10;
+ break;
+ case STATUS_SPEED_100:
+ speed = 100;
+ break;
+ case STATUS_SPEED_1000:
+ speed = 1000;
+ break;
+ default:
+ printf("%s: Unknown speed (status = %08x)\n",
+ device_xname(sc->sc_dev), status);
+ return -1;
+ }
+ lat_ns /= speed;
+ }
+ value = lat_ns;
+
+ while (value > LTRV_VALUE) {
+ scale ++;
+ value = howmany(value, __BIT(5));
+ }
+ if (scale > LTRV_SCALE_MAX) {
+ printf("%s: Invalid LTR latency scale %d\n",
+ device_xname(sc->sc_dev), scale);
+ return -1;
+ }
+ lat_enc = (uint16_t)(__SHIFTIN(scale, LTRV_SCALE) | value);
+
+ preg = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
+ WM_PCI_LTR_CAP_LPT);
+ max_snoop = preg & 0xffff;
+ max_nosnoop = preg >> 16;
+
+ max_ltr_enc = MAX(max_snoop, max_nosnoop);
+
+ if (lat_enc > max_ltr_enc) {
+ lat_enc = max_ltr_enc;
+ }
+ }
+ /* Snoop and No-Snoop latencies the same */
+ reg |= lat_enc | __SHIFTIN(lat_enc, LTRV_NONSNOOP);
+ CSR_WRITE(sc, WMREG_LTRV, reg);
+
+ return 0;
+}
+
/*
* I210 Errata 25 and I211 Errata 10
* Slow System Clock.
diff -r 5f37971afa33 -r 10614c324ffd sys/dev/pci/if_wmreg.h
--- a/sys/dev/pci/if_wmreg.h Wed Nov 16 07:13:01 2016 +0000
+++ b/sys/dev/pci/if_wmreg.h Wed Nov 16 07:24:52 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wmreg.h,v 1.91 2016/11/14 08:48:03 msaitoh Exp $ */
+/* $NetBSD: if_wmreg.h,v 1.92 2016/11/16 07:24:52 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -202,6 +202,8 @@
/* registers for FLASH access on ICH8 */
#define WM_ICH8_FLASH 0x0014
+#define WM_PCI_LTR_CAP_LPT 0xa8
+
/* XXX Only for PCH_SPT? */
#define WM_PCI_DESCRING_STATUS 0xe4
#define DESCRING_STATUS_FLUSH_REQ __BIT(8)
@@ -255,10 +257,10 @@
#define STATUS_FUNCID_MASK 3 /* ... */
#define STATUS_TXOFF (1U << 4) /* Tx paused */
#define STATUS_TBIMODE (1U << 5) /* fiber mode (Livengood) */
-#define STATUS_SPEED(x) ((x) << 6) /* speed indication */
-#define STATUS_SPEED_10 STATUS_SPEED(0)
-#define STATUS_SPEED_100 STATUS_SPEED(1)
-#define STATUS_SPEED_1000 STATUS_SPEED(2)
+#define STATUS_SPEED __BITS(7, 6) /* speed indication */
+#define STATUS_SPEED_10 0
+#define STATUS_SPEED_100 1
+#define STATUS_SPEED_1000 2
#define STATUS_ASDV(x) ((x) << 8) /* auto speed det. val. (Livengood) */
#define STATUS_LAN_INIT_DONE (1U << 9) /* Lan Init Completion by NVM */
#define STATUS_MTXCKOK (1U << 10) /* MTXD clock running */
@@ -308,6 +310,9 @@
#define EERD_ADDR_SHIFT 2 /* Shift to the address bits */
#define EERD_DATA_SHIFT 16 /* Offset to data in EEPROM read/write registers */
+#define WMREG_FEXTNVM6 0x0010 /* Future Extended NVM 6 */
+#define FEXTNVM6_K1_OFF_ENABLE __BIT(31)
+
#define WMREG_CTRL_EXT 0x0018 /* Extended Device Control Register */
#define CTRL_EXT_NSICR __BIT(0) /* Non Interrupt clear on read */
#define CTRL_EXT_GPI_EN(x) (1U << (x)) /* gpin interrupt enable */
@@ -368,6 +373,11 @@
#define SCTL_CTL_POLL_TIMEOUT 640
#define SCTL_DISABLE_SERDES_LOOPBACK 0x0400
+#define WMREG_FEXTNVM4 0x0024 /* Future Extended NVM 4 - RW */
+#define FEXTNVM4_BEACON_DURATION __BITS(2, 0)
+#define FEXTNVM4_BEACON_DURATION_8US 0x7
+#define FEXTNVM4_BEACON_DURATION_16US 0x3
+
#define WMREG_FCAL 0x0028 /* Flow Control Address Low */
#define FCAL_CONST 0x00c28001 /* Flow Control MAC addr low */
@@ -493,6 +503,15 @@
#define IVAR_MISC_TCPTIMER __BITS(0, 7)
#define IVAR_MISC_OTHER __BITS(8, 15)
+#define WMREG_LTRV 0x00f8 /* Latency Tolerance Reporting */
+#define LTRV_VALUE __BITS(9, 0)
+#define LTRV_SCALE __BITS(12, 10)
+#define LTRV_SCALE_MAX 5
+#define LTRV_SNOOP_REQ __BIT(15)
+#define LTRV_SEND __BIT(30)
+#define LTRV_NONSNOOP __BITS(31, 16)
+#define LTRV_NONSNOOP_REQ __BIT(31)
+
#define WMREG_RCTL 0x0100 /* Receive Control */
#define RCTL_EN (1U << 1) /* receiver enable */
#define RCTL_SBP (1U << 2) /* store bad packets */
@@ -728,6 +747,8 @@
#define PHY_CTRL_NOND0A_GBE_DIS (1 << 3)
#define PHY_CTRL_GBE_DIS (1 << 6)
+#define WMREG_PCIEANACFG 0x0f18 /* PCIE Analog Config */
+
#define WMREG_IOSFPC 0x0f28 /* Tx corrupted data */
#define WMREG_PBA 0x1000 /* Packet Buffer Allocation */
@@ -749,6 +770,7 @@
#define PBA_40K 0x0028
#define PBA_48K 0x0030 /* 48K, default Rx allocation */
#define PBA_64K 0x0040
+#define PBA_RXA_MASK __BITS(15, 0)
#define WMREG_PBS 0x1008 /* Packet Buffer Size (ICH) */
Home |
Main Index |
Thread Index |
Old Index