summaryrefslogtreecommitdiffstats
path: root/sys/dev/sk/if_sk.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/sk/if_sk.c')
-rw-r--r--sys/dev/sk/if_sk.c74
1 files changed, 52 insertions, 22 deletions
diff --git a/sys/dev/sk/if_sk.c b/sys/dev/sk/if_sk.c
index a83a606..963f754 100644
--- a/sys/dev/sk/if_sk.c
+++ b/sys/dev/sk/if_sk.c
@@ -413,6 +413,8 @@ static int sk_miibus_readreg(dev, phy, reg)
if (sc_if->sk_phytype == SK_PHYTYPE_XMAC && phy != 0)
return(0);
+ SK_IF_LOCK(sc_if);
+
SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8));
SK_XM_READ_2(sc_if, XM_PHY_DATA);
if (sc_if->sk_phytype != SK_PHYTYPE_XMAC) {
@@ -430,7 +432,9 @@ static int sk_miibus_readreg(dev, phy, reg)
}
}
DELAY(1);
- return(SK_XM_READ_2(sc_if, XM_PHY_DATA));
+ i = SK_XM_READ_2(sc_if, XM_PHY_DATA);
+ SK_IF_UNLOCK(sc_if);
+ return(i);
}
static int sk_miibus_writereg(dev, phy, reg, val)
@@ -441,6 +445,7 @@ static int sk_miibus_writereg(dev, phy, reg, val)
int i;
sc_if = device_get_softc(dev);
+ SK_IF_LOCK(sc_if);
SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8));
for (i = 0; i < SK_TIMEOUT; i++) {
@@ -460,6 +465,8 @@ static int sk_miibus_writereg(dev, phy, reg, val)
break;
}
+ SK_IF_UNLOCK(sc_if);
+
if (i == SK_TIMEOUT)
printf("sk%d: phy write timed out\n", sc_if->sk_unit);
@@ -474,7 +481,7 @@ static void sk_miibus_statchg(dev)
sc_if = device_get_softc(dev);
mii = device_get_softc(sc_if->sk_miibus);
-
+ SK_IF_LOCK(sc_if);
/*
* If this is a GMII PHY, manually set the XMAC's
* duplex mode accordingly.
@@ -486,6 +493,7 @@ static void sk_miibus_statchg(dev)
SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_GMIIFDX);
}
}
+ SK_IF_UNLOCK(sc_if);
return;
}
@@ -872,10 +880,10 @@ static int sk_ioctl(ifp, command, data)
{
struct sk_if_softc *sc_if = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *) data;
- int s, error = 0;
+ int error = 0;
struct mii_data *mii;
- s = splimp();
+ SK_IF_LOCK(sc_if);
switch(command) {
case SIOCSIFADDR:
@@ -928,7 +936,7 @@ static int sk_ioctl(ifp, command, data)
break;
}
- (void)splx(s);
+ SK_IF_UNLOCK(sc_if);
return(error);
}
@@ -1025,6 +1033,7 @@ static int sk_attach_xmac(dev)
sc_if = device_get_softc(dev);
sc = device_get_softc(device_get_parent(dev));
+ SK_LOCK(sc);
port = *(int *)device_get_ivars(dev);
free(device_get_ivars(dev), M_DEVBUF);
device_set_ivars(dev, NULL);
@@ -1113,6 +1122,7 @@ static int sk_attach_xmac(dev)
if (sc_if->sk_rdata == NULL) {
printf("sk%d: no memory for list buffers!\n", sc_if->sk_unit);
sc->sk_if[port] = NULL;
+ SK_UNLOCK(sc);
return(ENOMEM);
}
@@ -1125,6 +1135,7 @@ static int sk_attach_xmac(dev)
contigfree(sc_if->sk_rdata,
sizeof(struct sk_ring_data), M_DEVBUF);
sc->sk_if[port] = NULL;
+ SK_UNLOCK(sc);
return(ENOMEM);
}
@@ -1151,6 +1162,7 @@ static int sk_attach_xmac(dev)
printf("skc%d: no PHY found!\n", sc_if->sk_unit);
contigfree(sc_if->sk_rdata,
sizeof(struct sk_ring_data), M_DEVBUF);
+ SK_UNLOCK(sc);
return(ENXIO);
}
@@ -1160,6 +1172,8 @@ static int sk_attach_xmac(dev)
ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
callout_handle_init(&sc_if->sk_tick_ch);
+ SK_UNLOCK(sc);
+
return(0);
}
@@ -1170,13 +1184,10 @@ static int sk_attach_xmac(dev)
static int sk_attach(dev)
device_t dev;
{
- int s;
u_int32_t command;
struct sk_softc *sc;
int unit, error = 0, rid, *port;
- s = splimp();
-
sc = device_get_softc(dev);
unit = device_get_unit(dev);
bzero(sc, sizeof(struct sk_softc));
@@ -1266,6 +1277,8 @@ static int sk_attach(dev)
goto fail;
}
+ mtx_init(&sc->sk_mtx, "skc", MTX_DEF);
+ SK_LOCK(sc);
/* Reset the adapter. */
sk_reset(sc);
@@ -1345,9 +1358,12 @@ static int sk_attach(dev)
CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON);
bus_generic_attach(dev);
+ SK_UNLOCK(sc);
+ return(0);
fail:
- splx(s);
+ SK_UNLOCK(sc);
+ mtx_destroy(&sc->sk_mtx);
return(error);
}
@@ -1357,12 +1373,11 @@ static int sk_detach_xmac(dev)
struct sk_softc *sc;
struct sk_if_softc *sc_if;
struct ifnet *ifp;
- int s;
-
- s = splimp();
sc = device_get_softc(device_get_parent(dev));
sc_if = device_get_softc(dev);
+ SK_IF_LOCK(sc_if);
+
ifp = &sc_if->arpcom.ac_if;
sk_stop(sc_if);
ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
@@ -1371,6 +1386,7 @@ static int sk_detach_xmac(dev)
device_delete_child(dev, sc_if->sk_miibus);
contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF);
contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data), M_DEVBUF);
+ SK_IF_UNLOCK(sc_if);
return(0);
}
@@ -1379,11 +1395,9 @@ static int sk_detach(dev)
device_t dev;
{
struct sk_softc *sc;
- int s;
-
- s = splimp();
sc = device_get_softc(dev);
+ SK_LOCK(sc);
bus_generic_detach(dev);
if (sc->sk_devs[SK_PORT_A] != NULL)
@@ -1395,7 +1409,8 @@ static int sk_detach(dev)
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq);
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
- splx(s);
+ SK_UNLOCK(sc);
+ mtx_destroy(&sc->sk_mtx);
return(0);
}
@@ -1460,6 +1475,8 @@ static void sk_start(ifp)
sc_if = ifp->if_softc;
sc = sc_if->sk_softc;
+ SK_IF_LOCK(sc_if);
+
idx = sc_if->sk_cdata.sk_tx_prod;
while(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf == NULL) {
@@ -1492,6 +1509,7 @@ static void sk_start(ifp)
/* Set a timeout in case the chip goes out to lunch. */
ifp->if_timer = 5;
+ SK_IF_UNLOCK(sc_if);
return;
}
@@ -1516,6 +1534,7 @@ static void sk_shutdown(dev)
struct sk_softc *sc;
sc = device_get_softc(dev);
+ SK_LOCK(sc);
/* Turn off the 'driver is loaded' LED. */
CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_OFF);
@@ -1525,6 +1544,7 @@ static void sk_shutdown(dev)
* assert the resets on the attached XMAC(s).
*/
sk_reset(sc);
+ SK_UNLOCK(sc);
return;
}
@@ -1644,14 +1664,18 @@ static void sk_tick(xsc_if)
int i;
sc_if = xsc_if;
+ SK_IF_LOCK(sc_if);
ifp = &sc_if->arpcom.ac_if;
mii = device_get_softc(sc_if->sk_miibus);
- if (!(ifp->if_flags & IFF_UP))
+ if (!(ifp->if_flags & IFF_UP)) {
+ SK_IF_UNLOCK(sc_if);
return;
+ }
if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) {
sk_intr_bcom(sc_if);
+ SK_IF_UNLOCK(sc_if);
return;
}
@@ -1669,6 +1693,7 @@ static void sk_tick(xsc_if)
if (i != 3) {
sc_if->sk_tick_ch = timeout(sk_tick, sc_if, hz);
+ SK_IF_UNLOCK(sc_if);
return;
}
@@ -1679,6 +1704,7 @@ static void sk_tick(xsc_if)
mii_pollstat(mii);
untimeout(sk_tick, sc_if, sc_if->sk_tick_ch);
+ SK_IF_UNLOCK(sc_if);
return;
}
@@ -1785,6 +1811,8 @@ static void sk_intr(xsc)
struct ifnet *ifp0 = NULL, *ifp1 = NULL;
u_int32_t status;
+ SK_LOCK(sc);
+
sc_if0 = sc->sk_if[SK_PORT_A];
sc_if1 = sc->sk_if[SK_PORT_B];
@@ -1846,6 +1874,8 @@ static void sk_intr(xsc)
if (ifp1 != NULL && ifp1->if_snd.ifq_head != NULL)
sk_start(ifp1);
+ SK_UNLOCK(sc);
+
return;
}
@@ -2028,9 +2058,8 @@ static void sk_init(xsc)
struct sk_softc *sc;
struct ifnet *ifp;
struct mii_data *mii;
- int s;
- s = splimp();
+ SK_IF_LOCK(sc_if);
ifp = &sc_if->arpcom.ac_if;
sc = sc_if->sk_softc;
@@ -2100,7 +2129,7 @@ static void sk_init(xsc)
printf("sk%d: initialization failed: no "
"memory for rx buffers\n", sc_if->sk_unit);
sk_stop(sc_if);
- (void)splx(s);
+ SK_IF_UNLOCK(sc_if);
return;
}
sk_init_tx_ring(sc_if);
@@ -2126,7 +2155,7 @@ static void sk_init(xsc)
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
- splx(s);
+ SK_IF_UNLOCK(sc_if);
return;
}
@@ -2138,6 +2167,7 @@ static void sk_stop(sc_if)
struct sk_softc *sc;
struct ifnet *ifp;
+ SK_IF_LOCK(sc_if);
sc = sc_if->sk_softc;
ifp = &sc_if->arpcom.ac_if;
@@ -2198,6 +2228,6 @@ static void sk_stop(sc_if)
}
ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
-
+ SK_IF_UNLOCK(sc_if);
return;
}
OpenPOWER on IntegriCloud