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 | |
parent | c4d827c5ccc3a49227dbf9d4b248a2e86f388023 (diff) | |
parent | fcb3701849957917a234a61b58ad70ed35c83eda (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
-rw-r--r-- | drivers/bluetooth/btmrvl_main.c | 9 | ||||
-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 |
17 files changed, 138 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/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 94314a8e1029..8fe76dc4f373 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 4f886133639a..2f690e578b5c 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 d6beec765d65..31587a318f8b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
@@ -2652,6 +2652,7 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta, | |||
2652 | info->control.rates[0].flags = 0; | 2652 | info->control.rates[0].flags = 0; |
2653 | } | 2653 | } |
2654 | info->control.rates[0].idx = rate_idx; | 2654 | info->control.rates[0].idx = rate_idx; |
2655 | info->control.rates[0].count = 1; | ||
2655 | } | 2656 | } |
2656 | 2657 | ||
2657 | static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta, | 2658 | 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 42df1fdc5cbd..f0e96a927407 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 ead3a3e746a2..3aa30ddcbfea 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 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; |