/* * Tear down vap state and reclaim the ifnet. * The driver is assumed to have prepared for * this; e.g. by turning off interrupts for the * underlying device. */ void ieee80211_vap_detach(struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; struct ifnet *ifp = vap->iv_ifp; IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s parent %s\n", __func__, ieee80211_opmode_name[vap->iv_opmode], ic->ic_ifp->if_xname); /* NB: bpfdetach is called by ether_ifdetach and claims all taps */ ether_ifdetach(ifp); ieee80211_stop(vap); /* * Flush any deferred vap tasks. */ ieee80211_draintask(ic, &vap->iv_nstate_task); ieee80211_draintask(ic, &vap->iv_swbmiss_task); /* XXX band-aid until ifnet handles this for us */ taskqueue_drain(taskqueue_swi, &ifp->if_linktask); IEEE80211_LOCK(ic); KASSERT(vap->iv_state == IEEE80211_S_INIT , ("vap still running")); TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next); ieee80211_syncflag_locked(ic, IEEE80211_F_WME); #ifdef IEEE80211_SUPPORT_SUPERG ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP); #endif ieee80211_syncflag_locked(ic, IEEE80211_F_PCF); ieee80211_syncflag_locked(ic, IEEE80211_F_BURST); ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT); ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40); /* NB: this handles the bpfdetach done below */ ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_BPF); ieee80211_syncifflag_locked(ic, IFF_PROMISC); ieee80211_syncifflag_locked(ic, IFF_ALLMULTI); IEEE80211_UNLOCK(ic); ifmedia_removeall(&vap->iv_media); ieee80211_radiotap_vdetach(vap); ieee80211_regdomain_vdetach(vap); ieee80211_scan_vdetach(vap); #ifdef IEEE80211_SUPPORT_SUPERG ieee80211_superg_vdetach(vap); #endif ieee80211_ht_vdetach(vap); /* NB: must be before ieee80211_node_vdetach */ ieee80211_proto_vdetach(vap); ieee80211_crypto_vdetach(vap); ieee80211_power_vdetach(vap); ieee80211_node_vdetach(vap); ieee80211_sysctl_vdetach(vap); if_free(ifp); }
static void ieee80211_swscan_detach(struct ieee80211com *ic) { struct ieee80211_scan_state *ss = ic->ic_scan; if (ss != NULL) { scan_signal(ss, ISCAN_ABORT); ieee80211_draintask(ic, &SCAN_PRIVATE(ss)->ss_scan_start); taskqueue_drain_timeout(ic->ic_tq, &SCAN_PRIVATE(ss)->ss_scan_curchan); KASSERT((ic->ic_flags & IEEE80211_F_SCAN) == 0, ("scan still running")); /* * For now, do the ss_ops detach here rather * than ieee80211_scan_detach(). * * I'll figure out how to cleanly split things up * at a later date. */ if (ss->ss_ops != NULL) { ss->ss_ops->scan_detach(ss); ss->ss_ops = NULL; } ic->ic_scan = NULL; IEEE80211_FREE(SCAN_PRIVATE(ss), M_80211_SCAN); } }
void ieee80211_scan_detach(struct ieee80211com *ic) { struct ieee80211_scan_state *ss = ic->ic_scan; if (ss != NULL) { IEEE80211_LOCK(ic); SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_ABORT; scan_signal(ss); IEEE80211_UNLOCK(ic); ieee80211_draintask(ic, &SCAN_PRIVATE(ss)->ss_scan_task); callout_drain(&SCAN_PRIVATE(ss)->ss_scan_timer); KASSERT((ic->ic_flags & IEEE80211_F_SCAN) == 0, ("scan still running")); if (ss->ss_ops != NULL) { ss->ss_ops->scan_detach(ss); ss->ss_ops = NULL; } ic->ic_scan = NULL; free(SCAN_PRIVATE(ss), M_80211_SCAN); } #if defined(__ANTARES__) ieee80211_scan_sta_uninit(); #endif }
void athp_taskq_stop(struct ath10k *ar) { struct ieee80211com *ic = &ar->sc_ic; struct athp_taskq_head *h; h = ar->sc_taskq_head; if (h == NULL) return; ath10k_dbg(ar, ATH10K_DBG_TASKQ, "%s: called\n", __func__); ATHP_TASKQ_LOCK(h); h->is_running = 0; ATHP_TASKQ_UNLOCK(h); ieee80211_draintask(ic, &h->run_task); }
void ieee80211_scan_detach(struct ieee80211com *ic) { struct ieee80211_scan_state *ss = ic->ic_scan; if (ss != NULL) { SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_ABORT; scan_signal(ss); ieee80211_draintask(ic, &SCAN_PRIVATE(ss)->ss_scan_task); callout_stop(&SCAN_PRIVATE(ss)->ss_scan_timer); KASSERT((ic->ic_flags & IEEE80211_F_SCAN) == 0, ("scan still running")); if (ss->ss_ops != NULL) { ss->ss_ops->scan_detach(ss); ss->ss_ops = NULL; } ic->ic_scan = NULL; kfree(SCAN_PRIVATE(ss), M_80211_SCAN); } }