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