Make all network interrupt service routines MPSAFE part 1/3.
[dragonfly.git] / sys / dev / netif / rl / if_rl.c
index 2a02cf8..fe4fd63 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/pci/if_rl.c,v 1.38.2.16 2003/03/05 18:42:33 njl Exp $
- * $DragonFly: src/sys/dev/netif/rl/if_rl.c,v 1.22 2005/05/25 01:44:28 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/rl/if_rl.c,v 1.29 2005/11/28 17:13:43 dillon Exp $
  */
 
 /*
@@ -84,6 +84,8 @@
  * to select which interface to use depending on the chip type.
  */
 
+#include "opt_polling.h"
+
 #include <sys/param.h>
 #include <sys/endian.h>
 #include <sys/systm.h>
@@ -93,6 +95,8 @@
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/socket.h>
+#include <sys/serialize.h>
+#include <sys/thread2.h>
 
 #include <net/if.h>
 #include <net/ifq_var.h>
@@ -412,9 +416,7 @@ rl_mii_send(struct rl_softc *sc, uint32_t bits, int cnt)
 static int
 rl_mii_readreg(struct rl_softc *sc, struct rl_mii_frame *frame)        
 {
-       int i, ack, s;
-
-       s = splimp();
+       int ack, i;
 
        /*
         * Set up frame for RX.
@@ -487,8 +489,6 @@ rl_mii_readreg(struct rl_softc *sc, struct rl_mii_frame *frame)
        MII_SET(RL_MII_CLK);
        DELAY(1);
 
-       splx(s);
-
        return(ack ? 1 : 0);
 }
 
@@ -498,13 +498,9 @@ rl_mii_readreg(struct rl_softc *sc, struct rl_mii_frame *frame)
 static int
 rl_mii_writereg(struct rl_softc *sc, struct rl_mii_frame *frame)
 {
-       int s;
-
-       s = splimp();
        /*
         * Set up frame for TX.
         */
-
        frame->mii_stdelim = RL_MII_STARTDELIM;
        frame->mii_opcode = RL_MII_WRITEOP;
        frame->mii_turnaround = RL_MII_TURNAROUND;
@@ -534,8 +530,6 @@ rl_mii_writereg(struct rl_softc *sc, struct rl_mii_frame *frame)
         */
        MII_CLR(RL_MII_DIR);
 
-       splx(s);
-
        return(0);
 }
 
@@ -690,7 +684,7 @@ rl_setmulti(struct rl_softc *sc)
                        continue;
                h = ether_crc32_be(
                    LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
-                   ETHER_ADDR_LEN >> 26);
+                   ETHER_ADDR_LEN) >> 26;
                if (h < 32)
                        hashes[0] |= (1 << h);
                else
@@ -787,11 +781,7 @@ rl_attach(device_t dev)
                pci_write_config(dev, RL_PCI_INTLINE, irq, 4);
        }
 
-       /*
-        * Map control/status registers.
-        */
        pci_enable_busmaster(dev);
-       pci_enable_io(dev, RL_RES);
 
        rid = RL_RID; 
        sc->rl_res = bus_alloc_resource_any(dev, RL_RES, &rid, RF_ACTIVE);
@@ -937,10 +927,10 @@ rl_attach(device_t dev)
        /*
         * Call MI attach routine.
         */
-       ether_ifattach(ifp, eaddr);
+       ether_ifattach(ifp, eaddr, NULL);
 
-       error = bus_setup_intr(dev, sc->rl_irq, INTR_TYPE_NET, rl_intr,
-                              sc, &sc->rl_intrhand, NULL);
+       error = bus_setup_intr(dev, sc->rl_irq, INTR_NETSAFE, rl_intr,
+                              sc, &sc->rl_intrhand, ifp->if_serializer);
 
        if (error) {
                device_printf(dev, "couldn't set up irq\n");
@@ -960,12 +950,11 @@ rl_detach(device_t dev)
 {
        struct rl_softc *sc;
        struct ifnet *ifp;
-       int s;
 
        sc = device_get_softc(dev);
        ifp = &sc->arpcom.ac_if;
 
-       s = splimp();
+       lwkt_serialize_enter(ifp->if_serializer);
 
        if (device_is_attached(dev)) {
                rl_stop(sc);
@@ -978,7 +967,6 @@ rl_detach(device_t dev)
 
        if (sc->rl_intrhand)
                bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand);
-       splx(s);
 
        if (sc->rl_irq)
                bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
@@ -995,6 +983,8 @@ rl_detach(device_t dev)
        if (sc->rl_parent_tag)
                bus_dma_tag_destroy(sc->rl_parent_tag);
 
+       lwkt_serialize_exit(ifp->if_serializer);
+
        return(0);
 }
 
@@ -1164,7 +1154,7 @@ rl_rxeof(struct rl_softc *sc)
 
                ifp->if_ipackets++;
 
-               (*ifp->if_input)(ifp, m);
+               ifp->if_input(ifp, m);
        }
 }
 
