/* * Handle a station leaving an 11g network. */ static void ieee80211_node_leave_11g(struct ieee80211com *ic, struct ieee80211_node *ni) { if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)) { #ifdef DIAGNOSTIC if (ic->ic_longslotsta == 0) { panic("bogus long slot station count %d", ic->ic_longslotsta); } #endif /* leaving STA did not support short slot time */ if (--ic->ic_longslotsta == 0) { /* * All associated STAs now support short slot time, so * enable this feature and give the driver a chance to * reconfigure the hardware. Notice that IBSS always * use a long slot time. */ if ((ic->ic_caps & IEEE80211_C_SHSLOT) && ic->ic_opmode != IEEE80211_M_IBSS) ieee80211_set_shortslottime(ic, 1); } IEEE80211_DPRINTF(("[%s] long slot time station leaves, " "count now %d\n", ether_sprintf(ni->ni_macaddr), ic->ic_longslotsta)); } if (!(ni->ni_flags & IEEE80211_NODE_ERP)) { #ifdef DIAGNOSTIC if (ic->ic_nonerpsta == 0) { panic("bogus non-ERP station count %d\n", ic->ic_nonerpsta); } #endif /* leaving STA was non-ERP */ if (--ic->ic_nonerpsta == 0) { /* * All associated STAs are now ERP capable, disable use * of protection and re-enable short preamble support. */ ic->ic_flags &= ~IEEE80211_F_USEPROT; if (ic->ic_caps & IEEE80211_C_SHPREAMBLE) ic->ic_flags |= IEEE80211_F_SHPREAMBLE; } IEEE80211_DPRINTF(("[%s] non-ERP station leaves, " "count now %d\n", ether_sprintf(ni->ni_macaddr), ic->ic_nonerpsta)); } }
/* * Handle a station joining an 11g network. */ static void ieee80211_node_join_11g(struct ieee80211com *ic, struct ieee80211_node *ni) { if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)) { /* * Joining STA doesn't support short slot time. We must * disable the use of short slot time for all other associated * STAs and give the driver a chance to reconfigure the * hardware. */ if (++ic->ic_longslotsta == 1) { if (ic->ic_caps & IEEE80211_C_SHSLOT) ieee80211_set_shortslottime(ic, 0); } IEEE80211_DPRINTF(("[%s] station needs long slot time, " "count %d\n", ether_sprintf(ni->ni_macaddr), ic->ic_longslotsta)); } if (!ieee80211_iserp_sta(ni)) { /* * Joining STA is non-ERP. */ ic->ic_nonerpsta++; IEEE80211_DPRINTF(("[%s] station is non-ERP, %d non-ERP " "stations associated\n", ether_sprintf(ni->ni_macaddr), ic->ic_nonerpsta)); /* must enable the use of protection */ if (ic->ic_protmode != IEEE80211_PROT_NONE) { IEEE80211_DPRINTF(("%s: enable use of protection\n", __func__)); ic->ic_flags |= IEEE80211_F_USEPROT; } if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE; } else ni->ni_flags |= IEEE80211_NODE_ERP; }
/* * Handle a station leaving an 11g network. */ static void ieee80211_node_leave_11g(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; struct ieee80211vap *vap = ni->ni_vap; KASSERT((IEEE80211_IS_CHAN_ANYG(vap->iv_bsschan) || IEEE80211_IS_CHAN_11NG(vap->iv_bsschan)), ("not in 11g, bss %u:0x%x, curmode %u", vap->iv_bsschan->ic_freq, vap->iv_bsschan->ic_flags, ic->ic_curmode)); KASSERT((ni->ni_vap->iv_opmode == IEEE80211_M_HOSTAP || ni->ni_vap->iv_opmode == IEEE80211_M_BTAMP), (" node leave in invalid opmode ")); /* * If a long slot station do the slot time bookkeeping. */ if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) { if (ic->ic_longslotsta) { ic->ic_longslotsta--; IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, "long slot time station leaves, count now %d", ic->ic_longslotsta); } else { #ifdef NOT_YET KASSERT(ic->ic_longslotsta > 0, ("bogus long slot station count %d", ic->ic_longslotsta)); #endif IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, "bogus long slot station count %d", ic->ic_longslotsta); } if (ic->ic_longslotsta == 0) { /* * Re-enable use of short slot time if supported * and not operating in IBSS mode (per spec). */ if (ic->ic_caps & IEEE80211_C_SHSLOT) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC, "%s: re-enable use of short slot time\n", __func__); ieee80211_set_shortslottime(ic, 1); } } } /* * If a non-ERP station do the protection-related bookkeeping. */ if ((ni->ni_flags & IEEE80211_NODE_ERP) == 0) { KASSERT(ic->ic_nonerpsta > 0, ("bogus non-ERP station count %d", ic->ic_nonerpsta)); ic->ic_nonerpsta--; IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, "non-ERP station leaves, count now %d", ic->ic_nonerpsta); if (ic->ic_nonerpsta == 0) { struct ieee80211vap *tmpvap; ieee80211_update_erp_info(vap); /* XXX verify mode? */ if (ic->ic_caps & IEEE80211_C_SHPREAMBLE) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC, "%s: re-enable use of short preamble\n", __func__); ic->ic_flags |= IEEE80211_F_SHPREAMBLE; ic->ic_flags &= ~IEEE80211_F_USEBARKER; } TAILQ_FOREACH(tmpvap, &(ic)->ic_vaps, iv_next) ieee80211_vap_erpupdate_set(tmpvap); } } }
/* * Handle a station joining an 11g network. */ static void ieee80211_node_join_11g(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; struct ieee80211vap *vap = ni->ni_vap; KASSERT((IEEE80211_IS_CHAN_ANYG(vap->iv_bsschan) || IEEE80211_IS_CHAN_11NG(vap->iv_bsschan)), ("not in 11g, bss %u:0x%x, curmode %u", vap->iv_bsschan->ic_freq, vap->iv_bsschan->ic_flags, ic->ic_curmode)); KASSERT((ni->ni_vap->iv_opmode == IEEE80211_M_HOSTAP || ni->ni_vap->iv_opmode == IEEE80211_M_BTAMP), (" node join in invalid opmode ")); /* * Station isn't capable of short slot time. Bump * the count of long slot time stations and disable * use of short slot time. Note that the actual switch * over to long slot time use may not occur until the * next beacon transmission (per sec. 7.3.1.4 of 11g). */ if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) { ic->ic_longslotsta++; IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ASSOC, ni, "station needs long slot time, count %d", ic->ic_longslotsta); /* XXX vap's w/ conflicting needs won't work */ if (!IEEE80211_IS_CHAN_108G(vap->iv_bsschan)) { /* * Don't force slot time when switched to turbo * mode as non-ERP stations won't be present; this * need only be done when on the normal G channel. */ ieee80211_set_shortslottime(ic, 0); } } /* * If the new station is not an ERP station * then bump the counter and enable protection * if configured. */ if (!ieee80211_iserp_rateset(ic, &ni->ni_rates)) { ic->ic_nonerpsta++; IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ASSOC, ni, "station is !ERP, %d non-ERP stations associated", ic->ic_nonerpsta); /* * If protection is configured, enable it. */ if (ic->ic_protmode != IEEE80211_PROT_NONE) { IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_ASSOC, "%s: enable use of protection\n", __func__); ic->ic_flags |= IEEE80211_F_USEPROT; ic->ic_update_protmode(ic); } /* * If station does not support short preamble * then we must enable use of Barker preamble. */ if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) == 0) { IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ASSOC, ni, "%s", "station needs long preamble"); ic->ic_flags |= IEEE80211_F_USEBARKER; ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE; } /* Update ERP element if this is first non ERP station */ if (ic->ic_nonerpsta == 1) { struct ieee80211vap *tmpvap; TAILQ_FOREACH(tmpvap, &(ic)->ic_vaps, iv_next) ieee80211_vap_erpupdate_set(tmpvap); } } else ni->ni_flags |= IEEE80211_NODE_ERP; }
void ieee80211_mlme_join_infra_continue(struct ieee80211vap *vap, int32_t status) { struct ieee80211com *ic = vap->iv_ic; struct ieee80211_node *ni; struct ieee80211_mlme_priv *mlme_priv = vap->iv_mlme_priv; u_int32_t join_timeout_ms; if (mlme_priv->im_request_type != MLME_REQ_JOIN_INFRA) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s : im_request_type != JOIN_INFRA\n", __func__); return; } if (status != EOK) { mlme_priv->im_request_type = MLME_REQ_NONE; IEEE80211_DELIVER_EVENT_MLME_JOIN_COMPLETE_INFRA(vap, IEEE80211_STATUS_UNSPECIFIED); return; } /* iv_bss is valid only after ieee80211_sta_join */ ni = vap->iv_bss; IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s ni=%02X:%02X:%02X:%02X:%02X:%02X\n", __func__, ni->ni_macaddr[0], ni->ni_macaddr[1], ni->ni_macaddr[2], ni->ni_macaddr[3], ni->ni_macaddr[4], ni->ni_macaddr[5]); /* Update erp info */ if (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION) ic->ic_flags |= IEEE80211_F_USEPROT; else ic->ic_flags &= ~IEEE80211_F_USEPROT; ic->ic_update_protmode(ic); if(ni->ni_erp & IEEE80211_ERP_LONG_PREAMBLE) ic->ic_flags |= IEEE80211_F_USEBARKER; else ic->ic_flags &= (~IEEE80211_F_USEBARKER); /* Update slot time info */ ieee80211_set_shortslottime(ic, IEEE80211_IS_CHAN_A(vap->iv_bsschan) || IEEE80211_IS_CHAN_11NA(vap->iv_bsschan) || (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)); /* Put underlying H/W to JOIN state */ ieee80211_vap_join(vap); #ifdef ATH_SUPPORT_TxBF ieee80211_init_txbf(ic, ni); #endif /* Send a direct probe to increase the odds of receiving a probe response */ ieee80211_send_probereq(ni, ic->ic_myaddr, ni->ni_bssid, ni->ni_bssid, ni->ni_essid, ni->ni_esslen, vap->iv_opt_ie.ie, vap->iv_opt_ie.length); /* Set the timeout timer for Join Failure case. */ join_timeout_ms = IEEE80211_TU_TO_MS(mlme_priv->im_timeout * ni->ni_intval); IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: Setting Join Timeout timer for %d ms\n", __func__, join_timeout_ms); OS_SET_TIMER(&mlme_priv->im_timeout_timer, join_timeout_ms); /* Set the appropriate filtering function and wait for Join Beacon */ MLME_WAIT_FOR_BSS_JOIN(mlme_priv); }
/*zhaoyang1 transplant end*/ int wlan_set_param(wlan_if_t vaphandle, ieee80211_param param, u_int32_t val) { struct ieee80211vap *vap = vaphandle; struct ieee80211com *ic = vap->iv_ic; struct ieee80211_node_table *nt = &ic->ic_sta; int retv = 0; switch (param) { case IEEE80211_AUTO_ASSOC: if (val) IEEE80211_VAP_AUTOASSOC_ENABLE(vap); else IEEE80211_VAP_AUTOASSOC_DISABLE(vap); break; case IEEE80211_SAFE_MODE: if (val) IEEE80211_VAP_SAFEMODE_ENABLE(vap); else IEEE80211_VAP_SAFEMODE_DISABLE(vap); break; case IEEE80211_SEND_80211: if (val) IEEE80211_VAP_SEND_80211_ENABLE(vap); else IEEE80211_VAP_SEND_80211_DISABLE(vap); break; case IEEE80211_RECEIVE_80211: if (val) IEEE80211_VAP_DELIVER_80211_ENABLE(vap); else IEEE80211_VAP_DELIVER_80211_DISABLE(vap); break; case IEEE80211_FEATURE_DROP_UNENC: if (val) IEEE80211_VAP_DROP_UNENC_ENABLE(vap); else IEEE80211_VAP_DROP_UNENC_DISABLE(vap); break; #ifdef ATH_COALESCING case IEEE80211_FEATURE_TX_COALESCING: ic->ic_tx_coalescing = val; break; #endif case IEEE80211_SHORT_PREAMBLE: if (val) IEEE80211_ENABLE_CAP_SHPREAMBLE(ic); else IEEE80211_DISABLE_CAP_SHPREAMBLE(ic); retv = EOK; break; case IEEE80211_SHORT_SLOT: if (val) ieee80211_set_shortslottime(ic, 1); else ieee80211_set_shortslottime(ic, 0); break; case IEEE80211_RTS_THRESHOLD: /* XXX This may force us to flush any packets for which we are might have already calculated the RTS */ if (val > IEEE80211_RTS_MAX) vap->iv_rtsthreshold = IEEE80211_RTS_MAX; else vap->iv_rtsthreshold = (u_int16_t)val; break; case IEEE80211_FRAG_THRESHOLD: /* XXX We probably should flush our tx path when changing fragthresh */ if (val > 2346) vap->iv_fragthreshold = 2346; else if (val < 256) vap->iv_fragthreshold = 256; else vap->iv_fragthreshold = (u_int16_t)val; break; case IEEE80211_BEACON_INTVAL: ic->ic_intval = (u_int16_t)val; LIMIT_BEACON_PERIOD(ic->ic_intval); break; #if ATH_SUPPORT_AP_WDS_COMBO case IEEE80211_NO_BEACON: vap->iv_no_beacon = (u_int8_t) val; ic->ic_set_config(vap); break; #endif case IEEE80211_LISTEN_INTVAL: ic->ic_lintval = 1; vap->iv_bss->ni_lintval = ic->ic_lintval; break; case IEEE80211_ATIM_WINDOW: LIMIT_BEACON_PERIOD(val); vap->iv_atim_window = (u_int8_t)val; break; case IEEE80211_DTIM_INTVAL: LIMIT_DTIM_PERIOD(val); vap->iv_dtim_period = (u_int8_t)val; break; case IEEE80211_BMISS_COUNT_RESET: vap->iv_bmiss_count_for_reset = (u_int8_t)val; break; case IEEE80211_BMISS_COUNT_MAX: vap->iv_bmiss_count_max = (u_int8_t)val; break; case IEEE80211_TXPOWER: break; case IEEE80211_MULTI_DOMAIN: if(!ic->ic_country.isMultidomain) return -EINVAL; if (val) ic->ic_multiDomainEnabled = 1; else ic->ic_multiDomainEnabled = 0; break; case IEEE80211_MSG_FLAGS: /* * ic_debug will be overwritten every time the VAP debug level is changed. */ ic->ic_debug = val; vap->iv_debug = ic->ic_debug; break; case IEEE80211_FEATURE_WMM: if (!(ic->ic_caps & IEEE80211_C_WME)) return -EINVAL; if (val) ieee80211_vap_wme_set(vap); else ieee80211_vap_wme_clear(vap); break; case IEEE80211_FEATURE_PRIVACY: if (val) IEEE80211_VAP_PRIVACY_ENABLE(vap); else IEEE80211_VAP_PRIVACY_DISABLE(vap); break; case IEEE80211_FEATURE_WMM_PWRSAVE: /* * NB: AP WMM power save is a compilation option, * and can not be turned on/off at run time. */ if (vap->iv_opmode != IEEE80211_M_STA) return -EINVAL; if (val) ieee80211_set_wmm_power_save(vap, 1); else ieee80211_set_wmm_power_save(vap, 0); break; case IEEE80211_FEATURE_UAPSD: if (vap->iv_opmode == IEEE80211_M_STA) { ieee80211_set_uapsd_flags(vap, (u_int8_t)(val & WME_CAPINFO_UAPSD_ALL)); return ieee80211_pwrsave_uapsd_set_max_sp_length(vap, ((val & WME_CAPINFO_UAPSD_MAXSP_MASK)) >> WME_CAPINFO_UAPSD_MAXSP_SHIFT ); } else { if (IEEE80211_IS_UAPSD_ENABLED(ic)) {