aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-06-18 14:04:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-06-18 14:04:51 -0400
commit9d1059c2481885ba7a2af02fc1bf87cae88b302a (patch)
treeb9ff1d502017ea7939d26a99720801ffdbe2b3da /net
parentc4d827c5ccc3a49227dbf9d4b248a2e86f388023 (diff)
parentfcb3701849957917a234a61b58ad70ed35c83eda (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_core.c15
-rw-r--r--net/bluetooth/l2cap_core.c3
-rw-r--r--net/mac80211/cfg.c6
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/mlme.c87
-rw-r--r--net/mac80211/rate.c2
-rw-r--r--net/mac80211/util.c4
7 files changed, 105 insertions, 17 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index d817c932d634..ace5e55fe5a3 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -341,7 +341,6 @@ static void hci_init1_req(struct hci_request *req, unsigned long opt)
341 341
342static void bredr_setup(struct hci_request *req) 342static void bredr_setup(struct hci_request *req)
343{ 343{
344 struct hci_cp_delete_stored_link_key cp;
345 __le16 param; 344 __le16 param;
346 __u8 flt_type; 345 __u8 flt_type;
347 346
@@ -365,10 +364,6 @@ static void bredr_setup(struct hci_request *req)
365 param = __constant_cpu_to_le16(0x7d00); 364 param = __constant_cpu_to_le16(0x7d00);
366 hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param); 365 hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
367 366
368 bacpy(&cp.bdaddr, BDADDR_ANY);
369 cp.delete_all = 0x01;
370 hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
371
372 /* Read page scan parameters */ 367 /* Read page scan parameters */
373 if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) { 368 if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) {
374 hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); 369 hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
@@ -602,6 +597,16 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
602 struct hci_dev *hdev = req->hdev; 597 struct hci_dev *hdev = req->hdev;
603 u8 p; 598 u8 p;
604 599
600 /* Only send HCI_Delete_Stored_Link_Key if it is supported */
601 if (hdev->commands[6] & 0x80) {
602 struct hci_cp_delete_stored_link_key cp;
603
604 bacpy(&cp.bdaddr, BDADDR_ANY);
605 cp.delete_all = 0x01;
606 hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
607 sizeof(cp), &cp);
608 }
609
605 if (hdev->commands[5] & 0x10) 610 if (hdev->commands[5] & 0x10)
606 hci_setup_link_policy(req); 611 hci_setup_link_policy(req);
607 612
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 24bee07ee4ce..4be6a264b475 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2852,6 +2852,9 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2852 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u", 2852 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2853 conn, code, ident, dlen); 2853 conn, code, ident, dlen);
2854 2854
2855 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2856 return NULL;
2857
2855 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; 2858 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2856 count = min_t(unsigned int, conn->mtu, len); 2859 count = min_t(unsigned int, conn->mtu, len);
2857 2860
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 64cf294c2b96..082f270b5912 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1071,6 +1071,12 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1071 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); 1071 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
1072 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 1072 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
1073 1073
1074 if (sdata->wdev.cac_started) {
1075 cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
1076 cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED,
1077 GFP_KERNEL);
1078 }
1079
1074 drv_stop_ap(sdata->local, sdata); 1080 drv_stop_ap(sdata->local, sdata);
1075 1081
1076 /* free all potentially still buffered bcast frames */ 1082 /* free all potentially still buffered bcast frames */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 7a6f1a0207ec..f97cd9d9105f 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1513,10 +1513,11 @@ static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata,
1513 ieee80211_tx_skb_tid(sdata, skb, 7); 1513 ieee80211_tx_skb_tid(sdata, skb, 7);
1514} 1514}
1515 1515
1516u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action, 1516u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
1517 struct ieee802_11_elems *elems, 1517 struct ieee802_11_elems *elems,
1518 u64 filter, u32 crc); 1518 u64 filter, u32 crc);
1519static inline void ieee802_11_parse_elems(u8 *start, size_t len, bool action, 1519static inline void ieee802_11_parse_elems(const u8 *start, size_t len,
1520 bool action,
1520 struct ieee802_11_elems *elems) 1521 struct ieee802_11_elems *elems)
1521{ 1522{
1522 ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0); 1523 ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index ad9bb9e10cbb..9e49f557fa5c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2492,8 +2492,11 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2492 u16 capab_info, aid; 2492 u16 capab_info, aid;
2493 struct ieee802_11_elems elems; 2493 struct ieee802_11_elems elems;
2494 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; 2494 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
2495 const struct cfg80211_bss_ies *bss_ies = NULL;
2496 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
2495 u32 changed = 0; 2497 u32 changed = 0;
2496 int err; 2498 int err;
2499 bool ret;
2497 2500
2498 /* AssocResp and ReassocResp have identical structure */ 2501 /* AssocResp and ReassocResp have identical structure */
2499 2502
@@ -2525,21 +2528,86 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2525 ifmgd->aid = aid; 2528 ifmgd->aid = aid;
2526 2529
2527 /* 2530 /*
2531 * Some APs are erroneously not including some information in their
2532 * (re)association response frames. Try to recover by using the data
2533 * from the beacon or probe response. This seems to afflict mobile
2534 * 2G/3G/4G wifi routers, reported models include the "Onda PN51T",
2535 * "Vodafone PocketWiFi 2", "ZTE MF60" and a similar T-Mobile device.
2536 */
2537 if ((assoc_data->wmm && !elems.wmm_param) ||
2538 (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
2539 (!elems.ht_cap_elem || !elems.ht_operation)) ||
2540 (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
2541 (!elems.vht_cap_elem || !elems.vht_operation))) {
2542 const struct cfg80211_bss_ies *ies;
2543 struct ieee802_11_elems bss_elems;
2544
2545 rcu_read_lock();
2546 ies = rcu_dereference(cbss->ies);
2547 if (ies)
2548 bss_ies = kmemdup(ies, sizeof(*ies) + ies->len,
2549 GFP_ATOMIC);
2550 rcu_read_unlock();
2551 if (!bss_ies)
2552 return false;
2553
2554 ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
2555 false, &bss_elems);
2556 if (assoc_data->wmm &&
2557 !elems.wmm_param && bss_elems.wmm_param) {
2558 elems.wmm_param = bss_elems.wmm_param;
2559 sdata_info(sdata,
2560 "AP bug: WMM param missing from AssocResp\n");
2561 }
2562
2563 /*
2564 * Also check if we requested HT/VHT, otherwise the AP doesn't
2565 * have to include the IEs in the (re)association response.
2566 */
2567 if (!elems.ht_cap_elem && bss_elems.ht_cap_elem &&
2568 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
2569 elems.ht_cap_elem = bss_elems.ht_cap_elem;
2570 sdata_info(sdata,
2571 "AP bug: HT capability missing from AssocResp\n");
2572 }
2573 if (!elems.ht_operation && bss_elems.ht_operation &&
2574 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
2575 elems.ht_operation = bss_elems.ht_operation;
2576 sdata_info(sdata,
2577 "AP bug: HT operation missing from AssocResp\n");
2578 }
2579 if (!elems.vht_cap_elem && bss_elems.vht_cap_elem &&
2580 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
2581 elems.vht_cap_elem = bss_elems.vht_cap_elem;
2582 sdata_info(sdata,
2583 "AP bug: VHT capa missing from AssocResp\n");
2584 }
2585 if (!elems.vht_operation && bss_elems.vht_operation &&
2586 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
2587 elems.vht_operation = bss_elems.vht_operation;
2588 sdata_info(sdata,
2589 "AP bug: VHT operation missing from AssocResp\n");
2590 }
2591 }
2592
2593 /*
2528 * We previously checked these in the beacon/probe response, so 2594 * We previously checked these in the beacon/probe response, so
2529 * they should be present here. This is just a safety net. 2595 * they should be present here. This is just a safety net.
2530 */ 2596 */
2531 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && 2597 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
2532 (!elems.wmm_param || !elems.ht_cap_elem || !elems.ht_operation)) { 2598 (!elems.wmm_param || !elems.ht_cap_elem || !elems.ht_operation)) {
2533 sdata_info(sdata, 2599 sdata_info(sdata,
2534 "HT AP is missing WMM params or HT capability/operation in AssocResp\n"); 2600 "HT AP is missing WMM params or HT capability/operation\n");
2535 return false; 2601 ret = false;
2602 goto out;
2536 } 2603 }
2537 2604
2538 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && 2605 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
2539 (!elems.vht_cap_elem || !elems.vht_operation)) { 2606 (!elems.vht_cap_elem || !elems.vht_operation)) {
2540 sdata_info(sdata, 2607 sdata_info(sdata,
2541 "VHT AP is missing VHT capability/operation in AssocResp\n"); 2608 "VHT AP is missing VHT capability/operation\n");
2542 return false; 2609 ret = false;
2610 goto out;
2543 } 2611 }
2544 2612
2545 mutex_lock(&sdata->local->sta_mtx); 2613 mutex_lock(&sdata->local->sta_mtx);
@@ -2550,7 +2618,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2550 sta = sta_info_get(sdata, cbss->bssid); 2618 sta = sta_info_get(sdata, cbss->bssid);
2551 if (WARN_ON(!sta)) { 2619 if (WARN_ON(!sta)) {
2552 mutex_unlock(&sdata->local->sta_mtx); 2620 mutex_unlock(&sdata->local->sta_mtx);
2553 return false; 2621 ret = false;
2622 goto out;
2554 } 2623 }
2555 2624
2556 sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)]; 2625 sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
@@ -2603,7 +2672,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2603 sta->sta.addr); 2672 sta->sta.addr);
2604 WARN_ON(__sta_info_destroy(sta)); 2673 WARN_ON(__sta_info_destroy(sta));
2605 mutex_unlock(&sdata->local->sta_mtx); 2674 mutex_unlock(&sdata->local->sta_mtx);
2606 return false; 2675 ret = false;
2676 goto out;
2607 } 2677 }
2608 2678
2609 mutex_unlock(&sdata->local->sta_mtx); 2679 mutex_unlock(&sdata->local->sta_mtx);
@@ -2643,7 +2713,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2643 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); 2713 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
2644 ieee80211_sta_reset_beacon_monitor(sdata); 2714 ieee80211_sta_reset_beacon_monitor(sdata);
2645 2715
2646 return true; 2716 ret = true;
2717 out:
2718 kfree(bss_ies);
2719 return ret;
2647} 2720}
2648 2721
2649static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, 2722static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index d3f414fe67e0..a02bef35b134 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -615,7 +615,7 @@ static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata,
615 if (rates[i].idx < 0) 615 if (rates[i].idx < 0)
616 break; 616 break;
617 617
618 rate_idx_match_mask(&rates[i], sband, mask, chan_width, 618 rate_idx_match_mask(&rates[i], sband, chan_width, mask,
619 mcs_mask); 619 mcs_mask);
620 } 620 }
621} 621}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 5a6c1351d1d3..22654452a561 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -667,12 +667,12 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
667} 667}
668EXPORT_SYMBOL(ieee80211_queue_delayed_work); 668EXPORT_SYMBOL(ieee80211_queue_delayed_work);
669 669
670u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action, 670u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
671 struct ieee802_11_elems *elems, 671 struct ieee802_11_elems *elems,
672 u64 filter, u32 crc) 672 u64 filter, u32 crc)
673{ 673{
674 size_t left = len; 674 size_t left = len;
675 u8 *pos = start; 675 const u8 *pos = start;
676 bool calc_crc = filter != 0; 676 bool calc_crc = filter != 0;
677 DECLARE_BITMAP(seen_elems, 256); 677 DECLARE_BITMAP(seen_elems, 256);
678 const u8 *ie; 678 const u8 *ie;