diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-08-16 14:24:51 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-08-16 14:24:51 -0400 |
commit | d0746663667f37e7be5646bf68cb452c8375a23d (patch) | |
tree | 85ae5a3d5e5bae53815baba5dba372e4d53a9745 | |
parent | 41caa760d6acaf47cbd44c3d78307fb9be089111 (diff) | |
parent | 27b3eb9c06a7193bdc9800cd00764a130343bc8a (diff) |
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
28 files changed, 707 insertions, 372 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index 49267ea97568..f403ec3c5c9a 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl | |||
@@ -325,6 +325,7 @@ | |||
325 | <title>functions/definitions</title> | 325 | <title>functions/definitions</title> |
326 | !Finclude/net/mac80211.h ieee80211_rx_status | 326 | !Finclude/net/mac80211.h ieee80211_rx_status |
327 | !Finclude/net/mac80211.h mac80211_rx_flags | 327 | !Finclude/net/mac80211.h mac80211_rx_flags |
328 | !Finclude/net/mac80211.h mac80211_tx_info_flags | ||
328 | !Finclude/net/mac80211.h mac80211_tx_control_flags | 329 | !Finclude/net/mac80211.h mac80211_tx_control_flags |
329 | !Finclude/net/mac80211.h mac80211_rate_control_flags | 330 | !Finclude/net/mac80211.h mac80211_rate_control_flags |
330 | !Finclude/net/mac80211.h ieee80211_tx_rate | 331 | !Finclude/net/mac80211.h ieee80211_tx_rate |
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.c b/drivers/net/wireless/ath/ath6kl/testmode.c index acc9aa832f76..d67170ea1038 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.c +++ b/drivers/net/wireless/ath/ath6kl/testmode.c | |||
@@ -66,7 +66,8 @@ nla_put_failure: | |||
66 | ath6kl_warn("nla_put failed on testmode rx skb!\n"); | 66 | ath6kl_warn("nla_put failed on testmode rx skb!\n"); |
67 | } | 67 | } |
68 | 68 | ||
69 | int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len) | 69 | int ath6kl_tm_cmd(struct wiphy *wiphy, struct wireless_dev *wdev, |
70 | void *data, int len) | ||
70 | { | 71 | { |
71 | struct ath6kl *ar = wiphy_priv(wiphy); | 72 | struct ath6kl *ar = wiphy_priv(wiphy); |
72 | struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1]; | 73 | struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1]; |
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.h b/drivers/net/wireless/ath/ath6kl/testmode.h index fe651d6707df..9fbcdec3e208 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.h +++ b/drivers/net/wireless/ath/ath6kl/testmode.h | |||
@@ -20,7 +20,8 @@ | |||
20 | #ifdef CONFIG_NL80211_TESTMODE | 20 | #ifdef CONFIG_NL80211_TESTMODE |
21 | 21 | ||
22 | void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len); | 22 | void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len); |
23 | int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len); | 23 | int ath6kl_tm_cmd(struct wiphy *wiphy, struct wireless_dev *wdev, |
24 | void *data, int len); | ||
24 | 25 | ||
25 | #else | 26 | #else |
26 | 27 | ||
@@ -29,7 +30,9 @@ static inline void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, | |||
29 | { | 30 | { |
30 | } | 31 | } |
31 | 32 | ||
32 | static inline int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len) | 33 | static inline int ath6kl_tm_cmd(struct wiphy *wiphy, |
34 | struct wireless_dev *wdev, | ||
35 | void *data, int len) | ||
33 | { | 36 | { |
34 | return 0; | 37 | return 0; |
35 | } | 38 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 0370e44cec11..571f013cebbb 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -3155,7 +3155,9 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy, | |||
3155 | } | 3155 | } |
3156 | 3156 | ||
3157 | #ifdef CONFIG_NL80211_TESTMODE | 3157 | #ifdef CONFIG_NL80211_TESTMODE |
3158 | static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) | 3158 | static int brcmf_cfg80211_testmode(struct wiphy *wiphy, |
3159 | struct wireless_dev *wdev, | ||
3160 | void *data, int len) | ||
3159 | { | 3161 | { |
3160 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 3162 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
3161 | struct net_device *ndev = cfg_to_ndev(cfg); | 3163 | struct net_device *ndev = cfg_to_ndev(cfg); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 3db0bbb1d123..da442b81370a 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -87,7 +87,7 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, | |||
87 | priv->lib->bt_params->advanced_bt_coexist && | 87 | priv->lib->bt_params->advanced_bt_coexist && |
88 | (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) || | 88 | (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) || |
89 | ieee80211_is_reassoc_req(fc) || | 89 | ieee80211_is_reassoc_req(fc) || |
90 | skb->protocol == cpu_to_be16(ETH_P_PAE))) | 90 | info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) |
91 | tx_flags |= TX_CMD_FLG_IGNORE_BT; | 91 | tx_flags |= TX_CMD_FLG_IGNORE_BT; |
92 | 92 | ||
93 | 93 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 4491c1c72cc7..684c416d3493 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
@@ -33,10 +33,11 @@ | |||
33 | static inline bool iwl_trace_data(struct sk_buff *skb) | 33 | static inline bool iwl_trace_data(struct sk_buff *skb) |
34 | { | 34 | { |
35 | struct ieee80211_hdr *hdr = (void *)skb->data; | 35 | struct ieee80211_hdr *hdr = (void *)skb->data; |
36 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
36 | 37 | ||
37 | if (ieee80211_is_data(hdr->frame_control)) | 38 | if (!ieee80211_is_data(hdr->frame_control)) |
38 | return skb->protocol != cpu_to_be16(ETH_P_PAE); | 39 | return false; |
39 | return false; | 40 | return !(info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO); |
40 | } | 41 | } |
41 | 42 | ||
42 | static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans, | 43 | static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index ad9bbca99213..9f100363b177 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c | |||
@@ -73,7 +73,6 @@ | |||
73 | #include "iwl-prph.h" | 73 | #include "iwl-prph.h" |
74 | 74 | ||
75 | /* A TimeUnit is 1024 microsecond */ | 75 | /* A TimeUnit is 1024 microsecond */ |
76 | #define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024)) | ||
77 | #define MSEC_TO_TU(_msec) (_msec*1000/1024) | 76 | #define MSEC_TO_TU(_msec) (_msec*1000/1024) |
78 | 77 | ||
79 | /* | 78 | /* |
@@ -191,8 +190,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, | |||
191 | iwl_mvm_te_clear_data(mvm, te_data); | 190 | iwl_mvm_te_clear_data(mvm, te_data); |
192 | } else if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_START) { | 191 | } else if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_START) { |
193 | te_data->running = true; | 192 | te_data->running = true; |
194 | te_data->end_jiffies = jiffies + | 193 | te_data->end_jiffies = TU_TO_EXP_TIME(te_data->duration); |
195 | TU_TO_JIFFIES(te_data->duration); | ||
196 | 194 | ||
197 | if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) { | 195 | if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) { |
198 | set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status); | 196 | set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status); |
@@ -329,8 +327,7 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm, | |||
329 | lockdep_assert_held(&mvm->mutex); | 327 | lockdep_assert_held(&mvm->mutex); |
330 | 328 | ||
331 | if (te_data->running && | 329 | if (te_data->running && |
332 | time_after(te_data->end_jiffies, | 330 | time_after(te_data->end_jiffies, TU_TO_EXP_TIME(min_duration))) { |
333 | jiffies + TU_TO_JIFFIES(min_duration))) { | ||
334 | IWL_DEBUG_TE(mvm, "We have enough time in the current TE: %u\n", | 331 | IWL_DEBUG_TE(mvm, "We have enough time in the current TE: %u\n", |
335 | jiffies_to_msecs(te_data->end_jiffies - jiffies)); | 332 | jiffies_to_msecs(te_data->end_jiffies - jiffies)); |
336 | return; | 333 | return; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index f68ef9dd6a70..e05440d90319 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
@@ -91,11 +91,10 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
91 | tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR; | 91 | tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR; |
92 | 92 | ||
93 | /* High prio packet (wrt. BT coex) if it is EAPOL, MCAST or MGMT */ | 93 | /* High prio packet (wrt. BT coex) if it is EAPOL, MCAST or MGMT */ |
94 | if (info->band == IEEE80211_BAND_2GHZ && | 94 | if (info->band == IEEE80211_BAND_2GHZ && |
95 | (skb->protocol == cpu_to_be16(ETH_P_PAE) || | 95 | (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO || |
96 | is_multicast_ether_addr(hdr->addr1) || | 96 | is_multicast_ether_addr(hdr->addr1) || |
97 | ieee80211_is_back_req(fc) || | 97 | ieee80211_is_back_req(fc) || ieee80211_is_mgmt(fc))) |
98 | ieee80211_is_mgmt(fc))) | ||
99 | tx_flags |= TX_CMD_FLG_BT_DIS; | 98 | tx_flags |= TX_CMD_FLG_BT_DIS; |
100 | 99 | ||
101 | if (ieee80211_has_morefrags(fc)) | 100 | if (ieee80211_has_morefrags(fc)) |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 7b2a6229eedb..a0d2aacd5e09 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -1364,6 +1364,7 @@ static const struct nla_policy hwsim_testmode_policy[HWSIM_TM_ATTR_MAX + 1] = { | |||
1364 | static int hwsim_fops_ps_write(void *dat, u64 val); | 1364 | static int hwsim_fops_ps_write(void *dat, u64 val); |
1365 | 1365 | ||
1366 | static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw, | 1366 | static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw, |
1367 | struct ieee80211_vif *vif, | ||
1367 | void *data, int len) | 1368 | void *data, int len) |
1368 | { | 1369 | { |
1369 | struct mac80211_hwsim_data *hwsim = hw->priv; | 1370 | struct mac80211_hwsim_data *hwsim = hw->priv; |
diff --git a/drivers/net/wireless/ti/wlcore/testmode.c b/drivers/net/wireless/ti/wlcore/testmode.c index f3442762d884..527590f2adfb 100644 --- a/drivers/net/wireless/ti/wlcore/testmode.c +++ b/drivers/net/wireless/ti/wlcore/testmode.c | |||
@@ -356,7 +356,8 @@ out: | |||
356 | return ret; | 356 | return ret; |
357 | } | 357 | } |
358 | 358 | ||
359 | int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len) | 359 | int wl1271_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
360 | void *data, int len) | ||
360 | { | 361 | { |
361 | struct wl1271 *wl = hw->priv; | 362 | struct wl1271 *wl = hw->priv; |
362 | struct nlattr *tb[WL1271_TM_ATTR_MAX + 1]; | 363 | struct nlattr *tb[WL1271_TM_ATTR_MAX + 1]; |
diff --git a/drivers/net/wireless/ti/wlcore/testmode.h b/drivers/net/wireless/ti/wlcore/testmode.h index 8071654259ea..61d8434d859a 100644 --- a/drivers/net/wireless/ti/wlcore/testmode.h +++ b/drivers/net/wireless/ti/wlcore/testmode.h | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #include <net/mac80211.h> | 27 | #include <net/mac80211.h> |
28 | 28 | ||
29 | int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len); | 29 | int wl1271_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
30 | void *data, int len); | ||
30 | 31 | ||
31 | #endif /* __WL1271_TESTMODE_H__ */ | 32 | #endif /* __WL1271_TESTMODE_H__ */ |
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index b3ce299782af..23a8877f4ded 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h | |||
@@ -2288,4 +2288,8 @@ static inline bool ieee80211_check_tim(const struct ieee80211_tim_ie *tim, | |||
2288 | return !!(tim->virtual_map[index] & mask); | 2288 | return !!(tim->virtual_map[index] & mask); |
2289 | } | 2289 | } |
2290 | 2290 | ||
2291 | /* convert time units */ | ||
2292 | #define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) | ||
2293 | #define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) | ||
2294 | |||
2291 | #endif /* LINUX_IEEE80211_H */ | 2295 | #endif /* LINUX_IEEE80211_H */ |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index b7495c72061c..9ab7a0690d93 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -2081,7 +2081,7 @@ struct cfg80211_update_ft_ies_params { | |||
2081 | * @mgmt_tx_cancel_wait: Cancel the wait time from transmitting a management | 2081 | * @mgmt_tx_cancel_wait: Cancel the wait time from transmitting a management |
2082 | * frame on another channel | 2082 | * frame on another channel |
2083 | * | 2083 | * |
2084 | * @testmode_cmd: run a test mode command | 2084 | * @testmode_cmd: run a test mode command; @wdev may be %NULL |
2085 | * @testmode_dump: Implement a test mode dump. The cb->args[2] and up may be | 2085 | * @testmode_dump: Implement a test mode dump. The cb->args[2] and up may be |
2086 | * used by the function, but 0 and 1 must not be touched. Additionally, | 2086 | * used by the function, but 0 and 1 must not be touched. Additionally, |
2087 | * return error codes other than -ENOBUFS and -ENOENT will terminate the | 2087 | * return error codes other than -ENOBUFS and -ENOENT will terminate the |
@@ -2290,7 +2290,8 @@ struct cfg80211_ops { | |||
2290 | void (*rfkill_poll)(struct wiphy *wiphy); | 2290 | void (*rfkill_poll)(struct wiphy *wiphy); |
2291 | 2291 | ||
2292 | #ifdef CONFIG_NL80211_TESTMODE | 2292 | #ifdef CONFIG_NL80211_TESTMODE |
2293 | int (*testmode_cmd)(struct wiphy *wiphy, void *data, int len); | 2293 | int (*testmode_cmd)(struct wiphy *wiphy, struct wireless_dev *wdev, |
2294 | void *data, int len); | ||
2294 | int (*testmode_dump)(struct wiphy *wiphy, struct sk_buff *skb, | 2295 | int (*testmode_dump)(struct wiphy *wiphy, struct sk_buff *skb, |
2295 | struct netlink_callback *cb, | 2296 | struct netlink_callback *cb, |
2296 | void *data, int len); | 2297 | void *data, int len); |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9cda3728c2cb..e3e303778936 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -375,7 +375,7 @@ struct ieee80211_bss_conf { | |||
375 | }; | 375 | }; |
376 | 376 | ||
377 | /** | 377 | /** |
378 | * enum mac80211_tx_control_flags - flags to describe transmission information/status | 378 | * enum mac80211_tx_info_flags - flags to describe transmission information/status |
379 | * | 379 | * |
380 | * These flags are used with the @flags member of &ieee80211_tx_info. | 380 | * These flags are used with the @flags member of &ieee80211_tx_info. |
381 | * | 381 | * |
@@ -471,7 +471,7 @@ struct ieee80211_bss_conf { | |||
471 | * Note: If you have to add new flags to the enumeration, then don't | 471 | * Note: If you have to add new flags to the enumeration, then don't |
472 | * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary. | 472 | * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary. |
473 | */ | 473 | */ |
474 | enum mac80211_tx_control_flags { | 474 | enum mac80211_tx_info_flags { |
475 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), | 475 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), |
476 | IEEE80211_TX_CTL_ASSIGN_SEQ = BIT(1), | 476 | IEEE80211_TX_CTL_ASSIGN_SEQ = BIT(1), |
477 | IEEE80211_TX_CTL_NO_ACK = BIT(2), | 477 | IEEE80211_TX_CTL_NO_ACK = BIT(2), |
@@ -507,6 +507,18 @@ enum mac80211_tx_control_flags { | |||
507 | 507 | ||
508 | #define IEEE80211_TX_CTL_STBC_SHIFT 23 | 508 | #define IEEE80211_TX_CTL_STBC_SHIFT 23 |
509 | 509 | ||
510 | /** | ||
511 | * enum mac80211_tx_control_flags - flags to describe transmit control | ||
512 | * | ||
513 | * @IEEE80211_TX_CTRL_PORT_CTRL_PROTO: this frame is a port control | ||
514 | * protocol frame (e.g. EAP) | ||
515 | * | ||
516 | * These flags are used in tx_info->control.flags. | ||
517 | */ | ||
518 | enum mac80211_tx_control_flags { | ||
519 | IEEE80211_TX_CTRL_PORT_CTRL_PROTO = BIT(0), | ||
520 | }; | ||
521 | |||
510 | /* | 522 | /* |
511 | * This definition is used as a mask to clear all temporary flags, which are | 523 | * This definition is used as a mask to clear all temporary flags, which are |
512 | * set by the tx handlers for each transmission attempt by the mac80211 stack. | 524 | * set by the tx handlers for each transmission attempt by the mac80211 stack. |
@@ -680,7 +692,8 @@ struct ieee80211_tx_info { | |||
680 | /* NB: vif can be NULL for injected frames */ | 692 | /* NB: vif can be NULL for injected frames */ |
681 | struct ieee80211_vif *vif; | 693 | struct ieee80211_vif *vif; |
682 | struct ieee80211_key_conf *hw_key; | 694 | struct ieee80211_key_conf *hw_key; |
683 | /* 8 bytes free */ | 695 | u32 flags; |
696 | /* 4 bytes free */ | ||
684 | } control; | 697 | } control; |
685 | struct { | 698 | struct { |
686 | struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES]; | 699 | struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES]; |
@@ -2503,8 +2516,8 @@ enum ieee80211_roc_type { | |||
2503 | * in IEEE 802.11-2007 section 17.3.8.6 and modify ACK timeout | 2516 | * in IEEE 802.11-2007 section 17.3.8.6 and modify ACK timeout |
2504 | * accordingly. This callback is not required and may sleep. | 2517 | * accordingly. This callback is not required and may sleep. |
2505 | * | 2518 | * |
2506 | * @testmode_cmd: Implement a cfg80211 test mode command. | 2519 | * @testmode_cmd: Implement a cfg80211 test mode command. The passed @vif may |
2507 | * The callback can sleep. | 2520 | * be %NULL. The callback can sleep. |
2508 | * @testmode_dump: Implement a cfg80211 test mode dump. The callback can sleep. | 2521 | * @testmode_dump: Implement a cfg80211 test mode dump. The callback can sleep. |
2509 | * | 2522 | * |
2510 | * @flush: Flush all pending frames from the hardware queue, making sure | 2523 | * @flush: Flush all pending frames from the hardware queue, making sure |
@@ -2765,7 +2778,8 @@ struct ieee80211_ops { | |||
2765 | void (*rfkill_poll)(struct ieee80211_hw *hw); | 2778 | void (*rfkill_poll)(struct ieee80211_hw *hw); |
2766 | void (*set_coverage_class)(struct ieee80211_hw *hw, u8 coverage_class); | 2779 | void (*set_coverage_class)(struct ieee80211_hw *hw, u8 coverage_class); |
2767 | #ifdef CONFIG_NL80211_TESTMODE | 2780 | #ifdef CONFIG_NL80211_TESTMODE |
2768 | int (*testmode_cmd)(struct ieee80211_hw *hw, void *data, int len); | 2781 | int (*testmode_cmd)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
2782 | void *data, int len); | ||
2769 | int (*testmode_dump)(struct ieee80211_hw *hw, struct sk_buff *skb, | 2783 | int (*testmode_dump)(struct ieee80211_hw *hw, struct sk_buff *skb, |
2770 | struct netlink_callback *cb, | 2784 | struct netlink_callback *cb, |
2771 | void *data, int len); | 2785 | void *data, int len); |
@@ -3674,6 +3688,89 @@ void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf, | |||
3674 | int tid, struct ieee80211_key_seq *seq); | 3688 | int tid, struct ieee80211_key_seq *seq); |
3675 | 3689 | ||
3676 | /** | 3690 | /** |
3691 | * ieee80211_set_key_tx_seq - set key TX sequence counter | ||
3692 | * | ||
3693 | * @keyconf: the parameter passed with the set key | ||
3694 | * @seq: new sequence data | ||
3695 | * | ||
3696 | * This function allows a driver to set the current TX IV/PNs for the | ||
3697 | * given key. This is useful when resuming from WoWLAN sleep and the | ||
3698 | * device may have transmitted frames using the PTK, e.g. replies to | ||
3699 | * ARP requests. | ||
3700 | * | ||
3701 | * Note that this function may only be called when no TX processing | ||
3702 | * can be done concurrently. | ||
3703 | */ | ||
3704 | void ieee80211_set_key_tx_seq(struct ieee80211_key_conf *keyconf, | ||
3705 | struct ieee80211_key_seq *seq); | ||
3706 | |||
3707 | /** | ||
3708 | * ieee80211_set_key_rx_seq - set key RX sequence counter | ||
3709 | * | ||
3710 | * @keyconf: the parameter passed with the set key | ||
3711 | * @tid: The TID, or -1 for the management frame value (CCMP only); | ||
3712 | * the value on TID 0 is also used for non-QoS frames. For | ||
3713 | * CMAC, only TID 0 is valid. | ||
3714 | * @seq: new sequence data | ||
3715 | * | ||
3716 | * This function allows a driver to set the current RX IV/PNs for the | ||
3717 | * given key. This is useful when resuming from WoWLAN sleep and GTK | ||
3718 | * rekey may have been done while suspended. It should not be called | ||
3719 | * if IV checking is done by the device and not by mac80211. | ||
3720 | * | ||
3721 | * Note that this function may only be called when no RX processing | ||
3722 | * can be done concurrently. | ||
3723 | */ | ||
3724 | void ieee80211_set_key_rx_seq(struct ieee80211_key_conf *keyconf, | ||
3725 | int tid, struct ieee80211_key_seq *seq); | ||
3726 | |||
3727 | /** | ||
3728 | * ieee80211_remove_key - remove the given key | ||
3729 | * @keyconf: the parameter passed with the set key | ||
3730 | * | ||
3731 | * Remove the given key. If the key was uploaded to the hardware at the | ||
3732 | * time this function is called, it is not deleted in the hardware but | ||
3733 | * instead assumed to have been removed already. | ||
3734 | * | ||
3735 | * Note that due to locking considerations this function can (currently) | ||
3736 | * only be called during key iteration (ieee80211_iter_keys().) | ||
3737 | */ | ||
3738 | void ieee80211_remove_key(struct ieee80211_key_conf *keyconf); | ||
3739 | |||
3740 | /** | ||
3741 | * ieee80211_gtk_rekey_add - add a GTK key from rekeying during WoWLAN | ||
3742 | * @vif: the virtual interface to add the key on | ||
3743 | * @keyconf: new key data | ||
3744 | * | ||
3745 | * When GTK rekeying was done while the system was suspended, (a) new | ||
3746 | * key(s) will be available. These will be needed by mac80211 for proper | ||
3747 | * RX processing, so this function allows setting them. | ||
3748 | * | ||
3749 | * The function returns the newly allocated key structure, which will | ||
3750 | * have similar contents to the passed key configuration but point to | ||
3751 | * mac80211-owned memory. In case of errors, the function returns an | ||
3752 | * ERR_PTR(), use IS_ERR() etc. | ||
3753 | * | ||
3754 | * Note that this function assumes the key isn't added to hardware | ||
3755 | * acceleration, so no TX will be done with the key. Since it's a GTK | ||
3756 | * on managed (station) networks, this is true anyway. If the driver | ||
3757 | * calls this function from the resume callback and subsequently uses | ||
3758 | * the return code 1 to reconfigure the device, this key will be part | ||
3759 | * of the reconfiguration. | ||
3760 | * | ||
3761 | * Note that the driver should also call ieee80211_set_key_rx_seq() | ||
3762 | * for the new key for each TID to set up sequence counters properly. | ||
3763 | * | ||
3764 | * IMPORTANT: If this replaces a key that is present in the hardware, | ||
3765 | * then it will attempt to remove it during this call. In many cases | ||
3766 | * this isn't what you want, so call ieee80211_remove_key() first for | ||
3767 | * the key that's being replaced. | ||
3768 | */ | ||
3769 | struct ieee80211_key_conf * | ||
3770 | ieee80211_gtk_rekey_add(struct ieee80211_vif *vif, | ||
3771 | struct ieee80211_key_conf *keyconf); | ||
3772 | |||
3773 | /** | ||
3677 | * ieee80211_gtk_rekey_notify - notify userspace supplicant of rekeying | 3774 | * ieee80211_gtk_rekey_notify - notify userspace supplicant of rekeying |
3678 | * @vif: virtual interface the rekeying was done on | 3775 | * @vif: virtual interface the rekeying was done on |
3679 | * @bssid: The BSSID of the AP, for checking association | 3776 | * @bssid: The BSSID of the AP, for checking association |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 31fc2247bc37..2e7855a1b10d 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -2302,14 +2302,25 @@ static void ieee80211_rfkill_poll(struct wiphy *wiphy) | |||
2302 | } | 2302 | } |
2303 | 2303 | ||
2304 | #ifdef CONFIG_NL80211_TESTMODE | 2304 | #ifdef CONFIG_NL80211_TESTMODE |
2305 | static int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len) | 2305 | static int ieee80211_testmode_cmd(struct wiphy *wiphy, |
2306 | struct wireless_dev *wdev, | ||
2307 | void *data, int len) | ||
2306 | { | 2308 | { |
2307 | struct ieee80211_local *local = wiphy_priv(wiphy); | 2309 | struct ieee80211_local *local = wiphy_priv(wiphy); |
2310 | struct ieee80211_vif *vif = NULL; | ||
2308 | 2311 | ||
2309 | if (!local->ops->testmode_cmd) | 2312 | if (!local->ops->testmode_cmd) |
2310 | return -EOPNOTSUPP; | 2313 | return -EOPNOTSUPP; |
2311 | 2314 | ||
2312 | return local->ops->testmode_cmd(&local->hw, data, len); | 2315 | if (wdev) { |
2316 | struct ieee80211_sub_if_data *sdata; | ||
2317 | |||
2318 | sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); | ||
2319 | if (sdata->flags & IEEE80211_SDATA_IN_DRIVER) | ||
2320 | vif = &sdata->vif; | ||
2321 | } | ||
2322 | |||
2323 | return local->ops->testmode_cmd(&local->hw, vif, data, len); | ||
2313 | } | 2324 | } |
2314 | 2325 | ||
2315 | static int ieee80211_testmode_dump(struct wiphy *wiphy, | 2326 | static int ieee80211_testmode_dump(struct wiphy *wiphy, |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index e08387cdc8fd..74de0f10558a 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -34,13 +34,12 @@ | |||
34 | 34 | ||
35 | #define IEEE80211_IBSS_MAX_STA_ENTRIES 128 | 35 | #define IEEE80211_IBSS_MAX_STA_ENTRIES 128 |
36 | 36 | ||
37 | 37 | static struct beacon_data * | |
38 | static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | 38 | ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata, |
39 | const u8 *bssid, const int beacon_int, | 39 | const int beacon_int, const u32 basic_rates, |
40 | struct ieee80211_channel *chan, | 40 | const u16 capability, u64 tsf, |
41 | const u32 basic_rates, | 41 | struct cfg80211_chan_def *chandef, |
42 | const u16 capability, u64 tsf, | 42 | bool *have_higher_than_11mbit) |
43 | bool creator) | ||
44 | { | 43 | { |
45 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 44 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
46 | struct ieee80211_local *local = sdata->local; | 45 | struct ieee80211_local *local = sdata->local; |
@@ -48,70 +47,11 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
48 | struct ieee80211_mgmt *mgmt; | 47 | struct ieee80211_mgmt *mgmt; |
49 | u8 *pos; | 48 | u8 *pos; |
50 | struct ieee80211_supported_band *sband; | 49 | struct ieee80211_supported_band *sband; |
51 | struct cfg80211_bss *bss; | 50 | u32 rate_flags, rates = 0, rates_added = 0; |
52 | u32 bss_change, rate_flags, rates = 0, rates_added = 0; | ||
53 | struct cfg80211_chan_def chandef; | ||
54 | enum nl80211_bss_scan_width scan_width; | ||
55 | bool have_higher_than_11mbit = false; | ||
56 | struct beacon_data *presp; | 51 | struct beacon_data *presp; |
57 | int frame_len; | 52 | int frame_len; |
58 | int shift; | 53 | int shift; |
59 | 54 | ||
60 | sdata_assert_lock(sdata); | ||
61 | |||
62 | /* Reset own TSF to allow time synchronization work. */ | ||
63 | drv_reset_tsf(local, sdata); | ||
64 | |||
65 | if (!ether_addr_equal(ifibss->bssid, bssid)) | ||
66 | sta_info_flush(sdata); | ||
67 | |||
68 | /* if merging, indicate to driver that we leave the old IBSS */ | ||
69 | if (sdata->vif.bss_conf.ibss_joined) { | ||
70 | sdata->vif.bss_conf.ibss_joined = false; | ||
71 | sdata->vif.bss_conf.ibss_creator = false; | ||
72 | sdata->vif.bss_conf.enable_beacon = false; | ||
73 | netif_carrier_off(sdata->dev); | ||
74 | ieee80211_bss_info_change_notify(sdata, | ||
75 | BSS_CHANGED_IBSS | | ||
76 | BSS_CHANGED_BEACON_ENABLED); | ||
77 | } | ||
78 | |||
79 | presp = rcu_dereference_protected(ifibss->presp, | ||
80 | lockdep_is_held(&sdata->wdev.mtx)); | ||
81 | rcu_assign_pointer(ifibss->presp, NULL); | ||
82 | if (presp) | ||
83 | kfree_rcu(presp, rcu_head); | ||
84 | |||
85 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; | ||
86 | |||
87 | chandef = ifibss->chandef; | ||
88 | if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { | ||
89 | if (chandef.width == NL80211_CHAN_WIDTH_5 || | ||
90 | chandef.width == NL80211_CHAN_WIDTH_10 || | ||
91 | chandef.width == NL80211_CHAN_WIDTH_20_NOHT || | ||
92 | chandef.width == NL80211_CHAN_WIDTH_20) { | ||
93 | sdata_info(sdata, | ||
94 | "Failed to join IBSS, beacons forbidden\n"); | ||
95 | return; | ||
96 | } | ||
97 | chandef.width = NL80211_CHAN_WIDTH_20; | ||
98 | chandef.center_freq1 = chan->center_freq; | ||
99 | } | ||
100 | |||
101 | ieee80211_vif_release_channel(sdata); | ||
102 | if (ieee80211_vif_use_channel(sdata, &chandef, | ||
103 | ifibss->fixed_channel ? | ||
104 | IEEE80211_CHANCTX_SHARED : | ||
105 | IEEE80211_CHANCTX_EXCLUSIVE)) { | ||
106 | sdata_info(sdata, "Failed to join IBSS, no channel context\n"); | ||
107 | return; | ||
108 | } | ||
109 | |||
110 | memcpy(ifibss->bssid, bssid, ETH_ALEN); | ||
111 | |||
112 | sband = local->hw.wiphy->bands[chan->band]; | ||
113 | shift = ieee80211_vif_get_shift(&sdata->vif); | ||
114 | |||
115 | /* Build IBSS probe response */ | 55 | /* Build IBSS probe response */ |
116 | frame_len = sizeof(struct ieee80211_hdr_3addr) + | 56 | frame_len = sizeof(struct ieee80211_hdr_3addr) + |
117 | 12 /* struct ieee80211_mgmt.u.beacon */ + | 57 | 12 /* struct ieee80211_mgmt.u.beacon */ + |
@@ -125,7 +65,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
125 | ifibss->ie_len; | 65 | ifibss->ie_len; |
126 | presp = kzalloc(sizeof(*presp) + frame_len, GFP_KERNEL); | 66 | presp = kzalloc(sizeof(*presp) + frame_len, GFP_KERNEL); |
127 | if (!presp) | 67 | if (!presp) |
128 | return; | 68 | return NULL; |
129 | 69 | ||
130 | presp->head = (void *)(presp + 1); | 70 | presp->head = (void *)(presp + 1); |
131 | 71 | ||
@@ -146,12 +86,19 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
146 | memcpy(pos, ifibss->ssid, ifibss->ssid_len); | 86 | memcpy(pos, ifibss->ssid, ifibss->ssid_len); |
147 | pos += ifibss->ssid_len; | 87 | pos += ifibss->ssid_len; |
148 | 88 | ||
149 | rate_flags = ieee80211_chandef_rate_flags(&chandef); | 89 | sband = local->hw.wiphy->bands[chandef->chan->band]; |
90 | rate_flags = ieee80211_chandef_rate_flags(chandef); | ||
91 | shift = ieee80211_chandef_get_shift(chandef); | ||
92 | rates_n = 0; | ||
93 | if (have_higher_than_11mbit) | ||
94 | *have_higher_than_11mbit = false; | ||
95 | |||
150 | for (i = 0; i < sband->n_bitrates; i++) { | 96 | for (i = 0; i < sband->n_bitrates; i++) { |
151 | if ((rate_flags & sband->bitrates[i].flags) != rate_flags) | 97 | if ((rate_flags & sband->bitrates[i].flags) != rate_flags) |
152 | continue; | 98 | continue; |
153 | if (sband->bitrates[i].bitrate > 110) | 99 | if (sband->bitrates[i].bitrate > 110 && |
154 | have_higher_than_11mbit = true; | 100 | have_higher_than_11mbit) |
101 | *have_higher_than_11mbit = true; | ||
155 | 102 | ||
156 | rates |= BIT(i); | 103 | rates |= BIT(i); |
157 | rates_n++; | 104 | rates_n++; |
@@ -178,7 +125,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
178 | if (sband->band == IEEE80211_BAND_2GHZ) { | 125 | if (sband->band == IEEE80211_BAND_2GHZ) { |
179 | *pos++ = WLAN_EID_DS_PARAMS; | 126 | *pos++ = WLAN_EID_DS_PARAMS; |
180 | *pos++ = 1; | 127 | *pos++ = 1; |
181 | *pos++ = ieee80211_frequency_to_channel(chan->center_freq); | 128 | *pos++ = ieee80211_frequency_to_channel( |
129 | chandef->chan->center_freq); | ||
182 | } | 130 | } |
183 | 131 | ||
184 | *pos++ = WLAN_EID_IBSS_PARAMS; | 132 | *pos++ = WLAN_EID_IBSS_PARAMS; |
@@ -210,9 +158,9 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
210 | } | 158 | } |
211 | 159 | ||
212 | /* add HT capability and information IEs */ | 160 | /* add HT capability and information IEs */ |
213 | if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT && | 161 | if (chandef->width != NL80211_CHAN_WIDTH_20_NOHT && |
214 | chandef.width != NL80211_CHAN_WIDTH_5 && | 162 | chandef->width != NL80211_CHAN_WIDTH_5 && |
215 | chandef.width != NL80211_CHAN_WIDTH_10 && | 163 | chandef->width != NL80211_CHAN_WIDTH_10 && |
216 | sband->ht_cap.ht_supported) { | 164 | sband->ht_cap.ht_supported) { |
217 | struct ieee80211_sta_ht_cap ht_cap; | 165 | struct ieee80211_sta_ht_cap ht_cap; |
218 | 166 | ||
@@ -226,7 +174,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
226 | * keep them at 0 | 174 | * keep them at 0 |
227 | */ | 175 | */ |
228 | pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, | 176 | pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, |
229 | &chandef, 0); | 177 | chandef, 0); |
230 | } | 178 | } |
231 | 179 | ||
232 | if (local->hw.queues >= IEEE80211_NUM_ACS) { | 180 | if (local->hw.queues >= IEEE80211_NUM_ACS) { |
@@ -243,9 +191,94 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
243 | 191 | ||
244 | presp->head_len = pos - presp->head; | 192 | presp->head_len = pos - presp->head; |
245 | if (WARN_ON(presp->head_len > frame_len)) | 193 | if (WARN_ON(presp->head_len > frame_len)) |
194 | goto error; | ||
195 | |||
196 | return presp; | ||
197 | error: | ||
198 | kfree(presp); | ||
199 | return NULL; | ||
200 | } | ||
201 | |||
202 | static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | ||
203 | const u8 *bssid, const int beacon_int, | ||
204 | struct ieee80211_channel *chan, | ||
205 | const u32 basic_rates, | ||
206 | const u16 capability, u64 tsf, | ||
207 | bool creator) | ||
208 | { | ||
209 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | ||
210 | struct ieee80211_local *local = sdata->local; | ||
211 | struct ieee80211_supported_band *sband; | ||
212 | struct ieee80211_mgmt *mgmt; | ||
213 | struct cfg80211_bss *bss; | ||
214 | u32 bss_change; | ||
215 | struct cfg80211_chan_def chandef; | ||
216 | struct beacon_data *presp; | ||
217 | enum nl80211_bss_scan_width scan_width; | ||
218 | bool have_higher_than_11mbit; | ||
219 | |||
220 | sdata_assert_lock(sdata); | ||
221 | |||
222 | /* Reset own TSF to allow time synchronization work. */ | ||
223 | drv_reset_tsf(local, sdata); | ||
224 | |||
225 | if (!ether_addr_equal(ifibss->bssid, bssid)) | ||
226 | sta_info_flush(sdata); | ||
227 | |||
228 | /* if merging, indicate to driver that we leave the old IBSS */ | ||
229 | if (sdata->vif.bss_conf.ibss_joined) { | ||
230 | sdata->vif.bss_conf.ibss_joined = false; | ||
231 | sdata->vif.bss_conf.ibss_creator = false; | ||
232 | sdata->vif.bss_conf.enable_beacon = false; | ||
233 | netif_carrier_off(sdata->dev); | ||
234 | ieee80211_bss_info_change_notify(sdata, | ||
235 | BSS_CHANGED_IBSS | | ||
236 | BSS_CHANGED_BEACON_ENABLED); | ||
237 | } | ||
238 | |||
239 | presp = rcu_dereference_protected(ifibss->presp, | ||
240 | lockdep_is_held(&sdata->wdev.mtx)); | ||
241 | rcu_assign_pointer(ifibss->presp, NULL); | ||
242 | if (presp) | ||
243 | kfree_rcu(presp, rcu_head); | ||
244 | |||
245 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; | ||
246 | |||
247 | chandef = ifibss->chandef; | ||
248 | if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { | ||
249 | if (chandef.width == NL80211_CHAN_WIDTH_5 || | ||
250 | chandef.width == NL80211_CHAN_WIDTH_10 || | ||
251 | chandef.width == NL80211_CHAN_WIDTH_20_NOHT || | ||
252 | chandef.width == NL80211_CHAN_WIDTH_20) { | ||
253 | sdata_info(sdata, | ||
254 | "Failed to join IBSS, beacons forbidden\n"); | ||
255 | return; | ||
256 | } | ||
257 | chandef.width = NL80211_CHAN_WIDTH_20; | ||
258 | chandef.center_freq1 = chan->center_freq; | ||
259 | } | ||
260 | |||
261 | ieee80211_vif_release_channel(sdata); | ||
262 | if (ieee80211_vif_use_channel(sdata, &chandef, | ||
263 | ifibss->fixed_channel ? | ||
264 | IEEE80211_CHANCTX_SHARED : | ||
265 | IEEE80211_CHANCTX_EXCLUSIVE)) { | ||
266 | sdata_info(sdata, "Failed to join IBSS, no channel context\n"); | ||
267 | return; | ||
268 | } | ||
269 | |||
270 | memcpy(ifibss->bssid, bssid, ETH_ALEN); | ||
271 | |||
272 | sband = local->hw.wiphy->bands[chan->band]; | ||
273 | |||
274 | presp = ieee80211_ibss_build_presp(sdata, beacon_int, basic_rates, | ||
275 | capability, tsf, &chandef, | ||
276 | &have_higher_than_11mbit); | ||
277 | if (!presp) | ||
246 | return; | 278 | return; |
247 | 279 | ||
248 | rcu_assign_pointer(ifibss->presp, presp); | 280 | rcu_assign_pointer(ifibss->presp, presp); |
281 | mgmt = (void *)presp->head; | ||
249 | 282 | ||
250 | sdata->vif.bss_conf.enable_beacon = true; | 283 | sdata->vif.bss_conf.enable_beacon = true; |
251 | sdata->vif.bss_conf.beacon_int = beacon_int; | 284 | sdata->vif.bss_conf.beacon_int = beacon_int; |
@@ -891,6 +924,17 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
891 | return; | 924 | return; |
892 | } | 925 | } |
893 | 926 | ||
927 | /* if a fixed bssid and a fixed freq have been provided create the IBSS | ||
928 | * directly and do not waste time scanning | ||
929 | */ | ||
930 | if (ifibss->fixed_bssid && ifibss->fixed_channel) { | ||
931 | sdata_info(sdata, "Created IBSS using preconfigured BSSID %pM\n", | ||
932 | bssid); | ||
933 | ieee80211_sta_create_ibss(sdata); | ||
934 | return; | ||
935 | } | ||
936 | |||
937 | |||
894 | ibss_dbg(sdata, "sta_find_ibss: did not try to join ibss\n"); | 938 | ibss_dbg(sdata, "sta_find_ibss: did not try to join ibss\n"); |
895 | 939 | ||
896 | /* Selected IBSS not found in current scan results - try to scan */ | 940 | /* Selected IBSS not found in current scan results - try to scan */ |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index e94c84050e9c..b6186517ec56 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -53,9 +53,6 @@ struct ieee80211_local; | |||
53 | * increased memory use (about 2 kB of RAM per entry). */ | 53 | * increased memory use (about 2 kB of RAM per entry). */ |
54 | #define IEEE80211_FRAGMENT_MAX 4 | 54 | #define IEEE80211_FRAGMENT_MAX 4 |
55 | 55 | ||
56 | #define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) | ||
57 | #define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) | ||
58 | |||
59 | /* power level hasn't been configured (or set to automatic) */ | 56 | /* power level hasn't been configured (or set to automatic) */ |
60 | #define IEEE80211_UNSET_POWER_LEVEL INT_MIN | 57 | #define IEEE80211_UNSET_POWER_LEVEL INT_MIN |
61 | 58 | ||
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index e39cc91d0cf1..620677e897bd 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -93,6 +93,9 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
93 | 93 | ||
94 | might_sleep(); | 94 | might_sleep(); |
95 | 95 | ||
96 | if (key->flags & KEY_FLAG_TAINTED) | ||
97 | return -EINVAL; | ||
98 | |||
96 | if (!key->local->ops->set_key) | 99 | if (!key->local->ops->set_key) |
97 | goto out_unsupported; | 100 | goto out_unsupported; |
98 | 101 | ||
@@ -455,6 +458,7 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
455 | struct ieee80211_sub_if_data *sdata, | 458 | struct ieee80211_sub_if_data *sdata, |
456 | struct sta_info *sta) | 459 | struct sta_info *sta) |
457 | { | 460 | { |
461 | struct ieee80211_local *local = sdata->local; | ||
458 | struct ieee80211_key *old_key; | 462 | struct ieee80211_key *old_key; |
459 | int idx, ret; | 463 | int idx, ret; |
460 | bool pairwise; | 464 | bool pairwise; |
@@ -484,10 +488,13 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
484 | 488 | ||
485 | ieee80211_debugfs_key_add(key); | 489 | ieee80211_debugfs_key_add(key); |
486 | 490 | ||
487 | ret = ieee80211_key_enable_hw_accel(key); | 491 | if (!local->wowlan) { |
488 | 492 | ret = ieee80211_key_enable_hw_accel(key); | |
489 | if (ret) | 493 | if (ret) |
490 | ieee80211_key_free(key, true); | 494 | ieee80211_key_free(key, true); |
495 | } else { | ||
496 | ret = 0; | ||
497 | } | ||
491 | 498 | ||
492 | mutex_unlock(&sdata->local->key_mtx); | 499 | mutex_unlock(&sdata->local->key_mtx); |
493 | 500 | ||
@@ -540,7 +547,7 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw, | |||
540 | void *iter_data) | 547 | void *iter_data) |
541 | { | 548 | { |
542 | struct ieee80211_local *local = hw_to_local(hw); | 549 | struct ieee80211_local *local = hw_to_local(hw); |
543 | struct ieee80211_key *key; | 550 | struct ieee80211_key *key, *tmp; |
544 | struct ieee80211_sub_if_data *sdata; | 551 | struct ieee80211_sub_if_data *sdata; |
545 | 552 | ||
546 | ASSERT_RTNL(); | 553 | ASSERT_RTNL(); |
@@ -548,13 +555,14 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw, | |||
548 | mutex_lock(&local->key_mtx); | 555 | mutex_lock(&local->key_mtx); |
549 | if (vif) { | 556 | if (vif) { |
550 | sdata = vif_to_sdata(vif); | 557 | sdata = vif_to_sdata(vif); |
551 | list_for_each_entry(key, &sdata->key_list, list) | 558 | list_for_each_entry_safe(key, tmp, &sdata->key_list, list) |
552 | iter(hw, &sdata->vif, | 559 | iter(hw, &sdata->vif, |
553 | key->sta ? &key->sta->sta : NULL, | 560 | key->sta ? &key->sta->sta : NULL, |
554 | &key->conf, iter_data); | 561 | &key->conf, iter_data); |
555 | } else { | 562 | } else { |
556 | list_for_each_entry(sdata, &local->interfaces, list) | 563 | list_for_each_entry(sdata, &local->interfaces, list) |
557 | list_for_each_entry(key, &sdata->key_list, list) | 564 | list_for_each_entry_safe(key, tmp, |
565 | &sdata->key_list, list) | ||
558 | iter(hw, &sdata->vif, | 566 | iter(hw, &sdata->vif, |
559 | key->sta ? &key->sta->sta : NULL, | 567 | key->sta ? &key->sta->sta : NULL, |
560 | &key->conf, iter_data); | 568 | &key->conf, iter_data); |
@@ -751,3 +759,135 @@ void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf, | |||
751 | } | 759 | } |
752 | } | 760 | } |
753 | EXPORT_SYMBOL(ieee80211_get_key_rx_seq); | 761 | EXPORT_SYMBOL(ieee80211_get_key_rx_seq); |
762 | |||
763 | void ieee80211_set_key_tx_seq(struct ieee80211_key_conf *keyconf, | ||
764 | struct ieee80211_key_seq *seq) | ||
765 | { | ||
766 | struct ieee80211_key *key; | ||
767 | u64 pn64; | ||
768 | |||
769 | key = container_of(keyconf, struct ieee80211_key, conf); | ||
770 | |||
771 | switch (key->conf.cipher) { | ||
772 | case WLAN_CIPHER_SUITE_TKIP: | ||
773 | key->u.tkip.tx.iv32 = seq->tkip.iv32; | ||
774 | key->u.tkip.tx.iv16 = seq->tkip.iv16; | ||
775 | break; | ||
776 | case WLAN_CIPHER_SUITE_CCMP: | ||
777 | pn64 = (u64)seq->ccmp.pn[5] | | ||
778 | ((u64)seq->ccmp.pn[4] << 8) | | ||
779 | ((u64)seq->ccmp.pn[3] << 16) | | ||
780 | ((u64)seq->ccmp.pn[2] << 24) | | ||
781 | ((u64)seq->ccmp.pn[1] << 32) | | ||
782 | ((u64)seq->ccmp.pn[0] << 40); | ||
783 | atomic64_set(&key->u.ccmp.tx_pn, pn64); | ||
784 | break; | ||
785 | case WLAN_CIPHER_SUITE_AES_CMAC: | ||
786 | pn64 = (u64)seq->aes_cmac.pn[5] | | ||
787 | ((u64)seq->aes_cmac.pn[4] << 8) | | ||
788 | ((u64)seq->aes_cmac.pn[3] << 16) | | ||
789 | ((u64)seq->aes_cmac.pn[2] << 24) | | ||
790 | ((u64)seq->aes_cmac.pn[1] << 32) | | ||
791 | ((u64)seq->aes_cmac.pn[0] << 40); | ||
792 | atomic64_set(&key->u.aes_cmac.tx_pn, pn64); | ||
793 | break; | ||
794 | default: | ||
795 | WARN_ON(1); | ||
796 | break; | ||
797 | } | ||
798 | } | ||
799 | EXPORT_SYMBOL_GPL(ieee80211_set_key_tx_seq); | ||
800 | |||
801 | void ieee80211_set_key_rx_seq(struct ieee80211_key_conf *keyconf, | ||
802 | int tid, struct ieee80211_key_seq *seq) | ||
803 | { | ||
804 | struct ieee80211_key *key; | ||
805 | u8 *pn; | ||
806 | |||
807 | key = container_of(keyconf, struct ieee80211_key, conf); | ||
808 | |||
809 | switch (key->conf.cipher) { | ||
810 | case WLAN_CIPHER_SUITE_TKIP: | ||
811 | if (WARN_ON(tid < 0 || tid >= IEEE80211_NUM_TIDS)) | ||
812 | return; | ||
813 | key->u.tkip.rx[tid].iv32 = seq->tkip.iv32; | ||
814 | key->u.tkip.rx[tid].iv16 = seq->tkip.iv16; | ||
815 | break; | ||
816 | case WLAN_CIPHER_SUITE_CCMP: | ||
817 | if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS)) | ||
818 | return; | ||
819 | if (tid < 0) | ||
820 | pn = key->u.ccmp.rx_pn[IEEE80211_NUM_TIDS]; | ||
821 | else | ||
822 | pn = key->u.ccmp.rx_pn[tid]; | ||
823 | memcpy(pn, seq->ccmp.pn, IEEE80211_CCMP_PN_LEN); | ||
824 | break; | ||
825 | case WLAN_CIPHER_SUITE_AES_CMAC: | ||
826 | if (WARN_ON(tid != 0)) | ||
827 | return; | ||
828 | pn = key->u.aes_cmac.rx_pn; | ||
829 | memcpy(pn, seq->aes_cmac.pn, IEEE80211_CMAC_PN_LEN); | ||
830 | break; | ||
831 | default: | ||
832 | WARN_ON(1); | ||
833 | break; | ||
834 | } | ||
835 | } | ||
836 | EXPORT_SYMBOL_GPL(ieee80211_set_key_rx_seq); | ||
837 | |||
838 | void ieee80211_remove_key(struct ieee80211_key_conf *keyconf) | ||
839 | { | ||
840 | struct ieee80211_key *key; | ||
841 | |||
842 | key = container_of(keyconf, struct ieee80211_key, conf); | ||
843 | |||
844 | assert_key_lock(key->local); | ||
845 | |||
846 | /* | ||
847 | * if key was uploaded, we assume the driver will/has remove(d) | ||
848 | * it, so adjust bookkeeping accordingly | ||
849 | */ | ||
850 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | ||
851 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | ||
852 | |||
853 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | ||
854 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || | ||
855 | (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | ||
856 | increment_tailroom_need_count(key->sdata); | ||
857 | } | ||
858 | |||
859 | ieee80211_key_free(key, false); | ||
860 | } | ||
861 | EXPORT_SYMBOL_GPL(ieee80211_remove_key); | ||
862 | |||
863 | struct ieee80211_key_conf * | ||
864 | ieee80211_gtk_rekey_add(struct ieee80211_vif *vif, | ||
865 | struct ieee80211_key_conf *keyconf) | ||
866 | { | ||
867 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
868 | struct ieee80211_local *local = sdata->local; | ||
869 | struct ieee80211_key *key; | ||
870 | int err; | ||
871 | |||
872 | if (WARN_ON(!local->wowlan)) | ||
873 | return ERR_PTR(-EINVAL); | ||
874 | |||
875 | if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) | ||
876 | return ERR_PTR(-EINVAL); | ||
877 | |||
878 | key = ieee80211_key_alloc(keyconf->cipher, keyconf->keyidx, | ||
879 | keyconf->keylen, keyconf->key, | ||
880 | 0, NULL); | ||
881 | if (IS_ERR(key)) | ||
882 | return ERR_PTR(PTR_ERR(key)); | ||
883 | |||
884 | if (sdata->u.mgd.mfp != IEEE80211_MFP_DISABLED) | ||
885 | key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT; | ||
886 | |||
887 | err = ieee80211_key_link(key, sdata, NULL); | ||
888 | if (err) | ||
889 | return ERR_PTR(err); | ||
890 | |||
891 | return &key->conf; | ||
892 | } | ||
893 | EXPORT_SYMBOL_GPL(ieee80211_gtk_rekey_add); | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 21bccd849b3f..2aab1308690f 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1113,6 +1113,15 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1113 | case -1: | 1113 | case -1: |
1114 | cfg80211_chandef_create(&new_chandef, new_chan, | 1114 | cfg80211_chandef_create(&new_chandef, new_chan, |
1115 | NL80211_CHAN_NO_HT); | 1115 | NL80211_CHAN_NO_HT); |
1116 | /* keep width for 5/10 MHz channels */ | ||
1117 | switch (sdata->vif.bss_conf.chandef.width) { | ||
1118 | case NL80211_CHAN_WIDTH_5: | ||
1119 | case NL80211_CHAN_WIDTH_10: | ||
1120 | new_chandef.width = sdata->vif.bss_conf.chandef.width; | ||
1121 | break; | ||
1122 | default: | ||
1123 | break; | ||
1124 | } | ||
1116 | break; | 1125 | break; |
1117 | } | 1126 | } |
1118 | 1127 | ||
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index ba63ac851c2b..e126605cec66 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -210,7 +210,7 @@ static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc) | |||
210 | !ieee80211_is_data(fc); | 210 | !ieee80211_is_data(fc); |
211 | } | 211 | } |
212 | 212 | ||
213 | static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, | 213 | static void rc_send_low_basicrate(s8 *idx, u32 basic_rates, |
214 | struct ieee80211_supported_band *sband) | 214 | struct ieee80211_supported_band *sband) |
215 | { | 215 | { |
216 | u8 i; | 216 | u8 i; |
@@ -263,28 +263,37 @@ static void __rate_control_send_low(struct ieee80211_hw *hw, | |||
263 | } | 263 | } |
264 | 264 | ||
265 | 265 | ||
266 | bool rate_control_send_low(struct ieee80211_sta *sta, | 266 | bool rate_control_send_low(struct ieee80211_sta *pubsta, |
267 | void *priv_sta, | 267 | void *priv_sta, |
268 | struct ieee80211_tx_rate_control *txrc) | 268 | struct ieee80211_tx_rate_control *txrc) |
269 | { | 269 | { |
270 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); | 270 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); |
271 | struct ieee80211_supported_band *sband = txrc->sband; | 271 | struct ieee80211_supported_band *sband = txrc->sband; |
272 | struct sta_info *sta; | ||
272 | int mcast_rate; | 273 | int mcast_rate; |
274 | bool use_basicrate = false; | ||
273 | 275 | ||
274 | if (!sta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) { | 276 | if (!pubsta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) { |
275 | __rate_control_send_low(txrc->hw, sband, sta, info); | 277 | __rate_control_send_low(txrc->hw, sband, pubsta, info); |
276 | 278 | ||
277 | if (!sta && txrc->bss) { | 279 | if (!pubsta && txrc->bss) { |
278 | mcast_rate = txrc->bss_conf->mcast_rate[sband->band]; | 280 | mcast_rate = txrc->bss_conf->mcast_rate[sband->band]; |
279 | if (mcast_rate > 0) { | 281 | if (mcast_rate > 0) { |
280 | info->control.rates[0].idx = mcast_rate - 1; | 282 | info->control.rates[0].idx = mcast_rate - 1; |
281 | return true; | 283 | return true; |
282 | } | 284 | } |
285 | use_basicrate = true; | ||
286 | } else if (pubsta) { | ||
287 | sta = container_of(pubsta, struct sta_info, sta); | ||
288 | if (ieee80211_vif_is_mesh(&sta->sdata->vif)) | ||
289 | use_basicrate = true; | ||
290 | } | ||
283 | 291 | ||
284 | rc_send_low_broadcast(&info->control.rates[0].idx, | 292 | if (use_basicrate) |
293 | rc_send_low_basicrate(&info->control.rates[0].idx, | ||
285 | txrc->bss_conf->basic_rates, | 294 | txrc->bss_conf->basic_rates, |
286 | sband); | 295 | sband); |
287 | } | 296 | |
288 | return true; | 297 | return true; |
289 | } | 298 | } |
290 | return false; | 299 | return false; |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 61569425b723..a9909651dc0b 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -439,12 +439,13 @@ minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb) | |||
439 | { | 439 | { |
440 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 440 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
441 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | 441 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); |
442 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
442 | u16 tid; | 443 | u16 tid; |
443 | 444 | ||
444 | if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) | 445 | if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) |
445 | return; | 446 | return; |
446 | 447 | ||
447 | if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) | 448 | if (unlikely(info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) |
448 | return; | 449 | return; |
449 | 450 | ||
450 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; | 451 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; |
@@ -776,7 +777,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
776 | 777 | ||
777 | /* Don't use EAPOL frames for sampling on non-mrr hw */ | 778 | /* Don't use EAPOL frames for sampling on non-mrr hw */ |
778 | if (mp->hw->max_rates == 1 && | 779 | if (mp->hw->max_rates == 1 && |
779 | txrc->skb->protocol == cpu_to_be16(ETH_P_PAE)) | 780 | (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) |
780 | sample_idx = -1; | 781 | sample_idx = -1; |
781 | else | 782 | else |
782 | sample_idx = minstrel_get_sample_rate(mp, mi); | 783 | sample_idx = minstrel_get_sample_rate(mp, mi); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 6b85f95b9ba1..a84f319c11ad 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1055,207 +1055,6 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
1055 | 1055 | ||
1056 | 1056 | ||
1057 | static ieee80211_rx_result debug_noinline | 1057 | static ieee80211_rx_result debug_noinline |
1058 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | ||
1059 | { | ||
1060 | struct sk_buff *skb = rx->skb; | ||
1061 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
1062 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1063 | int keyidx; | ||
1064 | int hdrlen; | ||
1065 | ieee80211_rx_result result = RX_DROP_UNUSABLE; | ||
1066 | struct ieee80211_key *sta_ptk = NULL; | ||
1067 | int mmie_keyidx = -1; | ||
1068 | __le16 fc; | ||
1069 | |||
1070 | /* | ||
1071 | * Key selection 101 | ||
1072 | * | ||
1073 | * There are four types of keys: | ||
1074 | * - GTK (group keys) | ||
1075 | * - IGTK (group keys for management frames) | ||
1076 | * - PTK (pairwise keys) | ||
1077 | * - STK (station-to-station pairwise keys) | ||
1078 | * | ||
1079 | * When selecting a key, we have to distinguish between multicast | ||
1080 | * (including broadcast) and unicast frames, the latter can only | ||
1081 | * use PTKs and STKs while the former always use GTKs and IGTKs. | ||
1082 | * Unless, of course, actual WEP keys ("pre-RSNA") are used, then | ||
1083 | * unicast frames can also use key indices like GTKs. Hence, if we | ||
1084 | * don't have a PTK/STK we check the key index for a WEP key. | ||
1085 | * | ||
1086 | * Note that in a regular BSS, multicast frames are sent by the | ||
1087 | * AP only, associated stations unicast the frame to the AP first | ||
1088 | * which then multicasts it on their behalf. | ||
1089 | * | ||
1090 | * There is also a slight problem in IBSS mode: GTKs are negotiated | ||
1091 | * with each station, that is something we don't currently handle. | ||
1092 | * The spec seems to expect that one negotiates the same key with | ||
1093 | * every station but there's no such requirement; VLANs could be | ||
1094 | * possible. | ||
1095 | */ | ||
1096 | |||
1097 | /* | ||
1098 | * No point in finding a key and decrypting if the frame is neither | ||
1099 | * addressed to us nor a multicast frame. | ||
1100 | */ | ||
1101 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
1102 | return RX_CONTINUE; | ||
1103 | |||
1104 | /* start without a key */ | ||
1105 | rx->key = NULL; | ||
1106 | |||
1107 | if (rx->sta) | ||
1108 | sta_ptk = rcu_dereference(rx->sta->ptk); | ||
1109 | |||
1110 | fc = hdr->frame_control; | ||
1111 | |||
1112 | if (!ieee80211_has_protected(fc)) | ||
1113 | mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); | ||
1114 | |||
1115 | if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) { | ||
1116 | rx->key = sta_ptk; | ||
1117 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
1118 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
1119 | return RX_CONTINUE; | ||
1120 | /* Skip decryption if the frame is not protected. */ | ||
1121 | if (!ieee80211_has_protected(fc)) | ||
1122 | return RX_CONTINUE; | ||
1123 | } else if (mmie_keyidx >= 0) { | ||
1124 | /* Broadcast/multicast robust management frame / BIP */ | ||
1125 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
1126 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
1127 | return RX_CONTINUE; | ||
1128 | |||
1129 | if (mmie_keyidx < NUM_DEFAULT_KEYS || | ||
1130 | mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) | ||
1131 | return RX_DROP_MONITOR; /* unexpected BIP keyidx */ | ||
1132 | if (rx->sta) | ||
1133 | rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]); | ||
1134 | if (!rx->key) | ||
1135 | rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); | ||
1136 | } else if (!ieee80211_has_protected(fc)) { | ||
1137 | /* | ||
1138 | * The frame was not protected, so skip decryption. However, we | ||
1139 | * need to set rx->key if there is a key that could have been | ||
1140 | * used so that the frame may be dropped if encryption would | ||
1141 | * have been expected. | ||
1142 | */ | ||
1143 | struct ieee80211_key *key = NULL; | ||
1144 | struct ieee80211_sub_if_data *sdata = rx->sdata; | ||
1145 | int i; | ||
1146 | |||
1147 | if (ieee80211_is_mgmt(fc) && | ||
1148 | is_multicast_ether_addr(hdr->addr1) && | ||
1149 | (key = rcu_dereference(rx->sdata->default_mgmt_key))) | ||
1150 | rx->key = key; | ||
1151 | else { | ||
1152 | if (rx->sta) { | ||
1153 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) { | ||
1154 | key = rcu_dereference(rx->sta->gtk[i]); | ||
1155 | if (key) | ||
1156 | break; | ||
1157 | } | ||
1158 | } | ||
1159 | if (!key) { | ||
1160 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) { | ||
1161 | key = rcu_dereference(sdata->keys[i]); | ||
1162 | if (key) | ||
1163 | break; | ||
1164 | } | ||
1165 | } | ||
1166 | if (key) | ||
1167 | rx->key = key; | ||
1168 | } | ||
1169 | return RX_CONTINUE; | ||
1170 | } else { | ||
1171 | u8 keyid; | ||
1172 | /* | ||
1173 | * The device doesn't give us the IV so we won't be | ||
1174 | * able to look up the key. That's ok though, we | ||
1175 | * don't need to decrypt the frame, we just won't | ||
1176 | * be able to keep statistics accurate. | ||
1177 | * Except for key threshold notifications, should | ||
1178 | * we somehow allow the driver to tell us which key | ||
1179 | * the hardware used if this flag is set? | ||
1180 | */ | ||
1181 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
1182 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
1183 | return RX_CONTINUE; | ||
1184 | |||
1185 | hdrlen = ieee80211_hdrlen(fc); | ||
1186 | |||
1187 | if (rx->skb->len < 8 + hdrlen) | ||
1188 | return RX_DROP_UNUSABLE; /* TODO: count this? */ | ||
1189 | |||
1190 | /* | ||
1191 | * no need to call ieee80211_wep_get_keyidx, | ||
1192 | * it verifies a bunch of things we've done already | ||
1193 | */ | ||
1194 | skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); | ||
1195 | keyidx = keyid >> 6; | ||
1196 | |||
1197 | /* check per-station GTK first, if multicast packet */ | ||
1198 | if (is_multicast_ether_addr(hdr->addr1) && rx->sta) | ||
1199 | rx->key = rcu_dereference(rx->sta->gtk[keyidx]); | ||
1200 | |||
1201 | /* if not found, try default key */ | ||
1202 | if (!rx->key) { | ||
1203 | rx->key = rcu_dereference(rx->sdata->keys[keyidx]); | ||
1204 | |||
1205 | /* | ||
1206 | * RSNA-protected unicast frames should always be | ||
1207 | * sent with pairwise or station-to-station keys, | ||
1208 | * but for WEP we allow using a key index as well. | ||
1209 | */ | ||
1210 | if (rx->key && | ||
1211 | rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && | ||
1212 | rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && | ||
1213 | !is_multicast_ether_addr(hdr->addr1)) | ||
1214 | rx->key = NULL; | ||
1215 | } | ||
1216 | } | ||
1217 | |||
1218 | if (rx->key) { | ||
1219 | if (unlikely(rx->key->flags & KEY_FLAG_TAINTED)) | ||
1220 | return RX_DROP_MONITOR; | ||
1221 | |||
1222 | rx->key->tx_rx_count++; | ||
1223 | /* TODO: add threshold stuff again */ | ||
1224 | } else { | ||
1225 | return RX_DROP_MONITOR; | ||
1226 | } | ||
1227 | |||
1228 | switch (rx->key->conf.cipher) { | ||
1229 | case WLAN_CIPHER_SUITE_WEP40: | ||
1230 | case WLAN_CIPHER_SUITE_WEP104: | ||
1231 | result = ieee80211_crypto_wep_decrypt(rx); | ||
1232 | break; | ||
1233 | case WLAN_CIPHER_SUITE_TKIP: | ||
1234 | result = ieee80211_crypto_tkip_decrypt(rx); | ||
1235 | break; | ||
1236 | case WLAN_CIPHER_SUITE_CCMP: | ||
1237 | result = ieee80211_crypto_ccmp_decrypt(rx); | ||
1238 | break; | ||
1239 | case WLAN_CIPHER_SUITE_AES_CMAC: | ||
1240 | result = ieee80211_crypto_aes_cmac_decrypt(rx); | ||
1241 | break; | ||
1242 | default: | ||
1243 | /* | ||
1244 | * We can reach here only with HW-only algorithms | ||
1245 | * but why didn't it decrypt the frame?! | ||
1246 | */ | ||
1247 | return RX_DROP_UNUSABLE; | ||
1248 | } | ||
1249 | |||
1250 | /* the hdr variable is invalid after the decrypt handlers */ | ||
1251 | |||
1252 | /* either the frame has been decrypted or will be dropped */ | ||
1253 | status->flag |= RX_FLAG_DECRYPTED; | ||
1254 | |||
1255 | return result; | ||
1256 | } | ||
1257 | |||
1258 | static ieee80211_rx_result debug_noinline | ||
1259 | ieee80211_rx_h_check_more_data(struct ieee80211_rx_data *rx) | 1058 | ieee80211_rx_h_check_more_data(struct ieee80211_rx_data *rx) |
1260 | { | 1059 | { |
1261 | struct ieee80211_local *local; | 1060 | struct ieee80211_local *local; |
@@ -1556,6 +1355,207 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1556 | return RX_CONTINUE; | 1355 | return RX_CONTINUE; |
1557 | } /* ieee80211_rx_h_sta_process */ | 1356 | } /* ieee80211_rx_h_sta_process */ |
1558 | 1357 | ||
1358 | static ieee80211_rx_result debug_noinline | ||
1359 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | ||
1360 | { | ||
1361 | struct sk_buff *skb = rx->skb; | ||
1362 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
1363 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1364 | int keyidx; | ||
1365 | int hdrlen; | ||
1366 | ieee80211_rx_result result = RX_DROP_UNUSABLE; | ||
1367 | struct ieee80211_key *sta_ptk = NULL; | ||
1368 | int mmie_keyidx = -1; | ||
1369 | __le16 fc; | ||
1370 | |||
1371 | /* | ||
1372 | * Key selection 101 | ||
1373 | * | ||
1374 | * There are four types of keys: | ||
1375 | * - GTK (group keys) | ||
1376 | * - IGTK (group keys for management frames) | ||
1377 | * - PTK (pairwise keys) | ||
1378 | * - STK (station-to-station pairwise keys) | ||
1379 | * | ||
1380 | * When selecting a key, we have to distinguish between multicast | ||
1381 | * (including broadcast) and unicast frames, the latter can only | ||
1382 | * use PTKs and STKs while the former always use GTKs and IGTKs. | ||
1383 | * Unless, of course, actual WEP keys ("pre-RSNA") are used, then | ||
1384 | * unicast frames can also use key indices like GTKs. Hence, if we | ||
1385 | * don't have a PTK/STK we check the key index for a WEP key. | ||
1386 | * | ||
1387 | * Note that in a regular BSS, multicast frames are sent by the | ||
1388 | * AP only, associated stations unicast the frame to the AP first | ||
1389 | * which then multicasts it on their behalf. | ||
1390 | * | ||
1391 | * There is also a slight problem in IBSS mode: GTKs are negotiated | ||
1392 | * with each station, that is something we don't currently handle. | ||
1393 | * The spec seems to expect that one negotiates the same key with | ||
1394 | * every station but there's no such requirement; VLANs could be | ||
1395 | * possible. | ||
1396 | */ | ||
1397 | |||
1398 | /* | ||
1399 | * No point in finding a key and decrypting if the frame is neither | ||
1400 | * addressed to us nor a multicast frame. | ||
1401 | */ | ||
1402 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
1403 | return RX_CONTINUE; | ||
1404 | |||
1405 | /* start without a key */ | ||
1406 | rx->key = NULL; | ||
1407 | |||
1408 | if (rx->sta) | ||
1409 | sta_ptk = rcu_dereference(rx->sta->ptk); | ||
1410 | |||
1411 | fc = hdr->frame_control; | ||
1412 | |||
1413 | if (!ieee80211_has_protected(fc)) | ||
1414 | mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); | ||
1415 | |||
1416 | if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) { | ||
1417 | rx->key = sta_ptk; | ||
1418 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
1419 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
1420 | return RX_CONTINUE; | ||
1421 | /* Skip decryption if the frame is not protected. */ | ||
1422 | if (!ieee80211_has_protected(fc)) | ||
1423 | return RX_CONTINUE; | ||
1424 | } else if (mmie_keyidx >= 0) { | ||
1425 | /* Broadcast/multicast robust management frame / BIP */ | ||
1426 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
1427 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
1428 | return RX_CONTINUE; | ||
1429 | |||
1430 | if (mmie_keyidx < NUM_DEFAULT_KEYS || | ||
1431 | mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) | ||
1432 | return RX_DROP_MONITOR; /* unexpected BIP keyidx */ | ||
1433 | if (rx->sta) | ||
1434 | rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]); | ||
1435 | if (!rx->key) | ||
1436 | rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); | ||
1437 | } else if (!ieee80211_has_protected(fc)) { | ||
1438 | /* | ||
1439 | * The frame was not protected, so skip decryption. However, we | ||
1440 | * need to set rx->key if there is a key that could have been | ||
1441 | * used so that the frame may be dropped if encryption would | ||
1442 | * have been expected. | ||
1443 | */ | ||
1444 | struct ieee80211_key *key = NULL; | ||
1445 | struct ieee80211_sub_if_data *sdata = rx->sdata; | ||
1446 | int i; | ||
1447 | |||
1448 | if (ieee80211_is_mgmt(fc) && | ||
1449 | is_multicast_ether_addr(hdr->addr1) && | ||
1450 | (key = rcu_dereference(rx->sdata->default_mgmt_key))) | ||
1451 | rx->key = key; | ||
1452 | else { | ||
1453 | if (rx->sta) { | ||
1454 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) { | ||
1455 | key = rcu_dereference(rx->sta->gtk[i]); | ||
1456 | if (key) | ||
1457 | break; | ||
1458 | } | ||
1459 | } | ||
1460 | if (!key) { | ||
1461 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) { | ||
1462 | key = rcu_dereference(sdata->keys[i]); | ||
1463 | if (key) | ||
1464 | break; | ||
1465 | } | ||
1466 | } | ||
1467 | if (key) | ||
1468 | rx->key = key; | ||
1469 | } | ||
1470 | return RX_CONTINUE; | ||
1471 | } else { | ||
1472 | u8 keyid; | ||
1473 | /* | ||
1474 | * The device doesn't give us the IV so we won't be | ||
1475 | * able to look up the key. That's ok though, we | ||
1476 | * don't need to decrypt the frame, we just won't | ||
1477 | * be able to keep statistics accurate. | ||
1478 | * Except for key threshold notifications, should | ||
1479 | * we somehow allow the driver to tell us which key | ||
1480 | * the hardware used if this flag is set? | ||
1481 | */ | ||
1482 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
1483 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
1484 | return RX_CONTINUE; | ||
1485 | |||
1486 | hdrlen = ieee80211_hdrlen(fc); | ||
1487 | |||
1488 | if (rx->skb->len < 8 + hdrlen) | ||
1489 | return RX_DROP_UNUSABLE; /* TODO: count this? */ | ||
1490 | |||
1491 | /* | ||
1492 | * no need to call ieee80211_wep_get_keyidx, | ||
1493 | * it verifies a bunch of things we've done already | ||
1494 | */ | ||
1495 | skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); | ||
1496 | keyidx = keyid >> 6; | ||
1497 | |||
1498 | /* check per-station GTK first, if multicast packet */ | ||
1499 | if (is_multicast_ether_addr(hdr->addr1) && rx->sta) | ||
1500 | rx->key = rcu_dereference(rx->sta->gtk[keyidx]); | ||
1501 | |||
1502 | /* if not found, try default key */ | ||
1503 | if (!rx->key) { | ||
1504 | rx->key = rcu_dereference(rx->sdata->keys[keyidx]); | ||
1505 | |||
1506 | /* | ||
1507 | * RSNA-protected unicast frames should always be | ||
1508 | * sent with pairwise or station-to-station keys, | ||
1509 | * but for WEP we allow using a key index as well. | ||
1510 | */ | ||
1511 | if (rx->key && | ||
1512 | rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && | ||
1513 | rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && | ||
1514 | !is_multicast_ether_addr(hdr->addr1)) | ||
1515 | rx->key = NULL; | ||
1516 | } | ||
1517 | } | ||
1518 | |||
1519 | if (rx->key) { | ||
1520 | if (unlikely(rx->key->flags & KEY_FLAG_TAINTED)) | ||
1521 | return RX_DROP_MONITOR; | ||
1522 | |||
1523 | rx->key->tx_rx_count++; | ||
1524 | /* TODO: add threshold stuff again */ | ||
1525 | } else { | ||
1526 | return RX_DROP_MONITOR; | ||
1527 | } | ||
1528 | |||
1529 | switch (rx->key->conf.cipher) { | ||
1530 | case WLAN_CIPHER_SUITE_WEP40: | ||
1531 | case WLAN_CIPHER_SUITE_WEP104: | ||
1532 | result = ieee80211_crypto_wep_decrypt(rx); | ||
1533 | break; | ||
1534 | case WLAN_CIPHER_SUITE_TKIP: | ||
1535 | result = ieee80211_crypto_tkip_decrypt(rx); | ||
1536 | break; | ||
1537 | case WLAN_CIPHER_SUITE_CCMP: | ||
1538 | result = ieee80211_crypto_ccmp_decrypt(rx); | ||
1539 | break; | ||
1540 | case WLAN_CIPHER_SUITE_AES_CMAC: | ||
1541 | result = ieee80211_crypto_aes_cmac_decrypt(rx); | ||
1542 | break; | ||
1543 | default: | ||
1544 | /* | ||
1545 | * We can reach here only with HW-only algorithms | ||
1546 | * but why didn't it decrypt the frame?! | ||
1547 | */ | ||
1548 | return RX_DROP_UNUSABLE; | ||
1549 | } | ||
1550 | |||
1551 | /* the hdr variable is invalid after the decrypt handlers */ | ||
1552 | |||
1553 | /* either the frame has been decrypted or will be dropped */ | ||
1554 | status->flag |= RX_FLAG_DECRYPTED; | ||
1555 | |||
1556 | return result; | ||
1557 | } | ||
1558 | |||
1559 | static inline struct ieee80211_fragment_entry * | 1559 | static inline struct ieee80211_fragment_entry * |
1560 | ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | 1560 | ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, |
1561 | unsigned int frag, unsigned int seq, int rx_queue, | 1561 | unsigned int frag, unsigned int seq, int rx_queue, |
@@ -2939,10 +2939,10 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, | |||
2939 | */ | 2939 | */ |
2940 | rx->skb = skb; | 2940 | rx->skb = skb; |
2941 | 2941 | ||
2942 | CALL_RXH(ieee80211_rx_h_decrypt) | ||
2943 | CALL_RXH(ieee80211_rx_h_check_more_data) | 2942 | CALL_RXH(ieee80211_rx_h_check_more_data) |
2944 | CALL_RXH(ieee80211_rx_h_uapsd_and_pspoll) | 2943 | CALL_RXH(ieee80211_rx_h_uapsd_and_pspoll) |
2945 | CALL_RXH(ieee80211_rx_h_sta_process) | 2944 | CALL_RXH(ieee80211_rx_h_sta_process) |
2945 | CALL_RXH(ieee80211_rx_h_decrypt) | ||
2946 | CALL_RXH(ieee80211_rx_h_defragment) | 2946 | CALL_RXH(ieee80211_rx_h_defragment) |
2947 | CALL_RXH(ieee80211_rx_h_michael_mic_verify) | 2947 | CALL_RXH(ieee80211_rx_h_michael_mic_verify) |
2948 | /* must be after MMIC verify so header is counted in MPDU mic */ | 2948 | /* must be after MMIC verify so header is counted in MPDU mic */ |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 0e42322aa6b1..098ae854ad3c 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -539,9 +539,11 @@ ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx) | |||
539 | { | 539 | { |
540 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 540 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
541 | 541 | ||
542 | if (unlikely(tx->sdata->control_port_protocol == tx->skb->protocol && | 542 | if (unlikely(tx->sdata->control_port_protocol == tx->skb->protocol)) { |
543 | tx->sdata->control_port_no_encrypt)) | 543 | if (tx->sdata->control_port_no_encrypt) |
544 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 544 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
545 | info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO; | ||
546 | } | ||
545 | 547 | ||
546 | return TX_CONTINUE; | 548 | return TX_CONTINUE; |
547 | } | 549 | } |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index d23c5a705a68..e1b34a18b243 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1453,8 +1453,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1453 | local->resuming = true; | 1453 | local->resuming = true; |
1454 | 1454 | ||
1455 | if (local->wowlan) { | 1455 | if (local->wowlan) { |
1456 | local->wowlan = false; | ||
1457 | res = drv_resume(local); | 1456 | res = drv_resume(local); |
1457 | local->wowlan = false; | ||
1458 | if (res < 0) { | 1458 | if (res < 0) { |
1459 | local->resuming = false; | 1459 | local->resuming = false; |
1460 | return res; | 1460 | return res; |
diff --git a/net/rfkill/rfkill-regulator.c b/net/rfkill/rfkill-regulator.c index d11ac79246e4..cf5b145902e5 100644 --- a/net/rfkill/rfkill-regulator.c +++ b/net/rfkill/rfkill-regulator.c | |||
@@ -30,6 +30,7 @@ struct rfkill_regulator_data { | |||
30 | static int rfkill_regulator_set_block(void *data, bool blocked) | 30 | static int rfkill_regulator_set_block(void *data, bool blocked) |
31 | { | 31 | { |
32 | struct rfkill_regulator_data *rfkill_data = data; | 32 | struct rfkill_regulator_data *rfkill_data = data; |
33 | int ret = 0; | ||
33 | 34 | ||
34 | pr_debug("%s: blocked: %d\n", __func__, blocked); | 35 | pr_debug("%s: blocked: %d\n", __func__, blocked); |
35 | 36 | ||
@@ -40,15 +41,16 @@ static int rfkill_regulator_set_block(void *data, bool blocked) | |||
40 | } | 41 | } |
41 | } else { | 42 | } else { |
42 | if (!rfkill_data->reg_enabled) { | 43 | if (!rfkill_data->reg_enabled) { |
43 | regulator_enable(rfkill_data->vcc); | 44 | ret = regulator_enable(rfkill_data->vcc); |
44 | rfkill_data->reg_enabled = true; | 45 | if (!ret) |
46 | rfkill_data->reg_enabled = true; | ||
45 | } | 47 | } |
46 | } | 48 | } |
47 | 49 | ||
48 | pr_debug("%s: regulator_is_enabled after set_block: %d\n", __func__, | 50 | pr_debug("%s: regulator_is_enabled after set_block: %d\n", __func__, |
49 | regulator_is_enabled(rfkill_data->vcc)); | 51 | regulator_is_enabled(rfkill_data->vcc)); |
50 | 52 | ||
51 | return 0; | 53 | return ret; |
52 | } | 54 | } |
53 | 55 | ||
54 | static struct rfkill_ops rfkill_regulator_ops = { | 56 | static struct rfkill_ops rfkill_regulator_ops = { |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index adf1e98f4c3e..c6164da1c133 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -6593,19 +6593,30 @@ static struct genl_multicast_group nl80211_testmode_mcgrp = { | |||
6593 | static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) | 6593 | static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) |
6594 | { | 6594 | { |
6595 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6595 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6596 | struct wireless_dev *wdev = | ||
6597 | __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs); | ||
6596 | int err; | 6598 | int err; |
6597 | 6599 | ||
6600 | if (!rdev->ops->testmode_cmd) | ||
6601 | return -EOPNOTSUPP; | ||
6602 | |||
6603 | if (IS_ERR(wdev)) { | ||
6604 | err = PTR_ERR(wdev); | ||
6605 | if (err != -EINVAL) | ||
6606 | return err; | ||
6607 | wdev = NULL; | ||
6608 | } else if (wdev->wiphy != &rdev->wiphy) { | ||
6609 | return -EINVAL; | ||
6610 | } | ||
6611 | |||
6598 | if (!info->attrs[NL80211_ATTR_TESTDATA]) | 6612 | if (!info->attrs[NL80211_ATTR_TESTDATA]) |
6599 | return -EINVAL; | 6613 | return -EINVAL; |
6600 | 6614 | ||
6601 | err = -EOPNOTSUPP; | 6615 | rdev->testmode_info = info; |
6602 | if (rdev->ops->testmode_cmd) { | 6616 | err = rdev_testmode_cmd(rdev, wdev, |
6603 | rdev->testmode_info = info; | ||
6604 | err = rdev_testmode_cmd(rdev, | ||
6605 | nla_data(info->attrs[NL80211_ATTR_TESTDATA]), | 6617 | nla_data(info->attrs[NL80211_ATTR_TESTDATA]), |
6606 | nla_len(info->attrs[NL80211_ATTR_TESTDATA])); | 6618 | nla_len(info->attrs[NL80211_ATTR_TESTDATA])); |
6607 | rdev->testmode_info = NULL; | 6619 | rdev->testmode_info = NULL; |
6608 | } | ||
6609 | 6620 | ||
6610 | return err; | 6621 | return err; |
6611 | } | 6622 | } |
@@ -7566,14 +7577,12 @@ static int nl80211_set_cqm_txe(struct genl_info *info, | |||
7566 | u32 rate, u32 pkts, u32 intvl) | 7577 | u32 rate, u32 pkts, u32 intvl) |
7567 | { | 7578 | { |
7568 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 7579 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
7569 | struct wireless_dev *wdev; | ||
7570 | struct net_device *dev = info->user_ptr[1]; | 7580 | struct net_device *dev = info->user_ptr[1]; |
7581 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
7571 | 7582 | ||
7572 | if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL) | 7583 | if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL) |
7573 | return -EINVAL; | 7584 | return -EINVAL; |
7574 | 7585 | ||
7575 | wdev = dev->ieee80211_ptr; | ||
7576 | |||
7577 | if (!rdev->ops->set_cqm_txe_config) | 7586 | if (!rdev->ops->set_cqm_txe_config) |
7578 | return -EOPNOTSUPP; | 7587 | return -EOPNOTSUPP; |
7579 | 7588 | ||
@@ -7588,13 +7597,15 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, | |||
7588 | s32 threshold, u32 hysteresis) | 7597 | s32 threshold, u32 hysteresis) |
7589 | { | 7598 | { |
7590 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 7599 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
7591 | struct wireless_dev *wdev; | ||
7592 | struct net_device *dev = info->user_ptr[1]; | 7600 | struct net_device *dev = info->user_ptr[1]; |
7601 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
7593 | 7602 | ||
7594 | if (threshold > 0) | 7603 | if (threshold > 0) |
7595 | return -EINVAL; | 7604 | return -EINVAL; |
7596 | 7605 | ||
7597 | wdev = dev->ieee80211_ptr; | 7606 | /* disabling - hysteresis should also be zero then */ |
7607 | if (threshold == 0) | ||
7608 | hysteresis = 0; | ||
7598 | 7609 | ||
7599 | if (!rdev->ops->set_cqm_rssi_config) | 7610 | if (!rdev->ops->set_cqm_rssi_config) |
7600 | return -EOPNOTSUPP; | 7611 | return -EOPNOTSUPP; |
@@ -7613,36 +7624,33 @@ static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) | |||
7613 | int err; | 7624 | int err; |
7614 | 7625 | ||
7615 | cqm = info->attrs[NL80211_ATTR_CQM]; | 7626 | cqm = info->attrs[NL80211_ATTR_CQM]; |
7616 | if (!cqm) { | 7627 | if (!cqm) |
7617 | err = -EINVAL; | 7628 | return -EINVAL; |
7618 | goto out; | ||
7619 | } | ||
7620 | 7629 | ||
7621 | err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm, | 7630 | err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm, |
7622 | nl80211_attr_cqm_policy); | 7631 | nl80211_attr_cqm_policy); |
7623 | if (err) | 7632 | if (err) |
7624 | goto out; | 7633 | return err; |
7625 | 7634 | ||
7626 | if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] && | 7635 | if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] && |
7627 | attrs[NL80211_ATTR_CQM_RSSI_HYST]) { | 7636 | attrs[NL80211_ATTR_CQM_RSSI_HYST]) { |
7628 | s32 threshold; | 7637 | s32 threshold = nla_get_s32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]); |
7629 | u32 hysteresis; | 7638 | u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]); |
7630 | threshold = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]); | ||
7631 | hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]); | ||
7632 | err = nl80211_set_cqm_rssi(info, threshold, hysteresis); | ||
7633 | } else if (attrs[NL80211_ATTR_CQM_TXE_RATE] && | ||
7634 | attrs[NL80211_ATTR_CQM_TXE_PKTS] && | ||
7635 | attrs[NL80211_ATTR_CQM_TXE_INTVL]) { | ||
7636 | u32 rate, pkts, intvl; | ||
7637 | rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]); | ||
7638 | pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]); | ||
7639 | intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]); | ||
7640 | err = nl80211_set_cqm_txe(info, rate, pkts, intvl); | ||
7641 | } else | ||
7642 | err = -EINVAL; | ||
7643 | 7639 | ||
7644 | out: | 7640 | return nl80211_set_cqm_rssi(info, threshold, hysteresis); |
7645 | return err; | 7641 | } |
7642 | |||
7643 | if (attrs[NL80211_ATTR_CQM_TXE_RATE] && | ||
7644 | attrs[NL80211_ATTR_CQM_TXE_PKTS] && | ||
7645 | attrs[NL80211_ATTR_CQM_TXE_INTVL]) { | ||
7646 | u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]); | ||
7647 | u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]); | ||
7648 | u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]); | ||
7649 | |||
7650 | return nl80211_set_cqm_txe(info, rate, pkts, intvl); | ||
7651 | } | ||
7652 | |||
7653 | return -EINVAL; | ||
7646 | } | 7654 | } |
7647 | 7655 | ||
7648 | static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) | 7656 | static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) |
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index de870d4d0bcc..37ce9fdfe934 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
@@ -516,11 +516,12 @@ static inline void rdev_rfkill_poll(struct cfg80211_registered_device *rdev) | |||
516 | 516 | ||
517 | #ifdef CONFIG_NL80211_TESTMODE | 517 | #ifdef CONFIG_NL80211_TESTMODE |
518 | static inline int rdev_testmode_cmd(struct cfg80211_registered_device *rdev, | 518 | static inline int rdev_testmode_cmd(struct cfg80211_registered_device *rdev, |
519 | struct wireless_dev *wdev, | ||
519 | void *data, int len) | 520 | void *data, int len) |
520 | { | 521 | { |
521 | int ret; | 522 | int ret; |
522 | trace_rdev_testmode_cmd(&rdev->wiphy); | 523 | trace_rdev_testmode_cmd(&rdev->wiphy, wdev); |
523 | ret = rdev->ops->testmode_cmd(&rdev->wiphy, data, len); | 524 | ret = rdev->ops->testmode_cmd(&rdev->wiphy, wdev, data, len); |
524 | trace_rdev_return_int(&rdev->wiphy, ret); | 525 | trace_rdev_return_int(&rdev->wiphy, ret); |
525 | return ret; | 526 | return ret; |
526 | } | 527 | } |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index f0ebdcd394ef..ba5f0d6614d5 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -1293,15 +1293,17 @@ TRACE_EVENT(rdev_return_int_int, | |||
1293 | 1293 | ||
1294 | #ifdef CONFIG_NL80211_TESTMODE | 1294 | #ifdef CONFIG_NL80211_TESTMODE |
1295 | TRACE_EVENT(rdev_testmode_cmd, | 1295 | TRACE_EVENT(rdev_testmode_cmd, |
1296 | TP_PROTO(struct wiphy *wiphy), | 1296 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), |
1297 | TP_ARGS(wiphy), | 1297 | TP_ARGS(wiphy, wdev), |
1298 | TP_STRUCT__entry( | 1298 | TP_STRUCT__entry( |
1299 | WIPHY_ENTRY | 1299 | WIPHY_ENTRY |
1300 | WDEV_ENTRY | ||
1300 | ), | 1301 | ), |
1301 | TP_fast_assign( | 1302 | TP_fast_assign( |
1302 | WIPHY_ASSIGN; | 1303 | WIPHY_ASSIGN; |
1304 | WDEV_ASSIGN; | ||
1303 | ), | 1305 | ), |
1304 | TP_printk(WIPHY_PR_FMT, WIPHY_PR_ARG) | 1306 | TP_printk(WIPHY_PR_FMT WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG) |
1305 | ); | 1307 | ); |
1306 | 1308 | ||
1307 | TRACE_EVENT(rdev_testmode_dump, | 1309 | TRACE_EVENT(rdev_testmode_dump, |