--- a/sys/bus/u4b/wlan/if_rum.c +++ b/sys/bus/u4b/wlan/if_rum.c @@ -711,7 +711,13 @@ { struct rum_vap *rvp = RUM_VAP(vap); struct ieee80211com *ic = vap->iv_ic; + struct rum_softc *sc = ic->ic_softc; + /* Stop the ratectl callout/task pair BEFORE draining it, + * so the task cannot re-arm the callout after the drain. */ + RUM_LOCK(sc); + sc->ratectl_run = 0; + RUM_UNLOCK(sc); m_freem(rvp->bcn_mbuf); usb_callout_drain(&rvp->ratectl_ch); ieee80211_draintask(ic, &rvp->ratectl_task); @@ -932,6 +938,7 @@ IEEE80211_UNLOCK(ic); RUM_LOCK(sc); usb_callout_stop(&rvp->ratectl_ch); + sc->ratectl_run = 0; if (ostate == IEEE80211_S_SLEEP && vap->iv_opmode == IEEE80211_M_STA) { rum_clrbits(sc, RT2573_TXRX_CSR4, RT2573_ACKCTS_PWRMGT); @@ -3090,6 +3097,7 @@ /* clear statistic registers (STA_CSR0 to STA_CSR5) */ rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta); + sc->ratectl_run = 1; usb_callout_reset(&rvp->ratectl_ch, hz, rum_ratectl_timeout, rvp); } @@ -3137,7 +3145,8 @@ /* count TX retry-fail as Tx errors */ if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, fail); - usb_callout_reset(&rvp->ratectl_ch, hz, rum_ratectl_timeout, rvp); + if (sc->ratectl_run) + usb_callout_reset(&rvp->ratectl_ch, hz, rum_ratectl_timeout, rvp); RUM_UNLOCK(sc); } --- a/sys/bus/u4b/wlan/if_rumvar.h +++ b/sys/bus/u4b/wlan/if_rumvar.h @@ -152,6 +152,7 @@ uint8_t vap_key_count[1]; uint64_t keys_bmap; + uint8_t ratectl_run; struct { uint8_t val;