00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <linux/delay.h>
00015 #include <linux/if_ether.h>
00016 #include <linux/skbuff.h>
00017 #include <linux/if_arp.h>
00018 #include <linux/etherdevice.h>
00019 #include <linux/moduleparam.h>
00020 #include <linux/rtnetlink.h>
00021 #include <linux/pm_qos.h>
00022 #include <linux/crc32.h>
00023 #include <linux/slab.h>
00024 #include <linux/export.h>
00025 #include <net/mac80211.h>
00026 #include <asm/unaligned.h>
00027
00028 #include "ieee80211_i.h"
00029 #include "driver-ops.h"
00030 #include "rate.h"
00031 #include "led.h"
00032
00033 #define IEEE80211_AUTH_TIMEOUT (HZ / 5)
00034 #define IEEE80211_AUTH_MAX_TRIES 3
00035 #define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5)
00036 #define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
00037 #define IEEE80211_ASSOC_MAX_TRIES 3
00038
00039 static int max_nullfunc_tries = 2;
00040 module_param(max_nullfunc_tries, int, 0644);
00041 MODULE_PARM_DESC(max_nullfunc_tries,
00042 "Maximum nullfunc tx tries before disconnecting (reason 4).");
00043
00044 static int max_probe_tries = 5;
00045 module_param(max_probe_tries, int, 0644);
00046 MODULE_PARM_DESC(max_probe_tries,
00047 "Maximum probe tries before disconnecting (reason 4).");
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #define IEEE80211_BEACON_LOSS_COUNT 7
00058
00059
00060
00061
00062
00063 #define IEEE80211_CONNECTION_IDLE_TIME (30 * HZ)
00064
00065
00066
00067
00068
00069 static int probe_wait_ms = 500;
00070 module_param(probe_wait_ms, int, 0644);
00071 MODULE_PARM_DESC(probe_wait_ms,
00072 "Maximum time(ms) to wait for probe response"
00073 " before disconnecting (reason 4).");
00074
00075
00076
00077
00078
00079
00080 #define IEEE80211_SIGNAL_AVE_WEIGHT 3
00081
00082
00083
00084
00085
00086 #define IEEE80211_SIGNAL_AVE_MIN_COUNT 4
00087
00088 #define TMR_RUNNING_TIMER 0
00089 #define TMR_RUNNING_CHANSW 1
00090
00091 #define DEAUTH_DISASSOC_LEN (24 + 2 )
00092
00093
00094
00095
00096
00097
00098
00099 enum rx_mgmt_action {
00100
00101 RX_MGMT_NONE,
00102
00103
00104 RX_MGMT_CFG80211_DEAUTH,
00105
00106
00107 RX_MGMT_CFG80211_DISASSOC,
00108
00109
00110 RX_MGMT_CFG80211_RX_AUTH,
00111
00112
00113 RX_MGMT_CFG80211_RX_ASSOC,
00114
00115
00116 RX_MGMT_CFG80211_ASSOC_TIMEOUT,
00117 };
00118
00119
00120 static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
00121 {
00122 lockdep_assert_held(&ifmgd->mtx);
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 static void run_again(struct ieee80211_if_managed *ifmgd, unsigned long timeout)
00136 {
00137 ASSERT_MGD_MTX(ifmgd);
00138
00139 if (!timer_pending(&ifmgd->timer) ||
00140 time_before(timeout, ifmgd->timer.expires))
00141 mod_timer(&ifmgd->timer, timeout);
00142 }
00143
00144 void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
00145 {
00146 if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)
00147 return;
00148
00149 mod_timer(&sdata->u.mgd.bcn_mon_timer,
00150 round_jiffies_up(jiffies + sdata->u.mgd.beacon_timeout));
00151 }
00152
00153 void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
00154 {
00155 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
00156
00157 if (unlikely(!sdata->u.mgd.associated))
00158 return;
00159
00160 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
00161 return;
00162
00163 mod_timer(&sdata->u.mgd.conn_mon_timer,
00164 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
00165
00166 ifmgd->probe_send_count = 0;
00167 }
00168
00169 static int ecw2cw(int ecw)
00170 {
00171 return (1 << ecw) - 1;
00172 }
00173
00174 static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
00175 struct ieee80211_ht_operation *ht_oper,
00176 const u8 *bssid, bool reconfig)
00177 {
00178 struct ieee80211_local *local = sdata->local;
00179 struct ieee80211_supported_band *sband;
00180 struct sta_info *sta;
00181 u32 changed = 0;
00182 u16 ht_opmode;
00183 bool disable_40 = false;
00184
00185 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
00186
00187 switch (sdata->vif.bss_conf.channel_type) {
00188 case NL80211_CHAN_HT40PLUS:
00189 if (local->hw.conf.channel->flags & IEEE80211_CHAN_NO_HT40PLUS)
00190 disable_40 = true;
00191 break;
00192 case NL80211_CHAN_HT40MINUS:
00193 if (local->hw.conf.channel->flags & IEEE80211_CHAN_NO_HT40MINUS)
00194 disable_40 = true;
00195 break;
00196 default:
00197 break;
00198 }
00199
00200
00201 if (!(ht_oper->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
00202 disable_40 = true;
00203
00204 mutex_lock(&local->sta_mtx);
00205 sta = sta_info_get(sdata, bssid);
00206
00207 WARN_ON_ONCE(!sta);
00208
00209 if (sta && !sta->supports_40mhz)
00210 disable_40 = true;
00211
00212 if (sta && (!reconfig ||
00213 (disable_40 != !(sta->sta.ht_cap.cap &
00214 IEEE80211_HT_CAP_SUP_WIDTH_20_40)))) {
00215
00216 if (disable_40)
00217 sta->sta.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
00218 else
00219 sta->sta.ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
00220
00221 rate_control_rate_update(local, sband, sta,
00222 IEEE80211_RC_BW_CHANGED);
00223 }
00224 mutex_unlock(&local->sta_mtx);
00225
00226 ht_opmode = le16_to_cpu(ht_oper->operation_mode);
00227
00228
00229 if (!reconfig || (sdata->vif.bss_conf.ht_operation_mode != ht_opmode)) {
00230 changed |= BSS_CHANGED_HT;
00231 sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
00232 }
00233
00234 return changed;
00235 }
00236
00237
00238
00239 static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
00240 struct ieee80211_supported_band *sband,
00241 u32 *rates)
00242 {
00243 int i, j, count;
00244 *rates = 0;
00245 count = 0;
00246 for (i = 0; i < supp_rates_len; i++) {
00247 int rate = (supp_rates[i] & 0x7F) * 5;
00248
00249 for (j = 0; j < sband->n_bitrates; j++)
00250 if (sband->bitrates[j].bitrate == rate) {
00251 *rates |= BIT(j);
00252 count++;
00253 break;
00254 }
00255 }
00256
00257 return count;
00258 }
00259
00260 static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
00261 struct sk_buff *skb, const u8 *ht_oper_ie,
00262 struct ieee80211_supported_band *sband,
00263 struct ieee80211_channel *channel,
00264 enum ieee80211_smps_mode smps)
00265 {
00266 struct ieee80211_ht_operation *ht_oper;
00267 u8 *pos;
00268 u32 flags = channel->flags;
00269 u16 cap;
00270 struct ieee80211_sta_ht_cap ht_cap;
00271
00272 BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));
00273
00274 if (!ht_oper_ie)
00275 return;
00276
00277 if (ht_oper_ie[1] < sizeof(struct ieee80211_ht_operation))
00278 return;
00279
00280 memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
00281 ieee80211_apply_htcap_overrides(sdata, &ht_cap);
00282
00283 ht_oper = (struct ieee80211_ht_operation *)(ht_oper_ie + 2);
00284
00285
00286 cap = ht_cap.cap;
00287
00288 switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
00289 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
00290 if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
00291 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
00292 cap &= ~IEEE80211_HT_CAP_SGI_40;
00293 }
00294 break;
00295 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
00296 if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
00297 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
00298 cap &= ~IEEE80211_HT_CAP_SGI_40;
00299 }
00300 break;
00301 }
00302
00303
00304
00305
00306
00307
00308 if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_40MHZ) {
00309 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
00310 cap &= ~IEEE80211_HT_CAP_SGI_40;
00311 }
00312
00313
00314 cap &= ~IEEE80211_HT_CAP_SM_PS;
00315 switch (smps) {
00316 case IEEE80211_SMPS_AUTOMATIC:
00317 case IEEE80211_SMPS_NUM_MODES:
00318 WARN_ON(1);
00319 case IEEE80211_SMPS_OFF:
00320 cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
00321 IEEE80211_HT_CAP_SM_PS_SHIFT;
00322 break;
00323 case IEEE80211_SMPS_STATIC:
00324 cap |= WLAN_HT_CAP_SM_PS_STATIC <<
00325 IEEE80211_HT_CAP_SM_PS_SHIFT;
00326 break;
00327 case IEEE80211_SMPS_DYNAMIC:
00328 cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
00329 IEEE80211_HT_CAP_SM_PS_SHIFT;
00330 break;
00331 }
00332
00333
00334 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
00335 ieee80211_ie_build_ht_cap(pos, &ht_cap, cap);
00336 }
00337
00338 static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
00339 {
00340 struct ieee80211_local *local = sdata->local;
00341 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
00342 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
00343 struct sk_buff *skb;
00344 struct ieee80211_mgmt *mgmt;
00345 u8 *pos, qos_info;
00346 size_t offset = 0, noffset;
00347 int i, count, rates_len, supp_rates_len;
00348 u16 capab;
00349 struct ieee80211_supported_band *sband;
00350 u32 rates = 0;
00351
00352 lockdep_assert_held(&ifmgd->mtx);
00353
00354 sband = local->hw.wiphy->bands[local->oper_channel->band];
00355
00356 if (assoc_data->supp_rates_len) {
00357
00358
00359
00360
00361
00362
00363 rates_len = ieee80211_compatible_rates(assoc_data->supp_rates,
00364 assoc_data->supp_rates_len,
00365 sband, &rates);
00366 } else {
00367
00368
00369
00370
00371
00372 rates = ~0;
00373 rates_len = sband->n_bitrates;
00374 }
00375
00376 skb = alloc_skb(local->hw.extra_tx_headroom +
00377 sizeof(*mgmt) +
00378 2 + assoc_data->ssid_len +
00379 4 + rates_len +
00380 4 +
00381 2 + 2 * sband->n_channels +
00382 2 + sizeof(struct ieee80211_ht_cap) +
00383 assoc_data->ie_len +
00384 9,
00385 GFP_KERNEL);
00386 if (!skb)
00387 return;
00388
00389 skb_reserve(skb, local->hw.extra_tx_headroom);
00390
00391 capab = WLAN_CAPABILITY_ESS;
00392
00393 if (sband->band == IEEE80211_BAND_2GHZ) {
00394 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
00395 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
00396 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
00397 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
00398 }
00399
00400 if (assoc_data->capability & WLAN_CAPABILITY_PRIVACY)
00401 capab |= WLAN_CAPABILITY_PRIVACY;
00402
00403 if ((assoc_data->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
00404 (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
00405 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
00406
00407 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
00408 memset(mgmt, 0, 24);
00409 memcpy(mgmt->da, assoc_data->bss->bssid, ETH_ALEN);
00410 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
00411 memcpy(mgmt->bssid, assoc_data->bss->bssid, ETH_ALEN);
00412
00413 if (!is_zero_ether_addr(assoc_data->prev_bssid)) {
00414 skb_put(skb, 10);
00415 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
00416 IEEE80211_STYPE_REASSOC_REQ);
00417 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
00418 mgmt->u.reassoc_req.listen_interval =
00419 cpu_to_le16(local->hw.conf.listen_interval);
00420 memcpy(mgmt->u.reassoc_req.current_ap, assoc_data->prev_bssid,
00421 ETH_ALEN);
00422 } else {
00423 skb_put(skb, 4);
00424 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
00425 IEEE80211_STYPE_ASSOC_REQ);
00426 mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
00427 mgmt->u.assoc_req.listen_interval =
00428 cpu_to_le16(local->hw.conf.listen_interval);
00429 }
00430
00431
00432 pos = skb_put(skb, 2 + assoc_data->ssid_len);
00433 *pos++ = WLAN_EID_SSID;
00434 *pos++ = assoc_data->ssid_len;
00435 memcpy(pos, assoc_data->ssid, assoc_data->ssid_len);
00436
00437
00438 supp_rates_len = rates_len;
00439 if (supp_rates_len > 8)
00440 supp_rates_len = 8;
00441
00442 pos = skb_put(skb, supp_rates_len + 2);
00443 *pos++ = WLAN_EID_SUPP_RATES;
00444 *pos++ = supp_rates_len;
00445
00446 count = 0;
00447 for (i = 0; i < sband->n_bitrates; i++) {
00448 if (BIT(i) & rates) {
00449 int rate = sband->bitrates[i].bitrate;
00450 *pos++ = (u8) (rate / 5);
00451 if (++count == 8)
00452 break;
00453 }
00454 }
00455
00456 if (rates_len > count) {
00457 pos = skb_put(skb, rates_len - count + 2);
00458 *pos++ = WLAN_EID_EXT_SUPP_RATES;
00459 *pos++ = rates_len - count;
00460
00461 for (i++; i < sband->n_bitrates; i++) {
00462 if (BIT(i) & rates) {
00463 int rate = sband->bitrates[i].bitrate;
00464 *pos++ = (u8) (rate / 5);
00465 }
00466 }
00467 }
00468
00469 if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
00470
00471 pos = skb_put(skb, 4);
00472 *pos++ = WLAN_EID_PWR_CAPABILITY;
00473 *pos++ = 2;
00474 *pos++ = 0;
00475 *pos++ = local->oper_channel->max_power;
00476
00477
00478
00479 pos = skb_put(skb, 2 * sband->n_channels + 2);
00480 *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
00481 *pos++ = 2 * sband->n_channels;
00482 for (i = 0; i < sband->n_channels; i++) {
00483 *pos++ = ieee80211_frequency_to_channel(
00484 sband->channels[i].center_freq);
00485 *pos++ = 1;
00486 }
00487 }
00488
00489
00490 if (assoc_data->ie_len && assoc_data->ie) {
00491 static const u8 before_ht[] = {
00492 WLAN_EID_SSID,
00493 WLAN_EID_SUPP_RATES,
00494 WLAN_EID_EXT_SUPP_RATES,
00495 WLAN_EID_PWR_CAPABILITY,
00496 WLAN_EID_SUPPORTED_CHANNELS,
00497 WLAN_EID_RSN,
00498 WLAN_EID_QOS_CAPA,
00499 WLAN_EID_RRM_ENABLED_CAPABILITIES,
00500 WLAN_EID_MOBILITY_DOMAIN,
00501 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
00502 };
00503 noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len,
00504 before_ht, ARRAY_SIZE(before_ht),
00505 offset);
00506 pos = skb_put(skb, noffset - offset);
00507 memcpy(pos, assoc_data->ie + offset, noffset - offset);
00508 offset = noffset;
00509 }
00510
00511 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
00512 ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_operation_ie,
00513 sband, local->oper_channel, ifmgd->ap_smps);
00514
00515
00516 if (assoc_data->ie_len && assoc_data->ie) {
00517 noffset = ieee80211_ie_split_vendor(assoc_data->ie,
00518 assoc_data->ie_len,
00519 offset);
00520 pos = skb_put(skb, noffset - offset);
00521 memcpy(pos, assoc_data->ie + offset, noffset - offset);
00522 offset = noffset;
00523 }
00524
00525 if (assoc_data->wmm) {
00526 if (assoc_data->uapsd) {
00527 qos_info = ifmgd->uapsd_queues;
00528 qos_info |= (ifmgd->uapsd_max_sp_len <<
00529 IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
00530 } else {
00531 qos_info = 0;
00532 }
00533
00534 pos = skb_put(skb, 9);
00535 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
00536 *pos++ = 7;
00537 *pos++ = 0x00;
00538 *pos++ = 0x50;
00539 *pos++ = 0xf2;
00540 *pos++ = 2;
00541 *pos++ = 0;
00542 *pos++ = 1;
00543 *pos++ = qos_info;
00544 }
00545
00546
00547 if (assoc_data->ie_len && assoc_data->ie) {
00548 noffset = assoc_data->ie_len;
00549 pos = skb_put(skb, noffset - offset);
00550 memcpy(pos, assoc_data->ie + offset, noffset - offset);
00551 }
00552
00553 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
00554 ieee80211_tx_skb(sdata, skb);
00555 }
00556
00557 static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
00558 const u8 *bssid, u16 stype,
00559 u16 reason, bool send_frame,
00560 u8 *frame_buf)
00561 {
00562 struct ieee80211_local *local = sdata->local;
00563 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
00564 struct sk_buff *skb;
00565 struct ieee80211_mgmt *mgmt = (void *)frame_buf;
00566
00567
00568 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
00569 mgmt->duration = 0;
00570 mgmt->seq_ctrl = 0;
00571 memcpy(mgmt->da, bssid, ETH_ALEN);
00572 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
00573 memcpy(mgmt->bssid, bssid, ETH_ALEN);
00574
00575 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
00576
00577 if (send_frame) {
00578 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
00579 DEAUTH_DISASSOC_LEN);
00580 if (!skb)
00581 return;
00582
00583 skb_reserve(skb, local->hw.extra_tx_headroom);
00584
00585
00586 memcpy(skb_put(skb, DEAUTH_DISASSOC_LEN),
00587 mgmt, DEAUTH_DISASSOC_LEN);
00588
00589 if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
00590 IEEE80211_SKB_CB(skb)->flags |=
00591 IEEE80211_TX_INTFL_DONT_ENCRYPT;
00592 ieee80211_tx_skb(sdata, skb);
00593 }
00594 }
00595
00596 void ieee80211_send_pspoll(struct ieee80211_local *local,
00597 struct ieee80211_sub_if_data *sdata)
00598 {
00599 struct ieee80211_pspoll *pspoll;
00600 struct sk_buff *skb;
00601
00602 skb = ieee80211_pspoll_get(&local->hw, &sdata->vif);
00603 if (!skb)
00604 return;
00605
00606 pspoll = (struct ieee80211_pspoll *) skb->data;
00607 pspoll->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
00608
00609 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
00610 ieee80211_tx_skb(sdata, skb);
00611 }
00612
00613 void ieee80211_send_nullfunc(struct ieee80211_local *local,
00614 struct ieee80211_sub_if_data *sdata,
00615 int powersave)
00616 {
00617 struct sk_buff *skb;
00618 struct ieee80211_hdr_3addr *nullfunc;
00619 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
00620
00621 skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif);
00622 if (!skb)
00623 return;
00624
00625 nullfunc = (struct ieee80211_hdr_3addr *) skb->data;
00626 if (powersave)
00627 nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
00628
00629 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
00630 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
00631 IEEE80211_STA_CONNECTION_POLL))
00632 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE;
00633
00634 ieee80211_tx_skb(sdata, skb);
00635 }
00636
00637 static void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local,
00638 struct ieee80211_sub_if_data *sdata)
00639 {
00640 struct sk_buff *skb;
00641 struct ieee80211_hdr *nullfunc;
00642 __le16 fc;
00643
00644 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
00645 return;
00646
00647 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 30);
00648 if (!skb)
00649 return;
00650
00651 skb_reserve(skb, local->hw.extra_tx_headroom);
00652
00653 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 30);
00654 memset(nullfunc, 0, 30);
00655 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
00656 IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
00657 nullfunc->frame_control = fc;
00658 memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN);
00659 memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
00660 memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN);
00661 memcpy(nullfunc->addr4, sdata->vif.addr, ETH_ALEN);
00662
00663 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
00664 ieee80211_tx_skb(sdata, skb);
00665 }
00666
00667
00668 static void ieee80211_chswitch_work(struct work_struct *work)
00669 {
00670 struct ieee80211_sub_if_data *sdata =
00671 container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
00672 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
00673
00674 if (!ieee80211_sdata_running(sdata))
00675 return;
00676
00677 mutex_lock(&ifmgd->mtx);
00678 if (!ifmgd->associated)
00679 goto out;
00680
00681 sdata->local->oper_channel = sdata->local->csa_channel;
00682 if (!sdata->local->ops->channel_switch) {
00683
00684 ieee80211_hw_config(sdata->local,
00685 IEEE80211_CONF_CHANGE_CHANNEL);
00686 } else {
00687
00688 sdata->local->hw.conf.channel = sdata->local->oper_channel;
00689 }
00690
00691
00692 ifmgd->associated->channel = sdata->local->oper_channel;
00693
00694 ieee80211_wake_queues_by_reason(&sdata->local->hw,
00695 IEEE80211_QUEUE_STOP_REASON_CSA);
00696 out:
00697 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
00698 mutex_unlock(&ifmgd->mtx);
00699 }
00700
00701 void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
00702 {
00703 struct ieee80211_sub_if_data *sdata;
00704 struct ieee80211_if_managed *ifmgd;
00705
00706 sdata = vif_to_sdata(vif);
00707 ifmgd = &sdata->u.mgd;
00708
00709 trace_api_chswitch_done(sdata, success);
00710 if (!success) {
00711
00712
00713
00714
00715
00716
00717 sdata->local->csa_channel = sdata->local->oper_channel;
00718 }
00719
00720 ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
00721 }
00722 EXPORT_SYMBOL(ieee80211_chswitch_done);
00723
00724 static void ieee80211_chswitch_timer(unsigned long data)
00725 {
00726 struct ieee80211_sub_if_data *sdata =
00727 (struct ieee80211_sub_if_data *) data;
00728 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
00729
00730 if (sdata->local->quiescing) {
00731 set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
00732 return;
00733 }
00734
00735 ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
00736 }
00737
00738 void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
00739 struct ieee80211_channel_sw_ie *sw_elem,
00740 struct ieee80211_bss *bss,
00741 u64 timestamp)
00742 {
00743 struct cfg80211_bss *cbss =
00744 container_of((void *)bss, struct cfg80211_bss, priv);
00745 struct ieee80211_channel *new_ch;
00746 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
00747 int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
00748 cbss->channel->band);
00749
00750 ASSERT_MGD_MTX(ifmgd);
00751
00752 if (!ifmgd->associated)
00753 return;
00754
00755 if (sdata->local->scanning)
00756 return;
00757
00758
00759
00760
00761 if (ifmgd->flags & IEEE80211_STA_CSA_RECEIVED)
00762 return;
00763
00764 new_ch = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq);
00765 if (!new_ch || new_ch->flags & IEEE80211_CHAN_DISABLED)
00766 return;
00767
00768 sdata->local->csa_channel = new_ch;
00769
00770 if (sdata->local->ops->channel_switch) {
00771
00772 struct ieee80211_channel_switch ch_switch;
00773 memset(&ch_switch, 0, sizeof(ch_switch));
00774 ch_switch.timestamp = timestamp;
00775 if (sw_elem->mode) {
00776 ch_switch.block_tx = true;
00777 ieee80211_stop_queues_by_reason(&sdata->local->hw,
00778 IEEE80211_QUEUE_STOP_REASON_CSA);
00779 }
00780 ch_switch.channel = new_ch;
00781 ch_switch.count = sw_elem->count;
00782 ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
00783 drv_channel_switch(sdata->local, &ch_switch);
00784 return;
00785 }
00786
00787
00788 if (sw_elem->count <= 1) {
00789 ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
00790 } else {
00791 if (sw_elem->mode)
00792 ieee80211_stop_queues_by_reason(&sdata->local->hw,
00793 IEEE80211_QUEUE_STOP_REASON_CSA);
00794 ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
00795 mod_timer(&ifmgd->chswitch_timer,
00796 jiffies +
00797 msecs_to_jiffies(sw_elem->count *
00798 cbss->beacon_interval));
00799 }
00800 }
00801
00802 static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
00803 u16 capab_info, u8 *pwr_constr_elem,
00804 u8 pwr_constr_elem_len)
00805 {
00806 struct ieee80211_conf *conf = &sdata->local->hw.conf;
00807
00808 if (!(capab_info & WLAN_CAPABILITY_SPECTRUM_MGMT))
00809 return;
00810
00811
00812 if (pwr_constr_elem_len != 1)
00813 return;
00814
00815 if ((*pwr_constr_elem <= conf->channel->max_reg_power) &&
00816 (*pwr_constr_elem != sdata->local->power_constr_level)) {
00817 sdata->local->power_constr_level = *pwr_constr_elem;
00818 ieee80211_hw_config(sdata->local, 0);
00819 }
00820 }
00821
00822 void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif)
00823 {
00824 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
00825 struct ieee80211_local *local = sdata->local;
00826 struct ieee80211_conf *conf = &local->hw.conf;
00827
00828 WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
00829 !(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) ||
00830 (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS));
00831
00832 local->disable_dynamic_ps = false;
00833 conf->dynamic_ps_timeout = local->dynamic_ps_user_timeout;
00834 }
00835 EXPORT_SYMBOL(ieee80211_enable_dyn_ps);
00836
00837 void ieee80211_disable_dyn_ps(struct ieee80211_vif *vif)
00838 {
00839 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
00840 struct ieee80211_local *local = sdata->local;
00841 struct ieee80211_conf *conf = &local->hw.conf;
00842
00843 WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
00844 !(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) ||
00845 (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS));
00846
00847 local->disable_dynamic_ps = true;
00848 conf->dynamic_ps_timeout = 0;
00849 del_timer_sync(&local->dynamic_ps_timer);
00850 ieee80211_queue_work(&local->hw,
00851 &local->dynamic_ps_enable_work);
00852 }
00853 EXPORT_SYMBOL(ieee80211_disable_dyn_ps);
00854
00855
00856 static void ieee80211_enable_ps(struct ieee80211_local *local,
00857 struct ieee80211_sub_if_data *sdata)
00858 {
00859 struct ieee80211_conf *conf = &local->hw.conf;
00860
00861
00862
00863
00864
00865 if (local->scanning)
00866 return;
00867
00868 if (conf->dynamic_ps_timeout > 0 &&
00869 !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) {
00870 mod_timer(&local->dynamic_ps_timer, jiffies +
00871 msecs_to_jiffies(conf->dynamic_ps_timeout));
00872 } else {
00873 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
00874 ieee80211_send_nullfunc(local, sdata, 1);
00875
00876 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
00877 (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
00878 return;
00879
00880 conf->flags |= IEEE80211_CONF_PS;
00881 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
00882 }
00883 }
00884
00885 static void ieee80211_change_ps(struct ieee80211_local *local)
00886 {
00887 struct ieee80211_conf *conf = &local->hw.conf;
00888
00889 if (local->ps_sdata) {
00890 ieee80211_enable_ps(local, local->ps_sdata);
00891 } else if (conf->flags & IEEE80211_CONF_PS) {
00892 conf->flags &= ~IEEE80211_CONF_PS;
00893 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
00894 del_timer_sync(&local->dynamic_ps_timer);
00895 cancel_work_sync(&local->dynamic_ps_enable_work);
00896 }
00897 }
00898
00899 static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
00900 {
00901 struct ieee80211_if_managed *mgd = &sdata->u.mgd;
00902 struct sta_info *sta = NULL;
00903 bool authorized = false;
00904
00905 if (!mgd->powersave)
00906 return false;
00907
00908 if (mgd->broken_ap)
00909 return false;
00910
00911 if (!mgd->associated)
00912 return false;
00913
00914 if (!mgd->associated->beacon_ies)
00915 return false;
00916
00917 if (mgd->flags & (IEEE80211_STA_BEACON_POLL |
00918 IEEE80211_STA_CONNECTION_POLL))
00919 return false;
00920
00921 rcu_read_lock();
00922 sta = sta_info_get(sdata, mgd->bssid);
00923 if (sta)
00924 authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
00925 rcu_read_unlock();
00926
00927 return authorized;
00928 }
00929
00930
00931 void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
00932 {
00933 struct ieee80211_sub_if_data *sdata, *found = NULL;
00934 int count = 0;
00935 int timeout;
00936
00937 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) {
00938 local->ps_sdata = NULL;
00939 return;
00940 }
00941
00942 if (!list_empty(&local->work_list)) {
00943 local->ps_sdata = NULL;
00944 goto change;
00945 }
00946
00947 list_for_each_entry(sdata, &local->interfaces, list) {
00948 if (!ieee80211_sdata_running(sdata))
00949 continue;
00950 if (sdata->vif.type == NL80211_IFTYPE_AP) {
00951
00952
00953
00954
00955 count = 0;
00956 break;
00957 }
00958 if (sdata->vif.type != NL80211_IFTYPE_STATION)
00959 continue;
00960 found = sdata;
00961 count++;
00962 }
00963
00964 if (count == 1 && ieee80211_powersave_allowed(found)) {
00965 struct ieee80211_conf *conf = &local->hw.conf;
00966 s32 beaconint_us;
00967
00968 if (latency < 0)
00969 latency = pm_qos_request(PM_QOS_NETWORK_LATENCY);
00970
00971 beaconint_us = ieee80211_tu_to_usec(
00972 found->vif.bss_conf.beacon_int);
00973
00974 timeout = local->dynamic_ps_forced_timeout;
00975 if (timeout < 0) {
00976
00977
00978
00979
00980
00981
00982
00983 if (latency > (1900 * USEC_PER_MSEC) &&
00984 latency != (2000 * USEC_PER_SEC))
00985 timeout = 0;
00986 else
00987 timeout = 100;
00988 }
00989 local->dynamic_ps_user_timeout = timeout;
00990 if (!local->disable_dynamic_ps)
00991 conf->dynamic_ps_timeout =
00992 local->dynamic_ps_user_timeout;
00993
00994 if (beaconint_us > latency) {
00995 local->ps_sdata = NULL;
00996 } else {
00997 struct ieee80211_bss *bss;
00998 int maxslp = 1;
00999 u8 dtimper;
01000
01001 bss = (void *)found->u.mgd.associated->priv;
01002 dtimper = bss->dtim_period;
01003
01004
01005 if (!dtimper)
01006 dtimper = 1;
01007 else if (dtimper > 1)
01008 maxslp = min_t(int, dtimper,
01009 latency / beaconint_us);
01010
01011 local->hw.conf.max_sleep_period = maxslp;
01012 local->hw.conf.ps_dtim_period = dtimper;
01013 local->ps_sdata = found;
01014 }
01015 } else {
01016 local->ps_sdata = NULL;
01017 }
01018
01019 change:
01020 ieee80211_change_ps(local);
01021 }
01022
01023 void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
01024 {
01025 struct ieee80211_local *local =
01026 container_of(work, struct ieee80211_local,
01027 dynamic_ps_disable_work);
01028
01029 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
01030 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
01031 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
01032 }
01033
01034 ieee80211_wake_queues_by_reason(&local->hw,
01035 IEEE80211_QUEUE_STOP_REASON_PS);
01036 }
01037
01038 void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
01039 {
01040 struct ieee80211_local *local =
01041 container_of(work, struct ieee80211_local,
01042 dynamic_ps_enable_work);
01043 struct ieee80211_sub_if_data *sdata = local->ps_sdata;
01044 struct ieee80211_if_managed *ifmgd;
01045 unsigned long flags;
01046 int q;
01047
01048
01049 if (!sdata)
01050 return;
01051
01052 ifmgd = &sdata->u.mgd;
01053
01054 if (local->hw.conf.flags & IEEE80211_CONF_PS)
01055 return;
01056
01057 if (!local->disable_dynamic_ps &&
01058 local->hw.conf.dynamic_ps_timeout > 0) {
01059
01060 if (drv_tx_frames_pending(local)) {
01061 mod_timer(&local->dynamic_ps_timer, jiffies +
01062 msecs_to_jiffies(
01063 local->hw.conf.dynamic_ps_timeout));
01064 return;
01065 }
01066
01067
01068
01069
01070
01071
01072 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
01073 for (q = 0; q < local->hw.queues; q++) {
01074 if (local->queue_stop_reasons[q]) {
01075 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
01076 flags);
01077 mod_timer(&local->dynamic_ps_timer, jiffies +
01078 msecs_to_jiffies(
01079 local->hw.conf.dynamic_ps_timeout));
01080 return;
01081 }
01082 }
01083 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
01084 }
01085
01086 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
01087 !(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
01088 netif_tx_stop_all_queues(sdata->dev);
01089
01090 if (drv_tx_frames_pending(local))
01091 mod_timer(&local->dynamic_ps_timer, jiffies +
01092 msecs_to_jiffies(
01093 local->hw.conf.dynamic_ps_timeout));
01094 else {
01095 ieee80211_send_nullfunc(local, sdata, 1);
01096
01097 drv_flush(local, false);
01098 }
01099 }
01100
01101 if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
01102 (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) ||
01103 (ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
01104 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
01105 local->hw.conf.flags |= IEEE80211_CONF_PS;
01106 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
01107 }
01108
01109 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
01110 netif_tx_wake_all_queues(sdata->dev);
01111 }
01112
01113 void ieee80211_dynamic_ps_timer(unsigned long data)
01114 {
01115 struct ieee80211_local *local = (void *) data;
01116
01117 if (local->quiescing || local->suspended)
01118 return;
01119
01120 ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work);
01121 }
01122
01123
01124 static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
01125 struct ieee80211_sub_if_data *sdata,
01126 u8 *wmm_param, size_t wmm_param_len)
01127 {
01128 struct ieee80211_tx_queue_params params;
01129 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
01130 size_t left;
01131 int count;
01132 u8 *pos, uapsd_queues = 0;
01133
01134 if (!local->ops->conf_tx)
01135 return;
01136
01137 if (local->hw.queues < IEEE80211_NUM_ACS)
01138 return;
01139
01140 if (!wmm_param)
01141 return;
01142
01143 if (wmm_param_len < 8 || wmm_param[5] != 1)
01144 return;
01145
01146 if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
01147 uapsd_queues = ifmgd->uapsd_queues;
01148
01149 count = wmm_param[6] & 0x0f;
01150 if (count == ifmgd->wmm_last_param_set)
01151 return;
01152 ifmgd->wmm_last_param_set = count;
01153
01154 pos = wmm_param + 8;
01155 left = wmm_param_len - 8;
01156
01157 memset(¶ms, 0, sizeof(params));
01158
01159 local->wmm_acm = 0;
01160 for (; left >= 4; left -= 4, pos += 4) {
01161 int aci = (pos[0] >> 5) & 0x03;
01162 int acm = (pos[0] >> 4) & 0x01;
01163 bool uapsd = false;
01164 int queue;
01165
01166 switch (aci) {
01167 case 1:
01168 queue = 3;
01169 if (acm)
01170 local->wmm_acm |= BIT(1) | BIT(2);
01171 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
01172 uapsd = true;
01173 break;
01174 case 2:
01175 queue = 1;
01176 if (acm)
01177 local->wmm_acm |= BIT(4) | BIT(5);
01178 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
01179 uapsd = true;
01180 break;
01181 case 3:
01182 queue = 0;
01183 if (acm)
01184 local->wmm_acm |= BIT(6) | BIT(7);
01185 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
01186 uapsd = true;
01187 break;
01188 case 0:
01189 default:
01190 queue = 2;
01191 if (acm)
01192 local->wmm_acm |= BIT(0) | BIT(3);
01193 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
01194 uapsd = true;
01195 break;
01196 }
01197
01198 params.aifs = pos[0] & 0x0f;
01199 params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
01200 params.cw_min = ecw2cw(pos[1] & 0x0f);
01201 params.txop = get_unaligned_le16(pos + 2);
01202 params.uapsd = uapsd;
01203
01204 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
01205 wiphy_debug(local->hw.wiphy,
01206 "WMM queue=%d aci=%d acm=%d aifs=%d "
01207 "cWmin=%d cWmax=%d txop=%d uapsd=%d\n",
01208 queue, aci, acm,
01209 params.aifs, params.cw_min, params.cw_max,
01210 params.txop, params.uapsd);
01211 #endif
01212 sdata->tx_conf[queue] = params;
01213 if (drv_conf_tx(local, sdata, queue, ¶ms))
01214 wiphy_debug(local->hw.wiphy,
01215 "failed to set TX queue parameters for queue %d\n",
01216 queue);
01217 }
01218
01219
01220 sdata->vif.bss_conf.qos = true;
01221 }
01222
01223 static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
01224 {
01225 lockdep_assert_held(&sdata->local->mtx);
01226
01227 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
01228 IEEE80211_STA_BEACON_POLL);
01229 ieee80211_run_deferred_scan(sdata->local);
01230 }
01231
01232 static void ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
01233 {
01234 mutex_lock(&sdata->local->mtx);
01235 __ieee80211_stop_poll(sdata);
01236 mutex_unlock(&sdata->local->mtx);
01237 }
01238
01239 static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
01240 u16 capab, bool erp_valid, u8 erp)
01241 {
01242 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
01243 u32 changed = 0;
01244 bool use_protection;
01245 bool use_short_preamble;
01246 bool use_short_slot;
01247
01248 if (erp_valid) {
01249 use_protection = (erp & WLAN_ERP_USE_PROTECTION) != 0;
01250 use_short_preamble = (erp & WLAN_ERP_BARKER_PREAMBLE) == 0;
01251 } else {
01252 use_protection = false;
01253 use_short_preamble = !!(capab & WLAN_CAPABILITY_SHORT_PREAMBLE);
01254 }
01255
01256 use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
01257 if (sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ)
01258 use_short_slot = true;
01259
01260 if (use_protection != bss_conf->use_cts_prot) {
01261 bss_conf->use_cts_prot = use_protection;
01262 changed |= BSS_CHANGED_ERP_CTS_PROT;
01263 }
01264
01265 if (use_short_preamble != bss_conf->use_short_preamble) {
01266 bss_conf->use_short_preamble = use_short_preamble;
01267 changed |= BSS_CHANGED_ERP_PREAMBLE;
01268 }
01269
01270 if (use_short_slot != bss_conf->use_short_slot) {
01271 bss_conf->use_short_slot = use_short_slot;
01272 changed |= BSS_CHANGED_ERP_SLOT;
01273 }
01274
01275 return changed;
01276 }
01277
01278 static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
01279 struct cfg80211_bss *cbss,
01280 u32 bss_info_changed)
01281 {
01282 struct ieee80211_bss *bss = (void *)cbss->priv;
01283 struct ieee80211_local *local = sdata->local;
01284 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
01285
01286 bss_info_changed |= BSS_CHANGED_ASSOC;
01287
01288 bss_conf->beacon_int = cbss->beacon_interval;
01289 bss_conf->last_tsf = cbss->tsf;
01290
01291 bss_info_changed |= BSS_CHANGED_BEACON_INT;
01292 bss_info_changed |= ieee80211_handle_bss_capability(sdata,
01293 cbss->capability, bss->has_erp_value, bss->erp_value);
01294
01295 sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec(
01296 IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int));
01297
01298 sdata->u.mgd.associated = cbss;
01299 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
01300
01301 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;
01302
01303
01304 ieee80211_stop_poll(sdata);
01305
01306 ieee80211_led_assoc(local, 1);
01307
01308 if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD)
01309 bss_conf->dtim_period = bss->dtim_period;
01310 else
01311 bss_conf->dtim_period = 0;
01312
01313 bss_conf->assoc = 1;
01314
01315
01316 if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI &&
01317 bss_conf->cqm_rssi_thold)
01318 bss_info_changed |= BSS_CHANGED_CQM;
01319
01320
01321 if (bss_conf->arp_filter_enabled != sdata->arp_filter_state) {
01322 bss_conf->arp_filter_enabled = sdata->arp_filter_state;
01323 bss_info_changed |= BSS_CHANGED_ARP_FILTER;
01324 }
01325
01326 ieee80211_bss_info_change_notify(sdata, bss_info_changed);
01327
01328 mutex_lock(&local->iflist_mtx);
01329 ieee80211_recalc_ps(local, -1);
01330 ieee80211_recalc_smps(local);
01331 mutex_unlock(&local->iflist_mtx);
01332
01333 netif_tx_start_all_queues(sdata->dev);
01334 netif_carrier_on(sdata->dev);
01335 }
01336
01337 static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
01338 u16 stype, u16 reason, bool tx,
01339 u8 *frame_buf)
01340 {
01341 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
01342 struct ieee80211_local *local = sdata->local;
01343 struct sta_info *sta;
01344 u32 changed = 0;
01345
01346 ASSERT_MGD_MTX(ifmgd);
01347
01348 if (WARN_ON_ONCE(tx && !frame_buf))
01349 return;
01350
01351 if (WARN_ON(!ifmgd->associated))
01352 return;
01353
01354 ieee80211_stop_poll(sdata);
01355
01356 ifmgd->associated = NULL;
01357
01358
01359
01360
01361
01362
01363
01364 smp_mb();
01365
01366
01367
01368
01369
01370
01371
01372 netif_tx_stop_all_queues(sdata->dev);
01373 netif_carrier_off(sdata->dev);
01374
01375 mutex_lock(&local->sta_mtx);
01376 sta = sta_info_get(sdata, ifmgd->bssid);
01377 if (sta) {
01378 set_sta_flag(sta, WLAN_STA_BLOCK_BA);
01379 ieee80211_sta_tear_down_BA_sessions(sta, tx);
01380 }
01381 mutex_unlock(&local->sta_mtx);
01382
01383
01384 if (tx || frame_buf)
01385 ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype,
01386 reason, tx, frame_buf);
01387
01388
01389 if (tx)
01390 drv_flush(local, false);
01391
01392
01393 memset(ifmgd->bssid, 0, ETH_ALEN);
01394
01395
01396 sta_info_flush(local, sdata);
01397
01398
01399 changed |= ieee80211_reset_erp_info(sdata);
01400
01401 ieee80211_led_assoc(local, 0);
01402 changed |= BSS_CHANGED_ASSOC;
01403 sdata->vif.bss_conf.assoc = false;
01404
01405
01406 memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
01407 memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask));
01408
01409 local->power_constr_level = 0;
01410
01411 del_timer_sync(&local->dynamic_ps_timer);
01412 cancel_work_sync(&local->dynamic_ps_enable_work);
01413
01414 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
01415 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
01416 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
01417 }
01418 local->ps_sdata = NULL;
01419
01420
01421 if (sdata->vif.bss_conf.arp_filter_enabled) {
01422 sdata->vif.bss_conf.arp_filter_enabled = false;
01423 changed |= BSS_CHANGED_ARP_FILTER;
01424 }
01425
01426 sdata->vif.bss_conf.qos = false;
01427 changed |= BSS_CHANGED_QOS;
01428
01429
01430 changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
01431 ieee80211_bss_info_change_notify(sdata, changed);
01432
01433
01434 WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
01435 ieee80211_hw_config(local, 0);
01436
01437
01438 ieee80211_set_wmm_default(sdata, false);
01439
01440 del_timer_sync(&sdata->u.mgd.conn_mon_timer);
01441 del_timer_sync(&sdata->u.mgd.bcn_mon_timer);
01442 del_timer_sync(&sdata->u.mgd.timer);
01443 del_timer_sync(&sdata->u.mgd.chswitch_timer);
01444 }
01445
01446 void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
01447 struct ieee80211_hdr *hdr)
01448 {
01449
01450
01451
01452
01453
01454
01455
01456
01457 if (is_multicast_ether_addr(hdr->addr1))
01458 return;
01459
01460 ieee80211_sta_reset_conn_monitor(sdata);
01461 }
01462
01463 static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
01464 {
01465 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
01466 struct ieee80211_local *local = sdata->local;
01467
01468 mutex_lock(&local->mtx);
01469 if (!(ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
01470 IEEE80211_STA_CONNECTION_POLL))) {
01471 mutex_unlock(&local->mtx);
01472 return;
01473 }
01474
01475 __ieee80211_stop_poll(sdata);
01476
01477 mutex_lock(&local->iflist_mtx);
01478 ieee80211_recalc_ps(local, -1);
01479 mutex_unlock(&local->iflist_mtx);
01480
01481 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
01482 goto out;
01483
01484
01485
01486
01487
01488
01489 ieee80211_sta_reset_beacon_monitor(sdata);
01490
01491 mod_timer(&ifmgd->conn_mon_timer,
01492 round_jiffies_up(jiffies +
01493 IEEE80211_CONNECTION_IDLE_TIME));
01494 out:
01495 mutex_unlock(&local->mtx);
01496 }
01497
01498 void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
01499 struct ieee80211_hdr *hdr, bool ack)
01500 {
01501 if (!ieee80211_is_data(hdr->frame_control))
01502 return;
01503
01504 if (ack)
01505 ieee80211_sta_reset_conn_monitor(sdata);
01506
01507 if (ieee80211_is_nullfunc(hdr->frame_control) &&
01508 sdata->u.mgd.probe_send_count > 0) {
01509 if (ack)
01510 sdata->u.mgd.probe_send_count = 0;
01511 else
01512 sdata->u.mgd.nullfunc_failed = true;
01513 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
01514 }
01515 }
01516
01517 static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
01518 {
01519 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
01520 const u8 *ssid;
01521 u8 *dst = ifmgd->associated->bssid;
01522 u8 unicast_limit = max(1, max_probe_tries - 3);
01523
01524
01525
01526
01527
01528
01529 if (ifmgd->probe_send_count >= unicast_limit)
01530 dst = NULL;
01531
01532
01533
01534
01535
01536
01537
01538
01539 ifmgd->probe_send_count++;
01540
01541 if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
01542 ifmgd->nullfunc_failed = false;
01543 ieee80211_send_nullfunc(sdata->local, sdata, 0);
01544 } else {
01545 int ssid_len;
01546
01547 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
01548 if (WARN_ON_ONCE(ssid == NULL))
01549 ssid_len = 0;
01550 else
01551 ssid_len = ssid[1];
01552
01553 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid_len, NULL,
01554 0, (u32) -1, true, false);
01555 }
01556
01557 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
01558 run_again(ifmgd, ifmgd->probe_timeout);
01559 if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
01560 drv_flush(sdata->local, false);
01561 }
01562
01563 static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
01564 bool beacon)
01565 {
01566 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
01567 bool already = false;
01568
01569 if (!ieee80211_sdata_running(sdata))
01570 return;
01571
01572 mutex_lock(&ifmgd->mtx);
01573
01574 if (!ifmgd->associated)
01575 goto out;
01576
01577 mutex_lock(&sdata->local->mtx);
01578
01579 if (sdata->local->tmp_channel || sdata->local->scanning) {
01580 mutex_unlock(&sdata->local->mtx);
01581 goto out;
01582 }
01583
01584 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
01585 if (beacon)
01586 net_dbg_ratelimited("%s: detected beacon loss from AP - sending probe request\n",
01587 sdata->name);
01588 #endif
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
01602 IEEE80211_STA_CONNECTION_POLL))
01603 already = true;
01604
01605 if (beacon)
01606 ifmgd->flags |= IEEE80211_STA_BEACON_POLL;
01607 else
01608 ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL;
01609
01610 mutex_unlock(&sdata->local->mtx);
01611
01612 if (already)
01613 goto out;
01614
01615 mutex_lock(&sdata->local->iflist_mtx);
01616 ieee80211_recalc_ps(sdata->local, -1);
01617 mutex_unlock(&sdata->local->iflist_mtx);
01618
01619 ifmgd->probe_send_count = 0;
01620 ieee80211_mgd_probe_ap_send(sdata);
01621 out:
01622 mutex_unlock(&ifmgd->mtx);
01623 }
01624
01625 struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
01626 struct ieee80211_vif *vif)
01627 {
01628 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
01629 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
01630 struct sk_buff *skb;
01631 const u8 *ssid;
01632 int ssid_len;
01633
01634 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
01635 return NULL;
01636
01637 ASSERT_MGD_MTX(ifmgd);
01638
01639 if (!ifmgd->associated)
01640 return NULL;
01641
01642 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
01643 if (WARN_ON_ONCE(ssid == NULL))
01644 ssid_len = 0;
01645 else
01646 ssid_len = ssid[1];
01647
01648 skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid,
01649 (u32) -1, ssid + 2, ssid_len,
01650 NULL, 0, true);
01651
01652 return skb;
01653 }
01654 EXPORT_SYMBOL(ieee80211_ap_probereq_get);
01655
01656 static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
01657 {
01658 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
01659 struct ieee80211_local *local = sdata->local;
01660 u8 bssid[ETH_ALEN];
01661 u8 frame_buf[DEAUTH_DISASSOC_LEN];
01662
01663 mutex_lock(&ifmgd->mtx);
01664 if (!ifmgd->associated) {
01665 mutex_unlock(&ifmgd->mtx);
01666 return;
01667 }
01668
01669 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
01670
01671 printk(KERN_DEBUG "%s: Connection to AP %pM lost.\n",
01672 sdata->name, bssid);
01673
01674 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
01675 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
01676 false, frame_buf);
01677 mutex_unlock(&ifmgd->mtx);
01678
01679
01680
01681
01682
01683 cfg80211_send_deauth(sdata->dev, frame_buf, DEAUTH_DISASSOC_LEN);
01684
01685 mutex_lock(&local->mtx);
01686 ieee80211_recalc_idle(local);
01687 mutex_unlock(&local->mtx);
01688 }
01689
01690 void ieee80211_beacon_connection_loss_work(struct work_struct *work)
01691 {
01692 struct ieee80211_sub_if_data *sdata =
01693 container_of(work, struct ieee80211_sub_if_data,
01694 u.mgd.beacon_connection_loss_work);
01695 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
01696 struct sta_info *sta;
01697
01698 if (ifmgd->associated) {
01699 rcu_read_lock();
01700 sta = sta_info_get(sdata, ifmgd->bssid);
01701 if (sta)
01702 sta->beacon_loss_count++;
01703 rcu_read_unlock();
01704 }
01705
01706 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
01707 __ieee80211_connection_loss(sdata);
01708 else
01709 ieee80211_mgd_probe_ap(sdata, true);
01710 }
01711
01712 void ieee80211_beacon_loss(struct ieee80211_vif *vif)
01713 {
01714 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
01715 struct ieee80211_hw *hw = &sdata->local->hw;
01716
01717 trace_api_beacon_loss(sdata);
01718
01719 WARN_ON(hw->flags & IEEE80211_HW_CONNECTION_MONITOR);
01720 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
01721 }
01722 EXPORT_SYMBOL(ieee80211_beacon_loss);
01723
01724 void ieee80211_connection_loss(struct ieee80211_vif *vif)
01725 {
01726 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
01727 struct ieee80211_hw *hw = &sdata->local->hw;
01728
01729 trace_api_connection_loss(sdata);
01730
01731 WARN_ON(!(hw->flags & IEEE80211_HW_CONNECTION_MONITOR));
01732 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
01733 }
01734 EXPORT_SYMBOL(ieee80211_connection_loss);
01735
01736
01737 static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
01738 bool assoc)
01739 {
01740 struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
01741
01742 lockdep_assert_held(&sdata->u.mgd.mtx);
01743
01744 if (!assoc) {
01745 sta_info_destroy_addr(sdata, auth_data->bss->bssid);
01746
01747 memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
01748 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
01749 }
01750
01751 cfg80211_put_bss(auth_data->bss);
01752 kfree(auth_data);
01753 sdata->u.mgd.auth_data = NULL;
01754 }
01755
01756 static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
01757 struct ieee80211_mgmt *mgmt, size_t len)
01758 {
01759 struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
01760 u8 *pos;
01761 struct ieee802_11_elems elems;
01762
01763 pos = mgmt->u.auth.variable;
01764 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
01765 if (!elems.challenge)
01766 return;
01767 auth_data->expected_transaction = 4;
01768 ieee80211_send_auth(sdata, 3, auth_data->algorithm,
01769 elems.challenge - 2, elems.challenge_len + 2,
01770 auth_data->bss->bssid, auth_data->bss->bssid,
01771 auth_data->key, auth_data->key_len,
01772 auth_data->key_idx);
01773 }
01774
01775 static enum rx_mgmt_action __must_check
01776 ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
01777 struct ieee80211_mgmt *mgmt, size_t len)
01778 {
01779 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
01780 u8 bssid[ETH_ALEN];
01781 u16 auth_alg, auth_transaction, status_code;
01782 struct sta_info *sta;
01783
01784 lockdep_assert_held(&ifmgd->mtx);
01785
01786 if (len < 24 + 6)
01787 return RX_MGMT_NONE;
01788
01789 if (!ifmgd->auth_data || ifmgd->auth_data->done)
01790 return RX_MGMT_NONE;
01791
01792 memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
01793
01794 if (!ether_addr_equal(bssid, mgmt->bssid))
01795 return RX_MGMT_NONE;
01796
01797 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
01798 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
01799 status_code = le16_to_cpu(mgmt->u.auth.status_code);
01800
01801 if (auth_alg != ifmgd->auth_data->algorithm ||
01802 auth_transaction != ifmgd->auth_data->expected_transaction)
01803 return RX_MGMT_NONE;
01804
01805 if (status_code != WLAN_STATUS_SUCCESS) {
01806 printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n",
01807 sdata->name, mgmt->sa, status_code);
01808 ieee80211_destroy_auth_data(sdata, false);
01809 return RX_MGMT_CFG80211_RX_AUTH;
01810 }
01811
01812 switch (ifmgd->auth_data->algorithm) {
01813 case WLAN_AUTH_OPEN:
01814 case WLAN_AUTH_LEAP:
01815 case WLAN_AUTH_FT:
01816 break;
01817 case WLAN_AUTH_SHARED_KEY:
01818 if (ifmgd->auth_data->expected_transaction != 4) {
01819 ieee80211_auth_challenge(sdata, mgmt, len);
01820
01821 return RX_MGMT_NONE;
01822 }
01823 break;
01824 default:
01825 WARN_ONCE(1, "invalid auth alg %d",
01826 ifmgd->auth_data->algorithm);
01827 return RX_MGMT_NONE;
01828 }
01829
01830 printk(KERN_DEBUG "%s: authenticated\n", sdata->name);
01831 ifmgd->auth_data->done = true;
01832 ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
01833 run_again(ifmgd, ifmgd->auth_data->timeout);
01834
01835
01836 mutex_lock(&sdata->local->sta_mtx);
01837 sta = sta_info_get(sdata, bssid);
01838 if (!sta) {
01839 WARN_ONCE(1, "%s: STA %pM not found", sdata->name, bssid);
01840 goto out_err;
01841 }
01842 if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) {
01843 printk(KERN_DEBUG "%s: failed moving %pM to auth\n",
01844 sdata->name, bssid);
01845 goto out_err;
01846 }
01847 mutex_unlock(&sdata->local->sta_mtx);
01848
01849 return RX_MGMT_CFG80211_RX_AUTH;
01850 out_err:
01851 mutex_unlock(&sdata->local->sta_mtx);
01852
01853 return RX_MGMT_NONE;
01854 }
01855
01856
01857 static enum rx_mgmt_action __must_check
01858 ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
01859 struct ieee80211_mgmt *mgmt, size_t len)
01860 {
01861 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
01862 const u8 *bssid = NULL;
01863 u16 reason_code;
01864
01865 lockdep_assert_held(&ifmgd->mtx);
01866
01867 if (len < 24 + 2)
01868 return RX_MGMT_NONE;
01869
01870 if (!ifmgd->associated ||
01871 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
01872 return RX_MGMT_NONE;
01873
01874 bssid = ifmgd->associated->bssid;
01875
01876 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
01877
01878 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
01879 sdata->name, bssid, reason_code);
01880
01881 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
01882
01883 mutex_lock(&sdata->local->mtx);
01884 ieee80211_recalc_idle(sdata->local);
01885 mutex_unlock(&sdata->local->mtx);
01886
01887 return RX_MGMT_CFG80211_DEAUTH;
01888 }
01889
01890
01891 static enum rx_mgmt_action __must_check
01892 ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
01893 struct ieee80211_mgmt *mgmt, size_t len)
01894 {
01895 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
01896 u16 reason_code;
01897
01898 lockdep_assert_held(&ifmgd->mtx);
01899
01900 if (len < 24 + 2)
01901 return RX_MGMT_NONE;
01902
01903 if (!ifmgd->associated ||
01904 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
01905 return RX_MGMT_NONE;
01906
01907 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
01908
01909 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
01910 sdata->name, mgmt->sa, reason_code);
01911
01912 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
01913
01914 mutex_lock(&sdata->local->mtx);
01915 ieee80211_recalc_idle(sdata->local);
01916 mutex_unlock(&sdata->local->mtx);
01917
01918 return RX_MGMT_CFG80211_DISASSOC;
01919 }
01920
01921 static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
01922 u8 *supp_rates, unsigned int supp_rates_len,
01923 u32 *rates, u32 *basic_rates,
01924 bool *have_higher_than_11mbit,
01925 int *min_rate, int *min_rate_index)
01926 {
01927 int i, j;
01928
01929 for (i = 0; i < supp_rates_len; i++) {
01930 int rate = (supp_rates[i] & 0x7f) * 5;
01931 bool is_basic = !!(supp_rates[i] & 0x80);
01932
01933 if (rate > 110)
01934 *have_higher_than_11mbit = true;
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944 if (!!(supp_rates[i] & 0x80) &&
01945 (supp_rates[i] & 0x7f) == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
01946 continue;
01947
01948 for (j = 0; j < sband->n_bitrates; j++) {
01949 if (sband->bitrates[j].bitrate == rate) {
01950 *rates |= BIT(j);
01951 if (is_basic)
01952 *basic_rates |= BIT(j);
01953 if (rate < *min_rate) {
01954 *min_rate = rate;
01955 *min_rate_index = j;
01956 }
01957 break;
01958 }
01959 }
01960 }
01961 }
01962
01963 static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
01964 bool assoc)
01965 {
01966 struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
01967
01968 lockdep_assert_held(&sdata->u.mgd.mtx);
01969
01970 if (!assoc) {
01971 sta_info_destroy_addr(sdata, assoc_data->bss->bssid);
01972
01973 memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
01974 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
01975 }
01976
01977 kfree(assoc_data);
01978 sdata->u.mgd.assoc_data = NULL;
01979 }
01980
01981 static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
01982 struct cfg80211_bss *cbss,
01983 struct ieee80211_mgmt *mgmt, size_t len)
01984 {
01985 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
01986 struct ieee80211_local *local = sdata->local;
01987 struct ieee80211_supported_band *sband;
01988 struct sta_info *sta;
01989 u8 *pos;
01990 u16 capab_info, aid;
01991 struct ieee802_11_elems elems;
01992 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
01993 u32 changed = 0;
01994 int err;
01995
01996
01997
01998 aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
01999 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
02000
02001 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
02002 printk(KERN_DEBUG
02003 "%s: invalid AID value 0x%x; bits 15:14 not set\n",
02004 sdata->name, aid);
02005 aid &= ~(BIT(15) | BIT(14));
02006
02007 ifmgd->broken_ap = false;
02008
02009 if (aid == 0 || aid > IEEE80211_MAX_AID) {
02010 printk(KERN_DEBUG
02011 "%s: invalid AID value %d (out of range), turn off PS\n",
02012 sdata->name, aid);
02013 aid = 0;
02014 ifmgd->broken_ap = true;
02015 }
02016
02017 pos = mgmt->u.assoc_resp.variable;
02018 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
02019
02020 if (!elems.supp_rates) {
02021 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
02022 sdata->name);
02023 return false;
02024 }
02025
02026 ifmgd->aid = aid;
02027
02028 mutex_lock(&sdata->local->sta_mtx);
02029
02030
02031
02032
02033 sta = sta_info_get(sdata, cbss->bssid);
02034 if (WARN_ON(!sta)) {
02035 mutex_unlock(&sdata->local->sta_mtx);
02036 return false;
02037 }
02038
02039 sband = local->hw.wiphy->bands[local->oper_channel->band];
02040
02041 if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
02042 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
02043 elems.ht_cap_elem, &sta->sta.ht_cap);
02044
02045 sta->supports_40mhz =
02046 sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
02047
02048 rate_control_rate_init(sta);
02049
02050 if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED)
02051 set_sta_flag(sta, WLAN_STA_MFP);
02052
02053 if (elems.wmm_param)
02054 set_sta_flag(sta, WLAN_STA_WME);
02055
02056 err = sta_info_move_state(sta, IEEE80211_STA_AUTH);
02057 if (!err)
02058 err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
02059 if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
02060 err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
02061 if (err) {
02062 printk(KERN_DEBUG
02063 "%s: failed to move station %pM to desired state\n",
02064 sdata->name, sta->sta.addr);
02065 WARN_ON(__sta_info_destroy(sta));
02066 mutex_unlock(&sdata->local->sta_mtx);
02067 return false;
02068 }
02069
02070 mutex_unlock(&sdata->local->sta_mtx);
02071
02072
02073
02074
02075
02076
02077
02078 ifmgd->wmm_last_param_set = -1;
02079
02080 if (elems.wmm_param)
02081 ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
02082 elems.wmm_param_len);
02083 else
02084 ieee80211_set_wmm_default(sdata, false);
02085 changed |= BSS_CHANGED_QOS;
02086
02087 if (elems.ht_operation && elems.wmm_param &&
02088 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
02089 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation,
02090 cbss->bssid, false);
02091
02092
02093
02094 bss_conf->aid = aid;
02095 bss_conf->assoc_capability = capab_info;
02096 ieee80211_set_associated(sdata, cbss, changed);
02097
02098
02099
02100
02101
02102 if (ifmgd->use_4addr)
02103 ieee80211_send_4addr_nullfunc(local, sdata);
02104
02105
02106
02107
02108
02109 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
02110 ieee80211_sta_reset_beacon_monitor(sdata);
02111
02112 return true;
02113 }
02114
02115 static enum rx_mgmt_action __must_check
02116 ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
02117 struct ieee80211_mgmt *mgmt, size_t len,
02118 struct cfg80211_bss **bss)
02119 {
02120 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
02121 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
02122 u16 capab_info, status_code, aid;
02123 struct ieee802_11_elems elems;
02124 u8 *pos;
02125 bool reassoc;
02126
02127 lockdep_assert_held(&ifmgd->mtx);
02128
02129 if (!assoc_data)
02130 return RX_MGMT_NONE;
02131 if (!ether_addr_equal(assoc_data->bss->bssid, mgmt->bssid))
02132 return RX_MGMT_NONE;
02133
02134
02135
02136
02137
02138
02139 if (len < 24 + 6)
02140 return RX_MGMT_NONE;
02141
02142 reassoc = ieee80211_is_reassoc_req(mgmt->frame_control);
02143 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
02144 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
02145 aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
02146
02147 printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
02148 "status=%d aid=%d)\n",
02149 sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
02150 capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
02151
02152 pos = mgmt->u.assoc_resp.variable;
02153 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
02154
02155 if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
02156 elems.timeout_int && elems.timeout_int_len == 5 &&
02157 elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
02158 u32 tu, ms;
02159 tu = get_unaligned_le32(elems.timeout_int + 1);
02160 ms = tu * 1024 / 1000;
02161 printk(KERN_DEBUG "%s: %pM rejected association temporarily; "
02162 "comeback duration %u TU (%u ms)\n",
02163 sdata->name, mgmt->sa, tu, ms);
02164 assoc_data->timeout = jiffies + msecs_to_jiffies(ms);
02165 if (ms > IEEE80211_ASSOC_TIMEOUT)
02166 run_again(ifmgd, assoc_data->timeout);
02167 return RX_MGMT_NONE;
02168 }
02169
02170 *bss = assoc_data->bss;
02171
02172 if (status_code != WLAN_STATUS_SUCCESS) {
02173 printk(KERN_DEBUG "%s: %pM denied association (code=%d)\n",
02174 sdata->name, mgmt->sa, status_code);
02175 ieee80211_destroy_assoc_data(sdata, false);
02176 } else {
02177 if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) {
02178
02179 ieee80211_destroy_assoc_data(sdata, false);
02180 cfg80211_put_bss(*bss);
02181 return RX_MGMT_CFG80211_ASSOC_TIMEOUT;
02182 }
02183 printk(KERN_DEBUG "%s: associated\n", sdata->name);
02184
02185
02186
02187
02188
02189
02190 ieee80211_destroy_assoc_data(sdata, true);
02191 }
02192
02193 return RX_MGMT_CFG80211_RX_ASSOC;
02194 }
02195 static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
02196 struct ieee80211_mgmt *mgmt,
02197 size_t len,
02198 struct ieee80211_rx_status *rx_status,
02199 struct ieee802_11_elems *elems,
02200 bool beacon)
02201 {
02202 struct ieee80211_local *local = sdata->local;
02203 int freq;
02204 struct ieee80211_bss *bss;
02205 struct ieee80211_channel *channel;
02206 bool need_ps = false;
02207
02208 if (sdata->u.mgd.associated &&
02209 ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) {
02210 bss = (void *)sdata->u.mgd.associated->priv;
02211
02212 need_ps = !bss->dtim_period;
02213 }
02214
02215 if (elems->ds_params && elems->ds_params_len == 1)
02216 freq = ieee80211_channel_to_frequency(elems->ds_params[0],
02217 rx_status->band);
02218 else
02219 freq = rx_status->freq;
02220
02221 channel = ieee80211_get_channel(local->hw.wiphy, freq);
02222
02223 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
02224 return;
02225
02226 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
02227 channel, beacon);
02228 if (bss)
02229 ieee80211_rx_bss_put(local, bss);
02230
02231 if (!sdata->u.mgd.associated)
02232 return;
02233
02234 if (need_ps) {
02235 mutex_lock(&local->iflist_mtx);
02236 ieee80211_recalc_ps(local, -1);
02237 mutex_unlock(&local->iflist_mtx);
02238 }
02239
02240 if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) &&
02241 (memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid,
02242 ETH_ALEN) == 0)) {
02243 struct ieee80211_channel_sw_ie *sw_elem =
02244 (struct ieee80211_channel_sw_ie *)elems->ch_switch_elem;
02245 ieee80211_sta_process_chanswitch(sdata, sw_elem,
02246 bss, rx_status->mactime);
02247 }
02248 }
02249
02250
02251 static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
02252 struct sk_buff *skb)
02253 {
02254 struct ieee80211_mgmt *mgmt = (void *)skb->data;
02255 struct ieee80211_if_managed *ifmgd;
02256 struct ieee80211_rx_status *rx_status = (void *) skb->cb;
02257 size_t baselen, len = skb->len;
02258 struct ieee802_11_elems elems;
02259
02260 ifmgd = &sdata->u.mgd;
02261
02262 ASSERT_MGD_MTX(ifmgd);
02263
02264 if (!ether_addr_equal(mgmt->da, sdata->vif.addr))
02265 return;
02266
02267 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
02268 if (baselen > len)
02269 return;
02270
02271 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
02272 &elems);
02273
02274 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
02275
02276 if (ifmgd->associated &&
02277 ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
02278 ieee80211_reset_ap_probe(sdata);
02279
02280 if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies &&
02281 ether_addr_equal(mgmt->bssid, ifmgd->auth_data->bss->bssid)) {
02282
02283 printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name);
02284 ifmgd->auth_data->tries = 0;
02285 ifmgd->auth_data->timeout = jiffies;
02286 run_again(ifmgd, ifmgd->auth_data->timeout);
02287 }
02288 }
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303 static const u64 care_about_ies =
02304 (1ULL << WLAN_EID_COUNTRY) |
02305 (1ULL << WLAN_EID_ERP_INFO) |
02306 (1ULL << WLAN_EID_CHANNEL_SWITCH) |
02307 (1ULL << WLAN_EID_PWR_CONSTRAINT) |
02308 (1ULL << WLAN_EID_HT_CAPABILITY) |
02309 (1ULL << WLAN_EID_HT_OPERATION);
02310
02311 static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
02312 struct ieee80211_mgmt *mgmt,
02313 size_t len,
02314 struct ieee80211_rx_status *rx_status)
02315 {
02316 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
02317 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
02318 size_t baselen;
02319 struct ieee802_11_elems elems;
02320 struct ieee80211_local *local = sdata->local;
02321 u32 changed = 0;
02322 bool erp_valid, directed_tim = false;
02323 u8 erp_value = 0;
02324 u32 ncrc;
02325 u8 *bssid;
02326
02327 lockdep_assert_held(&ifmgd->mtx);
02328
02329
02330 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
02331 if (baselen > len)
02332 return;
02333
02334 if (rx_status->freq != local->hw.conf.channel->center_freq)
02335 return;
02336
02337 if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon &&
02338 ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) {
02339 ieee802_11_parse_elems(mgmt->u.beacon.variable,
02340 len - baselen, &elems);
02341
02342 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
02343 false);
02344 ifmgd->assoc_data->have_beacon = true;
02345 ifmgd->assoc_data->sent_assoc = false;
02346
02347 ifmgd->assoc_data->timeout = jiffies;
02348 run_again(ifmgd, ifmgd->assoc_data->timeout);
02349 return;
02350 }
02351
02352 if (!ifmgd->associated ||
02353 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
02354 return;
02355 bssid = ifmgd->associated->bssid;
02356
02357
02358 ifmgd->last_beacon_signal = rx_status->signal;
02359 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) {
02360 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
02361 ifmgd->ave_beacon_signal = rx_status->signal * 16;
02362 ifmgd->last_cqm_event_signal = 0;
02363 ifmgd->count_beacon_signal = 1;
02364 ifmgd->last_ave_beacon_signal = 0;
02365 } else {
02366 ifmgd->ave_beacon_signal =
02367 (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
02368 (16 - IEEE80211_SIGNAL_AVE_WEIGHT) *
02369 ifmgd->ave_beacon_signal) / 16;
02370 ifmgd->count_beacon_signal++;
02371 }
02372
02373 if (ifmgd->rssi_min_thold != ifmgd->rssi_max_thold &&
02374 ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) {
02375 int sig = ifmgd->ave_beacon_signal;
02376 int last_sig = ifmgd->last_ave_beacon_signal;
02377
02378
02379
02380
02381
02382 if (sig > ifmgd->rssi_max_thold &&
02383 (last_sig <= ifmgd->rssi_min_thold || last_sig == 0)) {
02384 ifmgd->last_ave_beacon_signal = sig;
02385 drv_rssi_callback(local, RSSI_EVENT_HIGH);
02386 } else if (sig < ifmgd->rssi_min_thold &&
02387 (last_sig >= ifmgd->rssi_max_thold ||
02388 last_sig == 0)) {
02389 ifmgd->last_ave_beacon_signal = sig;
02390 drv_rssi_callback(local, RSSI_EVENT_LOW);
02391 }
02392 }
02393
02394 if (bss_conf->cqm_rssi_thold &&
02395 ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT &&
02396 !(sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) {
02397 int sig = ifmgd->ave_beacon_signal / 16;
02398 int last_event = ifmgd->last_cqm_event_signal;
02399 int thold = bss_conf->cqm_rssi_thold;
02400 int hyst = bss_conf->cqm_rssi_hyst;
02401 if (sig < thold &&
02402 (last_event == 0 || sig < last_event - hyst)) {
02403 ifmgd->last_cqm_event_signal = sig;
02404 ieee80211_cqm_rssi_notify(
02405 &sdata->vif,
02406 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
02407 GFP_KERNEL);
02408 } else if (sig > thold &&
02409 (last_event == 0 || sig > last_event + hyst)) {
02410 ifmgd->last_cqm_event_signal = sig;
02411 ieee80211_cqm_rssi_notify(
02412 &sdata->vif,
02413 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
02414 GFP_KERNEL);
02415 }
02416 }
02417
02418 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) {
02419 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
02420 net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n",
02421 sdata->name);
02422 #endif
02423 mutex_lock(&local->mtx);
02424 ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL;
02425 ieee80211_run_deferred_scan(local);
02426 mutex_unlock(&local->mtx);
02427
02428 mutex_lock(&local->iflist_mtx);
02429 ieee80211_recalc_ps(local, -1);
02430 mutex_unlock(&local->iflist_mtx);
02431 }
02432
02433
02434
02435
02436
02437 ieee80211_sta_reset_beacon_monitor(sdata);
02438
02439 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
02440 ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable,
02441 len - baselen, &elems,
02442 care_about_ies, ncrc);
02443
02444 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
02445 directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len,
02446 ifmgd->aid);
02447
02448 if (ncrc != ifmgd->beacon_crc || !ifmgd->beacon_crc_valid) {
02449 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
02450 true);
02451
02452 ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
02453 elems.wmm_param_len);
02454 }
02455
02456 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) {
02457 if (directed_tim) {
02458 if (local->hw.conf.dynamic_ps_timeout > 0) {
02459 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
02460 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
02461 ieee80211_hw_config(local,
02462 IEEE80211_CONF_CHANGE_PS);
02463 }
02464 ieee80211_send_nullfunc(local, sdata, 0);
02465 } else if (!local->pspolling && sdata->u.mgd.powersave) {
02466 local->pspolling = true;
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476 ieee80211_send_pspoll(local, sdata);
02477 }
02478 }
02479 }
02480
02481 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
02482 return;
02483 ifmgd->beacon_crc = ncrc;
02484 ifmgd->beacon_crc_valid = true;
02485
02486 if (elems.erp_info && elems.erp_info_len >= 1) {
02487 erp_valid = true;
02488 erp_value = elems.erp_info[0];
02489 } else {
02490 erp_valid = false;
02491 }
02492 changed |= ieee80211_handle_bss_capability(sdata,
02493 le16_to_cpu(mgmt->u.beacon.capab_info),
02494 erp_valid, erp_value);
02495
02496
02497 if (elems.ht_cap_elem && elems.ht_operation && elems.wmm_param &&
02498 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) {
02499 struct ieee80211_supported_band *sband;
02500
02501 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
02502
02503 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation,
02504 bssid, true);
02505 }
02506
02507
02508 if (elems.country_elem) {
02509
02510 if (elems.pwr_constr_elem)
02511 ieee80211_handle_pwr_constr(sdata,
02512 le16_to_cpu(mgmt->u.probe_resp.capab_info),
02513 elems.pwr_constr_elem,
02514 elems.pwr_constr_elem_len);
02515 }
02516
02517 ieee80211_bss_info_change_notify(sdata, changed);
02518 }
02519
02520 void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
02521 struct sk_buff *skb)
02522 {
02523 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
02524 struct ieee80211_rx_status *rx_status;
02525 struct ieee80211_mgmt *mgmt;
02526 struct cfg80211_bss *bss = NULL;
02527 enum rx_mgmt_action rma = RX_MGMT_NONE;
02528 u16 fc;
02529
02530 rx_status = (struct ieee80211_rx_status *) skb->cb;
02531 mgmt = (struct ieee80211_mgmt *) skb->data;
02532 fc = le16_to_cpu(mgmt->frame_control);
02533
02534 mutex_lock(&ifmgd->mtx);
02535
02536 switch (fc & IEEE80211_FCTL_STYPE) {
02537 case IEEE80211_STYPE_BEACON:
02538 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
02539 break;
02540 case IEEE80211_STYPE_PROBE_RESP:
02541 ieee80211_rx_mgmt_probe_resp(sdata, skb);
02542 break;
02543 case IEEE80211_STYPE_AUTH:
02544 rma = ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len);
02545 break;
02546 case IEEE80211_STYPE_DEAUTH:
02547 rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
02548 break;
02549 case IEEE80211_STYPE_DISASSOC:
02550 rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
02551 break;
02552 case IEEE80211_STYPE_ASSOC_RESP:
02553 case IEEE80211_STYPE_REASSOC_RESP:
02554 rma = ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len, &bss);
02555 break;
02556 case IEEE80211_STYPE_ACTION:
02557 switch (mgmt->u.action.category) {
02558 case WLAN_CATEGORY_SPECTRUM_MGMT:
02559 ieee80211_sta_process_chanswitch(sdata,
02560 &mgmt->u.action.u.chan_switch.sw_elem,
02561 (void *)ifmgd->associated->priv,
02562 rx_status->mactime);
02563 break;
02564 }
02565 }
02566 mutex_unlock(&ifmgd->mtx);
02567
02568 switch (rma) {
02569 case RX_MGMT_NONE:
02570
02571 break;
02572 case RX_MGMT_CFG80211_DEAUTH:
02573 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
02574 break;
02575 case RX_MGMT_CFG80211_DISASSOC:
02576 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
02577 break;
02578 case RX_MGMT_CFG80211_RX_AUTH:
02579 cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, skb->len);
02580 break;
02581 case RX_MGMT_CFG80211_RX_ASSOC:
02582 cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, skb->len);
02583 break;
02584 case RX_MGMT_CFG80211_ASSOC_TIMEOUT:
02585 cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid);
02586 break;
02587 default:
02588 WARN(1, "unexpected: %d", rma);
02589 }
02590 }
02591
02592 static void ieee80211_sta_timer(unsigned long data)
02593 {
02594 struct ieee80211_sub_if_data *sdata =
02595 (struct ieee80211_sub_if_data *) data;
02596 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
02597 struct ieee80211_local *local = sdata->local;
02598
02599 if (local->quiescing) {
02600 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
02601 return;
02602 }
02603
02604 ieee80211_queue_work(&local->hw, &sdata->work);
02605 }
02606
02607 static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
02608 u8 *bssid, u8 reason)
02609 {
02610 struct ieee80211_local *local = sdata->local;
02611 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
02612 u8 frame_buf[DEAUTH_DISASSOC_LEN];
02613
02614 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason,
02615 false, frame_buf);
02616 mutex_unlock(&ifmgd->mtx);
02617
02618
02619
02620
02621
02622 cfg80211_send_deauth(sdata->dev, frame_buf, DEAUTH_DISASSOC_LEN);
02623
02624 mutex_lock(&local->mtx);
02625 ieee80211_recalc_idle(local);
02626 mutex_unlock(&local->mtx);
02627
02628 mutex_lock(&ifmgd->mtx);
02629 }
02630
02631 static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
02632 {
02633 struct ieee80211_local *local = sdata->local;
02634 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
02635 struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data;
02636
02637 lockdep_assert_held(&ifmgd->mtx);
02638
02639 if (WARN_ON_ONCE(!auth_data))
02640 return -EINVAL;
02641
02642 auth_data->tries++;
02643
02644 if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) {
02645 printk(KERN_DEBUG "%s: authentication with %pM timed out\n",
02646 sdata->name, auth_data->bss->bssid);
02647
02648
02649
02650
02651
02652 cfg80211_unlink_bss(local->hw.wiphy, auth_data->bss);
02653
02654 return -ETIMEDOUT;
02655 }
02656
02657 if (auth_data->bss->proberesp_ies) {
02658 printk(KERN_DEBUG "%s: send auth to %pM (try %d/%d)\n",
02659 sdata->name, auth_data->bss->bssid, auth_data->tries,
02660 IEEE80211_AUTH_MAX_TRIES);
02661
02662 auth_data->expected_transaction = 2;
02663 ieee80211_send_auth(sdata, 1, auth_data->algorithm,
02664 auth_data->ie, auth_data->ie_len,
02665 auth_data->bss->bssid,
02666 auth_data->bss->bssid, NULL, 0, 0);
02667 } else {
02668 const u8 *ssidie;
02669
02670 printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n",
02671 sdata->name, auth_data->bss->bssid, auth_data->tries,
02672 IEEE80211_AUTH_MAX_TRIES);
02673
02674 ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID);
02675 if (!ssidie)
02676 return -EINVAL;
02677
02678
02679
02680
02681 ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1],
02682 NULL, 0, (u32) -1, true, false);
02683 }
02684
02685 auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
02686 run_again(ifmgd, auth_data->timeout);
02687
02688 return 0;
02689 }
02690
02691 static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
02692 {
02693 struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
02694 struct ieee80211_local *local = sdata->local;
02695
02696 lockdep_assert_held(&sdata->u.mgd.mtx);
02697
02698 assoc_data->tries++;
02699 if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) {
02700 printk(KERN_DEBUG "%s: association with %pM timed out\n",
02701 sdata->name, assoc_data->bss->bssid);
02702
02703
02704
02705
02706
02707 cfg80211_unlink_bss(local->hw.wiphy, assoc_data->bss);
02708
02709 return -ETIMEDOUT;
02710 }
02711
02712 printk(KERN_DEBUG "%s: associate with %pM (try %d/%d)\n",
02713 sdata->name, assoc_data->bss->bssid, assoc_data->tries,
02714 IEEE80211_ASSOC_MAX_TRIES);
02715 ieee80211_send_assoc(sdata);
02716
02717 assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
02718 run_again(&sdata->u.mgd, assoc_data->timeout);
02719
02720 return 0;
02721 }
02722
02723 void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
02724 {
02725 struct ieee80211_local *local = sdata->local;
02726 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
02727
02728 mutex_lock(&ifmgd->mtx);
02729
02730 if (ifmgd->auth_data &&
02731 time_after(jiffies, ifmgd->auth_data->timeout)) {
02732 if (ifmgd->auth_data->done) {
02733
02734
02735
02736
02737 ieee80211_destroy_auth_data(sdata, false);
02738 } else if (ieee80211_probe_auth(sdata)) {
02739 u8 bssid[ETH_ALEN];
02740
02741 memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
02742
02743 ieee80211_destroy_auth_data(sdata, false);
02744
02745 mutex_unlock(&ifmgd->mtx);
02746 cfg80211_send_auth_timeout(sdata->dev, bssid);
02747 mutex_lock(&ifmgd->mtx);
02748 }
02749 } else if (ifmgd->auth_data)
02750 run_again(ifmgd, ifmgd->auth_data->timeout);
02751
02752 if (ifmgd->assoc_data &&
02753 time_after(jiffies, ifmgd->assoc_data->timeout)) {
02754 if (!ifmgd->assoc_data->have_beacon ||
02755 ieee80211_do_assoc(sdata)) {
02756 u8 bssid[ETH_ALEN];
02757
02758 memcpy(bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN);
02759
02760 ieee80211_destroy_assoc_data(sdata, false);
02761
02762 mutex_unlock(&ifmgd->mtx);
02763 cfg80211_send_assoc_timeout(sdata->dev, bssid);
02764 mutex_lock(&ifmgd->mtx);
02765 }
02766 } else if (ifmgd->assoc_data)
02767 run_again(ifmgd, ifmgd->assoc_data->timeout);
02768
02769 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
02770 IEEE80211_STA_CONNECTION_POLL) &&
02771 ifmgd->associated) {
02772 u8 bssid[ETH_ALEN];
02773 int max_tries;
02774
02775 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
02776
02777 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
02778 max_tries = max_nullfunc_tries;
02779 else
02780 max_tries = max_probe_tries;
02781
02782
02783 if (!ifmgd->probe_send_count)
02784 ieee80211_reset_ap_probe(sdata);
02785 else if (ifmgd->nullfunc_failed) {
02786 if (ifmgd->probe_send_count < max_tries) {
02787 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
02788 wiphy_debug(local->hw.wiphy,
02789 "%s: No ack for nullfunc frame to"
02790 " AP %pM, try %d/%i\n",
02791 sdata->name, bssid,
02792 ifmgd->probe_send_count, max_tries);
02793 #endif
02794 ieee80211_mgd_probe_ap_send(sdata);
02795 } else {
02796 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
02797 wiphy_debug(local->hw.wiphy,
02798 "%s: No ack for nullfunc frame to"
02799 " AP %pM, disconnecting.\n",
02800 sdata->name, bssid);
02801 #endif
02802 ieee80211_sta_connection_lost(sdata, bssid,
02803 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
02804 }
02805 } else if (time_is_after_jiffies(ifmgd->probe_timeout))
02806 run_again(ifmgd, ifmgd->probe_timeout);
02807 else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
02808 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
02809 wiphy_debug(local->hw.wiphy,
02810 "%s: Failed to send nullfunc to AP %pM"
02811 " after %dms, disconnecting.\n",
02812 sdata->name,
02813 bssid, probe_wait_ms);
02814 #endif
02815 ieee80211_sta_connection_lost(sdata, bssid,
02816 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
02817 } else if (ifmgd->probe_send_count < max_tries) {
02818 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
02819 wiphy_debug(local->hw.wiphy,
02820 "%s: No probe response from AP %pM"
02821 " after %dms, try %d/%i\n",
02822 sdata->name,
02823 bssid, probe_wait_ms,
02824 ifmgd->probe_send_count, max_tries);
02825 #endif
02826 ieee80211_mgd_probe_ap_send(sdata);
02827 } else {
02828
02829
02830
02831
02832 wiphy_debug(local->hw.wiphy,
02833 "%s: No probe response from AP %pM"
02834 " after %dms, disconnecting.\n",
02835 sdata->name,
02836 bssid, probe_wait_ms);
02837
02838 ieee80211_sta_connection_lost(sdata, bssid,
02839 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
02840 }
02841 }
02842
02843 mutex_unlock(&ifmgd->mtx);
02844
02845 mutex_lock(&local->mtx);
02846 ieee80211_recalc_idle(local);
02847 mutex_unlock(&local->mtx);
02848 }
02849
02850 static void ieee80211_sta_bcn_mon_timer(unsigned long data)
02851 {
02852 struct ieee80211_sub_if_data *sdata =
02853 (struct ieee80211_sub_if_data *) data;
02854 struct ieee80211_local *local = sdata->local;
02855
02856 if (local->quiescing)
02857 return;
02858
02859 ieee80211_queue_work(&sdata->local->hw,
02860 &sdata->u.mgd.beacon_connection_loss_work);
02861 }
02862
02863 static void ieee80211_sta_conn_mon_timer(unsigned long data)
02864 {
02865 struct ieee80211_sub_if_data *sdata =
02866 (struct ieee80211_sub_if_data *) data;
02867 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
02868 struct ieee80211_local *local = sdata->local;
02869
02870 if (local->quiescing)
02871 return;
02872
02873 ieee80211_queue_work(&local->hw, &ifmgd->monitor_work);
02874 }
02875
02876 static void ieee80211_sta_monitor_work(struct work_struct *work)
02877 {
02878 struct ieee80211_sub_if_data *sdata =
02879 container_of(work, struct ieee80211_sub_if_data,
02880 u.mgd.monitor_work);
02881
02882 ieee80211_mgd_probe_ap(sdata, false);
02883 }
02884
02885 static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
02886 {
02887 u32 flags;
02888
02889 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
02890 __ieee80211_stop_poll(sdata);
02891
02892
02893 flags = sdata->local->hw.flags;
02894 if (!(flags & IEEE80211_HW_CONNECTION_MONITOR))
02895 ieee80211_queue_work(&sdata->local->hw,
02896 &sdata->u.mgd.monitor_work);
02897
02898 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
02899 }
02900 }
02901
02902 #ifdef CONFIG_PM
02903 void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
02904 {
02905 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
02906
02907
02908
02909
02910
02911
02912
02913 cancel_work_sync(&ifmgd->request_smps_work);
02914
02915 cancel_work_sync(&ifmgd->monitor_work);
02916 cancel_work_sync(&ifmgd->beacon_connection_loss_work);
02917 if (del_timer_sync(&ifmgd->timer))
02918 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
02919
02920 cancel_work_sync(&ifmgd->chswitch_work);
02921 if (del_timer_sync(&ifmgd->chswitch_timer))
02922 set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
02923
02924
02925 del_timer_sync(&ifmgd->conn_mon_timer);
02926 del_timer_sync(&ifmgd->bcn_mon_timer);
02927 }
02928
02929 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
02930 {
02931 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
02932
02933 if (!ifmgd->associated)
02934 return;
02935
02936 if (sdata->flags & IEEE80211_SDATA_DISCONNECT_RESUME) {
02937 sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME;
02938 mutex_lock(&ifmgd->mtx);
02939 if (ifmgd->associated) {
02940 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
02941 wiphy_debug(sdata->local->hw.wiphy,
02942 "%s: driver requested disconnect after resume.\n",
02943 sdata->name);
02944 #endif
02945 ieee80211_sta_connection_lost(sdata,
02946 ifmgd->associated->bssid,
02947 WLAN_REASON_UNSPECIFIED);
02948 mutex_unlock(&ifmgd->mtx);
02949 return;
02950 }
02951 mutex_unlock(&ifmgd->mtx);
02952 }
02953
02954 if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running))
02955 add_timer(&ifmgd->timer);
02956 if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))
02957 add_timer(&ifmgd->chswitch_timer);
02958 ieee80211_sta_reset_beacon_monitor(sdata);
02959
02960 mutex_lock(&sdata->local->mtx);
02961 ieee80211_restart_sta_timer(sdata);
02962 mutex_unlock(&sdata->local->mtx);
02963 }
02964 #endif
02965
02966
02967 void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
02968 {
02969 struct ieee80211_if_managed *ifmgd;
02970
02971 ifmgd = &sdata->u.mgd;
02972 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work);
02973 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
02974 INIT_WORK(&ifmgd->beacon_connection_loss_work,
02975 ieee80211_beacon_connection_loss_work);
02976 INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_work);
02977 setup_timer(&ifmgd->timer, ieee80211_sta_timer,
02978 (unsigned long) sdata);
02979 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer,
02980 (unsigned long) sdata);
02981 setup_timer(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer,
02982 (unsigned long) sdata);
02983 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer,
02984 (unsigned long) sdata);
02985
02986 ifmgd->flags = 0;
02987 ifmgd->powersave = sdata->wdev.ps;
02988 ifmgd->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
02989 ifmgd->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
02990
02991 mutex_init(&ifmgd->mtx);
02992
02993 if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS)
02994 ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC;
02995 else
02996 ifmgd->req_smps = IEEE80211_SMPS_OFF;
02997 }
02998
02999
03000 void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
03001 {
03002 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
03003
03004
03005 rcu_read_lock();
03006 list_for_each_entry_rcu(sdata, &local->interfaces, list)
03007 ieee80211_restart_sta_timer(sdata);
03008 rcu_read_unlock();
03009 }
03010
03011 int ieee80211_max_network_latency(struct notifier_block *nb,
03012 unsigned long data, void *dummy)
03013 {
03014 s32 latency_usec = (s32) data;
03015 struct ieee80211_local *local =
03016 container_of(nb, struct ieee80211_local,
03017 network_latency_notifier);
03018
03019 mutex_lock(&local->iflist_mtx);
03020 ieee80211_recalc_ps(local, latency_usec);
03021 mutex_unlock(&local->iflist_mtx);
03022
03023 return 0;
03024 }
03025
03026 static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
03027 struct cfg80211_bss *cbss, bool assoc)
03028 {
03029 struct ieee80211_local *local = sdata->local;
03030 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
03031 struct ieee80211_bss *bss = (void *)cbss->priv;
03032 struct sta_info *sta;
03033 bool have_sta = false;
03034 int err;
03035 int ht_cfreq;
03036 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
03037 const u8 *ht_oper_ie;
03038 const struct ieee80211_ht_operation *ht_oper = NULL;
03039 struct ieee80211_supported_band *sband;
03040
03041 if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data))
03042 return -EINVAL;
03043
03044 if (assoc) {
03045 rcu_read_lock();
03046 have_sta = sta_info_get(sdata, cbss->bssid);
03047 rcu_read_unlock();
03048 }
03049
03050 if (!have_sta) {
03051 sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL);
03052 if (!sta)
03053 return -ENOMEM;
03054 }
03055
03056 mutex_lock(&local->mtx);
03057 ieee80211_recalc_idle(sdata->local);
03058 mutex_unlock(&local->mtx);
03059
03060
03061 sband = local->hw.wiphy->bands[cbss->channel->band];
03062
03063 ifmgd->flags &= ~IEEE80211_STA_DISABLE_40MHZ;
03064
03065 if (sband->ht_cap.ht_supported) {
03066 ht_oper_ie = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
03067 cbss->information_elements,
03068 cbss->len_information_elements);
03069 if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper))
03070 ht_oper = (void *)(ht_oper_ie + 2);
03071 }
03072
03073 if (ht_oper) {
03074 ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan,
03075 cbss->channel->band);
03076
03077 if (cbss->channel->center_freq != ht_cfreq) {
03078
03079
03080
03081
03082
03083
03084
03085 printk(KERN_DEBUG
03086 "%s: Wrong control channel: center-freq: %d"
03087 " ht-cfreq: %d ht->primary_chan: %d"
03088 " band: %d. Disabling HT.\n",
03089 sdata->name, cbss->channel->center_freq,
03090 ht_cfreq, ht_oper->primary_chan,
03091 cbss->channel->band);
03092 ht_oper = NULL;
03093 }
03094 }
03095
03096 if (ht_oper) {
03097 channel_type = NL80211_CHAN_HT20;
03098
03099 if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
03100 switch (ht_oper->ht_param &
03101 IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
03102 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
03103 channel_type = NL80211_CHAN_HT40PLUS;
03104 break;
03105 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
03106 channel_type = NL80211_CHAN_HT40MINUS;
03107 break;
03108 }
03109 }
03110 }
03111
03112 if (!ieee80211_set_channel_type(local, sdata, channel_type)) {
03113
03114 channel_type = NL80211_CHAN_HT20;
03115 printk(KERN_DEBUG
03116 "%s: disabling 40 MHz due to multi-vif mismatch\n",
03117 sdata->name);
03118 ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ;
03119 WARN_ON(!ieee80211_set_channel_type(local, sdata,
03120 channel_type));
03121 }
03122
03123 local->oper_channel = cbss->channel;
03124 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
03125
03126 if (!have_sta) {
03127 u32 rates = 0, basic_rates = 0;
03128 bool have_higher_than_11mbit;
03129 int min_rate = INT_MAX, min_rate_index = -1;
03130
03131 ieee80211_get_rates(sband, bss->supp_rates,
03132 bss->supp_rates_len,
03133 &rates, &basic_rates,
03134 &have_higher_than_11mbit,
03135 &min_rate, &min_rate_index);
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145 if (!basic_rates && min_rate_index >= 0) {
03146 printk(KERN_DEBUG
03147 "%s: No basic rates, using min rate instead.\n",
03148 sdata->name);
03149 basic_rates = BIT(min_rate_index);
03150 }
03151
03152 sta->sta.supp_rates[cbss->channel->band] = rates;
03153 sdata->vif.bss_conf.basic_rates = basic_rates;
03154
03155
03156 if (local->oper_channel->band == IEEE80211_BAND_2GHZ &&
03157 have_higher_than_11mbit)
03158 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
03159 else
03160 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
03161
03162 memcpy(ifmgd->bssid, cbss->bssid, ETH_ALEN);
03163
03164
03165 ieee80211_bss_info_change_notify(sdata,
03166 BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES);
03167
03168 if (assoc)
03169 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
03170
03171 err = sta_info_insert(sta);
03172 sta = NULL;
03173 if (err) {
03174 printk(KERN_DEBUG
03175 "%s: failed to insert STA entry for the AP (error %d)\n",
03176 sdata->name, err);
03177 return err;
03178 }
03179 } else
03180 WARN_ON_ONCE(!ether_addr_equal(ifmgd->bssid, cbss->bssid));
03181
03182 return 0;
03183 }
03184
03185
03186 int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
03187 struct cfg80211_auth_request *req)
03188 {
03189 struct ieee80211_local *local = sdata->local;
03190 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
03191 struct ieee80211_mgd_auth_data *auth_data;
03192 u16 auth_alg;
03193 int err;
03194
03195
03196
03197 switch (req->auth_type) {
03198 case NL80211_AUTHTYPE_OPEN_SYSTEM:
03199 auth_alg = WLAN_AUTH_OPEN;
03200 break;
03201 case NL80211_AUTHTYPE_SHARED_KEY:
03202 if (IS_ERR(local->wep_tx_tfm))
03203 return -EOPNOTSUPP;
03204 auth_alg = WLAN_AUTH_SHARED_KEY;
03205 break;
03206 case NL80211_AUTHTYPE_FT:
03207 auth_alg = WLAN_AUTH_FT;
03208 break;
03209 case NL80211_AUTHTYPE_NETWORK_EAP:
03210 auth_alg = WLAN_AUTH_LEAP;
03211 break;
03212 default:
03213 return -EOPNOTSUPP;
03214 }
03215
03216 auth_data = kzalloc(sizeof(*auth_data) + req->ie_len, GFP_KERNEL);
03217 if (!auth_data)
03218 return -ENOMEM;
03219
03220 auth_data->bss = req->bss;
03221
03222 if (req->ie && req->ie_len) {
03223 memcpy(auth_data->ie, req->ie, req->ie_len);
03224 auth_data->ie_len = req->ie_len;
03225 }
03226
03227 if (req->key && req->key_len) {
03228 auth_data->key_len = req->key_len;
03229 auth_data->key_idx = req->key_idx;
03230 memcpy(auth_data->key, req->key, req->key_len);
03231 }
03232
03233 auth_data->algorithm = auth_alg;
03234
03235
03236
03237 mutex_lock(&ifmgd->mtx);
03238
03239 if ((ifmgd->auth_data && !ifmgd->auth_data->done) ||
03240 ifmgd->assoc_data) {
03241 err = -EBUSY;
03242 goto err_free;
03243 }
03244
03245 if (ifmgd->auth_data)
03246 ieee80211_destroy_auth_data(sdata, false);
03247
03248
03249 ifmgd->auth_data = auth_data;
03250
03251 if (ifmgd->associated)
03252 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
03253
03254 printk(KERN_DEBUG "%s: authenticate with %pM\n",
03255 sdata->name, req->bss->bssid);
03256
03257 err = ieee80211_prep_connection(sdata, req->bss, false);
03258 if (err)
03259 goto err_clear;
03260
03261 err = ieee80211_probe_auth(sdata);
03262 if (err) {
03263 sta_info_destroy_addr(sdata, req->bss->bssid);
03264 goto err_clear;
03265 }
03266
03267
03268 cfg80211_ref_bss(auth_data->bss);
03269 err = 0;
03270 goto out_unlock;
03271
03272 err_clear:
03273 memset(ifmgd->bssid, 0, ETH_ALEN);
03274 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
03275 ifmgd->auth_data = NULL;
03276 err_free:
03277 kfree(auth_data);
03278 out_unlock:
03279 mutex_unlock(&ifmgd->mtx);
03280
03281 return err;
03282 }
03283
03284 int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
03285 struct cfg80211_assoc_request *req)
03286 {
03287 struct ieee80211_local *local = sdata->local;
03288 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
03289 struct ieee80211_bss *bss = (void *)req->bss->priv;
03290 struct ieee80211_mgd_assoc_data *assoc_data;
03291 struct ieee80211_supported_band *sband;
03292 const u8 *ssidie;
03293 int i, err;
03294
03295 ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
03296 if (!ssidie)
03297 return -EINVAL;
03298
03299 assoc_data = kzalloc(sizeof(*assoc_data) + req->ie_len, GFP_KERNEL);
03300 if (!assoc_data)
03301 return -ENOMEM;
03302
03303 mutex_lock(&ifmgd->mtx);
03304
03305 if (ifmgd->associated)
03306 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
03307
03308 if (ifmgd->auth_data && !ifmgd->auth_data->done) {
03309 err = -EBUSY;
03310 goto err_free;
03311 }
03312
03313 if (ifmgd->assoc_data) {
03314 err = -EBUSY;
03315 goto err_free;
03316 }
03317
03318 if (ifmgd->auth_data) {
03319 bool match;
03320
03321
03322 match = ether_addr_equal(ifmgd->bssid, req->bss->bssid);
03323 ieee80211_destroy_auth_data(sdata, match);
03324 }
03325
03326
03327
03328 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
03329 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
03330
03331 ifmgd->beacon_crc_valid = false;
03332
03333
03334
03335
03336
03337
03338
03339
03340 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
03341 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
03342 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
03343 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104)
03344 ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
03345
03346 if (req->flags & ASSOC_REQ_DISABLE_HT)
03347 ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
03348
03349
03350 sband = local->hw.wiphy->bands[req->bss->channel->band];
03351 if (!sband->ht_cap.ht_supported ||
03352 local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used)
03353 ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
03354
03355 memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa));
03356 memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask,
03357 sizeof(ifmgd->ht_capa_mask));
03358
03359 if (req->ie && req->ie_len) {
03360 memcpy(assoc_data->ie, req->ie, req->ie_len);
03361 assoc_data->ie_len = req->ie_len;
03362 }
03363
03364 assoc_data->bss = req->bss;
03365
03366 if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
03367 if (ifmgd->powersave)
03368 ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC;
03369 else
03370 ifmgd->ap_smps = IEEE80211_SMPS_OFF;
03371 } else
03372 ifmgd->ap_smps = ifmgd->req_smps;
03373
03374 assoc_data->capability = req->bss->capability;
03375 assoc_data->wmm = bss->wmm_used &&
03376 (local->hw.queues >= IEEE80211_NUM_ACS);
03377 assoc_data->supp_rates = bss->supp_rates;
03378 assoc_data->supp_rates_len = bss->supp_rates_len;
03379 assoc_data->ht_operation_ie =
03380 ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_OPERATION);
03381
03382 if (bss->wmm_used && bss->uapsd_supported &&
03383 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
03384 assoc_data->uapsd = true;
03385 ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED;
03386 } else {
03387 assoc_data->uapsd = false;
03388 ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED;
03389 }
03390
03391 memcpy(assoc_data->ssid, ssidie + 2, ssidie[1]);
03392 assoc_data->ssid_len = ssidie[1];
03393
03394 if (req->prev_bssid)
03395 memcpy(assoc_data->prev_bssid, req->prev_bssid, ETH_ALEN);
03396
03397 if (req->use_mfp) {
03398 ifmgd->mfp = IEEE80211_MFP_REQUIRED;
03399 ifmgd->flags |= IEEE80211_STA_MFP_ENABLED;
03400 } else {
03401 ifmgd->mfp = IEEE80211_MFP_DISABLED;
03402 ifmgd->flags &= ~IEEE80211_STA_MFP_ENABLED;
03403 }
03404
03405 if (req->crypto.control_port)
03406 ifmgd->flags |= IEEE80211_STA_CONTROL_PORT;
03407 else
03408 ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT;
03409
03410 sdata->control_port_protocol = req->crypto.control_port_ethertype;
03411 sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
03412
03413
03414
03415 ifmgd->assoc_data = assoc_data;
03416
03417 err = ieee80211_prep_connection(sdata, req->bss, true);
03418 if (err)
03419 goto err_clear;
03420
03421 if (!bss->dtim_period &&
03422 sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) {
03423
03424
03425
03426
03427 printk(KERN_DEBUG "%s: waiting for beacon from %pM\n",
03428 sdata->name, ifmgd->bssid);
03429 assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval);
03430 } else {
03431 assoc_data->have_beacon = true;
03432 assoc_data->sent_assoc = false;
03433 assoc_data->timeout = jiffies;
03434 }
03435 run_again(ifmgd, assoc_data->timeout);
03436
03437 if (bss->corrupt_data) {
03438 char *corrupt_type = "data";
03439 if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_BEACON) {
03440 if (bss->corrupt_data &
03441 IEEE80211_BSS_CORRUPT_PROBE_RESP)
03442 corrupt_type = "beacon and probe response";
03443 else
03444 corrupt_type = "beacon";
03445 } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP)
03446 corrupt_type = "probe response";
03447 printk(KERN_DEBUG "%s: associating with AP with corrupt %s\n",
03448 sdata->name, corrupt_type);
03449 }
03450
03451 err = 0;
03452 goto out;
03453 err_clear:
03454 memset(ifmgd->bssid, 0, ETH_ALEN);
03455 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
03456 ifmgd->assoc_data = NULL;
03457 err_free:
03458 kfree(assoc_data);
03459 out:
03460 mutex_unlock(&ifmgd->mtx);
03461
03462 return err;
03463 }
03464
03465 int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
03466 struct cfg80211_deauth_request *req)
03467 {
03468 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
03469 u8 frame_buf[DEAUTH_DISASSOC_LEN];
03470
03471 mutex_lock(&ifmgd->mtx);
03472
03473 if (ifmgd->auth_data) {
03474 ieee80211_destroy_auth_data(sdata, false);
03475 mutex_unlock(&ifmgd->mtx);
03476 return 0;
03477 }
03478
03479 printk(KERN_DEBUG
03480 "%s: deauthenticating from %pM by local choice (reason=%d)\n",
03481 sdata->name, req->bssid, req->reason_code);
03482
03483 if (ifmgd->associated &&
03484 ether_addr_equal(ifmgd->associated->bssid, req->bssid))
03485 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
03486 req->reason_code, true, frame_buf);
03487 else
03488 ieee80211_send_deauth_disassoc(sdata, req->bssid,
03489 IEEE80211_STYPE_DEAUTH,
03490 req->reason_code, true,
03491 frame_buf);
03492 mutex_unlock(&ifmgd->mtx);
03493
03494 __cfg80211_send_deauth(sdata->dev, frame_buf, DEAUTH_DISASSOC_LEN);
03495
03496 mutex_lock(&sdata->local->mtx);
03497 ieee80211_recalc_idle(sdata->local);
03498 mutex_unlock(&sdata->local->mtx);
03499
03500 return 0;
03501 }
03502
03503 int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
03504 struct cfg80211_disassoc_request *req)
03505 {
03506 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
03507 u8 bssid[ETH_ALEN];
03508 u8 frame_buf[DEAUTH_DISASSOC_LEN];
03509
03510 mutex_lock(&ifmgd->mtx);
03511
03512
03513
03514
03515
03516
03517
03518 if (ifmgd->associated != req->bss) {
03519 mutex_unlock(&ifmgd->mtx);
03520 return -ENOLINK;
03521 }
03522
03523 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n",
03524 sdata->name, req->bss->bssid, req->reason_code);
03525
03526 memcpy(bssid, req->bss->bssid, ETH_ALEN);
03527 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC,
03528 req->reason_code, !req->local_state_change,
03529 frame_buf);
03530 mutex_unlock(&ifmgd->mtx);
03531
03532 __cfg80211_send_disassoc(sdata->dev, frame_buf, DEAUTH_DISASSOC_LEN);
03533
03534 mutex_lock(&sdata->local->mtx);
03535 ieee80211_recalc_idle(sdata->local);
03536 mutex_unlock(&sdata->local->mtx);
03537
03538 return 0;
03539 }
03540
03541 void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
03542 {
03543 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
03544
03545 mutex_lock(&ifmgd->mtx);
03546 if (ifmgd->assoc_data)
03547 ieee80211_destroy_assoc_data(sdata, false);
03548 if (ifmgd->auth_data)
03549 ieee80211_destroy_auth_data(sdata, false);
03550 del_timer_sync(&ifmgd->timer);
03551 mutex_unlock(&ifmgd->mtx);
03552 }
03553
03554 void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
03555 enum nl80211_cqm_rssi_threshold_event rssi_event,
03556 gfp_t gfp)
03557 {
03558 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
03559
03560 trace_api_cqm_rssi_notify(sdata, rssi_event);
03561
03562 cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp);
03563 }
03564 EXPORT_SYMBOL(ieee80211_cqm_rssi_notify);
03565
03566 unsigned char ieee80211_get_operstate(struct ieee80211_vif *vif)
03567 {
03568 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
03569 return sdata->dev->operstate;
03570 }
03571 EXPORT_SYMBOL(ieee80211_get_operstate);