From owner-p4-projects@FreeBSD.ORG Fri Apr 18 18:17:36 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 225EB1065674; Fri, 18 Apr 2008 18:17:36 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D6CEB1065670 for ; Fri, 18 Apr 2008 18:17:35 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id C2B3C8FC25 for ; Fri, 18 Apr 2008 18:17:35 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m3IIHZZx057135 for ; Fri, 18 Apr 2008 18:17:35 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m3IIHZbW057133 for perforce@freebsd.org; Fri, 18 Apr 2008 18:17:35 GMT (envelope-from sam@freebsd.org) Date: Fri, 18 Apr 2008 18:17:35 GMT Message-Id: <200804181817.m3IIHZbW057133@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 140217 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Apr 2008 18:17:36 -0000 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) {