diff options
-rw-r--r-- | drivers/bluetooth/btmrvl_main.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmsmac/main.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/3945-rs.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/4965-rs.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/rs.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/rxon.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-drv.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/rs.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/tx.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 29 | ||||
-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 |
18 files changed, 142 insertions, 52 deletions
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 3a4343b3bd6d..9a9f51875df5 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c | |||
@@ -498,6 +498,10 @@ static int btmrvl_service_main_thread(void *data) | |||
498 | add_wait_queue(&thread->wait_q, &wait); | 498 | add_wait_queue(&thread->wait_q, &wait); |
499 | 499 | ||
500 | set_current_state(TASK_INTERRUPTIBLE); | 500 | set_current_state(TASK_INTERRUPTIBLE); |
501 | if (kthread_should_stop()) { | ||
502 | BT_DBG("main_thread: break from main thread"); | ||
503 | break; | ||
504 | } | ||
501 | 505 | ||
502 | if (adapter->wakeup_tries || | 506 | if (adapter->wakeup_tries || |
503 | ((!adapter->int_count) && | 507 | ((!adapter->int_count) && |
@@ -513,11 +517,6 @@ static int btmrvl_service_main_thread(void *data) | |||
513 | 517 | ||
514 | BT_DBG("main_thread woke up"); | 518 | BT_DBG("main_thread woke up"); |
515 | 519 | ||
516 | if (kthread_should_stop()) { | ||
517 | BT_DBG("main_thread: break from main thread"); | ||
518 | break; | ||
519 | } | ||
520 | |||
521 | spin_lock_irqsave(&priv->driver_lock, flags); | 520 | spin_lock_irqsave(&priv->driver_lock, flags); |
522 | if (adapter->int_count) { | 521 | if (adapter->int_count) { |
523 | adapter->int_count = 0; | 522 | adapter->int_count = 0; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index b98f2235978e..2c593570497c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -930,6 +930,10 @@ fail: | |||
930 | brcmf_fws_del_interface(ifp); | 930 | brcmf_fws_del_interface(ifp); |
931 | brcmf_fws_deinit(drvr); | 931 | brcmf_fws_deinit(drvr); |
932 | } | 932 | } |
933 | if (drvr->iflist[0]) { | ||
934 | free_netdev(ifp->ndev); | ||
935 | drvr->iflist[0] = NULL; | ||
936 | } | ||
933 | if (p2p_ifp) { | 937 | if (p2p_ifp) { |
934 | free_netdev(p2p_ifp->ndev); | 938 | free_netdev(p2p_ifp->ndev); |
935 | drvr->iflist[1] = NULL; | 939 | drvr->iflist[1] = NULL; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 28e7aeedd184..9fd6f2fef11b 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c | |||
@@ -3074,21 +3074,8 @@ static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail) | |||
3074 | */ | 3074 | */ |
3075 | static bool brcms_c_ps_allowed(struct brcms_c_info *wlc) | 3075 | static bool brcms_c_ps_allowed(struct brcms_c_info *wlc) |
3076 | { | 3076 | { |
3077 | /* disallow PS when one of the following global conditions meets */ | 3077 | /* not supporting PS so always return false for now */ |
3078 | if (!wlc->pub->associated) | 3078 | return false; |
3079 | return false; | ||
3080 | |||
3081 | /* disallow PS when one of these meets when not scanning */ | ||
3082 | if (wlc->filter_flags & FIF_PROMISC_IN_BSS) | ||
3083 | return false; | ||
3084 | |||
3085 | if (wlc->bsscfg->type == BRCMS_TYPE_AP) | ||
3086 | return false; | ||
3087 | |||
3088 | if (wlc->bsscfg->type == BRCMS_TYPE_ADHOC) | ||
3089 | return false; | ||
3090 | |||
3091 | return true; | ||
3092 | } | 3079 | } |
3093 | 3080 | ||
3094 | static void brcms_c_statsupd(struct brcms_c_info *wlc) | 3081 | static void brcms_c_statsupd(struct brcms_c_info *wlc) |
diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c index c9f197d9ca1e..fe31590a51b2 100644 --- a/drivers/net/wireless/iwlegacy/3945-rs.c +++ b/drivers/net/wireless/iwlegacy/3945-rs.c | |||
@@ -816,6 +816,7 @@ out: | |||
816 | rs_sta->last_txrate_idx = idx; | 816 | rs_sta->last_txrate_idx = idx; |
817 | info->control.rates[0].idx = rs_sta->last_txrate_idx; | 817 | info->control.rates[0].idx = rs_sta->last_txrate_idx; |
818 | } | 818 | } |
819 | info->control.rates[0].count = 1; | ||
819 | 820 | ||
820 | D_RATE("leave: %d\n", idx); | 821 | D_RATE("leave: %d\n", idx); |
821 | } | 822 | } |
diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c index 1fc0b227e120..ed3c42a63a43 100644 --- a/drivers/net/wireless/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/iwlegacy/4965-rs.c | |||
@@ -2268,7 +2268,7 @@ il4965_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta, | |||
2268 | info->control.rates[0].flags = 0; | 2268 | info->control.rates[0].flags = 0; |
2269 | } | 2269 | } |
2270 | info->control.rates[0].idx = rate_idx; | 2270 | info->control.rates[0].idx = rate_idx; |
2271 | 2271 | info->control.rates[0].count = 1; | |
2272 | } | 2272 | } |
2273 | 2273 | ||
2274 | static void * | 2274 | static void * |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c index 907bd6e50aad..10fbb176cc8e 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/iwlwifi/dvm/rs.c | |||
@@ -2799,7 +2799,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, | |||
2799 | info->control.rates[0].flags = 0; | 2799 | info->control.rates[0].flags = 0; |
2800 | } | 2800 | } |
2801 | info->control.rates[0].idx = rate_idx; | 2801 | info->control.rates[0].idx = rate_idx; |
2802 | 2802 | info->control.rates[0].count = 1; | |
2803 | } | 2803 | } |
2804 | 2804 | ||
2805 | static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, | 2805 | static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c index 707446fa00bd..cd1ad0019185 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c | |||
@@ -1378,7 +1378,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) | |||
1378 | struct iwl_chain_noise_data *data = &priv->chain_noise_data; | 1378 | struct iwl_chain_noise_data *data = &priv->chain_noise_data; |
1379 | int ret; | 1379 | int ret; |
1380 | 1380 | ||
1381 | if (!(priv->calib_disabled & IWL_CHAIN_NOISE_CALIB_DISABLED)) | 1381 | if (priv->calib_disabled & IWL_CHAIN_NOISE_CALIB_DISABLED) |
1382 | return; | 1382 | return; |
1383 | 1383 | ||
1384 | if ((data->state == IWL_CHAIN_NOISE_ALIVE) && | 1384 | if ((data->state == IWL_CHAIN_NOISE_ALIVE) && |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 39aad9893e0b..40fed1f511e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -1000,10 +1000,12 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) | |||
1000 | */ | 1000 | */ |
1001 | if (load_module) { | 1001 | if (load_module) { |
1002 | err = request_module("%s", op->name); | 1002 | err = request_module("%s", op->name); |
1003 | #ifdef CONFIG_IWLWIFI_OPMODE_MODULAR | ||
1003 | if (err) | 1004 | if (err) |
1004 | IWL_ERR(drv, | 1005 | IWL_ERR(drv, |
1005 | "failed to load module %s (error %d), is dynamic loading enabled?\n", | 1006 | "failed to load module %s (error %d), is dynamic loading enabled?\n", |
1006 | op->name, err); | 1007 | op->name, err); |
1008 | #endif | ||
1007 | } | 1009 | } |
1008 | return; | 1010 | return; |
1009 | 1011 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 55334d542e26..b99fe3163866 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
@@ -2546,6 +2546,7 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta, | |||
2546 | info->control.rates[0].flags = 0; | 2546 | info->control.rates[0].flags = 0; |
2547 | } | 2547 | } |
2548 | info->control.rates[0].idx = rate_idx; | 2548 | info->control.rates[0].idx = rate_idx; |
2549 | info->control.rates[0].count = 1; | ||
2549 | } | 2550 | } |
2550 | 2551 | ||
2551 | static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta, | 2552 | static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index f212f16502ff..48c1891e3df6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
@@ -180,7 +180,8 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, | |||
180 | tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE); | 180 | tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE); |
181 | return; | 181 | return; |
182 | } else if (ieee80211_is_back_req(fc)) { | 182 | } else if (ieee80211_is_back_req(fc)) { |
183 | tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE); | 183 | tx_cmd->tx_flags |= |
184 | cpu_to_le32(TX_CMD_FLG_ACK | TX_CMD_FLG_BAR); | ||
184 | } | 185 | } |
185 | 186 | ||
186 | /* HT rate doesn't make sense for a non data frame */ | 187 | /* HT rate doesn't make sense for a non data frame */ |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b52d70c75e1a..72f32e5caa4d 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -3027,19 +3027,26 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, | |||
3027 | * TODO: we do not use +6 dBm option to do not increase power beyond | 3027 | * TODO: we do not use +6 dBm option to do not increase power beyond |
3028 | * regulatory limit, however this could be utilized for devices with | 3028 | * regulatory limit, however this could be utilized for devices with |
3029 | * CAPABILITY_POWER_LIMIT. | 3029 | * CAPABILITY_POWER_LIMIT. |
3030 | * | ||
3031 | * TODO: add different temperature compensation code for RT3290 & RT5390 | ||
3032 | * to allow to use BBP_R1 for those chips. | ||
3030 | */ | 3033 | */ |
3031 | rt2800_bbp_read(rt2x00dev, 1, &r1); | 3034 | if (!rt2x00_rt(rt2x00dev, RT3290) && |
3032 | if (delta <= -12) { | 3035 | !rt2x00_rt(rt2x00dev, RT5390)) { |
3033 | power_ctrl = 2; | 3036 | rt2800_bbp_read(rt2x00dev, 1, &r1); |
3034 | delta += 12; | 3037 | if (delta <= -12) { |
3035 | } else if (delta <= -6) { | 3038 | power_ctrl = 2; |
3036 | power_ctrl = 1; | 3039 | delta += 12; |
3037 | delta += 6; | 3040 | } else if (delta <= -6) { |
3038 | } else { | 3041 | power_ctrl = 1; |
3039 | power_ctrl = 0; | 3042 | delta += 6; |
3043 | } else { | ||
3044 | power_ctrl = 0; | ||
3045 | } | ||
3046 | rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, power_ctrl); | ||
3047 | rt2800_bbp_write(rt2x00dev, 1, r1); | ||
3040 | } | 3048 | } |
3041 | rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, power_ctrl); | 3049 | |
3042 | rt2800_bbp_write(rt2x00dev, 1, r1); | ||
3043 | offset = TX_PWR_CFG_0; | 3050 | offset = TX_PWR_CFG_0; |
3044 | 3051 | ||
3045 | for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) { | 3052 | for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) { |
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; |