Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci sync OpenBSD if_msk.c revs 1.66-1.79 skipping fr...



details:   https://anonhg.NetBSD.org/src/rev/7600d67fc7d5
branches:  trunk
changeset: 324398:7600d67fc7d5
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Mon Jul 02 06:03:13 2018 +0000

description:
sync OpenBSD if_msk.c revs 1.66-1.79 skipping framework changes and already
present changes:
- Make Yukon-2 FE+ (88E8040, 88E8042) work
- 88E8057 is a Yukon 2 Ultra 2, and this might make it work on a little
  shiny green box in Japan
- Prevent null pointer dereference that could happen when we process an RX
  interrupt that was queued while stopping the interface.
- Remove holdover XMAC II writes/reads inherited from sk as
  they aren't required and cause problems like the 88E8072
  hard locking a system when enabling macsec bypass.
- Bypass macsec on extreme/supreme based chips.
  Makes my 88E8072 work.
- Add detach support to a few more drivers, and in others do the neccessary
  operations in the detach function in the right order.

towards resolution of PR kern/53301 but will need more work

tested by John Halfpenny on another 8040/Yukon-2 FE+ and reported
improving behaviour (system hang to stall) so committing as stopgap; also
tested on my SK-9E22 (Yukon-2 XL), there works without any issues both before
and after

diffstat:

 sys/dev/pci/if_msk.c    |  303 ++++++++++++++++++++++++-----------------------
 sys/dev/pci/if_mskvar.h |    4 +-
 2 files changed, 154 insertions(+), 153 deletions(-)

diffs (truncated from 633 to 300 lines):

diff -r 7522ddc7059e -r 7600d67fc7d5 sys/dev/pci/if_msk.c
--- a/sys/dev/pci/if_msk.c      Mon Jul 02 03:52:32 2018 +0000
+++ b/sys/dev/pci/if_msk.c      Mon Jul 02 06:03:13 2018 +0000
@@ -1,5 +1,5 @@
-/* $NetBSD: if_msk.c,v 1.67 2018/06/26 06:48:01 msaitoh Exp $ */
-/*     $OpenBSD: if_msk.c,v 1.65 2008/09/10 14:01:22 blambert Exp $ */
+/* $NetBSD: if_msk.c,v 1.68 2018/07/02 06:03:13 jdolecek Exp $ */
+/*     $OpenBSD: if_msk.c,v 1.79 2009/10/15 17:54:56 deraadt Exp $     */
 
 /*
  * Copyright (c) 1997, 1998, 1999, 2000
@@ -52,7 +52,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_msk.c,v 1.67 2018/06/26 06:48:01 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_msk.c,v 1.68 2018/07/02 06:03:13 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -106,7 +106,7 @@
 int msk_intr(void *);
 void msk_intr_yukon(struct sk_if_softc *);
 void msk_rxeof(struct sk_if_softc *, u_int16_t, u_int32_t);
-void msk_txeof(struct sk_if_softc *, int);
+void msk_txeof(struct sk_if_softc *);
 int msk_encap(struct sk_if_softc *, struct mbuf *, u_int32_t *);
 void msk_start(struct ifnet *);
 int msk_ioctl(struct ifnet *, u_long, void *);
@@ -114,12 +114,13 @@
 void msk_init_yukon(struct sk_if_softc *);
 void msk_stop(struct ifnet *, int);
 void msk_watchdog(struct ifnet *);
-int msk_newbuf(struct sk_if_softc *, int, struct mbuf *, bus_dmamap_t);
+int msk_newbuf(struct sk_if_softc *, struct mbuf *, bus_dmamap_t);
 int msk_alloc_jumbo_mem(struct sk_if_softc *);
 void *msk_jalloc(struct sk_if_softc *);
 void msk_jfree(struct mbuf *, void *, size_t, void *);
 int msk_init_rx_ring(struct sk_if_softc *);
 int msk_init_tx_ring(struct sk_if_softc *);
+void msk_fill_rx_ring(struct sk_if_softc *);
 
 void msk_update_int_mod(struct sk_softc *, int);
 
@@ -419,17 +420,11 @@
                cd->sk_rx_chain[i].sk_next = &cd->sk_rx_chain[nexti];
        }
 
-       for (i = 0; i < MSK_RX_RING_CNT; i++) {
-               if (msk_newbuf(sc_if, i, NULL,
-                   sc_if->sk_cdata.sk_rx_jumbo_map) == ENOBUFS) {
-                       aprint_error_dev(sc_if->sk_dev, "failed alloc of %dth mbuf\n", i);
-                       return (ENOBUFS);
-               }
-       }
-
-       sc_if->sk_cdata.sk_rx_prod = MSK_RX_RING_CNT - 1;
+       sc_if->sk_cdata.sk_rx_prod = 0;
        sc_if->sk_cdata.sk_rx_cons = 0;
-
+       sc_if->sk_cdata.sk_rx_cnt = 0;
+
+       msk_fill_rx_ring(sc_if);
        return (0);
 }
 
@@ -478,7 +473,7 @@
 }
 
 int
-msk_newbuf(struct sk_if_softc *sc_if, int i, struct mbuf *m,
+msk_newbuf(struct sk_if_softc *sc_if, struct mbuf *m,
          bus_dmamap_t dmamap)
 {
        struct mbuf             *m_new = NULL;
@@ -516,7 +511,7 @@
        }
        m_adj(m_new, ETHER_ALIGN);
 
-       c = &sc_if->sk_cdata.sk_rx_chain[i];
+       c = &sc_if->sk_cdata.sk_rx_chain[sc_if->sk_cdata.sk_rx_prod];
        r = c->sk_le;
        c->sk_mbuf = m_new;
        r->sk_addr = htole32(dmamap->dm_segs[0].ds_addr +
@@ -526,7 +521,11 @@
        r->sk_ctl = 0;
        r->sk_opcode = SK_Y2_RXOPC_PACKET | SK_Y2_RXOPC_OWN;
 
-       MSK_CDRXSYNC(sc_if, i, BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
+       MSK_CDRXSYNC(sc_if, sc_if->sk_cdata.sk_rx_prod,
+           BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
+
+       SK_INC(sc_if->sk_cdata.sk_rx_prod, MSK_RX_RING_CNT);
+       sc_if->sk_cdata.sk_rx_cnt++;
 
        return (0);
 }
@@ -765,6 +764,9 @@
        case SK_YUKON_FE:
                imtimer_ticks = SK_IMTIMER_TICKS_YUKON_FE;
                break;
+       case SK_YUKON_FE_P:
+               imtimer_ticks = SK_IMTIMER_TICKS_YUKON_FE_P;
+               break;
        case SK_YUKON_XL:
                imtimer_ticks = SK_IMTIMER_TICKS_YUKON_XL;
                break;
@@ -1121,16 +1123,24 @@
        sc_if->sk_rdata = (struct msk_ring_data *)kva;
        memset(sc_if->sk_rdata, 0, sizeof(struct msk_ring_data));
 
-       ifp = &sc_if->sk_ethercom.ec_if;
+       if (sc->sk_type != SK_YUKON_FE &&
+           sc->sk_type != SK_YUKON_FE_P)
+               sc_if->sk_pktlen = SK_JLEN;
+       else
+               sc_if->sk_pktlen = MCLBYTES;
+
        /* Try to allocate memory for jumbo buffers. */
        if (msk_alloc_jumbo_mem(sc_if)) {
                aprint_error(": jumbo buffer allocation failed\n");
                goto fail_3;
        }
