Date: Fri, 18 Apr 2008 18:17:35 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 140217 for review Message-ID: <200804181817.m3IIHZbW057133@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=140217 Change 140217 by sam@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) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200804181817.m3IIHZbW057133>