diff options
author | David S. Miller <davem@davemloft.net> | 2013-06-17 19:15:51 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-06-17 19:15:51 -0400 |
commit | c5b248dd051ee87e49307e576eb8d022722cf9a3 (patch) | |
tree | 1cec4727c5d9cc92f1ab151a673332c880559470 /net | |
parent | e00c7f1fad21ff81ac0a8dfbbb7cc3b7c806fa73 (diff) | |
parent | 722a300bf84ebebe21da164e75024c0ce7ca1868 (diff) |
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into wireless
John W. Linville says:
====================
This will probably be the last batch of wireless fixes intended
for 3.10. Many of these are one- or two-liners, and a couple of
others are mostly relocating existing code to avoid races or to
limit the code to effecting specific hardware, etc.
The mac80211 fixes have a couple of exceptions to the above.
Regarding those, Johannes says:
"Following davem's complaint about my patch, here's a new pull request
w/o the patch he was complaining about, but instead with the const
fix rolled into the fix.
I have a fix for radar detection, one for rate control and a workaround
for broken HT APs which is a regression fix because we didn't rely
on them to be correct before."
Johannes also sends some iwlwifi fixes:
"I picked up Nikolay's patch for the chain noise calibration bug
that seems to have been there forever, a fix from Emmanuel for
setting TX flags on BAR frames and a fix of my own to avoid printing
request_module() errors if the kernel isn't even modular. We also
have our own version of Stanislaw's fix for rate control."
Along with those...
Anderson Lizardo fixes a Bluetooth memory corruption bug when an MTU
value is set to too small of a value.
Arend van Spriel sends a revised brcmsmac bug that fixes a regression
caused by a bad return value in an earlier patch. He also sends a
brcmfmac fix to avoid an oops when loading the driver at boot.
Daniel Drake fixes a race condition in btmrvl that causes hangs on
suspend for OLPC hardware.
Johan Hedberg adds a check to avoid sending a
HCI_Delete_Stored_Link_Key command to devices that don't support them,
avoiding some scary looking log spam.
Stanislaw Gruszka gives us a fix for iwlegacy to be able to use rates
higher than 1Mb/s on older wireless networks. He also sends an rt2x00
fix to reinstate older tx power handling behavior for some devices
that didn't work well with the current code.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
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 1a89c80e6407..4fdb306e42e0 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1057,6 +1057,12 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
1057 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); | 1057 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); |
1058 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); | 1058 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); |
1059 | 1059 | ||
1060 | if (sdata->wdev.cac_started) { | ||
1061 | cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); | ||
1062 | cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED, | ||
1063 | GFP_KERNEL); | ||
1064 | } | ||
1065 | |||
1060 | drv_stop_ap(sdata->local, sdata); | 1066 | drv_stop_ap(sdata->local, sdata); |
1061 | 1067 | ||
1062 | /* free all potentially still buffered bcast frames */ | 1068 | /* free all potentially still buffered bcast frames */ |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 44be28cfc6c4..9ca8e3278cc0 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1497,10 +1497,11 @@ static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, | |||
1497 | ieee80211_tx_skb_tid(sdata, skb, 7); | 1497 | ieee80211_tx_skb_tid(sdata, skb, 7); |
1498 | } | 1498 | } |
1499 | 1499 | ||
1500 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action, | 1500 | u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, |
1501 | struct ieee802_11_elems *elems, | 1501 | struct ieee802_11_elems *elems, |
1502 | u64 filter, u32 crc); | 1502 | u64 filter, u32 crc); |
1503 | static inline void ieee802_11_parse_elems(u8 *start, size_t len, bool action, | 1503 | static inline void ieee802_11_parse_elems(const u8 *start, size_t len, |
1504 | bool action, | ||
1504 | struct ieee802_11_elems *elems) | 1505 | struct ieee802_11_elems *elems) |
1505 | { | 1506 | { |
1506 | ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0); | 1507 | ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a8c2130c8ba4..741448b30825 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2522,8 +2522,11 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2522 | u16 capab_info, aid; | 2522 | u16 capab_info, aid; |
2523 | struct ieee802_11_elems elems; | 2523 | struct ieee802_11_elems elems; |
2524 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; | 2524 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
2525 | const struct cfg80211_bss_ies *bss_ies = NULL; | ||
2526 | struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; | ||
2525 | u32 changed = 0; | 2527 | u32 changed = 0; |
2526 | int err; | 2528 | int err; |
2529 | bool ret; | ||
2527 | 2530 | ||
2528 | /* AssocResp and ReassocResp have identical structure */ | 2531 | /* AssocResp and ReassocResp have identical structure */ |
2529 | 2532 | ||
@@ -2555,21 +2558,86 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2555 | ifmgd->aid = aid; | 2558 | ifmgd->aid = aid; |
2556 | 2559 | ||
2557 | /* | 2560 | /* |
2561 | * Some APs are erroneously not including some information in their | ||
2562 | * (re)association response frames. Try to recover by using the data | ||
2563 | * from the beacon or probe response. This seems to afflict mobile | ||
2564 | * 2G/3G/4G wifi routers, reported models include the "Onda PN51T", | ||
2565 | * "Vodafone PocketWiFi 2", "ZTE MF60" and a similar T-Mobile device. | ||
2566 | */ | ||
2567 | if ((assoc_data->wmm && !elems.wmm_param) || | ||
2568 | (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && | ||
2569 | (!elems.ht_cap_elem || !elems.ht_operation)) || | ||
2570 | (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && | ||
2571 | (!elems.vht_cap_elem || !elems.vht_operation))) { | ||
2572 | const struct cfg80211_bss_ies *ies; | ||
2573 | struct ieee802_11_elems bss_elems; | ||
2574 | |||
2575 | rcu_read_lock(); | ||
2576 | ies = rcu_dereference(cbss->ies); | ||
2577 | if (ies) | ||
2578 | bss_ies = kmemdup(ies, sizeof(*ies) + ies->len, | ||
2579 | GFP_ATOMIC); | ||
2580 | rcu_read_unlock(); | ||
2581 | if (!bss_ies) | ||
2582 | return false; | ||
2583 | |||
2584 | ieee802_11_parse_elems(bss_ies->data, bss_ies->len, | ||
2585 | false, &bss_elems); | ||
2586 | if (assoc_data->wmm && | ||
2587 | !elems.wmm_param && bss_elems.wmm_param) { | ||
2588 | elems.wmm_param = bss_elems.wmm_param; | ||
2589 | sdata_info(sdata, | ||
2590 | "AP bug: WMM param missing from AssocResp\n"); | ||
2591 | } | ||
2592 | |||
2593 | /* | ||
2594 | * Also check if we requested HT/VHT, otherwise the AP doesn't | ||
2595 | * have to include the IEs in the (re)association response. | ||
2596 | */ | ||
2597 | if (!elems.ht_cap_elem && bss_elems.ht_cap_elem && | ||
2598 | !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { | ||
2599 | elems.ht_cap_elem = bss_elems.ht_cap_elem; | ||
2600 | sdata_info(sdata, | ||
2601 | "AP bug: HT capability missing from AssocResp\n"); | ||
2602 | } | ||
2603 | if (!elems.ht_operation && bss_elems.ht_operation && | ||
2604 | !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { | ||
2605 | elems.ht_operation = bss_elems.ht_operation; | ||
2606 | sdata_info(sdata, | ||
2607 | "AP bug: HT operation missing from AssocResp\n"); | ||
2608 | } | ||
2609 | if (!elems.vht_cap_elem && bss_elems.vht_cap_elem && | ||
2610 | !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) { | ||
2611 | elems.vht_cap_elem = bss_elems.vht_cap_elem; | ||
2612 | sdata_info(sdata, | ||
2613 | "AP bug: VHT capa missing from AssocResp\n"); | ||
2614 | } | ||
2615 | if (!elems.vht_operation && bss_elems.vht_operation && | ||
2616 | !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) { | ||
2617 | elems.vht_operation = bss_elems.vht_operation; | ||
2618 | sdata_info(sdata, | ||
2619 | "AP bug: VHT operation missing from AssocResp\n"); | ||
2620 | } | ||
2621 | } | ||
2622 | |||
2623 | /* | ||
2558 | * We previously checked these in the beacon/probe response, so | 2624 | * We previously checked these in the beacon/probe response, so |
2559 | * they should be present here. This is just a safety net. | 2625 | * they should be present here. This is just a safety net. |
2560 | */ | 2626 | */ |
2561 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && | 2627 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && |
2562 | (!elems.wmm_param || !elems.ht_cap_elem || !elems.ht_operation)) { | 2628 | (!elems.wmm_param || !elems.ht_cap_elem || !elems.ht_operation)) { |
2563 | sdata_info(sdata, | 2629 | sdata_info(sdata, |
2564 | "HT AP is missing WMM params or HT capability/operation in AssocResp\n"); | 2630 | "HT AP is missing WMM params or HT capability/operation\n"); |
2565 | return false; | 2631 | ret = false; |
2632 | goto out; | ||
2566 | } | 2633 | } |
2567 | 2634 | ||
2568 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && | 2635 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && |
2569 | (!elems.vht_cap_elem || !elems.vht_operation)) { | 2636 | (!elems.vht_cap_elem || !elems.vht_operation)) { |
2570 | sdata_info(sdata, | 2637 | sdata_info(sdata, |
2571 | "VHT AP is missing VHT capability/operation in AssocResp\n"); | 2638 | "VHT AP is missing VHT capability/operation\n"); |
2572 | return false; | 2639 | ret = false; |
2640 | goto out; | ||
2573 | } | 2641 | } |
2574 | 2642 | ||
2575 | mutex_lock(&sdata->local->sta_mtx); | 2643 | mutex_lock(&sdata->local->sta_mtx); |
@@ -2580,7 +2648,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2580 | sta = sta_info_get(sdata, cbss->bssid); | 2648 | sta = sta_info_get(sdata, cbss->bssid); |
2581 | if (WARN_ON(!sta)) { | 2649 | if (WARN_ON(!sta)) { |
2582 | mutex_unlock(&sdata->local->sta_mtx); | 2650 | mutex_unlock(&sdata->local->sta_mtx); |
2583 | return false; | 2651 | ret = false; |
2652 | goto out; | ||
2584 | } | 2653 | } |
2585 | 2654 | ||
2586 | sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)]; | 2655 | sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)]; |
@@ -2633,7 +2702,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2633 | sta->sta.addr); | 2702 | sta->sta.addr); |
2634 | WARN_ON(__sta_info_destroy(sta)); | 2703 | WARN_ON(__sta_info_destroy(sta)); |
2635 | mutex_unlock(&sdata->local->sta_mtx); | 2704 | mutex_unlock(&sdata->local->sta_mtx); |
2636 | return false; | 2705 | ret = false; |
2706 | goto out; | ||
2637 | } | 2707 | } |
2638 | 2708 | ||
2639 | mutex_unlock(&sdata->local->sta_mtx); | 2709 | mutex_unlock(&sdata->local->sta_mtx); |
@@ -2673,7 +2743,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2673 | ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); | 2743 | ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); |
2674 | ieee80211_sta_reset_beacon_monitor(sdata); | 2744 | ieee80211_sta_reset_beacon_monitor(sdata); |
2675 | 2745 | ||
2676 | return true; | 2746 | ret = true; |
2747 | out: | ||
2748 | kfree(bss_ies); | ||
2749 | return ret; | ||
2677 | } | 2750 | } |
2678 | 2751 | ||
2679 | static enum rx_mgmt_action __must_check | 2752 | static enum rx_mgmt_action __must_check |
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 27e07150eb46..72e6292955bb 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -661,12 +661,12 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, | |||
661 | } | 661 | } |
662 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); | 662 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); |
663 | 663 | ||
664 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action, | 664 | u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, |
665 | struct ieee802_11_elems *elems, | 665 | struct ieee802_11_elems *elems, |
666 | u64 filter, u32 crc) | 666 | u64 filter, u32 crc) |
667 | { | 667 | { |
668 | size_t left = len; | 668 | size_t left = len; |
669 | u8 *pos = start; | 669 | const u8 *pos = start; |
670 | bool calc_crc = filter != 0; | 670 | bool calc_crc = filter != 0; |
671 | DECLARE_BITMAP(seen_elems, 256); | 671 | DECLARE_BITMAP(seen_elems, 256); |
672 | const u8 *ie; | 672 | const u8 *ie; |