diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-02-24 15:03:32 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-02-24 15:03:32 -0500 |
commit | c77986c78aa941af8266272841567e78b72d54cc (patch) | |
tree | cb30e1bd7d5799bfce5a3837bcfddee059a81733 | |
parent | 9e4b4269ecee426f1647425a24186dd1566db554 (diff) | |
parent | 6658ab80fd4ef940fc2366ddb66690a15ea69c18 (diff) |
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
29 files changed, 312 insertions, 189 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index 46ad6faee9ab..044b76436e83 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl | |||
@@ -98,6 +98,8 @@ | |||
98 | !Finclude/net/cfg80211.h priv_to_wiphy | 98 | !Finclude/net/cfg80211.h priv_to_wiphy |
99 | !Finclude/net/cfg80211.h set_wiphy_dev | 99 | !Finclude/net/cfg80211.h set_wiphy_dev |
100 | !Finclude/net/cfg80211.h wdev_priv | 100 | !Finclude/net/cfg80211.h wdev_priv |
101 | !Finclude/net/cfg80211.h ieee80211_iface_limit | ||
102 | !Finclude/net/cfg80211.h ieee80211_iface_combination | ||
101 | </chapter> | 103 | </chapter> |
102 | <chapter> | 104 | <chapter> |
103 | <title>Actions and configuration</title> | 105 | <title>Actions and configuration</title> |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index beaf8140abbf..7492fc0f2766 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -1746,14 +1746,16 @@ out: | |||
1746 | return ret; | 1746 | return ret; |
1747 | } | 1747 | } |
1748 | 1748 | ||
1749 | static void iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw, | 1749 | static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw, |
1750 | struct ieee80211_vif *vif) | 1750 | struct ieee80211_vif *vif) |
1751 | { | 1751 | { |
1752 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | 1752 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); |
1753 | 1753 | ||
1754 | mutex_lock(&mvm->mutex); | 1754 | mutex_lock(&mvm->mutex); |
1755 | iwl_mvm_sched_scan_stop(mvm); | 1755 | iwl_mvm_sched_scan_stop(mvm); |
1756 | mutex_unlock(&mvm->mutex); | 1756 | mutex_unlock(&mvm->mutex); |
1757 | |||
1758 | return 0; | ||
1757 | } | 1759 | } |
1758 | 1760 | ||
1759 | static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, | 1761 | static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index f7e3562542fe..9d7a52f5a410 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -411,6 +411,7 @@ struct mac80211_hwsim_data { | |||
411 | 411 | ||
412 | struct mac_address addresses[2]; | 412 | struct mac_address addresses[2]; |
413 | int channels, idx; | 413 | int channels, idx; |
414 | bool use_chanctx; | ||
414 | 415 | ||
415 | struct ieee80211_channel *tmp_chan; | 416 | struct ieee80211_channel *tmp_chan; |
416 | struct delayed_work roc_done; | 417 | struct delayed_work roc_done; |
@@ -1088,7 +1089,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, | |||
1088 | return; | 1089 | return; |
1089 | } | 1090 | } |
1090 | 1091 | ||
1091 | if (data->channels == 1) { | 1092 | if (!data->use_chanctx) { |
1092 | channel = data->channel; | 1093 | channel = data->channel; |
1093 | } else if (txi->hw_queue == 4) { | 1094 | } else if (txi->hw_queue == 4) { |
1094 | channel = data->tmp_chan; | 1095 | channel = data->tmp_chan; |
@@ -1354,7 +1355,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) | |||
1354 | 1355 | ||
1355 | data->channel = conf->chandef.chan; | 1356 | data->channel = conf->chandef.chan; |
1356 | 1357 | ||
1357 | WARN_ON(data->channel && data->channels > 1); | 1358 | WARN_ON(data->channel && data->use_chanctx); |
1358 | 1359 | ||
1359 | data->power_level = conf->power_level; | 1360 | data->power_level = conf->power_level; |
1360 | if (!data->started || !data->beacon_int) | 1361 | if (!data->started || !data->beacon_int) |
@@ -1940,7 +1941,8 @@ static struct ieee80211_ops mac80211_hwsim_mchan_ops; | |||
1940 | 1941 | ||
1941 | static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, | 1942 | static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, |
1942 | const struct ieee80211_regdomain *regd, | 1943 | const struct ieee80211_regdomain *regd, |
1943 | bool reg_strict, bool p2p_device) | 1944 | bool reg_strict, bool p2p_device, |
1945 | bool use_chanctx) | ||
1944 | { | 1946 | { |
1945 | int err; | 1947 | int err; |
1946 | u8 addr[ETH_ALEN]; | 1948 | u8 addr[ETH_ALEN]; |
@@ -1950,11 +1952,14 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, | |||
1950 | const struct ieee80211_ops *ops = &mac80211_hwsim_ops; | 1952 | const struct ieee80211_ops *ops = &mac80211_hwsim_ops; |
1951 | int idx; | 1953 | int idx; |
1952 | 1954 | ||
1955 | if (WARN_ON(channels > 1 && !use_chanctx)) | ||
1956 | return -EINVAL; | ||
1957 | |||
1953 | spin_lock_bh(&hwsim_radio_lock); | 1958 | spin_lock_bh(&hwsim_radio_lock); |
1954 | idx = hwsim_radio_idx++; | 1959 | idx = hwsim_radio_idx++; |
1955 | spin_unlock_bh(&hwsim_radio_lock); | 1960 | spin_unlock_bh(&hwsim_radio_lock); |
1956 | 1961 | ||
1957 | if (channels > 1) | 1962 | if (use_chanctx) |
1958 | ops = &mac80211_hwsim_mchan_ops; | 1963 | ops = &mac80211_hwsim_mchan_ops; |
1959 | hw = ieee80211_alloc_hw(sizeof(*data), ops); | 1964 | hw = ieee80211_alloc_hw(sizeof(*data), ops); |
1960 | if (!hw) { | 1965 | if (!hw) { |
@@ -1995,20 +2000,21 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, | |||
1995 | hw->wiphy->addresses = data->addresses; | 2000 | hw->wiphy->addresses = data->addresses; |
1996 | 2001 | ||
1997 | data->channels = channels; | 2002 | data->channels = channels; |
2003 | data->use_chanctx = use_chanctx; | ||
1998 | data->idx = idx; | 2004 | data->idx = idx; |
1999 | 2005 | ||
2000 | if (data->channels > 1) { | 2006 | if (data->use_chanctx) { |
2001 | hw->wiphy->max_scan_ssids = 255; | 2007 | hw->wiphy->max_scan_ssids = 255; |
2002 | hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; | 2008 | hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; |
2003 | hw->wiphy->max_remain_on_channel_duration = 1000; | 2009 | hw->wiphy->max_remain_on_channel_duration = 1000; |
2004 | /* For channels > 1 DFS is not allowed */ | 2010 | /* For channels > 1 DFS is not allowed */ |
2005 | hw->wiphy->n_iface_combinations = 1; | 2011 | hw->wiphy->n_iface_combinations = 1; |
2006 | hw->wiphy->iface_combinations = &data->if_combination; | 2012 | hw->wiphy->iface_combinations = &data->if_combination; |
2007 | data->if_combination.num_different_channels = data->channels; | ||
2008 | if (p2p_device) | 2013 | if (p2p_device) |
2009 | data->if_combination = hwsim_if_comb_p2p_dev[0]; | 2014 | data->if_combination = hwsim_if_comb_p2p_dev[0]; |
2010 | else | 2015 | else |
2011 | data->if_combination = hwsim_if_comb[0]; | 2016 | data->if_combination = hwsim_if_comb[0]; |
2017 | data->if_combination.num_different_channels = data->channels; | ||
2012 | } else if (p2p_device) { | 2018 | } else if (p2p_device) { |
2013 | hw->wiphy->iface_combinations = hwsim_if_comb_p2p_dev; | 2019 | hw->wiphy->iface_combinations = hwsim_if_comb_p2p_dev; |
2014 | hw->wiphy->n_iface_combinations = | 2020 | hw->wiphy->n_iface_combinations = |
@@ -2156,7 +2162,7 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, | |||
2156 | debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps); | 2162 | debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps); |
2157 | debugfs_create_file("group", 0666, data->debugfs, data, | 2163 | debugfs_create_file("group", 0666, data->debugfs, data, |
2158 | &hwsim_fops_group); | 2164 | &hwsim_fops_group); |
2159 | if (data->channels == 1) | 2165 | if (!data->use_chanctx) |
2160 | debugfs_create_file("dfs_simulate_radar", 0222, | 2166 | debugfs_create_file("dfs_simulate_radar", 0222, |
2161 | data->debugfs, | 2167 | data->debugfs, |
2162 | data, &hwsim_simulate_radar); | 2168 | data, &hwsim_simulate_radar); |
@@ -2423,10 +2429,16 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) | |||
2423 | const struct ieee80211_regdomain *regd = NULL; | 2429 | const struct ieee80211_regdomain *regd = NULL; |
2424 | bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; | 2430 | bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; |
2425 | bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; | 2431 | bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; |
2432 | bool use_chanctx; | ||
2426 | 2433 | ||
2427 | if (info->attrs[HWSIM_ATTR_CHANNELS]) | 2434 | if (info->attrs[HWSIM_ATTR_CHANNELS]) |
2428 | chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]); | 2435 | chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]); |
2429 | 2436 | ||
2437 | if (info->attrs[HWSIM_ATTR_USE_CHANCTX]) | ||
2438 | use_chanctx = true; | ||
2439 | else | ||
2440 | use_chanctx = (chans > 1); | ||
2441 | |||
2430 | if (info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]) | 2442 | if (info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]) |
2431 | alpha2 = nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]); | 2443 | alpha2 = nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]); |
2432 | 2444 | ||
@@ -2439,7 +2451,7 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) | |||
2439 | } | 2451 | } |
2440 | 2452 | ||
2441 | return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict, | 2453 | return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict, |
2442 | p2p_device); | 2454 | p2p_device, use_chanctx); |
2443 | } | 2455 | } |
2444 | 2456 | ||
2445 | static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) | 2457 | static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) |
@@ -2658,7 +2670,8 @@ static int __init init_mac80211_hwsim(void) | |||
2658 | 2670 | ||
2659 | err = mac80211_hwsim_create_radio(channels, reg_alpha2, | 2671 | err = mac80211_hwsim_create_radio(channels, reg_alpha2, |
2660 | regd, reg_strict, | 2672 | regd, reg_strict, |
2661 | support_p2p_device); | 2673 | support_p2p_device, |
2674 | channels > 1); | ||
2662 | if (err < 0) | 2675 | if (err < 0) |
2663 | goto out_free_radios; | 2676 | goto out_free_radios; |
2664 | } | 2677 | } |
diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h index 6e72996ec8c1..c9d0315575ba 100644 --- a/drivers/net/wireless/mac80211_hwsim.h +++ b/drivers/net/wireless/mac80211_hwsim.h | |||
@@ -108,6 +108,9 @@ enum { | |||
108 | * @HWSIM_ATTR_REG_CUSTOM_REG: custom regulatory domain index (u32 attribute) | 108 | * @HWSIM_ATTR_REG_CUSTOM_REG: custom regulatory domain index (u32 attribute) |
109 | * @HWSIM_ATTR_REG_STRICT_REG: request REGULATORY_STRICT_REG (flag attribute) | 109 | * @HWSIM_ATTR_REG_STRICT_REG: request REGULATORY_STRICT_REG (flag attribute) |
110 | * @HWSIM_ATTR_SUPPORT_P2P_DEVICE: support P2P Device virtual interface (flag) | 110 | * @HWSIM_ATTR_SUPPORT_P2P_DEVICE: support P2P Device virtual interface (flag) |
111 | * @HWSIM_ATTR_USE_CHANCTX: used with the %HWSIM_CMD_CREATE_RADIO | ||
112 | * command to force use of channel contexts even when only a | ||
113 | * single channel is supported | ||
111 | * @__HWSIM_ATTR_MAX: enum limit | 114 | * @__HWSIM_ATTR_MAX: enum limit |
112 | */ | 115 | */ |
113 | 116 | ||
@@ -128,6 +131,7 @@ enum { | |||
128 | HWSIM_ATTR_REG_CUSTOM_REG, | 131 | HWSIM_ATTR_REG_CUSTOM_REG, |
129 | HWSIM_ATTR_REG_STRICT_REG, | 132 | HWSIM_ATTR_REG_STRICT_REG, |
130 | HWSIM_ATTR_SUPPORT_P2P_DEVICE, | 133 | HWSIM_ATTR_SUPPORT_P2P_DEVICE, |
134 | HWSIM_ATTR_USE_CHANCTX, | ||
131 | __HWSIM_ATTR_MAX, | 135 | __HWSIM_ATTR_MAX, |
132 | }; | 136 | }; |
133 | #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) | 137 | #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 436ba437a4ba..6948a97af839 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -2600,8 +2600,8 @@ static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy, | |||
2600 | static int | 2600 | static int |
2601 | mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, | 2601 | mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, |
2602 | u8 *peer, u8 action_code, u8 dialog_token, | 2602 | u8 *peer, u8 action_code, u8 dialog_token, |
2603 | u16 status_code, const u8 *extra_ies, | 2603 | u16 status_code, u32 peer_capability, |
2604 | size_t extra_ies_len) | 2604 | const u8 *extra_ies, size_t extra_ies_len) |
2605 | { | 2605 | { |
2606 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 2606 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
2607 | int ret; | 2607 | int ret; |
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 7aae5b3a0c2c..4175a57ac9f5 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c | |||
@@ -3668,8 +3668,8 @@ out: | |||
3668 | return ret; | 3668 | return ret; |
3669 | } | 3669 | } |
3670 | 3670 | ||
3671 | static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw, | 3671 | static int wl1271_op_sched_scan_stop(struct ieee80211_hw *hw, |
3672 | struct ieee80211_vif *vif) | 3672 | struct ieee80211_vif *vif) |
3673 | { | 3673 | { |
3674 | struct wl1271 *wl = hw->priv; | 3674 | struct wl1271 *wl = hw->priv; |
3675 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | 3675 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); |
@@ -3691,6 +3691,8 @@ static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw, | |||
3691 | wl1271_ps_elp_sleep(wl); | 3691 | wl1271_ps_elp_sleep(wl); |
3692 | out: | 3692 | out: |
3693 | mutex_unlock(&wl->mutex); | 3693 | mutex_unlock(&wl->mutex); |
3694 | |||
3695 | return 0; | ||
3694 | } | 3696 | } |
3695 | 3697 | ||
3696 | static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) | 3698 | static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 9f90554e88c4..8c9ba44fb7cf 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -2206,7 +2206,12 @@ struct cfg80211_qos_map { | |||
2206 | * @set_cqm_txe_config: Configure connection quality monitor TX error | 2206 | * @set_cqm_txe_config: Configure connection quality monitor TX error |
2207 | * thresholds. | 2207 | * thresholds. |
2208 | * @sched_scan_start: Tell the driver to start a scheduled scan. | 2208 | * @sched_scan_start: Tell the driver to start a scheduled scan. |
2209 | * @sched_scan_stop: Tell the driver to stop an ongoing scheduled scan. | 2209 | * @sched_scan_stop: Tell the driver to stop an ongoing scheduled scan. This |
2210 | * call must stop the scheduled scan and be ready for starting a new one | ||
2211 | * before it returns, i.e. @sched_scan_start may be called immediately | ||
2212 | * after that again and should not fail in that case. The driver should | ||
2213 | * not call cfg80211_sched_scan_stopped() for a requested stop (when this | ||
2214 | * method returns 0.) | ||
2210 | * | 2215 | * |
2211 | * @mgmt_frame_register: Notify driver that a management frame type was | 2216 | * @mgmt_frame_register: Notify driver that a management frame type was |
2212 | * registered. Note that this callback may not sleep, and cannot run | 2217 | * registered. Note that this callback may not sleep, and cannot run |
@@ -2465,7 +2470,8 @@ struct cfg80211_ops { | |||
2465 | 2470 | ||
2466 | int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev, | 2471 | int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev, |
2467 | u8 *peer, u8 action_code, u8 dialog_token, | 2472 | u8 *peer, u8 action_code, u8 dialog_token, |
2468 | u16 status_code, const u8 *buf, size_t len); | 2473 | u16 status_code, u32 peer_capability, |
2474 | const u8 *buf, size_t len); | ||
2469 | int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev, | 2475 | int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev, |
2470 | u8 *peer, enum nl80211_tdls_operation oper); | 2476 | u8 *peer, enum nl80211_tdls_operation oper); |
2471 | 2477 | ||
@@ -2610,9 +2616,12 @@ struct ieee80211_iface_limit { | |||
2610 | * only in special cases. | 2616 | * only in special cases. |
2611 | * @radar_detect_widths: bitmap of channel widths supported for radar detection | 2617 | * @radar_detect_widths: bitmap of channel widths supported for radar detection |
2612 | * | 2618 | * |
2613 | * These examples can be expressed as follows: | 2619 | * With this structure the driver can describe which interface |
2620 | * combinations it supports concurrently. | ||
2614 | * | 2621 | * |
2615 | * Allow #STA <= 1, #AP <= 1, matching BI, channels = 1, 2 total: | 2622 | * Examples: |
2623 | * | ||
2624 | * 1. Allow #STA <= 1, #AP <= 1, matching BI, channels = 1, 2 total: | ||
2616 | * | 2625 | * |
2617 | * struct ieee80211_iface_limit limits1[] = { | 2626 | * struct ieee80211_iface_limit limits1[] = { |
2618 | * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, | 2627 | * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, |
@@ -2626,7 +2635,7 @@ struct ieee80211_iface_limit { | |||
2626 | * }; | 2635 | * }; |
2627 | * | 2636 | * |
2628 | * | 2637 | * |
2629 | * Allow #{AP, P2P-GO} <= 8, channels = 1, 8 total: | 2638 | * 2. Allow #{AP, P2P-GO} <= 8, channels = 1, 8 total: |
2630 | * | 2639 | * |
2631 | * struct ieee80211_iface_limit limits2[] = { | 2640 | * struct ieee80211_iface_limit limits2[] = { |
2632 | * { .max = 8, .types = BIT(NL80211_IFTYPE_AP) | | 2641 | * { .max = 8, .types = BIT(NL80211_IFTYPE_AP) | |
@@ -2640,7 +2649,8 @@ struct ieee80211_iface_limit { | |||
2640 | * }; | 2649 | * }; |
2641 | * | 2650 | * |
2642 | * | 2651 | * |
2643 | * Allow #STA <= 1, #{P2P-client,P2P-GO} <= 3 on two channels, 4 total. | 2652 | * 3. Allow #STA <= 1, #{P2P-client,P2P-GO} <= 3 on two channels, 4 total. |
2653 | * | ||
2644 | * This allows for an infrastructure connection and three P2P connections. | 2654 | * This allows for an infrastructure connection and three P2P connections. |
2645 | * | 2655 | * |
2646 | * struct ieee80211_iface_limit limits3[] = { | 2656 | * struct ieee80211_iface_limit limits3[] = { |
@@ -2790,7 +2800,7 @@ struct wiphy_vendor_command { | |||
2790 | * @perm_addr: permanent MAC address of this device | 2800 | * @perm_addr: permanent MAC address of this device |
2791 | * @addr_mask: If the device supports multiple MAC addresses by masking, | 2801 | * @addr_mask: If the device supports multiple MAC addresses by masking, |
2792 | * set this to a mask with variable bits set to 1, e.g. if the last | 2802 | * set this to a mask with variable bits set to 1, e.g. if the last |
2793 | * four bits are variable then set it to 00:...:00:0f. The actual | 2803 | * four bits are variable then set it to 00-00-00-00-00-0f. The actual |
2794 | * variable bits shall be determined by the interfaces added, with | 2804 | * variable bits shall be determined by the interfaces added, with |
2795 | * interfaces not matching the mask being rejected to be brought up. | 2805 | * interfaces not matching the mask being rejected to be brought up. |
2796 | * @n_addresses: number of addresses in @addresses. | 2806 | * @n_addresses: number of addresses in @addresses. |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 4f0f29dce0aa..86faa413b37d 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -66,10 +66,6 @@ | |||
66 | * | 66 | * |
67 | * Secondly, when the hardware handles fragmentation, the frame handed to | 67 | * Secondly, when the hardware handles fragmentation, the frame handed to |
68 | * the driver from mac80211 is the MSDU, not the MPDU. | 68 | * the driver from mac80211 is the MSDU, not the MPDU. |
69 | * | ||
70 | * Finally, for received frames, the driver is able to indicate that it has | ||
71 | * filled a radiotap header and put that in front of the frame; if it does | ||
72 | * not do so then mac80211 may add this under certain circumstances. | ||
73 | */ | 69 | */ |
74 | 70 | ||
75 | /** | 71 | /** |
@@ -1507,8 +1503,6 @@ struct ieee80211_tx_control { | |||
1507 | * @IEEE80211_HW_CONNECTION_MONITOR: | 1503 | * @IEEE80211_HW_CONNECTION_MONITOR: |
1508 | * The hardware performs its own connection monitoring, including | 1504 | * The hardware performs its own connection monitoring, including |
1509 | * periodic keep-alives to the AP and probing the AP on beacon loss. | 1505 | * periodic keep-alives to the AP and probing the AP on beacon loss. |
1510 | * When this flag is set, signaling beacon-loss will cause an immediate | ||
1511 | * change to disassociated state. | ||
1512 | * | 1506 | * |
1513 | * @IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC: | 1507 | * @IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC: |
1514 | * This device needs to get data from beacon before association (i.e. | 1508 | * This device needs to get data from beacon before association (i.e. |
@@ -1644,10 +1638,6 @@ enum ieee80211_hw_flags { | |||
1644 | * the hw can report back. | 1638 | * the hw can report back. |
1645 | * @max_rate_tries: maximum number of tries for each stage | 1639 | * @max_rate_tries: maximum number of tries for each stage |
1646 | * | 1640 | * |
1647 | * @napi_weight: weight used for NAPI polling. You must specify an | ||
1648 | * appropriate value here if a napi_poll operation is provided | ||
1649 | * by your driver. | ||
1650 | * | ||
1651 | * @max_rx_aggregation_subframes: maximum buffer size (number of | 1641 | * @max_rx_aggregation_subframes: maximum buffer size (number of |
1652 | * sub-frames) to be used for A-MPDU block ack receiver | 1642 | * sub-frames) to be used for A-MPDU block ack receiver |
1653 | * aggregation. | 1643 | * aggregation. |
@@ -1701,7 +1691,6 @@ struct ieee80211_hw { | |||
1701 | int vif_data_size; | 1691 | int vif_data_size; |
1702 | int sta_data_size; | 1692 | int sta_data_size; |
1703 | int chanctx_data_size; | 1693 | int chanctx_data_size; |
1704 | int napi_weight; | ||
1705 | u16 queues; | 1694 | u16 queues; |
1706 | u16 max_listen_interval; | 1695 | u16 max_listen_interval; |
1707 | s8 max_signal; | 1696 | s8 max_signal; |
@@ -2471,6 +2460,7 @@ enum ieee80211_roc_type { | |||
2471 | * This process will continue until sched_scan_stop is called. | 2460 | * This process will continue until sched_scan_stop is called. |
2472 | * | 2461 | * |
2473 | * @sched_scan_stop: Tell the hardware to stop an ongoing scheduled scan. | 2462 | * @sched_scan_stop: Tell the hardware to stop an ongoing scheduled scan. |
2463 | * In this case, ieee80211_sched_scan_stopped() must not be called. | ||
2474 | * | 2464 | * |
2475 | * @sw_scan_start: Notifier function that is called just before a software scan | 2465 | * @sw_scan_start: Notifier function that is called just before a software scan |
2476 | * is started. Can be NULL, if the driver doesn't need this notification. | 2466 | * is started. Can be NULL, if the driver doesn't need this notification. |
@@ -2624,8 +2614,6 @@ enum ieee80211_roc_type { | |||
2624 | * callback. They must then call ieee80211_chswitch_done() to indicate | 2614 | * callback. They must then call ieee80211_chswitch_done() to indicate |
2625 | * completion of the channel switch. | 2615 | * completion of the channel switch. |
2626 | * | 2616 | * |
2627 | * @napi_poll: Poll Rx queue for incoming data frames. | ||
2628 | * | ||
2629 | * @set_antenna: Set antenna configuration (tx_ant, rx_ant) on the device. | 2617 | * @set_antenna: Set antenna configuration (tx_ant, rx_ant) on the device. |
2630 | * Parameters are bitmaps of allowed antennas to use for TX/RX. Drivers may | 2618 | * Parameters are bitmaps of allowed antennas to use for TX/RX. Drivers may |
2631 | * reject TX/RX mask combinations they cannot support by returning -EINVAL | 2619 | * reject TX/RX mask combinations they cannot support by returning -EINVAL |
@@ -2820,7 +2808,7 @@ struct ieee80211_ops { | |||
2820 | struct ieee80211_vif *vif, | 2808 | struct ieee80211_vif *vif, |
2821 | struct cfg80211_sched_scan_request *req, | 2809 | struct cfg80211_sched_scan_request *req, |
2822 | struct ieee80211_sched_scan_ies *ies); | 2810 | struct ieee80211_sched_scan_ies *ies); |
2823 | void (*sched_scan_stop)(struct ieee80211_hw *hw, | 2811 | int (*sched_scan_stop)(struct ieee80211_hw *hw, |
2824 | struct ieee80211_vif *vif); | 2812 | struct ieee80211_vif *vif); |
2825 | void (*sw_scan_start)(struct ieee80211_hw *hw); | 2813 | void (*sw_scan_start)(struct ieee80211_hw *hw); |
2826 | void (*sw_scan_complete)(struct ieee80211_hw *hw); | 2814 | void (*sw_scan_complete)(struct ieee80211_hw *hw); |
@@ -2884,7 +2872,6 @@ struct ieee80211_ops { | |||
2884 | void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop); | 2872 | void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop); |
2885 | void (*channel_switch)(struct ieee80211_hw *hw, | 2873 | void (*channel_switch)(struct ieee80211_hw *hw, |
2886 | struct ieee80211_channel_switch *ch_switch); | 2874 | struct ieee80211_channel_switch *ch_switch); |
2887 | int (*napi_poll)(struct ieee80211_hw *hw, int budget); | ||
2888 | int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); | 2875 | int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); |
2889 | int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); | 2876 | int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); |
2890 | 2877 | ||
@@ -3166,21 +3153,21 @@ void ieee80211_free_hw(struct ieee80211_hw *hw); | |||
3166 | */ | 3153 | */ |
3167 | void ieee80211_restart_hw(struct ieee80211_hw *hw); | 3154 | void ieee80211_restart_hw(struct ieee80211_hw *hw); |
3168 | 3155 | ||
3169 | /** ieee80211_napi_schedule - schedule NAPI poll | 3156 | /** |
3170 | * | 3157 | * ieee80211_napi_add - initialize mac80211 NAPI context |
3171 | * Use this function to schedule NAPI polling on a device. | 3158 | * @hw: the hardware to initialize the NAPI context on |
3172 | * | 3159 | * @napi: the NAPI context to initialize |
3173 | * @hw: the hardware to start polling | 3160 | * @napi_dev: dummy NAPI netdevice, here to not waste the space if the |
3174 | */ | 3161 | * driver doesn't use NAPI |
3175 | void ieee80211_napi_schedule(struct ieee80211_hw *hw); | 3162 | * @poll: poll function |
3176 | 3163 | * @weight: default weight | |
3177 | /** ieee80211_napi_complete - complete NAPI polling | ||
3178 | * | ||
3179 | * Use this function to finish NAPI polling on a device. | ||
3180 | * | 3164 | * |
3181 | * @hw: the hardware to stop polling | 3165 | * See also netif_napi_add(). |
3182 | */ | 3166 | */ |
3183 | void ieee80211_napi_complete(struct ieee80211_hw *hw); | 3167 | void ieee80211_napi_add(struct ieee80211_hw *hw, struct napi_struct *napi, |
3168 | struct net_device *napi_dev, | ||
3169 | int (*poll)(struct napi_struct *, int), | ||
3170 | int weight); | ||
3184 | 3171 | ||
3185 | /** | 3172 | /** |
3186 | * ieee80211_rx - receive frame | 3173 | * ieee80211_rx - receive frame |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index a12e6cae5132..ff72cab3cd3a 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
@@ -303,8 +303,9 @@ | |||
303 | * passed, all channels allowed for the current regulatory domain | 303 | * passed, all channels allowed for the current regulatory domain |
304 | * are used. Extra IEs can also be passed from the userspace by | 304 | * are used. Extra IEs can also be passed from the userspace by |
305 | * using the %NL80211_ATTR_IE attribute. | 305 | * using the %NL80211_ATTR_IE attribute. |
306 | * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT | 306 | * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT if |
307 | * if scheduled scan is not running. | 307 | * scheduled scan is not running. The caller may assume that as soon |
308 | * as the call returns, it is safe to start a new scheduled scan again. | ||
308 | * @NL80211_CMD_SCHED_SCAN_RESULTS: indicates that there are scheduled scan | 309 | * @NL80211_CMD_SCHED_SCAN_RESULTS: indicates that there are scheduled scan |
309 | * results available. | 310 | * results available. |
310 | * @NL80211_CMD_SCHED_SCAN_STOPPED: indicates that the scheduled scan has | 311 | * @NL80211_CMD_SCHED_SCAN_STOPPED: indicates that the scheduled scan has |
@@ -1575,6 +1576,9 @@ enum nl80211_commands { | |||
1575 | * advertise values that cannot always be met. In such cases, an attempt | 1576 | * advertise values that cannot always be met. In such cases, an attempt |
1576 | * to add a new station entry with @NL80211_CMD_NEW_STATION may fail. | 1577 | * to add a new station entry with @NL80211_CMD_NEW_STATION may fail. |
1577 | * | 1578 | * |
1579 | * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32. | ||
1580 | * As specified in the &enum nl80211_tdls_peer_capability. | ||
1581 | * | ||
1578 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1582 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
1579 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1583 | * @__NL80211_ATTR_AFTER_LAST: internal use |
1580 | */ | 1584 | */ |
@@ -1908,6 +1912,8 @@ enum nl80211_attrs { | |||
1908 | 1912 | ||
1909 | NL80211_ATTR_MAX_AP_ASSOC_STA, | 1913 | NL80211_ATTR_MAX_AP_ASSOC_STA, |
1910 | 1914 | ||
1915 | NL80211_ATTR_TDLS_PEER_CAPABILITY, | ||
1916 | |||
1911 | /* add attributes here, update the policy in nl80211.c */ | 1917 | /* add attributes here, update the policy in nl80211.c */ |
1912 | 1918 | ||
1913 | __NL80211_ATTR_AFTER_LAST, | 1919 | __NL80211_ATTR_AFTER_LAST, |
@@ -2437,10 +2443,7 @@ enum nl80211_reg_type { | |||
2437 | * in KHz. This is not a center a frequency but an actual regulatory | 2443 | * in KHz. This is not a center a frequency but an actual regulatory |
2438 | * band edge. | 2444 | * band edge. |
2439 | * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this | 2445 | * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this |
2440 | * frequency range, in KHz. If not present or 0, maximum available | 2446 | * frequency range, in KHz. |
2441 | * bandwidth should be calculated base on contiguous rules and wider | ||
2442 | * channels will be allowed to cross multiple contiguous/overlapping | ||
2443 | * frequency ranges. | ||
2444 | * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain | 2447 | * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain |
2445 | * for a given frequency range. The value is in mBi (100 * dBi). | 2448 | * for a given frequency range. The value is in mBi (100 * dBi). |
2446 | * If you don't have one then don't send this. | 2449 | * If you don't have one then don't send this. |
@@ -2511,6 +2514,9 @@ enum nl80211_sched_scan_match_attr { | |||
2511 | * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed, | 2514 | * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed, |
2512 | * this includes probe requests or modes of operation that require | 2515 | * this includes probe requests or modes of operation that require |
2513 | * beaconing. | 2516 | * beaconing. |
2517 | * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated | ||
2518 | * base on contiguous rules and wider channels will be allowed to cross | ||
2519 | * multiple contiguous/overlapping frequency ranges. | ||
2514 | */ | 2520 | */ |
2515 | enum nl80211_reg_rule_flags { | 2521 | enum nl80211_reg_rule_flags { |
2516 | NL80211_RRF_NO_OFDM = 1<<0, | 2522 | NL80211_RRF_NO_OFDM = 1<<0, |
@@ -2522,6 +2528,7 @@ enum nl80211_reg_rule_flags { | |||
2522 | NL80211_RRF_PTMP_ONLY = 1<<6, | 2528 | NL80211_RRF_PTMP_ONLY = 1<<6, |
2523 | NL80211_RRF_NO_IR = 1<<7, | 2529 | NL80211_RRF_NO_IR = 1<<7, |
2524 | __NL80211_RRF_NO_IBSS = 1<<8, | 2530 | __NL80211_RRF_NO_IBSS = 1<<8, |
2531 | NL80211_RRF_AUTO_BW = 1<<11, | ||
2525 | }; | 2532 | }; |
2526 | 2533 | ||
2527 | #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR | 2534 | #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR |
@@ -3843,11 +3850,6 @@ enum nl80211_ap_sme_features { | |||
3843 | * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested | 3850 | * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested |
3844 | * to work properly to suppport receiving regulatory hints from | 3851 | * to work properly to suppport receiving regulatory hints from |
3845 | * cellular base stations. | 3852 | * cellular base stations. |
3846 | * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: If this is set, an active | ||
3847 | * P2P Device (%NL80211_IFTYPE_P2P_DEVICE) requires its own channel | ||
3848 | * in the interface combinations, even when it's only used for scan | ||
3849 | * and remain-on-channel. This could be due to, for example, the | ||
3850 | * remain-on-channel implementation requiring a channel context. | ||
3851 | * @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of | 3853 | * @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of |
3852 | * equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station | 3854 | * equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station |
3853 | * mode | 3855 | * mode |
@@ -3889,7 +3891,7 @@ enum nl80211_feature_flags { | |||
3889 | NL80211_FEATURE_HT_IBSS = 1 << 1, | 3891 | NL80211_FEATURE_HT_IBSS = 1 << 1, |
3890 | NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, | 3892 | NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, |
3891 | NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, | 3893 | NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, |
3892 | NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4, | 3894 | /* bit 4 is reserved - don't use */ |
3893 | NL80211_FEATURE_SAE = 1 << 5, | 3895 | NL80211_FEATURE_SAE = 1 << 5, |
3894 | NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6, | 3896 | NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6, |
3895 | NL80211_FEATURE_SCAN_FLUSH = 1 << 7, | 3897 | NL80211_FEATURE_SCAN_FLUSH = 1 << 7, |
@@ -4079,4 +4081,20 @@ struct nl80211_vendor_cmd_info { | |||
4079 | __u32 subcmd; | 4081 | __u32 subcmd; |
4080 | }; | 4082 | }; |
4081 | 4083 | ||
4084 | /** | ||
4085 | * enum nl80211_tdls_peer_capability - TDLS peer flags. | ||
4086 | * | ||
4087 | * Used by tdls_mgmt() to determine which conditional elements need | ||
4088 | * to be added to TDLS Setup frames. | ||
4089 | * | ||
4090 | * @NL80211_TDLS_PEER_HT: TDLS peer is HT capable. | ||
4091 | * @NL80211_TDLS_PEER_VHT: TDLS peer is VHT capable. | ||
4092 | * @NL80211_TDLS_PEER_WMM: TDLS peer is WMM capable. | ||
4093 | */ | ||
4094 | enum nl80211_tdls_peer_capability { | ||
4095 | NL80211_TDLS_PEER_HT = 1<<0, | ||
4096 | NL80211_TDLS_PEER_VHT = 1<<1, | ||
4097 | NL80211_TDLS_PEER_WMM = 1<<2, | ||
4098 | }; | ||
4099 | |||
4082 | #endif /* __LINUX_NL80211_H */ | 4100 | #endif /* __LINUX_NL80211_H */ |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 363d19b5d5c8..1acb29109b45 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1347,9 +1347,6 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
1347 | params->vht_capa, sta); | 1347 | params->vht_capa, sta); |
1348 | 1348 | ||
1349 | if (params->opmode_notif_used) { | 1349 | if (params->opmode_notif_used) { |
1350 | enum ieee80211_band band = | ||
1351 | ieee80211_get_sdata_band(sdata); | ||
1352 | |||
1353 | /* returned value is only needed for rc update, but the | 1350 | /* returned value is only needed for rc update, but the |
1354 | * rc isn't initialized here yet, so ignore it | 1351 | * rc isn't initialized here yet, so ignore it |
1355 | */ | 1352 | */ |
@@ -3647,8 +3644,8 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, | |||
3647 | 3644 | ||
3648 | static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, | 3645 | static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, |
3649 | u8 *peer, u8 action_code, u8 dialog_token, | 3646 | u8 *peer, u8 action_code, u8 dialog_token, |
3650 | u16 status_code, const u8 *extra_ies, | 3647 | u16 status_code, u32 peer_capability, |
3651 | size_t extra_ies_len) | 3648 | const u8 *extra_ies, size_t extra_ies_len) |
3652 | { | 3649 | { |
3653 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3650 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3654 | struct ieee80211_local *local = sdata->local; | 3651 | struct ieee80211_local *local = sdata->local; |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index ebf80f3abd83..40a648938985 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -358,6 +358,18 @@ static ssize_t ieee80211_if_parse_tkip_mic_test( | |||
358 | } | 358 | } |
359 | IEEE80211_IF_FILE_W(tkip_mic_test); | 359 | IEEE80211_IF_FILE_W(tkip_mic_test); |
360 | 360 | ||
361 | static ssize_t ieee80211_if_parse_beacon_loss( | ||
362 | struct ieee80211_sub_if_data *sdata, const char *buf, int buflen) | ||
363 | { | ||
364 | if (!ieee80211_sdata_running(sdata) || !sdata->vif.bss_conf.assoc) | ||
365 | return -ENOTCONN; | ||
366 | |||
367 | ieee80211_beacon_loss(&sdata->vif); | ||
368 | |||
369 | return buflen; | ||
370 | } | ||
371 | IEEE80211_IF_FILE_W(beacon_loss); | ||
372 | |||
361 | static ssize_t ieee80211_if_fmt_uapsd_queues( | 373 | static ssize_t ieee80211_if_fmt_uapsd_queues( |
362 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) | 374 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) |
363 | { | 375 | { |
@@ -569,6 +581,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata) | |||
569 | DEBUGFS_ADD(beacon_timeout); | 581 | DEBUGFS_ADD(beacon_timeout); |
570 | DEBUGFS_ADD_MODE(smps, 0600); | 582 | DEBUGFS_ADD_MODE(smps, 0600); |
571 | DEBUGFS_ADD_MODE(tkip_mic_test, 0200); | 583 | DEBUGFS_ADD_MODE(tkip_mic_test, 0200); |
584 | DEBUGFS_ADD_MODE(beacon_loss, 0200); | ||
572 | DEBUGFS_ADD_MODE(uapsd_queues, 0600); | 585 | DEBUGFS_ADD_MODE(uapsd_queues, 0600); |
573 | DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600); | 586 | DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600); |
574 | } | 587 | } |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index ef8b385eff04..fc689f5d971e 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -354,16 +354,20 @@ drv_sched_scan_start(struct ieee80211_local *local, | |||
354 | return ret; | 354 | return ret; |
355 | } | 355 | } |
356 | 356 | ||
357 | static inline void drv_sched_scan_stop(struct ieee80211_local *local, | 357 | static inline int drv_sched_scan_stop(struct ieee80211_local *local, |
358 | struct ieee80211_sub_if_data *sdata) | 358 | struct ieee80211_sub_if_data *sdata) |
359 | { | 359 | { |
360 | int ret; | ||
361 | |||
360 | might_sleep(); | 362 | might_sleep(); |
361 | 363 | ||
362 | check_sdata_in_driver(sdata); | 364 | check_sdata_in_driver(sdata); |
363 | 365 | ||
364 | trace_drv_sched_scan_stop(local, sdata); | 366 | trace_drv_sched_scan_stop(local, sdata); |
365 | local->ops->sched_scan_stop(&local->hw, &sdata->vif); | 367 | ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif); |
366 | trace_drv_return_void(local); | 368 | trace_drv_return_int(local, ret); |
369 | |||
370 | return ret; | ||
367 | } | 371 | } |
368 | 372 | ||
369 | static inline void drv_sw_scan_start(struct ieee80211_local *local) | 373 | static inline void drv_sw_scan_start(struct ieee80211_local *local) |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index afbe2b203c3e..c150b68436d7 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -482,8 +482,6 @@ void ieee80211_request_smps(struct ieee80211_vif *vif, | |||
482 | return; | 482 | return; |
483 | 483 | ||
484 | if (vif->type == NL80211_IFTYPE_STATION) { | 484 | if (vif->type == NL80211_IFTYPE_STATION) { |
485 | if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF)) | ||
486 | smps_mode = IEEE80211_SMPS_AUTOMATIC; | ||
487 | if (sdata->u.mgd.driver_smps_mode == smps_mode) | 485 | if (sdata->u.mgd.driver_smps_mode == smps_mode) |
488 | return; | 486 | return; |
489 | sdata->u.mgd.driver_smps_mode = smps_mode; | 487 | sdata->u.mgd.driver_smps_mode = smps_mode; |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 4453e2725e40..e458ca0dffec 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -283,6 +283,11 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
283 | 283 | ||
284 | err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy, | 284 | err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy, |
285 | &chandef); | 285 | &chandef); |
286 | if (err < 0) { | ||
287 | sdata_info(sdata, | ||
288 | "Failed to join IBSS, invalid chandef\n"); | ||
289 | return; | ||
290 | } | ||
286 | if (err > 0) { | 291 | if (err > 0) { |
287 | if (!ifibss->userspace_handles_dfs) { | 292 | if (!ifibss->userspace_handles_dfs) { |
288 | sdata_info(sdata, | 293 | sdata_info(sdata, |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 0014b5396ce5..8603dfb52b3a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1242,6 +1242,8 @@ struct ieee80211_local { | |||
1242 | 1242 | ||
1243 | struct ieee80211_sub_if_data __rcu *p2p_sdata; | 1243 | struct ieee80211_sub_if_data __rcu *p2p_sdata; |
1244 | 1244 | ||
1245 | struct napi_struct *napi; | ||
1246 | |||
1245 | /* virtual monitor interface */ | 1247 | /* virtual monitor interface */ |
1246 | struct ieee80211_sub_if_data __rcu *monitor_sdata; | 1248 | struct ieee80211_sub_if_data __rcu *monitor_sdata; |
1247 | struct cfg80211_chan_def monitor_chandef; | 1249 | struct cfg80211_chan_def monitor_chandef; |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 96518ad200c4..be198f42f1f7 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -101,9 +101,8 @@ static u32 __ieee80211_idle_on(struct ieee80211_local *local) | |||
101 | static u32 __ieee80211_recalc_idle(struct ieee80211_local *local, | 101 | static u32 __ieee80211_recalc_idle(struct ieee80211_local *local, |
102 | bool force_active) | 102 | bool force_active) |
103 | { | 103 | { |
104 | bool working = false, scanning, active; | 104 | bool working, scanning, active; |
105 | unsigned int led_trig_start = 0, led_trig_stop = 0; | 105 | unsigned int led_trig_start = 0, led_trig_stop = 0; |
106 | struct ieee80211_roc_work *roc; | ||
107 | 106 | ||
108 | lockdep_assert_held(&local->mtx); | 107 | lockdep_assert_held(&local->mtx); |
109 | 108 | ||
@@ -111,12 +110,8 @@ static u32 __ieee80211_recalc_idle(struct ieee80211_local *local, | |||
111 | !list_empty(&local->chanctx_list) || | 110 | !list_empty(&local->chanctx_list) || |
112 | local->monitors; | 111 | local->monitors; |
113 | 112 | ||
114 | if (!local->ops->remain_on_channel) { | 113 | working = !local->ops->remain_on_channel && |
115 | list_for_each_entry(roc, &local->roc_list, list) { | 114 | !list_empty(&local->roc_list); |
116 | working = true; | ||
117 | break; | ||
118 | } | ||
119 | } | ||
120 | 115 | ||
121 | scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) || | 116 | scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) || |
122 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning); | 117 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 1f7d8422d62d..b055f6a55c68 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -1076,6 +1076,18 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1076 | } | 1076 | } |
1077 | EXPORT_SYMBOL(ieee80211_register_hw); | 1077 | EXPORT_SYMBOL(ieee80211_register_hw); |
1078 | 1078 | ||
1079 | void ieee80211_napi_add(struct ieee80211_hw *hw, struct napi_struct *napi, | ||
1080 | struct net_device *napi_dev, | ||
1081 | int (*poll)(struct napi_struct *, int), | ||
1082 | int weight) | ||
1083 | { | ||
1084 | struct ieee80211_local *local = hw_to_local(hw); | ||
1085 | |||
1086 | netif_napi_add(napi_dev, napi, poll, weight); | ||
1087 | local->napi = napi; | ||
1088 | } | ||
1089 | EXPORT_SYMBOL_GPL(ieee80211_napi_add); | ||
1090 | |||
1079 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) | 1091 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) |
1080 | { | 1092 | { |
1081 | struct ieee80211_local *local = hw_to_local(hw); | 1093 | struct ieee80211_local *local = hw_to_local(hw); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 61604834b914..46b62bb3677c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -131,13 +131,13 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata) | |||
131 | if (unlikely(!sdata->u.mgd.associated)) | 131 | if (unlikely(!sdata->u.mgd.associated)) |
132 | return; | 132 | return; |
133 | 133 | ||
134 | ifmgd->probe_send_count = 0; | ||
135 | |||
134 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | 136 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) |
135 | return; | 137 | return; |
136 | 138 | ||
137 | mod_timer(&sdata->u.mgd.conn_mon_timer, | 139 | mod_timer(&sdata->u.mgd.conn_mon_timer, |
138 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); | 140 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); |
139 | |||
140 | ifmgd->probe_send_count = 0; | ||
141 | } | 141 | } |
142 | 142 | ||
143 | static int ecw2cw(int ecw) | 143 | static int ecw2cw(int ecw) |
@@ -2249,6 +2249,62 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
2249 | /* ignore frame -- wait for timeout */ | 2249 | /* ignore frame -- wait for timeout */ |
2250 | } | 2250 | } |
2251 | 2251 | ||
2252 | #define case_WLAN(type) \ | ||
2253 | case WLAN_REASON_##type: return #type | ||
2254 | |||
2255 | static const char *ieee80211_get_reason_code_string(u16 reason_code) | ||
2256 | { | ||
2257 | switch (reason_code) { | ||
2258 | case_WLAN(UNSPECIFIED); | ||
2259 | case_WLAN(PREV_AUTH_NOT_VALID); | ||
2260 | case_WLAN(DEAUTH_LEAVING); | ||
2261 | case_WLAN(DISASSOC_DUE_TO_INACTIVITY); | ||
2262 | case_WLAN(DISASSOC_AP_BUSY); | ||
2263 | case_WLAN(CLASS2_FRAME_FROM_NONAUTH_STA); | ||
2264 | case_WLAN(CLASS3_FRAME_FROM_NONASSOC_STA); | ||
2265 | case_WLAN(DISASSOC_STA_HAS_LEFT); | ||
2266 | case_WLAN(STA_REQ_ASSOC_WITHOUT_AUTH); | ||
2267 | case_WLAN(DISASSOC_BAD_POWER); | ||
2268 | case_WLAN(DISASSOC_BAD_SUPP_CHAN); | ||
2269 | case_WLAN(INVALID_IE); | ||
2270 | case_WLAN(MIC_FAILURE); | ||
2271 | case_WLAN(4WAY_HANDSHAKE_TIMEOUT); | ||
2272 | case_WLAN(GROUP_KEY_HANDSHAKE_TIMEOUT); | ||
2273 | case_WLAN(IE_DIFFERENT); | ||
2274 | case_WLAN(INVALID_GROUP_CIPHER); | ||
2275 | case_WLAN(INVALID_PAIRWISE_CIPHER); | ||
2276 | case_WLAN(INVALID_AKMP); | ||
2277 | case_WLAN(UNSUPP_RSN_VERSION); | ||
2278 | case_WLAN(INVALID_RSN_IE_CAP); | ||
2279 | case_WLAN(IEEE8021X_FAILED); | ||
2280 | case_WLAN(CIPHER_SUITE_REJECTED); | ||
2281 | case_WLAN(DISASSOC_UNSPECIFIED_QOS); | ||
2282 | case_WLAN(DISASSOC_QAP_NO_BANDWIDTH); | ||
2283 | case_WLAN(DISASSOC_LOW_ACK); | ||
2284 | case_WLAN(DISASSOC_QAP_EXCEED_TXOP); | ||
2285 | case_WLAN(QSTA_LEAVE_QBSS); | ||
2286 | case_WLAN(QSTA_NOT_USE); | ||
2287 | case_WLAN(QSTA_REQUIRE_SETUP); | ||
2288 | case_WLAN(QSTA_TIMEOUT); | ||
2289 | case_WLAN(QSTA_CIPHER_NOT_SUPP); | ||
2290 | case_WLAN(MESH_PEER_CANCELED); | ||
2291 | case_WLAN(MESH_MAX_PEERS); | ||
2292 | case_WLAN(MESH_CONFIG); | ||
2293 | case_WLAN(MESH_CLOSE); | ||
2294 | case_WLAN(MESH_MAX_RETRIES); | ||
2295 | case_WLAN(MESH_CONFIRM_TIMEOUT); | ||
2296 | case_WLAN(MESH_INVALID_GTK); | ||
2297 | case_WLAN(MESH_INCONSISTENT_PARAM); | ||
2298 | case_WLAN(MESH_INVALID_SECURITY); | ||
2299 | case_WLAN(MESH_PATH_ERROR); | ||
2300 | case_WLAN(MESH_PATH_NOFORWARD); | ||
2301 | case_WLAN(MESH_PATH_DEST_UNREACHABLE); | ||
2302 | case_WLAN(MAC_EXISTS_IN_MBSS); | ||
2303 | case_WLAN(MESH_CHAN_REGULATORY); | ||
2304 | case_WLAN(MESH_CHAN); | ||
2305 | default: return "<unknown>"; | ||
2306 | } | ||
2307 | } | ||
2252 | 2308 | ||
2253 | static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | 2309 | static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, |
2254 | struct ieee80211_mgmt *mgmt, size_t len) | 2310 | struct ieee80211_mgmt *mgmt, size_t len) |
@@ -2270,8 +2326,8 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
2270 | 2326 | ||
2271 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); | 2327 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); |
2272 | 2328 | ||
2273 | sdata_info(sdata, "deauthenticated from %pM (Reason: %u)\n", | 2329 | sdata_info(sdata, "deauthenticated from %pM (Reason: %u=%s)\n", |
2274 | bssid, reason_code); | 2330 | bssid, reason_code, ieee80211_get_reason_code_string(reason_code)); |
2275 | 2331 | ||
2276 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 2332 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
2277 | 2333 | ||
@@ -4340,8 +4396,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
4340 | bool report_frame = false; | 4396 | bool report_frame = false; |
4341 | 4397 | ||
4342 | sdata_info(sdata, | 4398 | sdata_info(sdata, |
4343 | "deauthenticating from %pM by local choice (reason=%d)\n", | 4399 | "deauthenticating from %pM by local choice (Reason: %u=%s)\n", |
4344 | req->bssid, req->reason_code); | 4400 | req->bssid, req->reason_code, ieee80211_get_reason_code_string(req->reason_code)); |
4345 | 4401 | ||
4346 | if (ifmgd->auth_data) { | 4402 | if (ifmgd->auth_data) { |
4347 | drv_mgd_prepare_tx(sdata->local, sdata); | 4403 | drv_mgd_prepare_tx(sdata->local, sdata); |
@@ -4387,8 +4443,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
4387 | return -ENOLINK; | 4443 | return -ENOLINK; |
4388 | 4444 | ||
4389 | sdata_info(sdata, | 4445 | sdata_info(sdata, |
4390 | "disassociating from %pM by local choice (reason=%d)\n", | 4446 | "disassociating from %pM by local choice (Reason: %u=%s)\n", |
4391 | req->bss->bssid, req->reason_code); | 4447 | req->bss->bssid, req->reason_code, ieee80211_get_reason_code_string(req->reason_code)); |
4392 | 4448 | ||
4393 | memcpy(bssid, req->bss->bssid, ETH_ALEN); | 4449 | memcpy(bssid, req->bss->bssid, ETH_ALEN); |
4394 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, | 4450 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 593062109c50..58e4b7052d17 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1954,7 +1954,10 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1954 | /* deliver to local stack */ | 1954 | /* deliver to local stack */ |
1955 | skb->protocol = eth_type_trans(skb, dev); | 1955 | skb->protocol = eth_type_trans(skb, dev); |
1956 | memset(skb->cb, 0, sizeof(skb->cb)); | 1956 | memset(skb->cb, 0, sizeof(skb->cb)); |
1957 | netif_receive_skb(skb); | 1957 | if (rx->local->napi) |
1958 | napi_gro_receive(rx->local->napi, skb); | ||
1959 | else | ||
1960 | netif_receive_skb(skb); | ||
1958 | } | 1961 | } |
1959 | 1962 | ||
1960 | if (xmit_skb) { | 1963 | if (xmit_skb) { |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 88c81616f8f7..836f500dfbf3 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -472,9 +472,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
472 | if (local->ops->hw_scan) { | 472 | if (local->ops->hw_scan) { |
473 | u8 *ies; | 473 | u8 *ies; |
474 | 474 | ||
475 | local->hw_scan_ies_bufsize = 2 + IEEE80211_MAX_SSID_LEN + | 475 | local->hw_scan_ies_bufsize = local->scan_ies_len + req->ie_len; |
476 | local->scan_ies_len + | ||
477 | req->ie_len; | ||
478 | local->hw_scan_req = kmalloc( | 476 | local->hw_scan_req = kmalloc( |
479 | sizeof(*local->hw_scan_req) + | 477 | sizeof(*local->hw_scan_req) + |
480 | req->n_channels * sizeof(req->channels[0]) + | 478 | req->n_channels * sizeof(req->channels[0]) + |
@@ -979,8 +977,7 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
979 | struct cfg80211_chan_def chandef; | 977 | struct cfg80211_chan_def chandef; |
980 | int ret, i, iebufsz; | 978 | int ret, i, iebufsz; |
981 | 979 | ||
982 | iebufsz = 2 + IEEE80211_MAX_SSID_LEN + | 980 | iebufsz = local->scan_ies_len + req->ie_len; |
983 | local->scan_ies_len + req->ie_len; | ||
984 | 981 | ||
985 | lockdep_assert_held(&local->mtx); | 982 | lockdep_assert_held(&local->mtx); |
986 | 983 | ||
@@ -1059,7 +1056,7 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata) | |||
1059 | local->sched_scan_req = NULL; | 1056 | local->sched_scan_req = NULL; |
1060 | 1057 | ||
1061 | if (rcu_access_pointer(local->sched_scan_sdata)) | 1058 | if (rcu_access_pointer(local->sched_scan_sdata)) |
1062 | drv_sched_scan_stop(local, sdata); | 1059 | ret = drv_sched_scan_stop(local, sdata); |
1063 | 1060 | ||
1064 | out: | 1061 | out: |
1065 | mutex_unlock(&local->mtx); | 1062 | mutex_unlock(&local->mtx); |
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index f8ab7df1ab0d..5946450c5406 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -705,12 +705,8 @@ cfg80211_get_chan_state(struct wireless_dev *wdev, | |||
705 | case NL80211_IFTYPE_MONITOR: | 705 | case NL80211_IFTYPE_MONITOR: |
706 | case NL80211_IFTYPE_AP_VLAN: | 706 | case NL80211_IFTYPE_AP_VLAN: |
707 | case NL80211_IFTYPE_WDS: | 707 | case NL80211_IFTYPE_WDS: |
708 | /* these interface types don't really have a channel */ | ||
709 | return; | ||
710 | case NL80211_IFTYPE_P2P_DEVICE: | 708 | case NL80211_IFTYPE_P2P_DEVICE: |
711 | if (wdev->wiphy->features & | 709 | /* these interface types don't really have a channel */ |
712 | NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL) | ||
713 | *chanmode = CHAN_MODE_EXCLUSIVE; | ||
714 | return; | 710 | return; |
715 | case NL80211_IFTYPE_UNSPECIFIED: | 711 | case NL80211_IFTYPE_UNSPECIFIED: |
716 | case NUM_NL80211_IFTYPES: | 712 | case NUM_NL80211_IFTYPES: |
diff --git a/net/wireless/genregdb.awk b/net/wireless/genregdb.awk index 9a8217d2a908..fdfd3f063a9b 100644 --- a/net/wireless/genregdb.awk +++ b/net/wireless/genregdb.awk | |||
@@ -105,6 +105,8 @@ function parse_reg_rule() | |||
105 | flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " | 105 | flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " |
106 | } else if (flagarray[arg] == "NO-IR") { | 106 | } else if (flagarray[arg] == "NO-IR") { |
107 | flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " | 107 | flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " |
108 | } else if (flagarray[arg] == "AUTO-BW") { | ||
109 | flags = flags "\n\t\t\tNL80211_RRF_AUTO_BW | " | ||
108 | } | 110 | } |
109 | 111 | ||
110 | } | 112 | } |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 1470b90e438f..349db9ddc0d1 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -128,12 +128,11 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
128 | #endif | 128 | #endif |
129 | check_chan = params->chandef.chan; | 129 | check_chan = params->chandef.chan; |
130 | if (params->userspace_handles_dfs) { | 130 | if (params->userspace_handles_dfs) { |
131 | /* use channel NULL to check for radar even if the current | 131 | /* Check for radar even if the current channel is not |
132 | * channel is not a radar channel - it might decide to change | 132 | * a radar channel - it might decide to change to DFS |
133 | * to DFS channel later. | 133 | * channel later. |
134 | */ | 134 | */ |
135 | radar_detect_width = BIT(params->chandef.width); | 135 | radar_detect_width = BIT(params->chandef.width); |
136 | check_chan = NULL; | ||
137 | } | 136 | } |
138 | 137 | ||
139 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, | 138 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, |
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index d42a3fcb2f67..5af5cc6b2c4c 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c | |||
@@ -236,6 +236,12 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, | |||
236 | if (!netif_running(wdev->netdev)) | 236 | if (!netif_running(wdev->netdev)) |
237 | return -ENETDOWN; | 237 | return -ENETDOWN; |
238 | 238 | ||
239 | /* cfg80211_can_use_chan() calls | ||
240 | * cfg80211_can_use_iftype_chan() with no radar | ||
241 | * detection, so if we're trying to use a radar | ||
242 | * channel here, something is wrong. | ||
243 | */ | ||
244 | WARN_ON_ONCE(chandef->chan->flags & IEEE80211_CHAN_RADAR); | ||
239 | err = cfg80211_can_use_chan(rdev, wdev, chandef->chan, | 245 | err = cfg80211_can_use_chan(rdev, wdev, chandef->chan, |
240 | CHAN_MODE_SHARED); | 246 | CHAN_MODE_SHARED); |
241 | if (err) | 247 | if (err) |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8e6b6a2d35cb..2c38b28a85b9 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -384,6 +384,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
384 | .len = IEEE80211_QOS_MAP_LEN_MAX }, | 384 | .len = IEEE80211_QOS_MAP_LEN_MAX }, |
385 | [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN }, | 385 | [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN }, |
386 | [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, | 386 | [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, |
387 | [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, | ||
387 | }; | 388 | }; |
388 | 389 | ||
389 | /* policy for the key attributes */ | 390 | /* policy for the key attributes */ |
@@ -4627,6 +4628,8 @@ static int parse_reg_rule(struct nlattr *tb[], | |||
4627 | return -EINVAL; | 4628 | return -EINVAL; |
4628 | if (!tb[NL80211_ATTR_FREQ_RANGE_END]) | 4629 | if (!tb[NL80211_ATTR_FREQ_RANGE_END]) |
4629 | return -EINVAL; | 4630 | return -EINVAL; |
4631 | if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) | ||
4632 | return -EINVAL; | ||
4630 | if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]) | 4633 | if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]) |
4631 | return -EINVAL; | 4634 | return -EINVAL; |
4632 | 4635 | ||
@@ -4636,9 +4639,8 @@ static int parse_reg_rule(struct nlattr *tb[], | |||
4636 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]); | 4639 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]); |
4637 | freq_range->end_freq_khz = | 4640 | freq_range->end_freq_khz = |
4638 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]); | 4641 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]); |
4639 | if (tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) | 4642 | freq_range->max_bandwidth_khz = |
4640 | freq_range->max_bandwidth_khz = | 4643 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]); |
4641 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]); | ||
4642 | 4644 | ||
4643 | power_rule->max_eirp = | 4645 | power_rule->max_eirp = |
4644 | nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]); | 4646 | nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]); |
@@ -5710,8 +5712,8 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
5710 | request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF; | 5712 | request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF; |
5711 | } | 5713 | } |
5712 | 5714 | ||
5713 | if (info->attrs[NL80211_ATTR_IE]) { | 5715 | if (ie_len) { |
5714 | request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 5716 | request->ie_len = ie_len; |
5715 | memcpy((void *)request->ie, | 5717 | memcpy((void *)request->ie, |
5716 | nla_data(info->attrs[NL80211_ATTR_IE]), | 5718 | nla_data(info->attrs[NL80211_ATTR_IE]), |
5717 | request->ie_len); | 5719 | request->ie_len); |
@@ -5911,17 +5913,22 @@ skip_beacons: | |||
5911 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef)) | 5913 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef)) |
5912 | return -EINVAL; | 5914 | return -EINVAL; |
5913 | 5915 | ||
5914 | if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP || | 5916 | switch (dev->ieee80211_ptr->iftype) { |
5915 | dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO || | 5917 | case NL80211_IFTYPE_AP: |
5916 | dev->ieee80211_ptr->iftype == NL80211_IFTYPE_ADHOC) { | 5918 | case NL80211_IFTYPE_P2P_GO: |
5919 | case NL80211_IFTYPE_ADHOC: | ||
5920 | case NL80211_IFTYPE_MESH_POINT: | ||
5917 | err = cfg80211_chandef_dfs_required(wdev->wiphy, | 5921 | err = cfg80211_chandef_dfs_required(wdev->wiphy, |
5918 | ¶ms.chandef); | 5922 | ¶ms.chandef); |
5919 | if (err < 0) { | 5923 | if (err < 0) |
5920 | return err; | 5924 | return err; |
5921 | } else if (err) { | 5925 | if (err) { |
5922 | radar_detect_width = BIT(params.chandef.width); | 5926 | radar_detect_width = BIT(params.chandef.width); |
5923 | params.radar_required = true; | 5927 | params.radar_required = true; |
5924 | } | 5928 | } |
5929 | break; | ||
5930 | default: | ||
5931 | break; | ||
5925 | } | 5932 | } |
5926 | 5933 | ||
5927 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, | 5934 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, |
@@ -7269,6 +7276,7 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
7269 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 7276 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
7270 | struct net_device *dev = info->user_ptr[1]; | 7277 | struct net_device *dev = info->user_ptr[1]; |
7271 | u8 action_code, dialog_token; | 7278 | u8 action_code, dialog_token; |
7279 | u32 peer_capability = 0; | ||
7272 | u16 status_code; | 7280 | u16 status_code; |
7273 | u8 *peer; | 7281 | u8 *peer; |
7274 | 7282 | ||
@@ -7287,9 +7295,12 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
7287 | action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]); | 7295 | action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]); |
7288 | status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]); | 7296 | status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]); |
7289 | dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]); | 7297 | dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]); |
7298 | if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]) | ||
7299 | peer_capability = | ||
7300 | nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]); | ||
7290 | 7301 | ||
7291 | return rdev_tdls_mgmt(rdev, dev, peer, action_code, | 7302 | return rdev_tdls_mgmt(rdev, dev, peer, action_code, |
7292 | dialog_token, status_code, | 7303 | dialog_token, status_code, peer_capability, |
7293 | nla_data(info->attrs[NL80211_ATTR_IE]), | 7304 | nla_data(info->attrs[NL80211_ATTR_IE]), |
7294 | nla_len(info->attrs[NL80211_ATTR_IE])); | 7305 | nla_len(info->attrs[NL80211_ATTR_IE])); |
7295 | } | 7306 | } |
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index c8e225947adb..74d97d33c938 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
@@ -769,13 +769,16 @@ static inline int rdev_set_rekey_data(struct cfg80211_registered_device *rdev, | |||
769 | static inline int rdev_tdls_mgmt(struct cfg80211_registered_device *rdev, | 769 | static inline int rdev_tdls_mgmt(struct cfg80211_registered_device *rdev, |
770 | struct net_device *dev, u8 *peer, | 770 | struct net_device *dev, u8 *peer, |
771 | u8 action_code, u8 dialog_token, | 771 | u8 action_code, u8 dialog_token, |
772 | u16 status_code, const u8 *buf, size_t len) | 772 | u16 status_code, u32 peer_capability, |
773 | const u8 *buf, size_t len) | ||
773 | { | 774 | { |
774 | int ret; | 775 | int ret; |
775 | trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code, | 776 | trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code, |
776 | dialog_token, status_code, buf, len); | 777 | dialog_token, status_code, peer_capability, |
778 | buf, len); | ||
777 | ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code, | 779 | ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code, |
778 | dialog_token, status_code, buf, len); | 780 | dialog_token, status_code, peer_capability, |
781 | buf, len); | ||
779 | trace_rdev_return_int(&rdev->wiphy, ret); | 782 | trace_rdev_return_int(&rdev->wiphy, ret); |
780 | return ret; | 783 | return ret; |
781 | } | 784 | } |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 27c5253e7a61..6b6f33ad78f2 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -563,9 +563,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd, | |||
563 | if (freq_range_tmp->end_freq_khz < freq_range->start_freq_khz) | 563 | if (freq_range_tmp->end_freq_khz < freq_range->start_freq_khz) |
564 | break; | 564 | break; |
565 | 565 | ||
566 | if (freq_range_tmp->max_bandwidth_khz) | ||
567 | break; | ||
568 | |||
569 | freq_range = freq_range_tmp; | 566 | freq_range = freq_range_tmp; |
570 | } | 567 | } |
571 | 568 | ||
@@ -582,9 +579,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd, | |||
582 | if (freq_range_tmp->start_freq_khz > freq_range->end_freq_khz) | 579 | if (freq_range_tmp->start_freq_khz > freq_range->end_freq_khz) |
583 | break; | 580 | break; |
584 | 581 | ||
585 | if (freq_range_tmp->max_bandwidth_khz) | ||
586 | break; | ||
587 | |||
588 | freq_range = freq_range_tmp; | 582 | freq_range = freq_range_tmp; |
589 | } | 583 | } |
590 | 584 | ||
@@ -729,21 +723,29 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, | |||
729 | max_bandwidth1 = freq_range1->max_bandwidth_khz; | 723 | max_bandwidth1 = freq_range1->max_bandwidth_khz; |
730 | max_bandwidth2 = freq_range2->max_bandwidth_khz; | 724 | max_bandwidth2 = freq_range2->max_bandwidth_khz; |
731 | 725 | ||
732 | /* | 726 | if (rule1->flags & NL80211_RRF_AUTO_BW) |
733 | * In case max_bandwidth1 == 0 and max_bandwith2 == 0 set | 727 | max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1); |
734 | * output bandwidth as 0 (auto calculation). Next we will | 728 | if (rule2->flags & NL80211_RRF_AUTO_BW) |
735 | * calculate this correctly in handle_channel function. | 729 | max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2); |
736 | * In other case calculate output bandwidth here. | ||
737 | */ | ||
738 | if (max_bandwidth1 || max_bandwidth2) { | ||
739 | if (!max_bandwidth1) | ||
740 | max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1); | ||
741 | if (!max_bandwidth2) | ||
742 | max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2); | ||
743 | } | ||
744 | 730 | ||
745 | freq_range->max_bandwidth_khz = min(max_bandwidth1, max_bandwidth2); | 731 | freq_range->max_bandwidth_khz = min(max_bandwidth1, max_bandwidth2); |
746 | 732 | ||
733 | intersected_rule->flags = rule1->flags | rule2->flags; | ||
734 | |||
735 | /* | ||
736 | * In case NL80211_RRF_AUTO_BW requested for both rules | ||
737 | * set AUTO_BW in intersected rule also. Next we will | ||
738 | * calculate BW correctly in handle_channel function. | ||
739 | * In other case remove AUTO_BW flag while we calculate | ||
740 | * maximum bandwidth correctly and auto calculation is | ||
741 | * not required. | ||
742 | */ | ||
743 | if ((rule1->flags & NL80211_RRF_AUTO_BW) && | ||
744 | (rule2->flags & NL80211_RRF_AUTO_BW)) | ||
745 | intersected_rule->flags |= NL80211_RRF_AUTO_BW; | ||
746 | else | ||
747 | intersected_rule->flags &= ~NL80211_RRF_AUTO_BW; | ||
748 | |||
747 | freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz; | 749 | freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz; |
748 | if (freq_range->max_bandwidth_khz > freq_diff) | 750 | if (freq_range->max_bandwidth_khz > freq_diff) |
749 | freq_range->max_bandwidth_khz = freq_diff; | 751 | freq_range->max_bandwidth_khz = freq_diff; |
@@ -753,8 +755,6 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, | |||
753 | power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain, | 755 | power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain, |
754 | power_rule2->max_antenna_gain); | 756 | power_rule2->max_antenna_gain); |
755 | 757 | ||
756 | intersected_rule->flags = rule1->flags | rule2->flags; | ||
757 | |||
758 | if (!is_valid_reg_rule(intersected_rule)) | 758 | if (!is_valid_reg_rule(intersected_rule)) |
759 | return -EINVAL; | 759 | return -EINVAL; |
760 | 760 | ||
@@ -938,31 +938,42 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator) | |||
938 | EXPORT_SYMBOL(reg_initiator_name); | 938 | EXPORT_SYMBOL(reg_initiator_name); |
939 | 939 | ||
940 | #ifdef CONFIG_CFG80211_REG_DEBUG | 940 | #ifdef CONFIG_CFG80211_REG_DEBUG |
941 | static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, | 941 | static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd, |
942 | struct ieee80211_channel *chan, | ||
942 | const struct ieee80211_reg_rule *reg_rule) | 943 | const struct ieee80211_reg_rule *reg_rule) |
943 | { | 944 | { |
944 | const struct ieee80211_power_rule *power_rule; | 945 | const struct ieee80211_power_rule *power_rule; |
945 | const struct ieee80211_freq_range *freq_range; | 946 | const struct ieee80211_freq_range *freq_range; |
946 | char max_antenna_gain[32]; | 947 | char max_antenna_gain[32], bw[32]; |
947 | 948 | ||
948 | power_rule = ®_rule->power_rule; | 949 | power_rule = ®_rule->power_rule; |
949 | freq_range = ®_rule->freq_range; | 950 | freq_range = ®_rule->freq_range; |
950 | 951 | ||
951 | if (!power_rule->max_antenna_gain) | 952 | if (!power_rule->max_antenna_gain) |
952 | snprintf(max_antenna_gain, 32, "N/A"); | 953 | snprintf(max_antenna_gain, sizeof(max_antenna_gain), "N/A"); |
953 | else | 954 | else |
954 | snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain); | 955 | snprintf(max_antenna_gain, sizeof(max_antenna_gain), "%d", |
956 | power_rule->max_antenna_gain); | ||
957 | |||
958 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) | ||
959 | snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO", | ||
960 | freq_range->max_bandwidth_khz, | ||
961 | reg_get_max_bandwidth(regd, reg_rule)); | ||
962 | else | ||
963 | snprintf(bw, sizeof(bw), "%d KHz", | ||
964 | freq_range->max_bandwidth_khz); | ||
955 | 965 | ||
956 | REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n", | 966 | REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n", |
957 | chan->center_freq); | 967 | chan->center_freq); |
958 | 968 | ||
959 | REG_DBG_PRINT("%d KHz - %d KHz @ %d KHz), (%s mBi, %d mBm)\n", | 969 | REG_DBG_PRINT("%d KHz - %d KHz @ %s), (%s mBi, %d mBm)\n", |
960 | freq_range->start_freq_khz, freq_range->end_freq_khz, | 970 | freq_range->start_freq_khz, freq_range->end_freq_khz, |
961 | freq_range->max_bandwidth_khz, max_antenna_gain, | 971 | bw, max_antenna_gain, |
962 | power_rule->max_eirp); | 972 | power_rule->max_eirp); |
963 | } | 973 | } |
964 | #else | 974 | #else |
965 | static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, | 975 | static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd, |
976 | struct ieee80211_channel *chan, | ||
966 | const struct ieee80211_reg_rule *reg_rule) | 977 | const struct ieee80211_reg_rule *reg_rule) |
967 | { | 978 | { |
968 | return; | 979 | return; |
@@ -1022,17 +1033,16 @@ static void handle_channel(struct wiphy *wiphy, | |||
1022 | return; | 1033 | return; |
1023 | } | 1034 | } |
1024 | 1035 | ||
1025 | chan_reg_rule_print_dbg(chan, reg_rule); | 1036 | regd = reg_get_regdomain(wiphy); |
1037 | chan_reg_rule_print_dbg(regd, chan, reg_rule); | ||
1026 | 1038 | ||
1027 | power_rule = ®_rule->power_rule; | 1039 | power_rule = ®_rule->power_rule; |
1028 | freq_range = ®_rule->freq_range; | 1040 | freq_range = ®_rule->freq_range; |
1029 | 1041 | ||
1030 | max_bandwidth_khz = freq_range->max_bandwidth_khz; | 1042 | max_bandwidth_khz = freq_range->max_bandwidth_khz; |
1031 | /* Check if auto calculation requested */ | 1043 | /* Check if auto calculation requested */ |
1032 | if (!max_bandwidth_khz) { | 1044 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) |
1033 | regd = reg_get_regdomain(wiphy); | ||
1034 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); | 1045 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); |
1035 | } | ||
1036 | 1046 | ||
1037 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) | 1047 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) |
1038 | bw_flags = IEEE80211_CHAN_NO_HT40; | 1048 | bw_flags = IEEE80211_CHAN_NO_HT40; |
@@ -1437,14 +1447,14 @@ static void handle_channel_custom(struct wiphy *wiphy, | |||
1437 | return; | 1447 | return; |
1438 | } | 1448 | } |
1439 | 1449 | ||
1440 | chan_reg_rule_print_dbg(chan, reg_rule); | 1450 | chan_reg_rule_print_dbg(regd, chan, reg_rule); |
1441 | 1451 | ||
1442 | power_rule = ®_rule->power_rule; | 1452 | power_rule = ®_rule->power_rule; |
1443 | freq_range = ®_rule->freq_range; | 1453 | freq_range = ®_rule->freq_range; |
1444 | 1454 | ||
1445 | max_bandwidth_khz = freq_range->max_bandwidth_khz; | 1455 | max_bandwidth_khz = freq_range->max_bandwidth_khz; |
1446 | /* Check if auto calculation requested */ | 1456 | /* Check if auto calculation requested */ |
1447 | if (!max_bandwidth_khz) | 1457 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) |
1448 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); | 1458 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); |
1449 | 1459 | ||
1450 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) | 1460 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) |
@@ -2254,11 +2264,12 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd) | |||
2254 | freq_range = ®_rule->freq_range; | 2264 | freq_range = ®_rule->freq_range; |
2255 | power_rule = ®_rule->power_rule; | 2265 | power_rule = ®_rule->power_rule; |
2256 | 2266 | ||
2257 | if (!freq_range->max_bandwidth_khz) | 2267 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) |
2258 | snprintf(bw, 32, "%d KHz, AUTO", | 2268 | snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO", |
2269 | freq_range->max_bandwidth_khz, | ||
2259 | reg_get_max_bandwidth(rd, reg_rule)); | 2270 | reg_get_max_bandwidth(rd, reg_rule)); |
2260 | else | 2271 | else |
2261 | snprintf(bw, 32, "%d KHz", | 2272 | snprintf(bw, sizeof(bw), "%d KHz", |
2262 | freq_range->max_bandwidth_khz); | 2273 | freq_range->max_bandwidth_khz); |
2263 | 2274 | ||
2264 | /* | 2275 | /* |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 5eaeed59db07..aabccf13e07b 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -1468,9 +1468,10 @@ TRACE_EVENT(rdev_sched_scan_start, | |||
1468 | TRACE_EVENT(rdev_tdls_mgmt, | 1468 | TRACE_EVENT(rdev_tdls_mgmt, |
1469 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | 1469 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, |
1470 | u8 *peer, u8 action_code, u8 dialog_token, | 1470 | u8 *peer, u8 action_code, u8 dialog_token, |
1471 | u16 status_code, const u8 *buf, size_t len), | 1471 | u16 status_code, u32 peer_capability, |
1472 | const u8 *buf, size_t len), | ||
1472 | TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code, | 1473 | TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code, |
1473 | buf, len), | 1474 | peer_capability, buf, len), |
1474 | TP_STRUCT__entry( | 1475 | TP_STRUCT__entry( |
1475 | WIPHY_ENTRY | 1476 | WIPHY_ENTRY |
1476 | NETDEV_ENTRY | 1477 | NETDEV_ENTRY |
@@ -1478,6 +1479,7 @@ TRACE_EVENT(rdev_tdls_mgmt, | |||
1478 | __field(u8, action_code) | 1479 | __field(u8, action_code) |
1479 | __field(u8, dialog_token) | 1480 | __field(u8, dialog_token) |
1480 | __field(u16, status_code) | 1481 | __field(u16, status_code) |
1482 | __field(u32, peer_capability) | ||
1481 | __dynamic_array(u8, buf, len) | 1483 | __dynamic_array(u8, buf, len) |
1482 | ), | 1484 | ), |
1483 | TP_fast_assign( | 1485 | TP_fast_assign( |
@@ -1487,13 +1489,15 @@ TRACE_EVENT(rdev_tdls_mgmt, | |||
1487 | __entry->action_code = action_code; | 1489 | __entry->action_code = action_code; |
1488 | __entry->dialog_token = dialog_token; | 1490 | __entry->dialog_token = dialog_token; |
1489 | __entry->status_code = status_code; | 1491 | __entry->status_code = status_code; |
1492 | __entry->peer_capability = peer_capability; | ||
1490 | memcpy(__get_dynamic_array(buf), buf, len); | 1493 | memcpy(__get_dynamic_array(buf), buf, len); |
1491 | ), | 1494 | ), |
1492 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, " | 1495 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, " |
1493 | "dialog_token: %u, status_code: %u, buf: %#.2x ", | 1496 | "dialog_token: %u, status_code: %u, peer_capability: %u buf: %#.2x ", |
1494 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), | 1497 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), |
1495 | __entry->action_code, __entry->dialog_token, | 1498 | __entry->action_code, __entry->dialog_token, |
1496 | __entry->status_code, ((u8 *)__get_dynamic_array(buf))[0]) | 1499 | __entry->status_code, __entry->peer_capability, |
1500 | ((u8 *)__get_dynamic_array(buf))[0]) | ||
1497 | ); | 1501 | ); |
1498 | 1502 | ||
1499 | TRACE_EVENT(rdev_dump_survey, | 1503 | TRACE_EVENT(rdev_dump_survey, |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 780b4546c9c7..57b3ce7a6b92 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -1269,7 +1269,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | |||
1269 | enum cfg80211_chan_mode chmode; | 1269 | enum cfg80211_chan_mode chmode; |
1270 | int num_different_channels = 0; | 1270 | int num_different_channels = 0; |
1271 | int total = 1; | 1271 | int total = 1; |
1272 | bool radar_required = false; | ||
1273 | int i, j; | 1272 | int i, j; |
1274 | 1273 | ||
1275 | ASSERT_RTNL(); | 1274 | ASSERT_RTNL(); |
@@ -1277,35 +1276,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | |||
1277 | if (WARN_ON(hweight32(radar_detect) > 1)) | 1276 | if (WARN_ON(hweight32(radar_detect) > 1)) |
1278 | return -EINVAL; | 1277 | return -EINVAL; |
1279 | 1278 | ||
1280 | switch (iftype) { | 1279 | if (WARN_ON(iftype >= NUM_NL80211_IFTYPES)) |
1281 | case NL80211_IFTYPE_ADHOC: | ||
1282 | case NL80211_IFTYPE_AP: | ||
1283 | case NL80211_IFTYPE_AP_VLAN: | ||
1284 | case NL80211_IFTYPE_MESH_POINT: | ||
1285 | case NL80211_IFTYPE_P2P_GO: | ||
1286 | case NL80211_IFTYPE_WDS: | ||
1287 | /* if the interface could potentially choose a DFS channel, | ||
1288 | * then mark DFS as required. | ||
1289 | */ | ||
1290 | if (!chan) { | ||
1291 | if (chanmode != CHAN_MODE_UNDEFINED && radar_detect) | ||
1292 | radar_required = true; | ||
1293 | break; | ||
1294 | } | ||
1295 | radar_required = !!(chan->flags & IEEE80211_CHAN_RADAR); | ||
1296 | break; | ||
1297 | case NL80211_IFTYPE_P2P_CLIENT: | ||
1298 | case NL80211_IFTYPE_STATION: | ||
1299 | case NL80211_IFTYPE_P2P_DEVICE: | ||
1300 | case NL80211_IFTYPE_MONITOR: | ||
1301 | break; | ||
1302 | case NUM_NL80211_IFTYPES: | ||
1303 | case NL80211_IFTYPE_UNSPECIFIED: | ||
1304 | default: | ||
1305 | return -EINVAL; | ||
1306 | } | ||
1307 | |||
1308 | if (radar_required && !radar_detect) | ||
1309 | return -EINVAL; | 1280 | return -EINVAL; |
1310 | 1281 | ||
1311 | /* Always allow software iftypes */ | 1282 | /* Always allow software iftypes */ |