Source-Changes-HG archive

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

[src/nick-nhusb]: src/sys/dev/usb WIP MPification



details:   https://anonhg.NetBSD.org/src/rev/531dd2e21dd5
branches:  nick-nhusb
changeset: 334646:531dd2e21dd5
user:      skrll <skrll%NetBSD.org@localhost>
date:      Sat Apr 15 14:38:44 2017 +0000

description:
WIP MPification

diffstat:

 sys/dev/usb/if_smsc.c    |  226 +++++++++++++++++++++++++++++++---------------
 sys/dev/usb/if_smscvar.h |    4 +-
 2 files changed, 155 insertions(+), 75 deletions(-)

diffs (truncated from 534 to 300 lines):

diff -r 27b202b85b1c -r 531dd2e21dd5 sys/dev/usb/if_smsc.c
--- a/sys/dev/usb/if_smsc.c     Tue Feb 14 06:45:21 2017 +0000
+++ b/sys/dev/usb/if_smsc.c     Sat Apr 15 14:38:44 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_smsc.c,v 1.22.2.35 2017/02/06 10:20:01 skrll Exp $  */
+/*     $NetBSD: if_smsc.c,v 1.22.2.36 2017/04/15 14:38:44 skrll Exp $  */
 
 /*     $OpenBSD: if_smsc.c,v 1.4 2012/09/27 12:38:11 jsg Exp $ */
 /*     $FreeBSD: src/sys/dev/usb/net/if_smsc.c,v 1.1 2012/08/15 04:03:55 gonzo Exp $ */
@@ -172,6 +172,7 @@
 void            smsc_tick(void *);
 void            smsc_tick_task(void *);
 void            smsc_miibus_statchg(struct ifnet *);
+void            smsc_miibus_statchg_locked(struct ifnet *);
 int             smsc_miibus_readreg(device_t, int, int);
 void            smsc_miibus_writereg(device_t, int, int, int);
 int             smsc_ifmedia_upd(struct ifnet *);
@@ -312,14 +313,37 @@
 void
 smsc_miibus_statchg(struct ifnet *ifp)
 {
+       if (ifp == NULL)
+               return;
+
+       struct smsc_softc * const sc = ifp->if_softc;
+
+       mutex_enter(&sc->sc_lock);
+       if (sc->sc_dying) {
+               mutex_exit(&sc->sc_lock);
+               return;
+       }
+       smsc_miibus_statchg_locked(ifp);
+
+       mutex_exit(&sc->sc_lock);
+}
+
+
+void
+smsc_miibus_statchg_locked(struct ifnet *ifp)
+{
        struct smsc_softc * const sc = ifp->if_softc;
        struct mii_data * const mii = &sc->sc_mii;
        int err;
        uint32_t flow;
        uint32_t afc_cfg;
 
-       if ((ifp->if_flags & IFF_RUNNING) == 0)
+       KASSERT(mutex_owned(&sc->sc_lock));
+
+       if ((ifp->if_flags & IFF_RUNNING) == 0) {
+               smsc_dbg_printf(sc, "%s: not running\n", __func__);
                return;
+       }
 
        /* Use the MII status to determine link status */
        sc->sc_flags &= ~SMSC_FLAG_LINK;
@@ -405,15 +429,20 @@
        struct smsc_softc * const sc = ifp->if_softc;
        struct mii_data * const mii = &sc->sc_mii;
 
+       /* SMSC_LOCK */
+
        mii_pollstat(mii);
 
        ifmr->ifm_active = mii->mii_media_active;
        ifmr->ifm_status = mii->mii_media_status;
+
+       /* SMSC_UNLOCK */
 }
 
 static inline uint32_t
 smsc_hash(uint8_t addr[ETHER_ADDR_LEN])
 {
+
        return (ether_crc32_be(addr, ETHER_ADDR_LEN) >> 26) & 0x3f;
 }
 
@@ -426,6 +455,8 @@
        uint32_t hashtbl[2] = { 0, 0 };
        uint32_t hash;
 
