diff options
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, |
