Source-Changes-HG archive

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

[src/netbsd-7]: src/sys/dev Pull up the following revisions(s) (requested by ...



details:   https://anonhg.NetBSD.org/src/rev/7fc6776c48b5
branches:  netbsd-7
changeset: 445692:7fc6776c48b5
user:      sborrill <sborrill%NetBSD.org@localhost>
date:      Fri Nov 09 11:28:39 2018 +0000

description:
Pull up the following revisions(s) (requested by msaitoh in ticket #1648):
        sys/dev/mii/inbmphyreg.h                1.11
        sys/dev/pci/if_wm.c                     1.586-1.588, 1.590-1.596 via patch
        sys/dev/pci/if_wmreg.h                  1.108

- rename tu event counter to txunderrun.
- Try m_defrag() to reduce the number of DMA segment if bus_dmamap_load_mbuf()
   returned EFBIG. When m_defrag() is called, txqNNdefrag event counter is
   incremented. If the 2nd try of bus_dmamap_load_mbuf() failed, txqNNtoomanyseg
   event counter is incremented.
- Reduce the max number of DMA segments from 256 to 64 (it's the same value
   as other BSD's (EM_MAX_SCATTER) and more than before if_wm.c rev. 1.75's
   value (40)) because we do m_defrag() now.
- 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      |  264 +++++++++++++++++++++++++++++++++++++---------
 sys/dev/pci/if_wmreg.h   |    4 +-
 3 files changed, 217 insertions(+), 57 deletions(-)

diffs (truncated from 566 to 300 lines):

diff -r 8f7cce92029b -r 7fc6776c48b5 sys/dev/mii/inbmphyreg.h
--- a/sys/dev/mii/inbmphyreg.h  Tue Oct 30 19:54:56 2018 +0000
+++ b/sys/dev/mii/inbmphyreg.h  Fri Nov 09 11:28:39 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: inbmphyreg.h,v 1.3.30.2 2018/08/11 13:34:21 martin Exp $       */
+/*     $NetBSD: inbmphyreg.h,v 1.3.30.3 2018/11/09 11:28:39 sborrill 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 8f7cce92029b -r 7fc6776c48b5 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Tue Oct 30 19:54:56 2018 +0000
+++ b/sys/dev/pci/if_wm.c       Fri Nov 09 11:28:39 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wm.c,v 1.289.2.16 2018/10/30 08:35:56 sborrill Exp $        */
+/*     $NetBSD: if_wm.c,v 1.289.2.17 2018/11/09 11:28:39 sborrill 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.289.2.16 2018/10/30 08:35:56 sborrill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.289.2.17 2018/11/09 11:28:39 sborrill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -163,11 +163,12 @@
  * of packets, and we go ahead and manage up to 64 (16 for the i82547)
  * of them at a time.
  *
- * We allow up to 256 (!) DMA segments per packet.  Pathological packet
+ * We allow up to 64 (!) DMA segments per packet.  Pathological packet
  * chains containing many small mbufs have been observed in zero-copy
- * situations with jumbo frames.
- */
-#define        WM_NTXSEGS              256
+ * situations with jumbo frames. If a mbuf chain has more than 64 DMA segments,
+ * m_defrag() is called to reduce it.
+ */
+#define        WM_NTXSEGS              64
 #define        WM_IFQUEUELEN           256
 #define        WM_TXQUEUELEN_MAX       64
 #define        WM_TXQUEUELEN_MAX_82547 16
@@ -366,9 +367,10 @@
        struct evcnt sc_ev_txtsopain;   /* painful header manip. for TSO */
 
        struct evcnt sc_ev_txseg[WM_NTXSEGS]; /* Tx packets w/ N segments */
-       struct evcnt sc_ev_txdrop;      /* Tx packets dropped(too many segs) */
-
-       struct evcnt sc_ev_tu;          /* Tx underrun */
+       struct evcnt sc_ev_txdrop;      /* Tx packets dropped(other than txtoomanysegs) */
+       struct evcnt sc_ev_txtoomanysegs; /* Tx packets dropped(too many segs) */
+       struct evcnt sc_ev_txdefrag;    /* Tx m_defrag() */
+       struct evcnt sc_ev_txunderrun;  /* Tx underrun */
 
        struct evcnt sc_ev_tx_xoff;     /* Tx PAUSE(!0) frames */
        struct evcnt sc_ev_tx_xon;      /* Tx PAUSE(0) frames */
@@ -808,6 +810,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);
@@ -1617,10 +1620,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");
-                       }
                }
 
        }
@@ -2637,9 +2639,12 @@
 
        evcnt_attach_dynamic(&sc->sc_ev_txdrop, EVCNT_TYPE_MISC,
            NULL, xname, "txdrop");