+       KASSERT(mutex_owned(&sc->sc_lock));
+
        if (sc->sc_dying)
                return;
 
@@ -441,16 +472,19 @@
                sc->sc_mac_csr &= ~(SMSC_MAC_CSR_PRMS | SMSC_MAC_CSR_MCPAS);
        }
 
+       ETHER_LOCK(&sc->sc_ec);
        ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
        while (enm != NULL) {
-               if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
-                   ETHER_ADDR_LEN) != 0)
+               if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
+                       ETHER_UNLOCK(&sc->sc_ec);
                        goto allmulti;
+               }
 
                hash = smsc_hash(enm->enm_addrlo);
                hashtbl[hash >> 5] |= 1 << (hash & 0x1F);
                ETHER_NEXT_MULTI(step, enm);
        }
+       ETHER_UNLOCK(&sc->sc_ec);
 
        /* Debug */
        if (sc->sc_mac_csr & SMSC_MAC_CSR_HPFILT) {
@@ -528,6 +562,7 @@
 void
 smsc_reset(struct smsc_softc *sc)
 {
+       KASSERT(mutex_owned(&sc->sc_lock));
        if (sc->sc_dying)
                return;
 
@@ -600,6 +635,10 @@
                goto fail3;
        }
 
+       mutex_enter(&sc->sc_rxlock);
+       mutex_enter(&sc->sc_txlock);
+       sc->sc_stopping = false;
+
        /* Start up the receive pipe. */
        for (size_t i = 0; i < SMSC_RX_LIST_CNT; i++) {
                struct smsc_chain *c = &sc->sc_cdata.rx_chain[i];
@@ -608,7 +647,8 @@
                usbd_transfer(c->sc_xfer);
        }
 
-       sc->sc_stopping = false;
+       mutex_exit(&sc->sc_txlock);
+       mutex_exit(&sc->sc_rxlock);
 
        /* Indicate we are up and running. */
        ifp->if_flags |= IFF_RUNNING;
@@ -650,20 +690,24 @@
 
        /* Don't send anything if there is no link or controller is busy. */
        if ((sc->sc_flags & SMSC_FLAG_LINK) == 0) {
+               smsc_dbg_printf(sc, "%s: no link\n", __func__);
                return;
        }
 
-       if ((ifp->if_flags & (IFF_OACTIVE|IFF_RUNNING)) != IFF_RUNNING)
+       if ((ifp->if_flags & (IFF_OACTIVE|IFF_RUNNING)) != IFF_RUNNING) {
+               smsc_dbg_printf(sc, "%s: not running\n", __func__);
                return;
+       }
 
        IFQ_POLL(&ifp->if_snd, m_head);
        if (m_head == NULL)
                return;
 
+       IFQ_DEQUEUE(&ifp->if_snd, m_head);
        if (smsc_encap(sc, m_head, 0)) {
+               m_free(m_head);
                return;
        }
-       IFQ_DEQUEUE(&ifp->if_snd, m_head);
 
        bpf_mtap(ifp, m_head);
 
@@ -683,10 +727,19 @@
        if (sc == NULL)
                return;
 
-       if (sc->sc_dying)
+       mutex_enter(&sc->sc_lock);
+
+       if (sc->sc_dying) {
+               mutex_exit(&sc->sc_lock);
                return;
+       }
 
-       usb_add_task(sc->sc_udev, &sc->sc_tick_task, USB_TASKQ_DRIVER);
+       if (!sc->sc_ttpending) {
+               sc->sc_ttpending = true;
+               usb_add_task(sc->sc_udev, &sc->sc_tick_task, USB_TASKQ_DRIVER);
+       }
+
+       mutex_exit(&sc->sc_lock);
 }
 
 void
