/* * 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); }
void ieee80211_vap_detach(struct ieee80211vap *vap) { int i; ieee80211_quiet_vdetach(vap); ieee80211_vap_ath_info_detach(vap->iv_vap_ath_info_handle); ieee80211_node_latevdetach(vap); ieee80211_proto_vdetach(vap); ieee80211_power_vdetach(vap); ieee80211_aow_vdetach(vap); ieee80211_mlme_vdetach(vap); ieee80211_ald_vdetach(vap); ieee80211_scs_vdetach(vap); ieee80211_rrm_vdetach(vap); ieee80211_wnm_vdetach(vap); /* * detach ique features/functions */ if (vap->iv_ique_ops.me_detach) { vap->iv_ique_ops.me_detach(vap); } if (vap->iv_ique_ops.hbr_detach) { vap->iv_ique_ops.hbr_detach(vap); } ieee80211_aplist_vdetach(&(vap->iv_candidate_aplist)); ieee80211_aplist_config_vdetach(&(vap->iv_aplist_config)); ieee80211_resmgr_vdetach(vap->iv_ic->ic_resmgr, vap); ieee80211_acl_detach(vap); ieee80211_scan_table_vdetach(&(vap->iv_scan_table)); ieee80211_acl_detach(vap); #if ATH_SUPPORT_WIFIPOS ieee80211_wifipos_vdetach(vap); #endif for (i = 0; i < IEEE80211_WEP_NKID; i++) { ieee80211_crypto_freekey(vap, &vap->iv_nw_keys[i]); } spin_lock_destroy(&vap->iv_lock); }
void ieee80211_vap_detach(struct ieee80211vap *vap) { int i; ieee80211_vap_ath_info_detach(vap->iv_vap_ath_info_handle); ieee80211_node_latevdetach(vap); ieee80211_proto_vdetach(vap); ieee80211_power_vdetach(vap); ieee80211_mlme_vdetach(vap); ieee80211_scs_vdetach(vap); #if 0 /*zhaoyang1 transplant from 717*/ /*Begin:Added by duanmingzhe for traffic limit*/ del_timer(&(vap->traffic_limit_timer)); /*End:Added by duanmingzhe for traffic limit*/ /*zhaoyang1 transplant end*/ #endif /* * detach ique features/functions */ if (vap->iv_ique_ops.me_detach) { vap->iv_ique_ops.me_detach(vap); } if (vap->iv_ique_ops.hbr_detach) { vap->iv_ique_ops.hbr_detach(vap); } ieee80211_aplist_vdetach(&(vap->iv_candidate_aplist)); ieee80211_aplist_config_vdetach(&(vap->iv_aplist_config)); ieee80211_resmgr_vdetach(vap->iv_ic->ic_resmgr, vap); ieee80211_acl_detach(vap); ieee80211_scan_table_vdetach(&(vap->iv_scan_table)); ieee80211_acl_detach(vap); for (i = 0; i < IEEE80211_WEP_NKID; i++) { ieee80211_crypto_freekey(vap, &vap->iv_nw_keys[i]); } spin_lock_destroy(&vap->iv_lock); }