diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-06-18 14:04:51 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-06-18 14:04:51 -0400 |
commit | 9d1059c2481885ba7a2af02fc1bf87cae88b302a (patch) | |
tree | b9ff1d502017ea7939d26a99720801ffdbe2b3da /net | |
parent | c4d827c5ccc3a49227dbf9d4b248a2e86f388023 (diff) | |
parent | fcb3701849957917a234a61b58ad70ed35c83eda (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.c | 15 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 3 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 6 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 5 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 87 | ||||
-rw-r--r-- | net/mac80211/rate.c | 2 | ||||
-rw-r--r-- | net/mac80211/util.c | 4 |
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 | ||
342 | static void bredr_setup(struct hci_request *req) | 342 | static 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, ¶m); | 365 | hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); |
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 | ||
1516 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action, | 1516 | u32 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); |
1519 | static inline void ieee802_11_parse_elems(u8 *start, size_t len, bool action, | 1519 | static 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 | ||
2649 | static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | 2722 | static 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 | } |
668 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); | 668 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); |
669 | 669 | ||
670 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action, | 670 | u32 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; |