@@ -932,18 +985,17 @@
 {
        struct ifnet *ifp = &ec->ec_if;
        struct smsc_softc *sc = ifp->if_softc;
-       int rc = 0;
 
        mutex_enter(&sc->sc_lock);
 
-       int change = ifp->if_flags ^ sc->sc_if_flags;
-       sc->sc_if_flags = ifp->if_flags;
-
+       const int change = ifp->if_flags ^ sc->sc_if_flags;
        if ((change & ~(IFF_CANTCHANGE | IFF_DEBUG)) != 0) {
-               rc = ENETRESET;
-               goto out;
+               mutex_exit(&sc->sc_lock);
+               return ENETRESET;
        }
 
+       smsc_dbg_printf(sc, "%s: change %x\n", __func__, change);
+
        if ((change & IFF_PROMISC) != 0) {
                if (ifp->if_flags & IFF_PROMISC) {
                        sc->sc_mac_csr |= SMSC_MAC_CSR_PRMS;
@@ -955,25 +1007,20 @@
                smsc_setmulti(sc);
        }
 
-out:
        mutex_exit(&sc->sc_lock);
 
-       return rc;
+       return 0;
 }
 
 
 int
 smsc_ioctl(struct ifnet *ifp, u_long cmd, void *data)
 {
-       struct smsc_softc *sc = ifp->if_softc;
-       int s, error = 0;
+       struct smsc_softc * const sc = ifp->if_softc;
 
-       if (sc->sc_dying)
-               return EIO;
+       smsc_dbg_printf(sc, "%s: cmd %0lx data %p\n", __func__, cmd, data);
 
-       s = splnet();
-       error = ether_ioctl(ifp, cmd, data);
-       splx(s);
+       int error = ether_ioctl(ifp, cmd, data);
 
        if (error == ENETRESET) {
                error = 0;
@@ -985,6 +1032,13 @@
                        }
                }
        }
+
+       mutex_enter(&sc->sc_rxlock);
+       mutex_enter(&sc->sc_txlock);
+       sc->sc_if_flags = ifp->if_flags;
+       mutex_exit(&sc->sc_txlock);
+       mutex_exit(&sc->sc_rxlock);
+
        return error;
 }
 
@@ -1062,7 +1116,7 @@
                }
        }
 
-       usb_init_task(&sc->sc_tick_task, smsc_tick_task, sc, 0);
+       usb_init_task(&sc->sc_tick_task, smsc_tick_task, sc, USB_TASKQ_MPSAFE);
 
        mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
        mutex_init(&sc->sc_txlock, MUTEX_DEFAULT, IPL_SOFTUSB);
@@ -1143,17 +1197,17 @@
        } else
                ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
 
+       callout_init(&sc->sc_stat_ch, CALLOUT_MPSAFE);
+
        if_initialize(ifp);
        sc->sc_ipq = if_percpuq_create(&sc->sc_ec.ec_if);
        ether_ifattach(ifp, sc->sc_enaddr);
+       ether_set_ifflags_cb(&sc->sc_ec, smsc_ifflags_cb);
        if_register(ifp);
-       ether_set_ifflags_cb(&sc->sc_ec, smsc_ifflags_cb);
 
        rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev),
            RND_TYPE_NET, RND_FLAG_DEFAULT);
 
-       callout_init(&sc->sc_stat_ch, 0);
-
        usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
 }
 
@@ -1162,16 +1216,15 @@
 {
        struct smsc_softc *sc = device_private(self);
        struct ifnet *ifp = &sc->sc_ec.ec_if;
-       int s;
 
-       callout_stop(&sc->sc_stat_ch);
+       mutex_enter(&sc->sc_lock);
+       sc->sc_dying = true;
+       mutex_exit(&sc->sc_lock);
 
-       if (sc->sc_ep[SMSC_ENDPT_TX] != NULL)
-               usbd_abort_pipe(sc->sc_ep[SMSC_ENDPT_TX]);
-       if (sc->sc_ep[SMSC_ENDPT_RX] != NULL)
-               usbd_abort_pipe(sc->sc_ep[SMSC_ENDPT_RX]);
-       if (sc->sc_ep[SMSC_ENDPT_INTR] != NULL)



Home | Main Index | Thread Index | Old Index