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 some missing fixes to alc(4) to sync with th...



details:   https://anonhg.NetBSD.org/src/rev/73110ea4fd60
branches:  trunk
changeset: 340489:73110ea4fd60
user:      leot <leot%NetBSD.org@localhost>
date:      Tue Sep 08 08:24:42 2015 +0000

description:
Add some missing fixes to alc(4) to sync with the latest FreeBSD and OpenBSD
alc(4)s.

Fix a long standing bug in MAC statistics register access. One
additional register was erroneously added in the MAC register set
such that 7 TX statistics counters were wrong. (from OpenBSD, if_alc.c 1.29)

Remove setting an initial assumed baudrate upon driver attach which is not
necessarily correct, there might not even be a link when attaching.
(from OpenBSD, if_alc.c 1.22)

Add some missing bus_dmamap_sync()'s and sync the others with
the FreeBSD code. (from OpenBSD, if_alc.c 1.21)

Help with the watchdog timeouts seen when unplugging the cable from
the alc(4) NIC while running or the NIC not working if the cable is
not plugged in upon boot up. (from OpenBSD, if_alc.c 1.16)

ok mrg@

diffstat:

 sys/dev/pci/if_alc.c    |  64 ++++++++++++++++++++++++++++--------------------
 sys/dev/pci/if_alcreg.h |   4 +--
 2 files changed, 38 insertions(+), 30 deletions(-)

diffs (234 lines):

diff -r 5d22f670da5b -r 73110ea4fd60 sys/dev/pci/if_alc.c
--- a/sys/dev/pci/if_alc.c      Tue Sep 08 05:48:07 2015 +0000
+++ b/sys/dev/pci/if_alc.c      Tue Sep 08 08:24:42 2015 +0000
@@ -527,6 +527,9 @@
        struct alc_softc *sc = ifp->if_softc;
        struct mii_data *mii = &sc->sc_miibus;
 
+       if ((ifp->if_flags & IFF_UP) == 0)
+               return;
+
        mii_pollstat(mii);
        ifmr->ifm_status = mii->mii_media_status;
        ifmr->ifm_active = mii->mii_media_active;
@@ -1405,7 +1408,6 @@
        ifp->if_start = alc_start;
        ifp->if_stop = alc_stop;
        ifp->if_watchdog = alc_watchdog;
-       ifp->if_baudrate = IF_Gbps(1);
        IFQ_SET_MAXLEN(&ifp->if_snd, ALC_TX_RING_CNT - 1);
        IFQ_SET_READY(&ifp->if_snd);
        strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
@@ -1959,6 +1961,10 @@
 
        if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
                return;
+       if ((sc->alc_flags & ALC_FLAG_LINK) == 0)
+               return;
+       if (IFQ_IS_EMPTY(&ifp->if_snd))
+               return;
 
        /* Reclaim transmitted frames. */
        if (sc->alc_cdata.alc_tx_cnt >= ALC_TX_DESC_HIWAT)
@@ -2021,9 +2027,7 @@
        printf("%s: watchdog timeout\n", device_xname(sc->sc_dev));
        ifp->if_oerrors++;
        alc_init_backend(ifp, false);
-
-       if (!IFQ_IS_EMPTY(&ifp->if_snd))
-                alc_start(ifp);
+       alc_start(ifp);
 }
 
 static int
