PERFORCE change 140217 for review
Sam Leffler
sam at FreeBSD.org
Fri Apr 18 18:17:36 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=140217
Change 140217 by sam at sam_ebb on 2008/04/18 18:16:56
don't hold the softc lock over ieee80211_start_all and
untangle some other locking; also make watchdog timer handling
consistent
Affected files ...
.. //depot/projects/vap/sys/dev/ral/rt2560.c#27 edit
.. //depot/projects/vap/sys/dev/ral/rt2661.c#25 edit
Differences ...
==== //depot/projects/vap/sys/dev/ral/rt2560.c#27 (text) ====
@@ -158,7 +158,9 @@
static int rt2560_bbp_init(struct rt2560_softc *);
static void rt2560_set_txantenna(struct rt2560_softc *, int);
static void rt2560_set_rxantenna(struct rt2560_softc *, int);
+static void rt2560_init_locked(struct rt2560_softc *);
static void rt2560_init(void *);
+static void rt2560_stop_locked(struct rt2560_softc *);
static int rt2560_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
@@ -1978,20 +1980,22 @@
struct rt2560_softc *sc = arg;
struct ifnet *ifp = sc->sc_ifp;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ RAL_LOCK_ASSERT(sc);
+
+ KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running"));
+
+ if (sc->sc_invalid) /* card ejected */
return;
rt2560_encryption_intr(sc);
rt2560_tx_intr(sc);
- if (sc->sc_tx_timer > 0) {
- if (--sc->sc_tx_timer == 0) {
- device_printf(sc->sc_dev, "device timeout\n");
- rt2560_init(sc);
- ifp->if_oerrors++;
- /* watchdog timeout is set in rt2560_init() */
- return;
- }
+ if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
+ if_printf(ifp, "device timeout\n");
+ rt2560_init_locked(sc);
+ ifp->if_oerrors++;
+ /* NB: callout is reset in rt2560_init() */
+ return;
}
callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc);
}
@@ -2002,21 +2006,25 @@
struct rt2560_softc *sc = ifp->if_softc;
struct ieee80211com *ic = ifp->if_l2com;
struct ifreq *ifr = (struct ifreq *) data;
- int error = 0;
+ int error = 0, startall;
switch (cmd) {
case SIOCSIFFLAGS:
+ RAL_LOCK(sc);
+ startall = 0;
if (ifp->if_flags & IFF_UP) {
- RAL_LOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ rt2560_init_locked(sc);
+ startall = 1;
+ } else
rt2560_update_promisc(ifp);
- else
- rt2560_init(sc);
- RAL_UNLOCK(sc);
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- rt2560_stop(sc);
+ rt2560_stop_locked(sc);
}
+ RAL_UNLOCK(sc);
+ if (startall) /* NB: need to drop lock */
+ ieee80211_start_all(ic);
break;
case SIOCGIFMEDIA:
case SIOCSIFMEDIA:
@@ -2621,18 +2629,18 @@
}
static void
-rt2560_init(void *priv)
+rt2560_init_locked(struct rt2560_softc *sc)
{
#define N(a) (sizeof (a) / sizeof ((a)[0]))
- struct rt2560_softc *sc = priv;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
uint32_t tmp;
int i;
- rt2560_stop(sc);
+ RAL_LOCK_ASSERT(sc);
+
+ rt2560_stop_locked(sc);
- RAL_LOCK(sc);
/* setup tx rings */
tmp = RT2560_PRIO_RING_COUNT << 24 |
RT2560_ATIM_RING_COUNT << 16 |
@@ -2706,27 +2714,36 @@
ifp->if_drv_flags |= IFF_DRV_RUNNING;
callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc);
+#undef N
+}
+static void
+rt2560_init(void *priv)
+{
+ struct rt2560_softc *sc = priv;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+
+ RAL_LOCK(sc);
+ rt2560_init_locked(sc);
RAL_UNLOCK(sc);
- ieee80211_start_all(ic); /* start all vap's */
-#undef N
+ ieee80211_start_all(ic);
}
-void
-rt2560_stop(void *arg)
+static void
+rt2560_stop_locked(struct rt2560_softc *sc)
{
- struct rt2560_softc *sc = arg;
struct ifnet *ifp = sc->sc_ifp;
volatile int *flags = &sc->sc_flags;
- while (*flags & RT2560_F_INPUT_RUNNING) {
- tsleep(sc, 0, "ralrunning", hz/10);
- }
+ RAL_LOCK_ASSERT(sc);
- RAL_LOCK(sc);
+ while (*flags & RT2560_F_INPUT_RUNNING)
+ msleep(sc, &sc->sc_mtx, 0, "ralrunning", hz/10);
callout_stop(&sc->watchdog_ch);
+ sc->sc_tx_timer = 0;
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
@@ -2751,9 +2768,16 @@
rt2560_reset_tx_ring(sc, &sc->bcnq);
rt2560_reset_rx_ring(sc, &sc->rxq);
}
- sc->sc_tx_timer = 0;
sc->sc_flags &= ~(RT2560_F_PRIO_OACTIVE | RT2560_F_DATA_OACTIVE);
+}
+
+void
+rt2560_stop(void *arg)
+{
+ struct rt2560_softc *sc = arg;
+ RAL_LOCK(sc);
+ rt2560_stop_locked(sc);
RAL_UNLOCK(sc);
}
==== //depot/projects/vap/sys/dev/ral/rt2661.c#25 (text) ====
@@ -157,9 +157,10 @@
static void rt2661_read_eeprom(struct rt2661_softc *,
struct ieee80211com *);
static int rt2661_bbp_init(struct rt2661_softc *);
+static void rt2661_init_locked(struct rt2661_softc *);
static void rt2661_init(void *);
+static void rt2661_stop_locked(struct rt2661_softc *);
static void rt2661_stop(void *);
-static void rt2661_stop_locked(struct rt2661_softc *);
static int rt2661_load_microcode(struct rt2661_softc *);
#ifdef notyet
static void rt2661_rx_tune(struct rt2661_softc *);
@@ -357,7 +358,6 @@
RAL_LOCK(sc);
rt2661_stop_locked(sc);
- callout_stop(&sc->watchdog_ch);
RAL_UNLOCK(sc);
bpfdetach(ifp);
@@ -1660,7 +1660,6 @@
}
sc->sc_tx_timer = 5;
- callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
}
}
@@ -1709,7 +1708,6 @@
if (rt2661_tx_mgt(sc, m, ni) != 0)
goto bad;
sc->sc_tx_timer = 5;
- callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
RAL_UNLOCK(sc);
@@ -1725,16 +1723,23 @@
rt2661_watchdog(void *arg)
{
struct rt2661_softc *sc = (struct rt2661_softc *)arg;
+ struct ifnet *ifp = sc->sc_ifp;
+
+ RAL_LOCK_ASSERT(sc);
+
+ KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running"));
- if (sc->sc_tx_timer > 0 && !sc->sc_invalid) {
- if (--sc->sc_tx_timer == 0) {
- device_printf(sc->sc_dev, "device timeout\n");
- rt2661_init(sc);
- sc->sc_ifp->if_oerrors++;
- return;
- }
- callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
+ if (sc->sc_invalid) /* card ejected */
+ return;
+
+ if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
+ if_printf(ifp, "device timeout\n");
+ rt2661_init_locked(sc);
+ ifp->if_oerrors++;
+ /* NB: callout is reset in rt2661_init() */
+ return;
}
+ callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
}
static int
@@ -1743,19 +1748,25 @@
struct rt2661_softc *sc = ifp->if_softc;
struct ieee80211com *ic = ifp->if_l2com;
struct ifreq *ifr = (struct ifreq *) data;
- int error = 0;
+ int error = 0, startall;
switch (cmd) {
case SIOCSIFFLAGS:
+ RAL_LOCK(sc);
+ startall = 0;
if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ rt2661_init_locked(sc);
+ startall = 1;
+ } else
rt2661_update_promisc(ifp);
- else
- rt2661_init(sc);
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- rt2661_stop(sc);
+ rt2661_stop_locked(sc);
}
+ RAL_UNLOCK(sc);
+ if (startall) /* NB: need to drop lock */
+ ieee80211_start_all(ic);
break;
case SIOCGIFMEDIA:
case SIOCSIFMEDIA:
@@ -2317,16 +2328,15 @@
}
static void
-rt2661_init(void *priv)
+rt2661_init_locked(struct rt2661_softc *sc)
{
#define N(a) (sizeof (a) / sizeof ((a)[0]))
- struct rt2661_softc *sc = priv;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
uint32_t tmp, sta[3];
int i, error, ntries;
- RAL_LOCK(sc);
+ RAL_LOCK_ASSERT(sc);
if ((sc->sc_flags & RAL_FW_LOADED) == 0) {
error = rt2661_load_microcode(sc);
@@ -2334,7 +2344,6 @@
if_printf(ifp,
"%s: could not load 8051 microcode, error %d\n",
__func__, error);
- RAL_UNLOCK(sc);
return;
}
sc->sc_flags |= RAL_FW_LOADED;
@@ -2401,13 +2410,11 @@
if (ntries == 1000) {
printf("timeout waiting for BBP/RF to wakeup\n");
rt2661_stop_locked(sc);
- RAL_UNLOCK(sc);
return;
}
if (rt2661_bbp_init(sc) != 0) {
rt2661_stop_locked(sc);
- RAL_UNLOCK(sc);
return;
}
@@ -2451,20 +2458,22 @@
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
ifp->if_drv_flags |= IFF_DRV_RUNNING;
- RAL_UNLOCK(sc);
-
- ieee80211_start_all(ic); /* start all vap's */
+ callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
#undef N
}
-void
-rt2661_stop(void *priv)
+static void
+rt2661_init(void *priv)
{
struct rt2661_softc *sc = priv;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
RAL_LOCK(sc);
- rt2661_stop_locked(sc);
+ rt2661_init_locked(sc);
RAL_UNLOCK(sc);
+
+ ieee80211_start_all(ic);
}
void
@@ -2474,12 +2483,13 @@
uint32_t tmp;
volatile int *flags = &sc->sc_flags;
- while (*flags & RAL_INPUT_RUNNING) {
+ while (*flags & RAL_INPUT_RUNNING)
msleep(sc, &sc->sc_mtx, 0, "ralrunning", hz/10);
- }
+
+ callout_stop(&sc->watchdog_ch);
+ sc->sc_tx_timer = 0;
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- sc->sc_tx_timer = 0;
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
/* abort Tx (for all 5 Tx rings) */
@@ -2511,6 +2521,16 @@
}
}
+void
+rt2661_stop(void *priv)
+{
+ struct rt2661_softc *sc = priv;
+
+ RAL_LOCK(sc);
+ rt2661_stop_locked(sc);
+ RAL_UNLOCK(sc);
+}
+
static int
rt2661_load_microcode(struct rt2661_softc *sc)
{
More information about the p4-projects
mailing list