+
        sc_if->sk_ethercom.ec_capabilities = ETHERCAP_VLAN_MTU;
-       if (sc->sk_type != SK_YUKON_FE)
+       if (sc->sk_type != SK_YUKON_FE &&
+           sc->sk_type != SK_YUKON_FE_P)
                sc_if->sk_ethercom.ec_capabilities |= ETHERCAP_JUMBO_MTU;
 
+       ifp = &sc_if->sk_ethercom.ec_if;
        ifp->if_softc = sc_if;
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
        ifp->if_ioctl = msk_ioctl;
@@ -1215,6 +1225,8 @@
        if (sc->sk_if[sc_if->sk_port] == NULL)
                return (0);
 
+       msk_stop(ifp, 0);
+
        rnd_detach_source(&sc->rnd_source);
 
        callout_halt(&sc_if->sk_tick_ch, NULL);
@@ -1232,11 +1244,11 @@
        ether_ifdetach(ifp);
        if_detach(ifp);
 
-       bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map);
        bus_dmamem_unmap(sc->sc_dmatag, sc_if->sk_rdata,
            sizeof(struct msk_ring_data));
        bus_dmamem_free(sc->sc_dmatag,
            &sc_if->sk_ring_seg, sc_if->sk_ring_nseg);
+       bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map);
        sc->sk_if[sc_if->sk_port] = NULL;
 
        return (0);
@@ -1354,7 +1366,8 @@
        sc->sk_pc = pc;
 
        if (bus_dmamem_alloc(sc->sc_dmatag,
-           MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc), PAGE_SIZE,
+           MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
+           MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
            0, &sc->sk_status_seg, 1, &sc->sk_status_nseg, BUS_DMA_NOWAIT)) {
                aprint_error(": can't alloc status buffers\n");
                goto fail_2;
@@ -1632,10 +1645,8 @@
 
        return;
 
- fail_6:
+fail_6:
        bus_dmamap_unload(sc->sc_dmatag, sc->sk_status_map);
-fail_5:
-       bus_dmamap_destroy(sc->sc_dmatag, sc->sk_status_map);
 fail_4:
        bus_dmamem_unmap(sc->sc_dmatag, kva,
            MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
@@ -1643,6 +1654,8 @@
        bus_dmamem_free(sc->sc_dmatag,
            &sc->sk_status_seg, sc->sk_status_nseg);
        sc->sk_status_nseg = 0;
+fail_5:
+       bus_dmamap_destroy(sc->sc_dmatag, sc->sk_status_map);
 fail_2:
        pci_intr_disestablish(pc, sc->sk_intrhand);
        sc->sk_intrhand = NULL;
@@ -1657,6 +1670,9 @@
        struct sk_softc *sc = (struct sk_softc *)self;
        int rv;
 
+       if (sc->sk_intrhand)
+               pci_intr_disestablish(sc->sk_pc, sc->sk_intrhand);
+
        rv = config_detach_children(self, flags);
        if (rv != 0)
                return (rv);
@@ -1669,9 +1685,6 @@
                    &sc->sk_status_seg, sc->sk_status_nseg);
        }
 
