Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-8]: src/sys/dev Pull up the following, requested by msaitoh in ti...



details:   https://anonhg.NetBSD.org/src/rev/5a61147c6510
branches:  netbsd-8
changeset: 445675:5a61147c6510
user:      martin <martin%NetBSD.org@localhost>
date:      Thu Nov 08 12:09:18 2018 +0000

description:
Pull up the following, requested by msaitoh in tickt #1085:

        sys/dev/mii/inbmphyreg.h                1.11
        sys/dev/pci/if_wmreg.h                  1.108
        sys/dev/pci/if_wm.c                     1.590-1.596 via patch

- 82574 and newer document says the status field has neither EC
  (Excessive Collision) bit nor LC (Late Collision) bit (reserved), so
  don't check the bit.
- Add workaround for DMA hang problem which result in TX device timeout
  on PCH_LPT with I218. Same as FreeBSD and Linux. This workaround is
  only for device ID 0x155a, 0x15a2, 0x1559 and 0x15a3.
- Fix a PCH2 specific bug that wrong PHY register value can be read
  when boot. Same as FreeBSD and Linux.
- After writing MDIC register, don't read quickly the same register but
  do delay(50). Same as other OSes.
- Add missing wm_gate_hw_phy_config_ich8lan(false) in
  wm_phy_post_reset() on PCH2. wm_gate_hw_phy_config_ich8lan(true) is
  called in wm_reset(), so wm_gate_hw_phy_config_ich8lan(false) should
  be called after reset in wm_phy_post_reset().
- On PCH2, set the phy config counter to 50msec after (PHY) reset.
- KNF & Use macro.

diffstat:

 sys/dev/mii/inbmphyreg.h |    6 +-
 sys/dev/pci/if_wm.c      |  212 +++++++++++++++++++++++++++++++++++++---------
 sys/dev/pci/if_wmreg.h   |    4 +-
 3 files changed, 175 insertions(+), 47 deletions(-)

diffs (truncated from 471 to 300 lines):

diff -r 54951e57099a -r 5a61147c6510 sys/dev/mii/inbmphyreg.h
--- a/sys/dev/mii/inbmphyreg.h  Thu Nov 08 12:04:48 2018 +0000
+++ b/sys/dev/mii/inbmphyreg.h  Thu Nov 08 12:09:18 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: inbmphyreg.h,v 1.9.8.1 2017/08/01 23:33:18 snj Exp $   */
+/*     $NetBSD: inbmphyreg.h,v 1.9.8.2 2018/11/08 12:09:18 martin Exp $        */
 /*******************************************************************************
 Copyright (c) 2001-2005, Intel Corporation 
 All rights reserved.
@@ -104,6 +104,10 @@
 #define        HV_PM_CTRL              BME1000_REG(770, 17)
 #define        HV_PM_CTRL_K1_ENA       __BIT(14)
 
+#define        I217_INBAND_CTRL        BME1000_REG(770, 18)
+#define        I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_MASK      0x3f00
+#define        I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT     8
+
 #define        IGP3_KMRN_DIAG          BME1000_REG(770, 19)
 #define        IGP3_KMRN_DIAG_PCS_LOCK_LOSS    (1 << 1)
 
diff -r 54951e57099a -r 5a61147c6510 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Thu Nov 08 12:04:48 2018 +0000
+++ b/sys/dev/pci/if_wm.c       Thu Nov 08 12:09:18 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wm.c,v 1.508.4.24 2018/10/30 09:25:13 sborrill Exp $        */
+/*     $NetBSD: if_wm.c,v 1.508.4.25 2018/11/08 12:09:18 martin 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.508.4.24 2018/10/30 09:25:13 sborrill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.508.4.25 2018/11/08 12:09:18 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -966,6 +966,7 @@
 static void    wm_gig_downshift_workaround_ich8lan(struct wm_softc *);
 static void    wm_hv_phy_workaround_ich8lan(struct wm_softc *);
 static void    wm_lv_phy_workaround_ich8lan(struct wm_softc *);
+static int     wm_k1_workaround_lpt_lp(struct wm_softc *, bool);
 static int     wm_k1_gig_workaround_hv(struct wm_softc *, int);
 static void    wm_set_mdio_slow_mode_hv(struct wm_softc *);
 static void    wm_configure_k1_ich8lan(struct wm_softc *, int);
@@ -1869,10 +1870,9 @@
                                        0, &sc->sc_iot, &sc->sc_ioh,
                                        NULL, &sc->sc_ios) == 0) {
                                sc->sc_flags |= WM_F_IOH_VALID;
-                       } else {
+                       } else
                                aprint_error_dev(sc->sc_dev,
                                    "WARNING: unable to map I/O space\n");
-                       }
                }
 
        }
@@ -3258,9 +3258,9 @@
 
                error = 0;
 
-               if (cmd == SIOCSIFCAP) {
+               if (cmd == SIOCSIFCAP)
                        error = (*ifp->if_init)(ifp);
-               } else if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI)
+               else if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI)
                        ;
                else if (ifp->if_flags & IFF_RUNNING) {
                        /*
@@ -3858,7 +3858,7 @@
        /* Perform any necessary post-reset workarounds */
        if (sc->sc_type == WM_T_PCH)
                wm_hv_phy_workaround_ich8lan(sc);
