aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-06-19 12:55:06 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-06-19 12:55:12 -0400
commitf93beba705842af466e7c916b39630cacb40e9c6 (patch)
tree0f296f0b1e419eb4fc242e188376a4fdd80085fa /net/mac80211/mlme.c
parent52874a5e3917dde3b081521b014d6e4b226aacff (diff)
parent3a5a423bb958ad22eeccca66c533e85bf69ba10e (diff)
Merge remote-tracking branch 'mac80211/master' into HEAD
Merge mac80211 to avoid conflicts with the nl80211 attrbuf changes. Conflicts: net/mac80211/iface.c net/wireless/nl80211.c Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c87
1 files changed, 80 insertions, 7 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index e0939eb79060..34d54fe81483 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2502,8 +2502,11 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2502 u16 capab_info, aid; 2502 u16 capab_info, aid;
2503 struct ieee802_11_elems elems; 2503 struct ieee802_11_elems elems;
2504 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; 2504 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
2505 const struct cfg80211_bss_ies *bss_ies = NULL;
2506 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
2505 u32 changed = 0; 2507 u32 changed = 0;
2506 int err; 2508 int err;
2509 bool ret;
2507 2510
2508 /* AssocResp and ReassocResp have identical structure */ 2511 /* AssocResp and ReassocResp have identical structure */
2509 2512
@@ -2535,21 +2538,86 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2535 ifmgd->aid = aid; 2538 ifmgd->aid = aid;
2536 2539
2537 /* 2540 /*
2541 * Some APs are erroneously not including some information in their
2542 * (re)association response frames. Try to recover by using the data
2543 * from the beacon or probe response. This seems to afflict mobile
2544 * 2G/3G/4G wifi routers, reported models include the "Onda PN51T",
2545 * "Vodafone PocketWiFi 2", "ZTE MF60" and a similar T-Mobile device.
2546 */
2547 if ((assoc_data->wmm && !elems.wmm_param) ||
2548 (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
2549 (!elems.ht_cap_elem || !elems.ht_operation)) ||
2550 (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
2551 (!elems.vht_cap_elem || !elems.vht_operation))) {
2552 const struct cfg80211_bss_ies *ies;
2553 struct ieee802_11_elems bss_elems;
2554
2555 rcu_read_lock();
2556 ies = rcu_dereference(cbss->ies);
2557 if (ies)
2558 bss_ies = kmemdup(ies, sizeof(*ies) + ies->len,
2559 GFP_ATOMIC);
2560 rcu_read_unlock();
2561 if (!bss_ies)
2562 return false;
2563
2564 ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
2565 false, &bss_elems);
2566 if (assoc_data->wmm &&
2567 !elems.wmm_param && bss_elems.wmm_param) {
2568 elems.wmm_param = bss_elems.wmm_param;
2569 sdata_info(sdata,
2570 "AP bug: WMM param missing from AssocResp\n");
2571 }
2572
2573 /*
2574 * Also check if we requested HT/VHT, otherwise the AP doesn't
2575 * have to include the IEs in the (re)association response.
2576 */
2577 if (!elems.ht_cap_elem && bss_elems.ht_cap_elem &&
2578 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
2579 elems.ht_cap_elem = bss_elems.ht_cap_elem;
2580 sdata_info(sdata,
2581 "AP bug: HT capability missing from AssocResp\n");
2582 }
2583 if (!elems.ht_operation && bss_elems.ht_operation &&
2584 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
2585 elems.ht_operation = bss_elems.ht_operation;
2586 sdata_info(sdata,
2587 "AP bug: HT operation missing from AssocResp\n");
2588 }
2589 if (!elems.vht_cap_elem && bss_elems.vht_cap_elem &&
2590 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
2591 elems.vht_cap_elem = bss_elems.vht_cap_elem;
2592 sdata_info(sdata,
2593 "AP bug: VHT capa missing from AssocResp\n");
2594 }
2595 if (!elems.vht_operation && bss_elems.vht_operation &&
2596 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
2597 elems.vht_operation = bss_elems.vht_operation;
2598 sdata_info(sdata,
2599 "AP bug: VHT operation missing from AssocResp\n");
2600 }
2601 }
2602
2603 /*
2538 * We previously checked these in the beacon/probe response, so 2604 * We previously checked these in the beacon/probe response, so
2539 * they should be present here. This is just a safety net. 2605 * they should be present here. This is just a safety net.
2540 */ 2606 */
2541 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && 2607 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
2542 (!elems.wmm_param || !elems.ht_cap_elem || !elems.ht_operation)) { 2608 (!elems.wmm_param || !elems.ht_cap_elem || !elems.ht_operation)) {
2543 sdata_info(sdata, 2609 sdata_info(sdata,
2544 "HT AP is missing WMM params or HT capability/operation in AssocResp\n"); 2610 "HT AP is missing WMM params or HT capability/operation\n");
2545 return false; 2611 ret = false;
2612 goto out;
2546 } 2613 }
2547 2614
2548 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && 2615 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
2549 (!elems.vht_cap_elem || !elems.vht_operation)) { 2616 (!elems.vht_cap_elem || !elems.vht_operation)) {
2550 sdata_info(sdata, 2617 sdata_info(sdata,
2551 "VHT AP is missing VHT capability/operation in AssocResp\n"); 2618 "VHT AP is missing VHT capability/operation\n");
2552 return false; 2619 ret = false;
2620 goto out;
2553 } 2621 }
2554 2622
2555 mutex_lock(&sdata->local->sta_mtx); 2623 mutex_lock(&sdata->local->sta_mtx);
@@ -2560,7 +2628,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2560 sta = sta_info_get(sdata, cbss->bssid); 2628 sta = sta_info_get(sdata, cbss->bssid);
2561 if (WARN_ON(!sta)) { 2629 if (WARN_ON(!sta)) {
2562 mutex_unlock(&sdata->local->sta_mtx); 2630 mutex_unlock(&sdata->local->sta_mtx);
2563 return false; 2631 ret = false;
2632 goto out;
2564 } 2633 }
2565 2634
2566 sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)]; 2635 sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
@@ -2613,7 +2682,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2613 sta->sta.addr); 2682 sta->sta.addr);
2614 WARN_ON(__sta_info_destroy(sta)); 2683 WARN_ON(__sta_info_destroy(sta));
2615 mutex_unlock(&sdata->local->sta_mtx); 2684 mutex_unlock(&sdata->local->sta_mtx);
2616 return false; 2685 ret = false;
2686 goto out;
2617 } 2687 }
2618 2688
2619 mutex_unlock(&sdata->local->sta_mtx); 2689 mutex_unlock(&sdata->local->sta_mtx);
@@ -2653,7 +2723,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2653 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); 2723 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
2654 ieee80211_sta_reset_beacon_monitor(sdata); 2724 ieee80211_sta_reset_beacon_monitor(sdata);
2655 2725
2656 return true; 2726 ret = true;
2727 out:
2728 kfree(bss_ies);
2729 return ret;
2657} 2730}
2658 2731
2659static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, 2732static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,