-       if (sc->sk_intrhand)
-               pci_intr_disestablish(sc->sk_pc, sc->sk_intrhand);
-
        if (sc->sk_bsize > 0)
                bus_space_unmap(sc->sk_btag, sc->sk_bhandle, sc->sk_bsize);
 
@@ -1828,31 +1841,21 @@
 msk_watchdog(struct ifnet *ifp)
 {
        struct sk_if_softc *sc_if = ifp->if_softc;
-       u_int32_t reg;
-       int idx;
 
        /*
         * Reclaim first as there is a possibility of losing Tx completion
         * interrupts.
         */
-       if (sc_if->sk_port == SK_PORT_A)
-               reg = SK_STAT_BMU_TXA1_RIDX;
-       else
-               reg = SK_STAT_BMU_TXA2_RIDX;
-
-       idx = sk_win_read_2(sc_if->sk_softc, reg);
-       if (sc_if->sk_cdata.sk_tx_cons != idx) {
-               msk_txeof(sc_if, idx);
-               if (sc_if->sk_cdata.sk_tx_cnt != 0) {
-                       aprint_error_dev(sc_if->sk_dev, "watchdog timeout\n");
-
-                       ifp->if_oerrors++;
-
-                       /* XXX Resets both ports; we shouldn't do that. */
-                       mskc_reset(sc_if->sk_softc);
-                       msk_reset(sc_if);
-                       msk_init(ifp);
-               }
+       msk_txeof(sc_if);
+       if (sc_if->sk_cdata.sk_tx_cnt != 0) {
+               aprint_error_dev(sc_if->sk_dev, "watchdog timeout\n");
+
+               ifp->if_oerrors++;
+
+               /* XXX Resets both ports; we shouldn't do that. */
+               mskc_reset(sc_if->sk_softc);
+               msk_reset(sc_if);
+               msk_init(ifp);
        }
 }
 
@@ -1908,8 +1911,6 @@
        DPRINTFN(2, ("msk_rxeof\n"));
 
        cur = sc_if->sk_cdata.sk_rx_cons;
-       SK_INC(sc_if->sk_cdata.sk_rx_cons, MSK_RX_RING_CNT);
-       SK_INC(sc_if->sk_cdata.sk_rx_prod, MSK_RX_RING_CNT);
 
        /* Sync the descriptor */
        MSK_CDRXSYNC(sc_if, cur, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
@@ -1919,6 +1920,9 @@
                return;
 
        dmamap = sc_if->sk_cdata.sk_rx_jumbo_map;
+       SK_INC(sc_if->sk_cdata.sk_rx_cons, MSK_RX_RING_CNT);
+       sc_if->sk_cdata.sk_rx_cnt--;
+
        bus_dmamap_sync(sc_if->sk_softc->sc_dmatag, dmamap, 0,
            dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
 
@@ -1929,7 +1933,7 @@
            total_len > ETHER_MAX_LEN_JUMBO ||
            msk_rxvalid(sc, rxstat, total_len) == 0) {
                ifp->if_ierrors++;
-               msk_newbuf(sc_if, cur, m, dmamap);
+               msk_newbuf(sc_if, m, dmamap);
                return;
        }
 
@@ -1939,11 +1943,11 @@
         * so it can be re-used. If allocating mbufs fails, then we
         * have to drop the packet.
         */
-       if (msk_newbuf(sc_if, cur, NULL, dmamap) == ENOBUFS) {
+       if (msk_newbuf(sc_if, NULL, dmamap) == ENOBUFS) {
                struct mbuf             *m0;
                m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
                    total_len + ETHER_ALIGN, 0, ifp, NULL);
-               msk_newbuf(sc_if, cur, m, dmamap);
+               msk_newbuf(sc_if, m, dmamap);
                if (m0 == NULL) {
                        ifp->if_ierrors++;
                        return;
@@ -1960,41 +1964,43 @@
 }
 
 void
-msk_txeof(struct sk_if_softc *sc_if, int idx)
+msk_txeof(struct sk_if_softc *sc_if)
 {
        struct sk_softc         *sc = sc_if->sk_softc;
        struct msk_tx_desc      *cur_tx;



Home | Main Index | Thread Index | Old Index