@@ -2089,13 +2093,13 @@
        if ((sc->alc_flags & ALC_FLAG_SMB_BUG) == 0) {
                bus_dmamap_sync(sc->sc_dmat, sc->alc_cdata.alc_smb_map, 0,
                    sc->alc_cdata.alc_smb_map->dm_mapsize,
-                   BUS_DMASYNC_POSTREAD);
+                   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
                smb = sc->alc_rdata.alc_smb;
                /* Update done, clear. */
                smb->updated = 0;
                bus_dmamap_sync(sc->sc_dmat, sc->alc_cdata.alc_smb_map, 0,
                    sc->alc_cdata.alc_smb_map->dm_mapsize,
-                   BUS_DMASYNC_PREWRITE);
+                   BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
        } else {
                for (reg = &sb.rx_frames, i = 0; reg <= &sb.rx_pkts_filtered;
                    reg++) {
@@ -2124,7 +2128,7 @@
        if ((sc->alc_flags & ALC_FLAG_SMB_BUG) == 0) {
                bus_dmamap_sync(sc->sc_dmat, sc->alc_cdata.alc_smb_map, 0,
                    sc->alc_cdata.alc_smb_map->dm_mapsize,
-                   BUS_DMASYNC_POSTREAD);
+                   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
                smb = sc->alc_rdata.alc_smb;
                if (smb->updated == 0)
                        return;
@@ -2190,7 +2194,6 @@
        stat->tx_multi_colls += smb->tx_multi_colls;
        stat->tx_late_colls += smb->tx_late_colls;
        stat->tx_excess_colls += smb->tx_excess_colls;
-       stat->tx_abort += smb->tx_abort;
        stat->tx_underrun += smb->tx_underrun;
        stat->tx_desc_underrun += smb->tx_desc_underrun;
        stat->tx_lenerrs += smb->tx_lenerrs;
@@ -2203,17 +2206,10 @@
 
        ifp->if_collisions += smb->tx_single_colls +
            smb->tx_multi_colls * 2 + smb->tx_late_colls +
-           smb->tx_abort * HDPX_CFG_RETRY_DEFAULT;
-
-       /*
-        * XXX
-        * tx_pkts_truncated counter looks suspicious. It constantly
-        * increments with no sign of Tx errors. This may indicate
-        * the counter name is not correct one so I've removed the
-        * counter in output errors.
-        */
-       ifp->if_oerrors += smb->tx_abort + smb->tx_late_colls +
-           smb->tx_underrun;
+           smb->tx_excess_colls * HDPX_CFG_RETRY_DEFAULT;
+
+       ifp->if_oerrors += smb->tx_late_colls + smb->tx_excess_colls +
+           smb->tx_underrun + smb->tx_pkts_truncated;
 
        ifp->if_ipackets += smb->rx_frames;
 
@@ -2226,7 +2222,8 @@
                /* Update done, clear. */
                smb->updated = 0;
                bus_dmamap_sync(sc->sc_dmat, sc->alc_cdata.alc_smb_map, 0,
-               sc->alc_cdata.alc_smb_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
+               sc->alc_cdata.alc_smb_map->dm_mapsize,
+               BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
        }
 }
 
@@ -2318,6 +2315,8 @@
                txd = &sc->alc_cdata.alc_txdesc[cons];
                if (txd->tx_m != NULL) {
                        /* Reclaim transmitted mbufs. */
+                       bus_dmamap_sync(sc->sc_dmat, txd->tx_dmamap, 0,
+                           txd->tx_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                        bus_dmamap_unload(sc->sc_dmat, txd->tx_dmamap);
                        m_freem(txd->tx_m);
                        txd->tx_m = NULL;
@@ -2326,7 +2325,7 @@
 
        if ((sc->alc_flags & ALC_FLAG_CMB_BUG) == 0)
            bus_dmamap_sync(sc->sc_dmat, sc->alc_cdata.alc_cmb_map, 0,
-               sc->alc_cdata.alc_cmb_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
+               sc->alc_cdata.alc_cmb_map->dm_mapsize, BUS_DMASYNC_PREREAD);
        sc->alc_cdata.alc_tx_cons = cons;
        /*
         * Unarm watchdog timer only when there is no pending
@@ -2381,6 +2380,8 @@
        map = rxd->rx_dmamap;
        rxd->rx_dmamap = sc->alc_cdata.alc_rx_sparemap;
        sc->alc_cdata.alc_rx_sparemap = map;
+       bus_dmamap_sync(sc->sc_dmat, rxd->rx_dmamap, 0, rxd->rx_dmamap->dm_mapsize,
+           BUS_DMASYNC_PREREAD);
        rxd->rx_m = m;
        rxd->rx_desc->addr = htole64(rxd->rx_dmamap->dm_segs[0].ds_addr);
        return (0);
@@ -2395,9 +2396,11 @@
        int rr_cons, prog;
 
        bus_dmamap_sync(sc->sc_dmat, sc->alc_cdata.alc_rr_ring_map, 0,
-           sc->alc_cdata.alc_rr_ring_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
+           sc->alc_cdata.alc_rr_ring_map->dm_mapsize,
+           BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
        bus_dmamap_sync(sc->sc_dmat, sc->alc_cdata.alc_rx_ring_map, 0,
-           sc->alc_cdata.alc_rx_ring_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
+           sc->alc_cdata.alc_rx_ring_map->dm_mapsize,
+           BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
        rr_cons = sc->alc_cdata.alc_rr_cons;
        for (prog = 0; (ifp->if_flags & IFF_RUNNING) != 0;) {
                rrd = &sc->alc_rdata.alc_rr_ring[rr_cons];
@@ -2427,7 +2430,7 @@
                /* Sync Rx return descriptors. */
                bus_dmamap_sync(sc->sc_dmat, sc->alc_cdata.alc_rr_ring_map, 0,
                    sc->alc_cdata.alc_rr_ring_map->dm_mapsize,
-                   BUS_DMASYNC_PREWRITE);
+                   BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
                /*
                 * Sync updated Rx descriptors such that controller see
                 * modified buffer addresses.
@@ -3153,6 +3156,8 @@
        for (i = 0; i < ALC_RX_RING_CNT; i++) {
                rxd = &sc->alc_cdata.alc_rxdesc[i];
                if (rxd->rx_m != NULL) {
+                       bus_dmamap_sync(sc->sc_dmat, rxd->rx_dmamap, 0,
+                           rxd->rx_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
                        bus_dmamap_unload(sc->sc_dmat, rxd->rx_dmamap);
                        m_freem(rxd->rx_m);
                        rxd->rx_m = NULL;
@@ -3161,6 +3166,8 @@
        for (i = 0; i < ALC_TX_RING_CNT; i++) {
                txd = &sc->alc_cdata.alc_txdesc[i];
                if (txd->tx_m != NULL) {
+                       bus_dmamap_sync(sc->sc_dmat, txd->tx_dmamap, 0,
+                           txd->tx_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                        bus_dmamap_unload(sc->sc_dmat, txd->tx_dmamap);
                        m_freem(txd->tx_m);
                        txd->tx_m = NULL;
@@ -3319,7 +3326,8 @@
        rd = &sc->alc_rdata;
        memset(rd->alc_rr_ring, 0, ALC_RR_RING_SZ);
        bus_dmamap_sync(sc->sc_dmat, sc->alc_cdata.alc_rr_ring_map, 0,
-           sc->alc_cdata.alc_rr_ring_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
+           sc->alc_cdata.alc_rr_ring_map->dm_mapsize,
+           BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 }
 
 static void
@@ -3330,7 +3338,8 @@
        rd = &sc->alc_rdata;
        memset(rd->alc_cmb, 0, ALC_CMB_SZ);
        bus_dmamap_sync(sc->sc_dmat, sc->alc_cdata.alc_cmb_map, 0,
-           sc->alc_cdata.alc_cmb_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
+           sc->alc_cdata.alc_cmb_map->dm_mapsize,
+           BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 }
 
 static void
@@ -3341,7 +3350,8 @@
        rd = &sc->alc_rdata;
        memset(rd->alc_smb, 0, ALC_SMB_SZ);
        bus_dmamap_sync(sc->sc_dmat, sc->alc_cdata.alc_smb_map, 0,
-           sc->alc_cdata.alc_smb_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
+           sc->alc_cdata.alc_smb_map->dm_mapsize,
+           BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 }
 
 static void
diff -r 5d22f670da5b -r 73110ea4fd60 sys/dev/pci/if_alcreg.h
--- a/sys/dev/pci/if_alcreg.h   Tue Sep 08 05:48:07 2015 +0000
+++ b/sys/dev/pci/if_alcreg.h   Tue Sep 08 08:24:42 2015 +0000
@@ -200,7 +200,7 @@
  * alc(4) does not rely on Tx completion interrupts, so set it
  * somewhat large value to reduce Tx completion interrupts.
  */
-#define        ALC_IM_TX_TIMER_DEFAULT         50000   /* 50ms */
+#define        ALC_IM_TX_TIMER_DEFAULT         1000    /* 1ms */
 
 #define        ALC_GPHY_CFG                    0x140C  /* 16 bits, 32 bits on AR816x */
 #define        GPHY_CFG_EXT_RESET              0x0001
@@ -1147,7 +1147,6 @@
        uint32_t tx_multi_colls;
        uint32_t tx_late_colls;
        uint32_t tx_excess_colls;
-       uint32_t tx_abort;
        uint32_t tx_underrun;
        uint32_t tx_desc_underrun;
        uint32_t tx_lenerrs;
@@ -1421,7 +1420,6 @@
        uint32_t tx_multi_colls;
        uint32_t tx_late_colls;
        uint32_t tx_excess_colls;
-       uint32_t tx_abort;
        uint32_t tx_underrun;
        uint32_t tx_desc_underrun;
        uint32_t tx_lenerrs;



Home | Main Index | Thread Index | Old Index