-
-       evcnt_attach_dynamic(&sc->sc_ev_tu, EVCNT_TYPE_MISC,
-           NULL, xname, "tu");
+       evcnt_attach_dynamic(&sc->sc_ev_txtoomanysegs, EVCNT_TYPE_MISC,
+           NULL, xname, "txtoomanysegs");
+       evcnt_attach_dynamic(&sc->sc_ev_txdefrag, EVCNT_TYPE_MISC,
+           NULL, xname, "txdefrag");
+       evcnt_attach_dynamic(&sc->sc_ev_txunderrun, EVCNT_TYPE_MISC,
+           NULL, xname, "txunderrun");
 
        evcnt_attach_dynamic(&sc->sc_ev_tx_xoff, EVCNT_TYPE_MISC,
            NULL, xname, "tx_xoff");
@@ -3632,7 +3637,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 */
@@ -3647,7 +3652,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 */
@@ -4403,6 +4417,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);
 
@@ -5031,9 +5053,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:
@@ -5050,7 +5072,8 @@
                                    MCLBYTES);
                                break;
                        }
-               } else panic("wm_init: i82542 requires MCLBYTES = 2048");
+               } else
+                       panic("wm_init: i82542 requires MCLBYTES = 2048");
        }
 
        /* Enable ECC */
@@ -5232,9 +5255,9 @@
        if ((m0->m_pkthdr.csum_flags &
            (M_CSUM_TSOv4 | M_CSUM_UDPv4 | M_CSUM_TCPv4)) != 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;
@@ -5526,6 +5549,7 @@
        bus_size_t seglen, curlen;
        uint32_t cksumcmd;
        uint8_t cksumfields;
+       bool remap = true;
 
        KASSERT(WM_TX_LOCKED(sc));
 
@@ -5592,11 +5616,23 @@
                 * since we can't sanely copy a jumbo packet to a single
                 * buffer.
                 */
+retry:
                error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
                    BUS_DMA_WRITE | BUS_DMA_NOWAIT);
-               if (error) {
+               if (__predict_false(error)) {
                        if (error == EFBIG) {
-                               WM_EVCNT_INCR(&sc->sc_ev_txdrop);
+                               if (remap == true) {
+                                       struct mbuf *m;
+
+                                       remap = false;
+                                       m = m_defrag(m0, M_NOWAIT);
+                                       if (m != NULL) {
+                                               WM_EVCNT_INCR(&sc->sc_ev_txdefrag);
+                                               m0 = m;
+                                               goto retry;
+                                       }
+                               }
+                               WM_EVCNT_INCR(&sc->sc_ev_txtoomanysegs);
                                log(LOG_ERR, "%s: Tx packet consumes too many "
                                    "DMA segments, dropping...\n",
                                    device_xname(sc->sc_dev));
@@ -5973,22 +6009,22 @@
        if (m0->m_pkthdr.csum_flags &
            (M_CSUM_UDPv4 | M_CSUM_TCPv4 | M_CSUM_TSOv4)) {
                WM_EVCNT_INCR(&sc->sc_ev_txtusum);
-               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_EVCNT_INCR(&sc->sc_ev_txtusum6);
-               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;
        }
@@ -6037,6 +6073,7 @@
        bus_dmamap_t dmamap;
        int error, nexttx, lasttx = -1, seg, segs_needed;
        bool do_csum, sent;
+       bool remap = true;
 
        KASSERT(WM_TX_LOCKED(sc));
 
@@ -6085,11 +6122,23 @@
                 * since we can't sanely copy a jumbo packet to a single
                 * buffer.
                 */
+retry:
                error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
                    BUS_DMA_WRITE | BUS_DMA_NOWAIT);
                if (error) {
                        if (error == EFBIG) {
-                               WM_EVCNT_INCR(&sc->sc_ev_txdrop);
+                               if (remap == true) {
+                                       struct mbuf *m;
+
+                                       remap = false;
+                                       m = m_defrag(m0, M_NOWAIT);
+                                       if (m != NULL) {
+                                               WM_EVCNT_INCR(&sc->sc_ev_txdefrag);
+                                               m0 = m;
+                                               goto retry;
+                                       }
+                               }
+                               WM_EVCNT_INCR(&sc->sc_ev_txtoomanysegs);
                                log(LOG_ERR, "%s: Tx packet consumes too many "
                                    "DMA segments, dropping...\n",
                                    device_xname(sc->sc_dev));
@@ -6190,9 +6239,9 @@
                                    htole32(WTX_CMD_VLE);
                                sc->sc_txdescs[nexttx].wtx_fields.wtxu_vlan =
                                    htole16(VLAN_TAG_VALUE(mtag) & 0xffff);
-                       } else {
+                       } else
                                sc->sc_txdescs[nexttx].wtx_fields.wtxu_vlan =0;
-                       }
+
                        dcmdlen = 0;
                } else {
                        /* setup an advanced data descriptor */
@@ -6354,16 +6403,30 @@
 
 #ifdef WM_EVENT_COUNTERS
                if (status & WTX_ST_TU)
-                       WM_EVCNT_INCR(&sc->sc_ev_tu);
+                       WM_EVCNT_INCR(&sc->sc_ev_txunderrun);
 #endif /* WM_EVENT_COUNTERS */
 
-               if (status & (WTX_ST_EC | WTX_ST_LC)) {
+               /*
+                * 82574 and newer's document says the status field has neither



Home | Main Index | Thread Index | Old Index