Source-Changes-HG archive

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

[src/nick-nhusb]: src/sys First pass at making this driver and attachments NE...



details:   https://anonhg.NetBSD.org/src/rev/89a687394265
branches:  nick-nhusb
changeset: 334523:89a687394265
user:      skrll <skrll%NetBSD.org@localhost>
date:      Sun Jun 12 07:18:52 2016 +0000

description:
First pass at making this driver and attachments NET_MPSAFE aware.

I've not tested this yet.

diffstat:

 sys/arch/arm/allwinner/awin_gige.c  |    8 +-
 sys/arch/arm/amlogic/amlogic_gmac.c |   10 ++-
 sys/dev/ic/dwc_gmac.c               |  119 ++++++++++++++++++++++++++++++-----
 sys/dev/ic/dwc_gmac_var.h           |    8 ++-
 4 files changed, 121 insertions(+), 24 deletions(-)

diffs (truncated from 437 to 300 lines):

diff -r eb646d8d1fca -r 89a687394265 sys/arch/arm/allwinner/awin_gige.c
--- a/sys/arch/arm/allwinner/awin_gige.c        Fri Jun 10 14:53:31 2016 +0000
+++ b/sys/arch/arm/allwinner/awin_gige.c        Sun Jun 12 07:18:52 2016 +0000
@@ -34,7 +34,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: awin_gige.c,v 1.19.2.1 2015/04/06 15:17:51 skrll Exp $");
+__KERNEL_RCSID(1, "$NetBSD: awin_gige.c,v 1.19.2.2 2016/06/12 07:18:52 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -153,7 +153,11 @@
        /*
         * Interrupt handler
         */
-       sc->sc_ih = intr_establish(loc->loc_intr, IPL_NET, IST_LEVEL,
+       int mpsafe = 0;
+#ifdef NET_MPSAFE
+       mpsafe |= IST_MPSAFE;
+#endif
+       sc->sc_ih = intr_establish(loc->loc_intr, IPL_NET, IST_LEVEL | mpsafe,
            awin_gige_intr, sc);
        if (sc->sc_ih == NULL) {
                aprint_error_dev(self, "failed to establish interrupt %d\n",
diff -r eb646d8d1fca -r 89a687394265 sys/arch/arm/amlogic/amlogic_gmac.c
--- a/sys/arch/arm/amlogic/amlogic_gmac.c       Fri Jun 10 14:53:31 2016 +0000
+++ b/sys/arch/arm/amlogic/amlogic_gmac.c       Sun Jun 12 07:18:52 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: amlogic_gmac.c,v 1.2.4.2 2015/04/06 15:17:51 skrll Exp $ */
+/* $NetBSD: amlogic_gmac.c,v 1.2.4.3 2016/06/12 07:18:52 skrll Exp $ */
 
 /*-
  * Copyright (c) 2013, 2014, 2015 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: amlogic_gmac.c,v 1.2.4.2 2015/04/06 15:17:51 skrll Exp $");
+__KERNEL_RCSID(1, "$NetBSD: amlogic_gmac.c,v 1.2.4.3 2016/06/12 07:18:52 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -92,7 +92,11 @@
        /*
         * Interrupt handler
         */
-       sc->sc_ih = intr_establish(loc->loc_intr, IPL_NET, IST_EDGE,
+       int mpsafe = 0;
+#ifdef NET_MPSAFE
+       mpsafe |= IST_MPSAFE;
+#endif
+       sc->sc_ih = intr_establish(loc->loc_intr, IPL_NET, IST_EDGE | mpsafe,
            amlogic_gmac_intr, sc);
        if (sc->sc_ih == NULL) {
                aprint_error_dev(self, "failed to establish interrupt %d\n",
diff -r eb646d8d1fca -r 89a687394265 sys/dev/ic/dwc_gmac.c
--- a/sys/dev/ic/dwc_gmac.c     Fri Jun 10 14:53:31 2016 +0000
+++ b/sys/dev/ic/dwc_gmac.c     Sun Jun 12 07:18:52 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: dwc_gmac.c,v 1.28.2.3 2016/03/19 11:30:09 skrll Exp $ */
+/* $NetBSD: dwc_gmac.c,v 1.28.2.4 2016/06/12 07:18:52 skrll Exp $ */
 
 /*-
  * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc.
@@ -41,11 +41,14 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.28.2.3 2016/03/19 11:30:09 skrll Exp $");
+__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.28.2.4 2016/06/12 07:18:52 skrll Exp $");
 
 /* #define     DWC_GMAC_DEBUG  1 */
 
+#ifdef _KERNEL_OPT
 #include "opt_inet.h"
+#include "opt_net_mpsafe.h"
+#endif
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -85,8 +88,11 @@
 static void dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *);
 static void dwc_gmac_txdesc_sync(struct dwc_gmac_softc *sc, int start, int end, int ops);
 static int dwc_gmac_init(struct ifnet *ifp);
+static int dwc_gmac_init_locked(struct ifnet *ifp);
 static void dwc_gmac_stop(struct ifnet *ifp, int disable);
+static void dwc_gmac_stop_locked(struct ifnet *ifp, int disable);
 static void dwc_gmac_start(struct ifnet *ifp);
+static void dwc_gmac_start_locked(struct ifnet *ifp);
 static int dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0);
 static int dwc_gmac_ioctl(struct ifnet *, u_long, void *);
 static void dwc_gmac_tx_intr(struct dwc_gmac_softc *sc);
@@ -128,6 +134,10 @@
 static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *sc, uint32_t ffilt);
 #endif
 
+#ifdef NET_MPSAFE
+#define DWCGMAC_MPSAFE 1
+#endif
+
 void
 dwc_gmac_attach(struct dwc_gmac_softc *sc, uint32_t mii_clk)
 {
@@ -136,7 +146,6 @@
        struct mii_data * const mii = &sc->sc_mii;
        struct ifnet * const ifp = &sc->sc_ec.ec_if;
        prop_dictionary_t dict;
-       int s;
 
        mutex_init(&sc->sc_mdio_lock, MUTEX_DEFAULT, IPL_NET);
        sc->sc_mii_clk = mii_clk & 7;
@@ -198,12 +207,15 @@
                goto fail;
        }
 
-       mutex_init(&sc->sc_rxq.r_mtx, MUTEX_DEFAULT, IPL_NET);
        if (dwc_gmac_alloc_rx_ring(sc, &sc->sc_rxq) != 0) {
                aprint_error_dev(sc->sc_dev, "could not allocate Rx ring\n");
                goto fail;
        }
 
+       sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
+       mutex_init(&sc->sc_txq.t_mtx, MUTEX_DEFAULT, IPL_NET);
+       mutex_init(&sc->sc_rxq.r_mtx, MUTEX_DEFAULT, IPL_NET);
+
        /*
         * Prepare interface data
         */
@@ -245,19 +257,22 @@
        /*
         * Ready, attach interface
         */
-       if_attach(ifp);
+       /* Attach the interface. */
+       if_initialize(ifp);
+       sc->sc_ipq = if_percpuq_create(&sc->sc_ec.ec_if);
        ether_ifattach(ifp, enaddr);
        ether_set_ifflags_cb(&sc->sc_ec, dwc_gmac_ifflags_cb);
+       if_register(ifp);
 
        /*
         * Enable interrupts
         */
-       s = splnet();
+       mutex_enter(sc->sc_lock);
        bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTMASK,
            AWIN_DEF_MAC_INTRMASK);
        bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE,
            GMAC_DEF_DMA_INT_MASK);
-       splx(s);
+       mutex_exit(sc->sc_lock);
 
        return;
 
@@ -439,6 +454,7 @@
        struct dwc_gmac_dev_dmadesc *desc;
        int i;
 
+       mutex_enter(&ring->r_mtx);
        for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
                desc = &sc->sc_rxq.r_desc[i];
                desc->ddesc_cntl = htole32(
@@ -455,6 +471,7 @@
        /* reset DMA address to start of ring */
        bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR,
            sc->sc_rxq.r_physaddr);
+       mutex_exit(&ring->r_mtx);
 }
 
 static int
@@ -618,6 +635,7 @@
 {
        int i;
 
+       mutex_enter(&ring->t_mtx);
        for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
                struct dwc_gmac_tx_data *data = &ring->t_data[i];
 
@@ -640,6 +658,7 @@
 
        ring->t_queued = 0;
        ring->t_cur = ring->t_next = 0;
+       mutex_exit(&ring->t_mtx);
 }
 
 static void
@@ -729,6 +748,18 @@
 dwc_gmac_init(struct ifnet *ifp)
 {
        struct dwc_gmac_softc *sc = ifp->if_softc;
+
+       mutex_enter(sc->sc_lock);
+       int ret = dwc_gmac_init_locked(ifp);
+       mutex_exit(sc->sc_lock);
+
+       return ret;
+}
+
+static int
+dwc_gmac_init_locked(struct ifnet *ifp)
+{
+       struct dwc_gmac_softc *sc = ifp->if_softc;
        uint32_t ffilt;
 
        if (ifp->if_flags & IFF_RUNNING)
@@ -781,6 +812,8 @@
            AWIN_GMAC_DMA_OPMODE, GMAC_DMA_OP_RXSTART | GMAC_DMA_OP_TXSTART |
            GMAC_DMA_OP_RXSTOREFORWARD | GMAC_DMA_OP_TXSTOREFORWARD);
 
+       sc->sc_stopping = false;
+
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
 
@@ -791,6 +824,20 @@
 dwc_gmac_start(struct ifnet *ifp)
 {
        struct dwc_gmac_softc *sc = ifp->if_softc;
+
+       mutex_enter(sc->sc_lock);
+       if (!sc->sc_stopping) {
+               mutex_enter(&sc->sc_txq.t_mtx);
+               dwc_gmac_start_locked(ifp);
+               mutex_exit(&sc->sc_txq.t_mtx);
+       }
+       mutex_exit(sc->sc_lock);
+}
+
+static void
+dwc_gmac_start_locked(struct ifnet *ifp)
+{
+       struct dwc_gmac_softc *sc = ifp->if_softc;
        int old = sc->sc_txq.t_queued;
        int start = sc->sc_txq.t_cur;
        struct mbuf *m0;
@@ -832,6 +879,18 @@
 {
        struct dwc_gmac_softc *sc = ifp->if_softc;
 
+       mutex_enter(sc->sc_lock);
+       dwc_gmac_stop_locked(ifp, disable);
+       mutex_exit(sc->sc_lock);
+}
+
+static void
+dwc_gmac_stop_locked(struct ifnet *ifp, int disable)
+{
+       struct dwc_gmac_softc *sc = ifp->if_softc;
+
+       sc->sc_stopping = true;
+
        bus_space_write_4(sc->sc_bst, sc->sc_bsh,
            AWIN_GMAC_DMA_OPMODE,
            bus_space_read_4(sc->sc_bst, sc->sc_bsh,
@@ -940,8 +999,11 @@
 
        if ((change & ~(IFF_CANTCHANGE|IFF_DEBUG)) != 0)
                return ENETRESET;
-       if ((change & IFF_PROMISC) != 0)
+       if ((change & IFF_PROMISC) != 0) {
+               mutex_enter(sc->sc_lock);
                dwc_gmac_setmulti(sc);
+               mutex_exit(sc->sc_lock);
+       }
        return 0;
 }
 
@@ -949,11 +1011,16 @@
 dwc_gmac_ioctl(struct ifnet *ifp, u_long cmd, void *data)
 {
        struct dwc_gmac_softc *sc = ifp->if_softc;
-       int s, error = 0;
+       int error = 0;
+
+       int s = splnet();
+       error = ether_ioctl(ifp, cmd, data);
 
-       s = splnet();
+#ifdef DWCGMAC_MPSAFE
+       splx(s);
+#endif
 
-       if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
+       if (error == ENETRESET) {
                error = 0;
                if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI)
                        ;
@@ -962,7 +1029,9 @@
                         * Multicast list has changed; set the hardware filter
                         * accordingly.
                         */
+                       mutex_enter(sc->sc_lock);
                        dwc_gmac_setmulti(sc);
+                       mutex_exit(sc->sc_lock);
                }
        }
 
@@ -970,7 +1039,11 @@
        if (ifp->if_flags & IFF_UP)



Home | Main Index | Thread Index | Old Index