-       if (sc->sc_type == WM_T_PCH2)
+       else if (sc->sc_type == WM_T_PCH2)
                wm_lv_phy_workaround_ich8lan(sc);
 
        /* Clear the host wakeup bit after lcd reset */
@@ -3873,7 +3873,16 @@
        /* Configure the LCD with the extended configuration region in NVM */
        wm_init_lcd_from_nvm(sc);
 
-       /* Configure the LCD with the OEM bits in NVM */
+       /* XXX Configure the LCD with the OEM bits in NVM */
+
+       if (sc->sc_type == WM_T_PCH2) {
+               /* Ungate automatic PHY configuration on non-managed 82579 */
+               if ((CSR_READ(sc, WMREG_FWSM) & FWSM_FW_VALID) == 0) {
+                       delay(10 * 1000);
+                       wm_gate_hw_phy_config_ich8lan(sc, false);
+               }
+               /* XXX Set EEE LPI Update Timer to 200usec */   
+       }
 }
 
 /* Only for PCH and newer */
@@ -4510,9 +4519,8 @@
                if (sc->sc_type != WM_T_82574) {
                        CSR_WRITE(sc, WMREG_EIMC, 0xffffffffU);
                        CSR_WRITE(sc, WMREG_EIAC, 0);
-               } else {
+               } else
                        CSR_WRITE(sc, WMREG_EIAC_82574, 0);
-               }
        }
 
        /* Stop the transmit and receive processes. */
@@ -4651,6 +4659,14 @@
                break;
        }
 
+       /* Set Phy Config Counter to 50msec */
+       if (sc->sc_type == WM_T_PCH2) {
+               reg = CSR_READ(sc, WMREG_FEXTNVM3);
+               reg &= ~FEXTNVM3_PHY_CFG_COUNTER_MASK;
+               reg |= FEXTNVM3_PHY_CFG_COUNTER_50MS;
+               CSR_WRITE(sc, WMREG_FEXTNVM3, reg);
+       }
+       
        if (phy_reset != 0)
                wm_get_cfg_done(sc);
 
@@ -5867,9 +5883,9 @@
                        CSR_WRITE(sc, WMREG_RLPML, ETHER_MAX_LEN_JUMBO);
        }
 
-       if (MCLBYTES == 2048) {
+       if (MCLBYTES == 2048)
                sc->sc_rctl |= RCTL_2k;
-       } else {
+       else {
                if (sc->sc_type >= WM_T_82543) {
                        switch (MCLBYTES) {
                        case 4096:
@@ -5886,7 +5902,8 @@
                                    MCLBYTES);
                                break;
                        }
-               } else panic("wm_init: i82542 requires MCLBYTES = 2048");
+               } else
+                       panic("wm_init: i82542 requires MCLBYTES = 2048");
        }
 
        /* Enable ECC */
@@ -6926,9 +6943,9 @@
        if ((m0->m_pkthdr.csum_flags &
            (M_CSUM_TSOv4 | M_CSUM_UDPv4 | M_CSUM_TCPv4 | M_CSUM_IPv4)) != 0) {
                iphl = M_CSUM_DATA_IPv4_IPHL(m0->m_pkthdr.csum_data);
-       } else {
+       } else
                iphl = M_CSUM_DATA_IPv6_HL(m0->m_pkthdr.csum_data);
-       }
+
        ipcse = offset + iphl - 1;
 
        cmd = WTX_CMD_DEXT | WTX_DTYP_D;
@@ -7657,22 +7674,22 @@
        if (m0->m_pkthdr.csum_flags &
            (M_CSUM_UDPv4 | M_CSUM_TCPv4 | M_CSUM_TSOv4)) {
                WM_Q_EVCNT_INCR(txq, tusum);
-               if (m0->m_pkthdr.csum_flags & (M_CSUM_TCPv4 | M_CSUM_TSOv4)) {
+               if (m0->m_pkthdr.csum_flags & (M_CSUM_TCPv4 | M_CSUM_TSOv4))
                        cmdc |= NQTXC_CMD_TCP;
-               } else {
+               else
                        cmdc |= NQTXC_CMD_UDP;
-               }
+
                cmdc |= NQTXC_CMD_IP4;
                *fieldsp |= NQTXD_FIELDS_TUXSM;
        }
        if (m0->m_pkthdr.csum_flags &
            (M_CSUM_UDPv6 | M_CSUM_TCPv6 | M_CSUM_TSOv6)) {
                WM_Q_EVCNT_INCR(txq, tusum6);
-               if (m0->m_pkthdr.csum_flags & (M_CSUM_TCPv6 | M_CSUM_TSOv6)) {
+               if (m0->m_pkthdr.csum_flags & (M_CSUM_TCPv6 | M_CSUM_TSOv6))
                        cmdc |= NQTXC_CMD_TCP;
-               } else {
+               else
                        cmdc |= NQTXC_CMD_UDP;
-               }
+
                cmdc |= NQTXC_CMD_IP6;
                *fieldsp |= NQTXD_FIELDS_TUXSM;
        }