@@ -1227,16 +1217,15 @@ rl_tick(void *xsc)
 {
        struct rl_softc *sc = xsc;
        struct mii_data *mii;
-       int s;
 
-       s = splimp();
+       lwkt_serialize_enter(sc->arpcom.ac_if.if_serializer);
 
        mii = device_get_softc(sc->rl_miibus);
        mii_tick(mii);
 
-       splx(s);
-
        callout_reset(&sc->rl_stat_timer, hz, rl_tick, sc);
+
+       lwkt_serialize_exit(sc->arpcom.ac_if.if_serializer);
 }
 
 #ifdef DEVICE_POLLING
@@ -1386,7 +1375,7 @@ rl_start(struct ifnet *ifp)
        sc = ifp->if_softc;
 
        while(RL_CUR_TXMBUF(sc) == NULL) {
-               m_head = ifq_dequeue(&ifp->if_snd);
+               m_head = ifq_dequeue(&ifp->if_snd, NULL);
                if (m_head == NULL)
                        break;
 
@@ -1436,11 +1425,8 @@ rl_init(void *xsc)
        struct rl_softc *sc = xsc;
        struct ifnet *ifp = &sc->arpcom.ac_if;
        struct mii_data *mii;
-       int s;
        uint32_t rxcfg = 0;
 
-       s = splimp();
-
        mii = device_get_softc(sc->rl_miibus);
 
        /*
@@ -1539,8 +1525,6 @@ rl_init(void *xsc)
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
 
-       splx(s);
-
        callout_reset(&sc->rl_stat_timer, hz, rl_tick, sc);
 }
 
@@ -1580,9 +1564,7 @@ rl_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
        struct rl_softc *sc = ifp->if_softc;
        struct ifreq *ifr = (struct ifreq *) data;
        struct mii_data *mii;
-       int s, error = 0;
-
-       s = splimp();
+       int error = 0;
 
        switch (command) {
        case SIOCSIFFLAGS:
@@ -1611,8 +1593,6 @@ rl_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
                break;
        }
 
-       splx(s);
-
        return(error);
 }
 
@@ -1620,18 +1600,18 @@ static void
 rl_watchdog(struct ifnet *ifp)
 {
        struct rl_softc *sc = ifp->if_softc;
-       int s;
-
-       s = splimp();
 
        device_printf(sc->rl_dev, "watchdog timeout\n");
+
+       lwkt_serialize_enter(ifp->if_serializer);
+
        ifp->if_oerrors++;
 
        rl_txeof(sc);
        rl_rxeof(sc);
        rl_init(sc);
 
-       splx(s);
+       lwkt_serialize_exit(ifp->if_serializer);
 }
 
 /*
@@ -1680,8 +1660,9 @@ rl_shutdown(device_t dev)
        struct rl_softc *sc;
 
        sc = device_get_softc(dev);
-
+       lwkt_serialize_enter(sc->arpcom.ac_if.if_serializer);
        rl_stop(sc);
+       lwkt_serialize_exit(sc->arpcom.ac_if.if_serializer);
 }
 
 /*
@@ -1695,6 +1676,7 @@ rl_suspend(device_t dev)
        struct rl_softc *sc = device_get_softc(dev);
        int i;
 
+       lwkt_serialize_enter(sc->arpcom.ac_if.if_serializer);
        rl_stop(sc);
 
        for (i = 0; i < 5; i++)
@@ -1706,6 +1688,7 @@ rl_suspend(device_t dev)
 
        sc->suspended = 1;
 
+       lwkt_serialize_exit(sc->arpcom.ac_if.if_serializer);
        return (0);
 }
 
@@ -1720,6 +1703,8 @@ static int rl_resume(device_t dev)
        struct ifnet *ifp = &sc->arpcom.ac_if;
        int             i;
 
+       lwkt_serialize_enter(ifp->if_serializer);
+
        /* better way to do this? */
        for (i = 0; i < 5; i++)
                pci_write_config(dev, PCIR_BAR(i), sc->saved_maps[i], 4);
@@ -1737,6 +1722,6 @@ static int rl_resume(device_t dev)
                 rl_init(sc);
 
        sc->suspended = 0;
-
+       lwkt_serialize_exit(ifp->if_serializer);
        return (0);
 }