summaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-03-29 16:23:26 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-29 16:23:26 -0400
commite15f20ea33b8e5074145abe464b4b48acea505d9 (patch)
treead173bb9facf7b0673a2cc313c2d52778b8f18ff /net/mac80211
parente3e67a4f07433d0159dcbd2abe7d6bdf6e1268c8 (diff)
parentc470bdc1aaf36669e04ba65faf1092b2d1c6cabe (diff)
Merge tag 'mac80211-next-for-davem-2018-03-29' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg says: ==================== We have a fair number of patches, but many of them are from the first bullet here: * EAPoL-over-nl80211 from Denis - this will let us fix some long-standing issues with bridging, races with encryption and more * DFS offload support from the qtnfmac folks * regulatory database changes for the new ETSI adaptivity requirements * various other fixes and small enhancements ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c12
-rw-r--r--net/mac80211/ht.c15
-rw-r--r--net/mac80211/ibss.c3
-rw-r--r--net/mac80211/ieee80211_i.h12
-rw-r--r--net/mac80211/iface.c2
-rw-r--r--net/mac80211/key.c8
-rw-r--r--net/mac80211/main.c10
-rw-r--r--net/mac80211/mesh.c3
-rw-r--r--net/mac80211/mlme.c168
-rw-r--r--net/mac80211/rx.c45
-rw-r--r--net/mac80211/scan.c4
-rw-r--r--net/mac80211/tx.c46
-rw-r--r--net/mac80211/util.c47
-rw-r--r--net/mac80211/vht.c32
14 files changed, 311 insertions, 96 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index fd68f6fb02d7..85dbaa891059 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -4,6 +4,7 @@
4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
5 * Copyright 2013-2015 Intel Mobile Communications GmbH 5 * Copyright 2013-2015 Intel Mobile Communications GmbH
6 * Copyright (C) 2015-2017 Intel Deutschland GmbH 6 * Copyright (C) 2015-2017 Intel Deutschland GmbH
7 * Copyright (C) 2018 Intel Corporation
7 * 8 *
8 * This file is GPLv2 as found in COPYING. 9 * This file is GPLv2 as found in COPYING.
9 */ 10 */
@@ -925,6 +926,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
925 */ 926 */
926 sdata->control_port_protocol = params->crypto.control_port_ethertype; 927 sdata->control_port_protocol = params->crypto.control_port_ethertype;
927 sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt; 928 sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt;
929 sdata->control_port_over_nl80211 =
930 params->crypto.control_port_over_nl80211;
928 sdata->encrypt_headroom = ieee80211_cs_headroom(sdata->local, 931 sdata->encrypt_headroom = ieee80211_cs_headroom(sdata->local,
929 &params->crypto, 932 &params->crypto,
930 sdata->vif.type); 933 sdata->vif.type);
@@ -934,6 +937,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
934 params->crypto.control_port_ethertype; 937 params->crypto.control_port_ethertype;
935 vlan->control_port_no_encrypt = 938 vlan->control_port_no_encrypt =
936 params->crypto.control_port_no_encrypt; 939 params->crypto.control_port_no_encrypt;
940 vlan->control_port_over_nl80211 =
941 params->crypto.control_port_over_nl80211;
937 vlan->encrypt_headroom = 942 vlan->encrypt_headroom =
938 ieee80211_cs_headroom(sdata->local, 943 ieee80211_cs_headroom(sdata->local,
939 &params->crypto, 944 &params->crypto,
@@ -2019,6 +2024,8 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
2019 if (err) 2024 if (err)
2020 return err; 2025 return err;
2021 2026
2027 sdata->control_port_over_nl80211 = setup->control_port_over_nl80211;
2028
2022 /* can mesh use other SMPS modes? */ 2029 /* can mesh use other SMPS modes? */
2023 sdata->smps_mode = IEEE80211_SMPS_OFF; 2030 sdata->smps_mode = IEEE80211_SMPS_OFF;
2024 sdata->needed_rx_chains = sdata->local->rx_chains; 2031 sdata->needed_rx_chains = sdata->local->rx_chains;
@@ -2156,6 +2163,8 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
2156 */ 2163 */
2157 p.uapsd = false; 2164 p.uapsd = false;
2158 2165
2166 ieee80211_regulatory_limit_wmm_params(sdata, &p, params->ac);
2167
2159 sdata->tx_conf[params->ac] = p; 2168 sdata->tx_conf[params->ac] = p;
2160 if (drv_conf_tx(local, sdata, params->ac, &p)) { 2169 if (drv_conf_tx(local, sdata, params->ac, &p)) {
2161 wiphy_debug(local->hw.wiphy, 2170 wiphy_debug(local->hw.wiphy,
@@ -2313,6 +2322,8 @@ static int ieee80211_set_mcast_rate(struct wiphy *wiphy, struct net_device *dev,
2313 memcpy(sdata->vif.bss_conf.mcast_rate, rate, 2322 memcpy(sdata->vif.bss_conf.mcast_rate, rate,
2314 sizeof(int) * NUM_NL80211_BANDS); 2323 sizeof(int) * NUM_NL80211_BANDS);
2315 2324
2325 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_MCAST_RATE);
2326
2316 return 0; 2327 return 0;
2317} 2328}
2318 2329
@@ -3786,4 +3797,5 @@ const struct cfg80211_ops mac80211_config_ops = {
3786 .add_nan_func = ieee80211_add_nan_func, 3797 .add_nan_func = ieee80211_add_nan_func,
3787 .del_nan_func = ieee80211_del_nan_func, 3798 .del_nan_func = ieee80211_del_nan_func,
3788 .set_multicast_to_unicast = ieee80211_set_multicast_to_unicast, 3799 .set_multicast_to_unicast = ieee80211_set_multicast_to_unicast,
3800 .tx_control_port = ieee80211_tx_control_port,
3789}; 3801};
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index d7523530d3f8..c78036a0ac94 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -466,6 +466,21 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
466 __ieee80211_stop_tx_ba_session(sta, tid, AGG_STOP_PEER_REQUEST); 466 __ieee80211_stop_tx_ba_session(sta, tid, AGG_STOP_PEER_REQUEST);
467} 467}
468 468
469enum nl80211_smps_mode
470ieee80211_smps_mode_to_smps_mode(enum ieee80211_smps_mode smps)
471{
472 switch (smps) {
473 case IEEE80211_SMPS_OFF:
474 return NL80211_SMPS_OFF;
475 case IEEE80211_SMPS_STATIC:
476 return NL80211_SMPS_STATIC;
477 case IEEE80211_SMPS_DYNAMIC:
478 return NL80211_SMPS_DYNAMIC;
479 default:
480 return NL80211_SMPS_OFF;
481 }
482}
483
469int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, 484int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
470 enum ieee80211_smps_mode smps, const u8 *da, 485 enum ieee80211_smps_mode smps, const u8 *da,
471 const u8 *bssid) 486 const u8 *bssid)
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index db07e0de9a03..6449a1c2283b 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -1839,11 +1839,12 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1839 IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED 1839 IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED
1840 | IEEE80211_HT_PARAM_RIFS_MODE; 1840 | IEEE80211_HT_PARAM_RIFS_MODE;
1841 1841
1842 changed |= BSS_CHANGED_HT; 1842 changed |= BSS_CHANGED_HT | BSS_CHANGED_MCAST_RATE;
1843 ieee80211_bss_info_change_notify(sdata, changed); 1843 ieee80211_bss_info_change_notify(sdata, changed);
1844 1844
1845 sdata->smps_mode = IEEE80211_SMPS_OFF; 1845 sdata->smps_mode = IEEE80211_SMPS_OFF;
1846 sdata->needed_rx_chains = local->rx_chains; 1846 sdata->needed_rx_chains = local->rx_chains;
1847 sdata->control_port_over_nl80211 = params->control_port_over_nl80211;
1847 1848
1848 ieee80211_queue_work(&local->hw, &sdata->work); 1849 ieee80211_queue_work(&local->hw, &sdata->work);
1849 1850
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ae9c33cd8ada..6372dbdadf53 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -4,6 +4,7 @@
4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
5 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> 5 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2013-2015 Intel Mobile Communications GmbH 6 * Copyright 2013-2015 Intel Mobile Communications GmbH
7 * Copyright (C) 2018 Intel Corporation
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
@@ -899,6 +900,7 @@ struct ieee80211_sub_if_data {
899 u16 sequence_number; 900 u16 sequence_number;
900 __be16 control_port_protocol; 901 __be16 control_port_protocol;
901 bool control_port_no_encrypt; 902 bool control_port_no_encrypt;
903 bool control_port_over_nl80211;
902 int encrypt_headroom; 904 int encrypt_headroom;
903 905
904 atomic_t num_tx_queued; 906 atomic_t num_tx_queued;
@@ -1734,6 +1736,9 @@ void ieee80211_check_fast_xmit(struct sta_info *sta);
1734void ieee80211_check_fast_xmit_all(struct ieee80211_local *local); 1736void ieee80211_check_fast_xmit_all(struct ieee80211_local *local);
1735void ieee80211_check_fast_xmit_iface(struct ieee80211_sub_if_data *sdata); 1737void ieee80211_check_fast_xmit_iface(struct ieee80211_sub_if_data *sdata);
1736void ieee80211_clear_fast_xmit(struct sta_info *sta); 1738void ieee80211_clear_fast_xmit(struct sta_info *sta);
1739int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
1740 const u8 *buf, size_t len,
1741 const u8 *dest, __be16 proto, bool unencrypted);
1737 1742
1738/* HT */ 1743/* HT */
1739void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, 1744void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
@@ -1788,6 +1793,8 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid);
1788void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid); 1793void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid);
1789 1794
1790u8 ieee80211_mcs_to_chains(const struct ieee80211_mcs_info *mcs); 1795u8 ieee80211_mcs_to_chains(const struct ieee80211_mcs_info *mcs);
1796enum nl80211_smps_mode
1797ieee80211_smps_mode_to_smps_mode(enum ieee80211_smps_mode smps);
1791 1798
1792/* VHT */ 1799/* VHT */
1793void 1800void
@@ -1814,6 +1821,8 @@ void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,
1814 struct ieee80211_sta_vht_cap *vht_cap); 1821 struct ieee80211_sta_vht_cap *vht_cap);
1815void ieee80211_get_vht_mask_from_cap(__le16 vht_cap, 1822void ieee80211_get_vht_mask_from_cap(__le16 vht_cap,
1816 u16 vht_mask[NL80211_VHT_NSS_MAX]); 1823 u16 vht_mask[NL80211_VHT_NSS_MAX]);
1824enum nl80211_chan_width
1825ieee80211_sta_rx_bw_to_chan_width(struct sta_info *sta);
1817 1826
1818/* Spectrum management */ 1827/* Spectrum management */
1819void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, 1828void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
@@ -1865,6 +1874,9 @@ extern const void *const mac80211_wiphy_privid; /* for wiphy privid */
1865int ieee80211_frame_duration(enum nl80211_band band, size_t len, 1874int ieee80211_frame_duration(enum nl80211_band band, size_t len,
1866 int rate, int erp, int short_preamble, 1875 int rate, int erp, int short_preamble,
1867 int shift); 1876 int shift);
1877void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
1878 struct ieee80211_tx_queue_params *qparam,
1879 int ac);
1868void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, 1880void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1869 bool bss_notify, bool enable_qos); 1881 bool bss_notify, bool enable_qos);
1870void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, 1882void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index d13ba064951f..555e389b7dfa 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -519,6 +519,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
519 master->control_port_protocol; 519 master->control_port_protocol;
520 sdata->control_port_no_encrypt = 520 sdata->control_port_no_encrypt =
521 master->control_port_no_encrypt; 521 master->control_port_no_encrypt;
522 sdata->control_port_over_nl80211 =
523 master->control_port_over_nl80211;
522 sdata->vif.cab_queue = master->vif.cab_queue; 524 sdata->vif.cab_queue = master->vif.cab_queue;
523 memcpy(sdata->vif.hw_queue, master->vif.hw_queue, 525 memcpy(sdata->vif.hw_queue, master->vif.hw_queue,
524 sizeof(sdata->vif.hw_queue)); 526 sizeof(sdata->vif.hw_queue));
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index aee05ec3f7ea..ee0d0cc8dc3b 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -126,7 +126,7 @@ static void decrease_tailroom_need_count(struct ieee80211_sub_if_data *sdata,
126 126
127static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) 127static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
128{ 128{
129 struct ieee80211_sub_if_data *sdata; 129 struct ieee80211_sub_if_data *sdata = key->sdata;
130 struct sta_info *sta; 130 struct sta_info *sta;
131 int ret = -EOPNOTSUPP; 131 int ret = -EOPNOTSUPP;
132 132
@@ -162,7 +162,6 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
162 if (sta && !sta->uploaded) 162 if (sta && !sta->uploaded)
163 goto out_unsupported; 163 goto out_unsupported;
164 164
165 sdata = key->sdata;
166 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { 165 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
167 /* 166 /*
168 * The driver doesn't know anything about VLAN interfaces. 167 * The driver doesn't know anything about VLAN interfaces.
@@ -214,8 +213,11 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
214 /* all of these we can do in software - if driver can */ 213 /* all of these we can do in software - if driver can */
215 if (ret == 1) 214 if (ret == 1)
216 return 0; 215 return 0;
217 if (ieee80211_hw_check(&key->local->hw, SW_CRYPTO_CONTROL)) 216 if (ieee80211_hw_check(&key->local->hw, SW_CRYPTO_CONTROL)) {
217 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
218 return 0;
218 return -EINVAL; 219 return -EINVAL;
220 }
219 return 0; 221 return 0;
220 default: 222 default:
221 return -EINVAL; 223 return -EINVAL;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0785d04a80bc..9ea17afaa237 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -554,6 +554,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
554 NL80211_FEATURE_USERSPACE_MPM | 554 NL80211_FEATURE_USERSPACE_MPM |
555 NL80211_FEATURE_FULL_AP_CLIENT_STATE; 555 NL80211_FEATURE_FULL_AP_CLIENT_STATE;
556 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA); 556 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA);
557 wiphy_ext_feature_set(wiphy,
558 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211);
557 559
558 if (!ops->hw_scan) 560 if (!ops->hw_scan)
559 wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | 561 wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
@@ -930,8 +932,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
930 IEEE80211_HT_CAP_SM_PS_SHIFT; 932 IEEE80211_HT_CAP_SM_PS_SHIFT;
931 } 933 }
932 934
933 /* if low-level driver supports AP, we also support VLAN */ 935 /* if low-level driver supports AP, we also support VLAN.
934 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { 936 * drivers advertising SW_CRYPTO_CONTROL should enable AP_VLAN
937 * based on their support to transmit SW encrypted packets.
938 */
939 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP) &&
940 !ieee80211_hw_check(&local->hw, SW_CRYPTO_CONTROL)) {
935 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); 941 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
936 hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN); 942 hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN);
937 } 943 }
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 6a381cbe1e33..d51da26e9c18 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -880,7 +880,8 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
880 BSS_CHANGED_BEACON_ENABLED | 880 BSS_CHANGED_BEACON_ENABLED |
881 BSS_CHANGED_HT | 881 BSS_CHANGED_HT |
882 BSS_CHANGED_BASIC_RATES | 882 BSS_CHANGED_BASIC_RATES |
883 BSS_CHANGED_BEACON_INT; 883 BSS_CHANGED_BEACON_INT |
884 BSS_CHANGED_MCAST_RATE;
884 885
885 local->fif_other_bss++; 886 local->fif_other_bss++;
886 /* mesh ifaces must set allmulti to forward mcast traffic */ 887 /* mesh ifaces must set allmulti to forward mcast traffic */
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index fe4aefb06d9f..69449db7e283 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1787,12 +1787,14 @@ static bool ieee80211_sta_wmm_params(struct ieee80211_local *local,
1787 params[ac].acm = acm; 1787 params[ac].acm = acm;
1788 params[ac].uapsd = uapsd; 1788 params[ac].uapsd = uapsd;
1789 1789
1790 if (params[ac].cw_min > params[ac].cw_max) { 1790 if (params->cw_min == 0 ||
1791 params[ac].cw_min > params[ac].cw_max) {
1791 sdata_info(sdata, 1792 sdata_info(sdata,
1792 "AP has invalid WMM params (CWmin/max=%d/%d for ACI %d), using defaults\n", 1793 "AP has invalid WMM params (CWmin/max=%d/%d for ACI %d), using defaults\n",
1793 params[ac].cw_min, params[ac].cw_max, aci); 1794 params[ac].cw_min, params[ac].cw_max, aci);
1794 return false; 1795 return false;
1795 } 1796 }
1797 ieee80211_regulatory_limit_wmm_params(sdata, &params[ac], ac);
1796 } 1798 }
1797 1799
1798 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 1800 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
@@ -2011,8 +2013,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
2011 2013
2012 /* deauthenticate/disassociate now */ 2014 /* deauthenticate/disassociate now */
2013 if (tx || frame_buf) { 2015 if (tx || frame_buf) {
2014 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2015
2016 /* 2016 /*
2017 * In multi channel scenarios guarantee that the virtual 2017 * In multi channel scenarios guarantee that the virtual
2018 * interface is granted immediate airtime to transmit the 2018 * interface is granted immediate airtime to transmit the
@@ -3307,82 +3307,14 @@ static const u64 care_about_ies =
3307 (1ULL << WLAN_EID_HT_OPERATION) | 3307 (1ULL << WLAN_EID_HT_OPERATION) |
3308 (1ULL << WLAN_EID_EXT_CHANSWITCH_ANN); 3308 (1ULL << WLAN_EID_EXT_CHANSWITCH_ANN);
3309 3309
3310static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, 3310static void ieee80211_handle_beacon_sig(struct ieee80211_sub_if_data *sdata,
3311 struct ieee80211_mgmt *mgmt, size_t len, 3311 struct ieee80211_if_managed *ifmgd,
3312 struct ieee80211_rx_status *rx_status) 3312 struct ieee80211_bss_conf *bss_conf,
3313 struct ieee80211_local *local,
3314 struct ieee80211_rx_status *rx_status)
3313{ 3315{
3314 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3315 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
3316 size_t baselen;
3317 struct ieee802_11_elems elems;
3318 struct ieee80211_local *local = sdata->local;
3319 struct ieee80211_chanctx_conf *chanctx_conf;
3320 struct ieee80211_channel *chan;
3321 struct sta_info *sta;
3322 u32 changed = 0;
3323 bool erp_valid;
3324 u8 erp_value = 0;
3325 u32 ncrc;
3326 u8 *bssid;
3327 u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
3328
3329 sdata_assert_lock(sdata);
3330
3331 /* Process beacon from the current BSS */
3332 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
3333 if (baselen > len)
3334 return;
3335
3336 rcu_read_lock();
3337 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
3338 if (!chanctx_conf) {
3339 rcu_read_unlock();
3340 return;
3341 }
3342
3343 if (rx_status->freq != chanctx_conf->def.chan->center_freq) {
3344 rcu_read_unlock();
3345 return;
3346 }
3347 chan = chanctx_conf->def.chan;
3348 rcu_read_unlock();
3349
3350 if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon &&
3351 ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) {
3352 ieee802_11_parse_elems(mgmt->u.beacon.variable,
3353 len - baselen, false, &elems);
3354
3355 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
3356 if (elems.tim && !elems.parse_error) {
3357 const struct ieee80211_tim_ie *tim_ie = elems.tim;
3358 ifmgd->dtim_period = tim_ie->dtim_period;
3359 }
3360 ifmgd->have_beacon = true;
3361 ifmgd->assoc_data->need_beacon = false;
3362 if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) {
3363 sdata->vif.bss_conf.sync_tsf =
3364 le64_to_cpu(mgmt->u.beacon.timestamp);
3365 sdata->vif.bss_conf.sync_device_ts =
3366 rx_status->device_timestamp;
3367 if (elems.tim)
3368 sdata->vif.bss_conf.sync_dtim_count =
3369 elems.tim->dtim_count;
3370 else
3371 sdata->vif.bss_conf.sync_dtim_count = 0;
3372 }
3373 /* continue assoc process */
3374 ifmgd->assoc_data->timeout = jiffies;
3375 ifmgd->assoc_data->timeout_started = true;
3376 run_again(sdata, ifmgd->assoc_data->timeout);
3377 return;
3378 }
3379
3380 if (!ifmgd->associated ||
3381 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
3382 return;
3383 bssid = ifmgd->associated->bssid;
3384
3385 /* Track average RSSI from the Beacon frames of the current AP */ 3316 /* Track average RSSI from the Beacon frames of the current AP */
3317
3386 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) { 3318 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) {
3387 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE; 3319 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
3388 ewma_beacon_signal_init(&ifmgd->ave_beacon_signal); 3320 ewma_beacon_signal_init(&ifmgd->ave_beacon_signal);
@@ -3469,6 +3401,86 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3469 sig, GFP_KERNEL); 3401 sig, GFP_KERNEL);
3470 } 3402 }
3471 } 3403 }
3404}
3405
3406static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3407 struct ieee80211_mgmt *mgmt, size_t len,
3408 struct ieee80211_rx_status *rx_status)
3409{
3410 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3411 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
3412 size_t baselen;
3413 struct ieee802_11_elems elems;
3414 struct ieee80211_local *local = sdata->local;
3415 struct ieee80211_chanctx_conf *chanctx_conf;
3416 struct ieee80211_channel *chan;
3417 struct sta_info *sta;
3418 u32 changed = 0;
3419 bool erp_valid;
3420 u8 erp_value = 0;
3421 u32 ncrc;
3422 u8 *bssid;
3423 u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
3424
3425 sdata_assert_lock(sdata);
3426
3427 /* Process beacon from the current BSS */
3428 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
3429 if (baselen > len)
3430 return;
3431
3432 rcu_read_lock();
3433 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
3434 if (!chanctx_conf) {
3435 rcu_read_unlock();
3436 return;
3437 }
3438
3439 if (rx_status->freq != chanctx_conf->def.chan->center_freq) {
3440 rcu_read_unlock();
3441 return;
3442 }
3443 chan = chanctx_conf->def.chan;
3444 rcu_read_unlock();
3445
3446 if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon &&
3447 ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) {
3448 ieee802_11_parse_elems(mgmt->u.beacon.variable,
3449 len - baselen, false, &elems);
3450
3451 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
3452 if (elems.tim && !elems.parse_error) {
3453 const struct ieee80211_tim_ie *tim_ie = elems.tim;
3454 ifmgd->dtim_period = tim_ie->dtim_period;
3455 }
3456 ifmgd->have_beacon = true;
3457 ifmgd->assoc_data->need_beacon = false;
3458 if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) {
3459 sdata->vif.bss_conf.sync_tsf =
3460 le64_to_cpu(mgmt->u.beacon.timestamp);
3461 sdata->vif.bss_conf.sync_device_ts =
3462 rx_status->device_timestamp;
3463 if (elems.tim)
3464 sdata->vif.bss_conf.sync_dtim_count =
3465 elems.tim->dtim_count;
3466 else
3467 sdata->vif.bss_conf.sync_dtim_count = 0;
3468 }
3469 /* continue assoc process */
3470 ifmgd->assoc_data->timeout = jiffies;
3471 ifmgd->assoc_data->timeout_started = true;
3472 run_again(sdata, ifmgd->assoc_data->timeout);
3473 return;
3474 }
3475
3476 if (!ifmgd->associated ||
3477 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
3478 return;
3479 bssid = ifmgd->associated->bssid;
3480
3481 if (!(rx_status->flag & RX_FLAG_NO_SIGNAL_VAL))
3482 ieee80211_handle_beacon_sig(sdata, ifmgd, bss_conf,
3483 local, rx_status);
3472 3484
3473 if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) { 3485 if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) {
3474 mlme_dbg_ratelimited(sdata, 3486 mlme_dbg_ratelimited(sdata,
@@ -4845,6 +4857,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4845 4857
4846 sdata->control_port_protocol = req->crypto.control_port_ethertype; 4858 sdata->control_port_protocol = req->crypto.control_port_ethertype;
4847 sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt; 4859 sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
4860 sdata->control_port_over_nl80211 =
4861 req->crypto.control_port_over_nl80211;
4848 sdata->encrypt_headroom = ieee80211_cs_headroom(local, &req->crypto, 4862 sdata->encrypt_headroom = ieee80211_cs_headroom(local, &req->crypto,
4849 sdata->vif.type); 4863 sdata->vif.type);
4850 4864
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9c898a3688c6..03102aff0953 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2245,6 +2245,32 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc)
2245 return true; 2245 return true;
2246} 2246}
2247 2247
2248static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb,
2249 struct ieee80211_rx_data *rx)
2250{
2251 struct ieee80211_sub_if_data *sdata = rx->sdata;
2252 struct net_device *dev = sdata->dev;
2253
2254 if (unlikely((skb->protocol == sdata->control_port_protocol ||
2255 skb->protocol == cpu_to_be16(ETH_P_PREAUTH)) &&
2256 sdata->control_port_over_nl80211)) {
2257 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2258 bool noencrypt = status->flag & RX_FLAG_DECRYPTED;
2259 struct ethhdr *ehdr = eth_hdr(skb);
2260
2261 cfg80211_rx_control_port(dev, skb->data, skb->len,
2262 ehdr->h_source,
2263 be16_to_cpu(skb->protocol), noencrypt);
2264 dev_kfree_skb(skb);
2265 } else {
2266 /* deliver to local stack */
2267 if (rx->napi)
2268 napi_gro_receive(rx->napi, skb);
2269 else
2270 netif_receive_skb(skb);
2271 }
2272}
2273
2248/* 2274/*
2249 * requires that rx->skb is a frame with ethernet header 2275 * requires that rx->skb is a frame with ethernet header
2250 */ 2276 */
@@ -2329,13 +2355,10 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
2329#endif 2355#endif
2330 2356
2331 if (skb) { 2357 if (skb) {
2332 /* deliver to local stack */
2333 skb->protocol = eth_type_trans(skb, dev); 2358 skb->protocol = eth_type_trans(skb, dev);
2334 memset(skb->cb, 0, sizeof(skb->cb)); 2359 memset(skb->cb, 0, sizeof(skb->cb));
2335 if (rx->napi) 2360
2336 napi_gro_receive(rx->napi, skb); 2361 ieee80211_deliver_skb_to_local_stack(skb, rx);
2337 else
2338 netif_receive_skb(skb);
2339 } 2362 }
2340 2363
2341 if (xmit_skb) { 2364 if (xmit_skb) {
@@ -2804,7 +2827,8 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
2804 !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) { 2827 !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {
2805 int sig = 0; 2828 int sig = 0;
2806 2829
2807 if (ieee80211_hw_check(&rx->local->hw, SIGNAL_DBM)) 2830 if (ieee80211_hw_check(&rx->local->hw, SIGNAL_DBM) &&
2831 !(status->flag & RX_FLAG_NO_SIGNAL_VAL))
2808 sig = status->signal; 2832 sig = status->signal;
2809 2833
2810 cfg80211_report_obss_beacon(rx->local->hw.wiphy, 2834 cfg80211_report_obss_beacon(rx->local->hw.wiphy,
@@ -2882,7 +2906,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2882 if (rx->sta->sta.smps_mode == smps_mode) 2906 if (rx->sta->sta.smps_mode == smps_mode)
2883 goto handled; 2907 goto handled;
2884 rx->sta->sta.smps_mode = smps_mode; 2908 rx->sta->sta.smps_mode = smps_mode;
2885 sta_opmode.smps_mode = smps_mode; 2909 sta_opmode.smps_mode =
2910 ieee80211_smps_mode_to_smps_mode(smps_mode);
2886 sta_opmode.changed = STA_OPMODE_SMPS_MODE_CHANGED; 2911 sta_opmode.changed = STA_OPMODE_SMPS_MODE_CHANGED;
2887 2912
2888 sband = rx->local->hw.wiphy->bands[status->band]; 2913 sband = rx->local->hw.wiphy->bands[status->band];
@@ -2920,7 +2945,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2920 2945
2921 rx->sta->sta.bandwidth = new_bw; 2946 rx->sta->sta.bandwidth = new_bw;
2922 sband = rx->local->hw.wiphy->bands[status->band]; 2947 sband = rx->local->hw.wiphy->bands[status->band];
2923 sta_opmode.bw = new_bw; 2948 sta_opmode.bw =
2949 ieee80211_sta_rx_bw_to_chan_width(rx->sta);
2924 sta_opmode.changed = STA_OPMODE_MAX_BW_CHANGED; 2950 sta_opmode.changed = STA_OPMODE_MAX_BW_CHANGED;
2925 2951
2926 rate_control_rate_update(local, sband, rx->sta, 2952 rate_control_rate_update(local, sband, rx->sta,
@@ -3145,7 +3171,8 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
3145 * it transmitted were processed or returned. 3171 * it transmitted were processed or returned.
3146 */ 3172 */
3147 3173
3148 if (ieee80211_hw_check(&rx->local->hw, SIGNAL_DBM)) 3174 if (ieee80211_hw_check(&rx->local->hw, SIGNAL_DBM) &&
3175 !(status->flag & RX_FLAG_NO_SIGNAL_VAL))
3149 sig = status->signal; 3176 sig = status->signal;
3150 3177
3151 if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig, 3178 if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig,
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index ef2becaade50..a3b1bcc2b461 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -73,7 +73,9 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
73 bool signal_valid; 73 bool signal_valid;
74 struct ieee80211_sub_if_data *scan_sdata; 74 struct ieee80211_sub_if_data *scan_sdata;
75 75
76 if (ieee80211_hw_check(&local->hw, SIGNAL_DBM)) 76 if (rx_status->flag & RX_FLAG_NO_SIGNAL_VAL)
77 bss_meta.signal = 0; /* invalid signal indication */
78 else if (ieee80211_hw_check(&local->hw, SIGNAL_DBM))
77 bss_meta.signal = rx_status->signal * 100; 79 bss_meta.signal = rx_status->signal * 100;
78 else if (ieee80211_hw_check(&local->hw, SIGNAL_UNSPEC)) 80 else if (ieee80211_hw_check(&local->hw, SIGNAL_UNSPEC))
79 bss_meta.signal = (rx_status->signal * 100) / local->hw.max_signal; 81 bss_meta.signal = (rx_status->signal * 100) / local->hw.max_signal;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 933c67b5f845..535de3161a78 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4757,3 +4757,49 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
4757 ieee80211_xmit(sdata, NULL, skb); 4757 ieee80211_xmit(sdata, NULL, skb);
4758 local_bh_enable(); 4758 local_bh_enable();
4759} 4759}
4760
4761int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
4762 const u8 *buf, size_t len,
4763 const u8 *dest, __be16 proto, bool unencrypted)
4764{
4765 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
4766 struct ieee80211_local *local = sdata->local;
4767 struct sk_buff *skb;
4768 struct ethhdr *ehdr;
4769 u32 flags;
4770
4771 /* Only accept CONTROL_PORT_PROTOCOL configured in CONNECT/ASSOCIATE
4772 * or Pre-Authentication
4773 */
4774 if (proto != sdata->control_port_protocol &&
4775 proto != cpu_to_be16(ETH_P_PREAUTH))
4776 return -EINVAL;
4777
4778 if (unencrypted)
4779 flags = IEEE80211_TX_INTFL_DONT_ENCRYPT;
4780 else
4781 flags = 0;
4782
4783 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
4784 sizeof(struct ethhdr) + len);
4785 if (!skb)
4786 return -ENOMEM;
4787
4788 skb_reserve(skb, local->hw.extra_tx_headroom + sizeof(struct ethhdr));
4789
4790 skb_put_data(skb, buf, len);
4791
4792 ehdr = skb_push(skb, sizeof(struct ethhdr));
4793 memcpy(ehdr->h_dest, dest, ETH_ALEN);
4794 memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN);
4795 ehdr->h_proto = proto;
4796
4797 skb->dev = dev;
4798 skb->protocol = htons(ETH_P_802_3);
4799 skb_reset_network_header(skb);
4800 skb_reset_mac_header(skb);
4801
4802 __ieee80211_subif_start_xmit(skb, skb->dev, flags);
4803
4804 return 0;
4805}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 1f82191ce601..11f9cfc016d9 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -5,6 +5,7 @@
5 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 5 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2013-2014 Intel Mobile Communications GmbH 6 * Copyright 2013-2014 Intel Mobile Communications GmbH
7 * Copyright (C) 2015-2017 Intel Deutschland GmbH 7 * Copyright (C) 2015-2017 Intel Deutschland GmbH
8 * Copyright (C) 2018 Intel Corporation
8 * 9 *
9 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
@@ -1113,6 +1114,48 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
1113 return crc; 1114 return crc;
1114} 1115}
1115 1116
1117void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
1118 struct ieee80211_tx_queue_params
1119 *qparam, int ac)
1120{
1121 struct ieee80211_chanctx_conf *chanctx_conf;
1122 const struct ieee80211_reg_rule *rrule;
1123 struct ieee80211_wmm_ac *wmm_ac;
1124 u16 center_freq = 0;
1125
1126 if (sdata->vif.type != NL80211_IFTYPE_AP &&
1127 sdata->vif.type != NL80211_IFTYPE_STATION)
1128 return;
1129
1130 rcu_read_lock();
1131 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1132 if (chanctx_conf)
1133 center_freq = chanctx_conf->def.chan->center_freq;
1134
1135 if (!center_freq) {
1136 rcu_read_unlock();
1137 return;
1138 }
1139
1140 rrule = freq_reg_info(sdata->wdev.wiphy, MHZ_TO_KHZ(center_freq));
1141
1142 if (IS_ERR_OR_NULL(rrule) || !rrule->wmm_rule) {
1143 rcu_read_unlock();
1144 return;
1145 }
1146
1147 if (sdata->vif.type == NL80211_IFTYPE_AP)
1148 wmm_ac = &rrule->wmm_rule->ap[ac];
1149 else
1150 wmm_ac = &rrule->wmm_rule->client[ac];
1151 qparam->cw_min = max_t(u16, qparam->cw_min, wmm_ac->cw_min);
1152 qparam->cw_max = max_t(u16, qparam->cw_max, wmm_ac->cw_max);
1153 qparam->aifs = max_t(u8, qparam->aifs, wmm_ac->aifsn);
1154 qparam->txop = !qparam->txop ? wmm_ac->cot / 32 :
1155 min_t(u16, qparam->txop, wmm_ac->cot / 32);
1156 rcu_read_unlock();
1157}
1158
1116void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, 1159void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1117 bool bss_notify, bool enable_qos) 1160 bool bss_notify, bool enable_qos)
1118{ 1161{
@@ -1206,6 +1249,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1206 break; 1249 break;
1207 } 1250 }
1208 } 1251 }
1252 ieee80211_regulatory_limit_wmm_params(sdata, &qparam, ac);
1209 1253
1210 qparam.uapsd = false; 1254 qparam.uapsd = false;
1211 1255
@@ -1968,7 +2012,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1968 BSS_CHANGED_CQM | 2012 BSS_CHANGED_CQM |
1969 BSS_CHANGED_QOS | 2013 BSS_CHANGED_QOS |
1970 BSS_CHANGED_IDLE | 2014 BSS_CHANGED_IDLE |
1971 BSS_CHANGED_TXPOWER; 2015 BSS_CHANGED_TXPOWER |
2016 BSS_CHANGED_MCAST_RATE;
1972 2017
1973 if (sdata->vif.mu_mimo_owner) 2018 if (sdata->vif.mu_mimo_owner)
1974 changed |= BSS_CHANGED_MU_GROUPS; 2019 changed |= BSS_CHANGED_MU_GROUPS;
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index 5714dee76b12..259325cbcc31 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -358,6 +358,36 @@ enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta)
358 return NL80211_CHAN_WIDTH_80; 358 return NL80211_CHAN_WIDTH_80;
359} 359}
360 360
361enum nl80211_chan_width
362ieee80211_sta_rx_bw_to_chan_width(struct sta_info *sta)
363{
364 enum ieee80211_sta_rx_bandwidth cur_bw = sta->sta.bandwidth;
365 struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap;
366 u32 cap_width;
367
368 switch (cur_bw) {
369 case IEEE80211_STA_RX_BW_20:
370 if (!sta->sta.ht_cap.ht_supported)
371 return NL80211_CHAN_WIDTH_20_NOHT;
372 else
373 return NL80211_CHAN_WIDTH_20;
374 case IEEE80211_STA_RX_BW_40:
375 return NL80211_CHAN_WIDTH_40;
376 case IEEE80211_STA_RX_BW_80:
377 return NL80211_CHAN_WIDTH_80;
378 case IEEE80211_STA_RX_BW_160:
379 cap_width =
380 vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
381
382 if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)
383 return NL80211_CHAN_WIDTH_160;
384
385 return NL80211_CHAN_WIDTH_80P80;
386 default:
387 return NL80211_CHAN_WIDTH_20;
388 }
389}
390
361enum ieee80211_sta_rx_bandwidth 391enum ieee80211_sta_rx_bandwidth
362ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width) 392ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width)
363{ 393{
@@ -484,7 +514,7 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
484 new_bw = ieee80211_sta_cur_vht_bw(sta); 514 new_bw = ieee80211_sta_cur_vht_bw(sta);
485 if (new_bw != sta->sta.bandwidth) { 515 if (new_bw != sta->sta.bandwidth) {
486 sta->sta.bandwidth = new_bw; 516 sta->sta.bandwidth = new_bw;
487 sta_opmode.bw = new_bw; 517 sta_opmode.bw = ieee80211_sta_rx_bw_to_chan_width(sta);
488 changed |= IEEE80211_RC_BW_CHANGED; 518 changed |= IEEE80211_RC_BW_CHANGED;
489 sta_opmode.changed |= STA_OPMODE_MAX_BW_CHANGED; 519 sta_opmode.changed |= STA_OPMODE_MAX_BW_CHANGED;
490 } 520 }