@@ -7970,9 +7987,9 @@
                                    htole32(WTX_CMD_VLE);
                                txq->txq_descs[nexttx].wtx_fields.wtxu_vlan =
                                    htole16(vlan_get_tag(m0));
-                       } else {
+                       } else
                                txq->txq_descs[nexttx].wtx_fields.wtxu_vlan =0;
-                       }
+
                        dcmdlen = 0;
                } else {
                        /* setup an advanced data descriptor */
@@ -8188,13 +8205,27 @@
                        WM_Q_EVCNT_INCR(txq, underrun);
 #endif /* WM_EVENT_COUNTERS */
 
-               if (status & (WTX_ST_EC | WTX_ST_LC)) {
+               /*
+                * 82574 and newer's document says the status field has neither
+                * EC (Excessive Collision) bit nor LC (Late Collision) bit
+                * (reserved). Refer "PCIe GbE Controller Open Source Software
+                * Developer's Manual", 82574 datasheet and newer.
+                *
+                * XXX I saw the LC bit was set on I218 even though the media
+                * was full duplex, so the bit might be used for other
+                * meaning ...(I have no document).
+                */
+
+               if (((status & (WTX_ST_EC | WTX_ST_LC)) != 0)
+                   && ((sc->sc_type < WM_T_82574)
+                       || (sc->sc_type == WM_T_80003))) {
                        ifp->if_oerrors++;
                        if (status & WTX_ST_LC)
                                log(LOG_WARNING, "%s: late collision\n",
                                    device_xname(sc->sc_dev));
                        else if (status & WTX_ST_EC) {
-                               ifp->if_collisions += 16;
+                               ifp->if_collisions +=
+                                   TX_COLLISION_THRESHOLD + 1;
                                log(LOG_WARNING, "%s: excessive collisions\n",
                                    device_xname(sc->sc_dev));
                        }
@@ -8657,10 +8688,12 @@
                __func__));
 
        if (icr & ICR_LSC) {
+               uint32_t status = CSR_READ(sc, WMREG_STATUS);
                uint32_t reg;
-               uint32_t status = CSR_READ(sc, WMREG_STATUS);
-
-               if ((status & STATUS_LU) != 0) {
+               bool link;
+
+               link = status & STATUS_LU;
+               if (link) {
                        DPRINTF(WM_DEBUG_LINK, ("%s: LINK: LSC -> up %s\n",
                                device_xname(sc->sc_dev),
                                (status & STATUS_FD) ? "FDX" : "HDX"));
@@ -8668,7 +8701,7 @@
                        DPRINTF(WM_DEBUG_LINK, ("%s: LINK: LSC -> down\n",
                                device_xname(sc->sc_dev)));
                }
-               if ((sc->sc_type == WM_T_ICH8) && ((status & STATUS_LU) == 0))
+               if ((sc->sc_type == WM_T_ICH8) && (link == false))
                        wm_gig_downshift_workaround_ich8lan(sc);
 
                if ((sc->sc_type == WM_T_ICH8)
@@ -8748,8 +8781,12 @@
                        CSR_WRITE(sc, WMREG_FEXTNVM4, reg);
                }
 
-               /* XXX Work-around I218 hang issue */
-               /* e1000_k1_workaround_lpt_lp() */
+               /* Work-around I218 hang issue */
+               if ((sc->sc_pcidevid == PCI_PRODUCT_INTEL_I218_LM) ||
+                   (sc->sc_pcidevid == PCI_PRODUCT_INTEL_I218_V) ||
+                   (sc->sc_pcidevid == PCI_PRODUCT_INTEL_I218_LM3) ||
+                   (sc->sc_pcidevid == PCI_PRODUCT_INTEL_I218_V3))
+                       wm_k1_workaround_lpt_lp(sc, link);
 
                if (sc->sc_type >= WM_T_PCH_LPT) {
                        /*
@@ -9807,10 +9844,9 @@
                                CSR_WRITE(sc, WMREG_CTRL_EXT, ctrl_ext);
                        }
                }
-       } else {
+       } else
                mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
                    MII_OFFSET_ANY, MIIF_DOPAUSE);
-       }
 
        /*
         * If the MAC is PCH2 or PCH_LPT and failed to detect MII PHY, call
@@ -10066,28 +10102,35 @@
            MDIC_REGADD(reg));
 
        for (i = 0; i < WM_GEN_POLL_TIMEOUT * 3; i++) {
+               delay(50);
                mdic = CSR_READ(sc, WMREG_MDIC);
                if (mdic & MDIC_READY)
                        break;
-               delay(50);
        }
 
        if ((mdic & MDIC_READY) == 0) {
                log(LOG_WARNING, "%s: MDIC read timed out: phy %d reg %d\n",
                    device_xname(dev), phy, reg);
-               rv = 0;
+               return 0;
        } else if (mdic & MDIC_E) {
 #if 0 /* This is normal if no PHY is present. */
                log(LOG_WARNING, "%s: MDIC read error: phy %d reg %d\n",
                    device_xname(dev), phy, reg);



Home | Main Index | Thread Index | Old Index