--- a/sys/bus/u4b/wlan/if_urtwn.c +++ b/sys/bus/u4b/wlan/if_urtwn.c @@ -837,8 +837,12 @@ struct urtwn_softc *sc = ic->ic_softc; struct urtwn_vap *uvp = URTWN_VAP(vap); - if (uvp->bcn_mbuf != NULL) + /* Serialize against urtwn_update_beacon()/urtwn_tx_beacon(). */ + if (uvp->bcn_mbuf != NULL) { + URTWN_LOCK(sc); m_freem(uvp->bcn_mbuf); + URTWN_UNLOCK(sc); + } if (vap->iv_opmode == IEEE80211_M_IBSS) ieee80211_draintask(ic, &uvp->tsf_task_adhoc); if (URTWN_CHIP_HAS_RATECTL(sc)) @@ -2203,15 +2207,17 @@ return; } } - URTWN_UNLOCK(sc); if (item == IEEE80211_BEACON_TIM) mcast = 1; /* XXX */ setbit(bo->bo_flags, item); + /* + * Keep sc_mtx held: uvp->bcn_mbuf must not be freed/replaced by a + * concurrent urtwn_setup_beacon() (newstate drops the com lock) + * or urtwn_vap_delete() while we write into it. + */ ieee80211_beacon_update(ni, uvp->bcn_mbuf, mcast); - - URTWN_LOCK(sc); urtwn_tx_beacon(sc, uvp); URTWN_UNLOCK(sc); }