aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-11-26 14:46:41 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-11-26 14:46:41 -0500
commit62c8003ecb973986958e9dade4a7e598349caf48 (patch)
tree0e831639cd6449c2955234cfc37ef46481c788d1
parente4cb3ff9311e0817e65cda7bc53898348aab7527 (diff)
parentec816087e8978b74c1bd5fae0e335dd97d964e9f (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c27
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c11
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/dev.h1
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c2
-rw-r--r--drivers/net/wireless/libertas/cfg.c24
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c68
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c46
-rw-r--r--drivers/net/wireless/mwifiex/main.h2
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c1
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c3
-rw-r--r--drivers/net/wireless/orinoco/cfg.c11
-rw-r--r--drivers/net/wireless/rndis_wlan.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c9
-rw-r--r--include/linux/ieee80211.h38
-rw-r--r--include/net/cfg80211.h170
-rw-r--r--include/net/mac80211.h66
-rw-r--r--include/uapi/linux/nl80211.h96
-rw-r--r--net/mac80211/cfg.c137
-rw-r--r--net/mac80211/chan.c128
-rw-r--r--net/mac80211/debugfs_netdev.c2
-rw-r--r--net/mac80211/driver-ops.h5
-rw-r--r--net/mac80211/ibss.c46
-rw-r--r--net/mac80211/ieee80211_i.h22
-rw-r--r--net/mac80211/iface.c5
-rw-r--r--net/mac80211/main.c23
-rw-r--r--net/mac80211/mesh.c36
-rw-r--r--net/mac80211/mesh.h14
-rw-r--r--net/mac80211/mesh_plink.c47
-rw-r--r--net/mac80211/mesh_sync.c2
-rw-r--r--net/mac80211/mlme.c94
-rw-r--r--net/mac80211/offchannel.c8
-rw-r--r--net/mac80211/rate.c5
-rw-r--r--net/mac80211/rate.h2
-rw-r--r--net/mac80211/rx.c41
-rw-r--r--net/mac80211/scan.c9
-rw-r--r--net/mac80211/sta_info.c2
-rw-r--r--net/mac80211/sta_info.h8
-rw-r--r--net/mac80211/trace.h29
-rw-r--r--net/mac80211/tx.c20
-rw-r--r--net/mac80211/util.c59
-rw-r--r--net/mac80211/wme.c40
-rw-r--r--net/wireless/chan.c280
-rw-r--r--net/wireless/core.h23
-rw-r--r--net/wireless/ibss.c27
-rw-r--r--net/wireless/mesh.c49
-rw-r--r--net/wireless/mlme.c36
-rw-r--r--net/wireless/nl80211.c415
-rw-r--r--net/wireless/nl80211.h8
-rw-r--r--net/wireless/rdev-ops.h42
-rw-r--r--net/wireless/scan.c45
-rw-r--r--net/wireless/trace.h295
-rw-r--r--net/wireless/util.c79
-rw-r--r--net/wireless/wext-compat.c28
-rw-r--r--net/wireless/wext-sme.c11
55 files changed, 1642 insertions, 1062 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 83d8c5eabbee..5516a8ccc3c6 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1074,15 +1074,18 @@ out:
1074void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, 1074void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
1075 enum wmi_phy_mode mode) 1075 enum wmi_phy_mode mode)
1076{ 1076{
1077 enum nl80211_channel_type type; 1077 struct cfg80211_chan_def chandef;
1078 1078
1079 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, 1079 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1080 "channel switch notify nw_type %d freq %d mode %d\n", 1080 "channel switch notify nw_type %d freq %d mode %d\n",
1081 vif->nw_type, freq, mode); 1081 vif->nw_type, freq, mode);
1082 1082
1083 type = (mode == WMI_11G_HT20) ? NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT; 1083 cfg80211_chandef_create(&chandef,
1084 ieee80211_get_channel(vif->ar->wiphy, freq),
1085 (mode == WMI_11G_HT20) ?
1086 NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
1084 1087
1085 cfg80211_ch_switch_notify(vif->ndev, freq, type); 1088 cfg80211_ch_switch_notify(vif->ndev, &chandef);
1086} 1089}
1087 1090
1088static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, 1091static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
@@ -1594,8 +1597,8 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1594 vif->ssid_len = ibss_param->ssid_len; 1597 vif->ssid_len = ibss_param->ssid_len;
1595 memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len); 1598 memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
1596 1599
1597 if (ibss_param->channel) 1600 if (ibss_param->chandef.chan)
1598 vif->ch_hint = ibss_param->channel->center_freq; 1601 vif->ch_hint = ibss_param->chandef.chan->center_freq;
1599 1602
1600 if (ibss_param->channel_fixed) { 1603 if (ibss_param->channel_fixed) {
1601 /* 1604 /*
@@ -2878,7 +2881,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2878 p.ssid_len = vif->ssid_len; 2881 p.ssid_len = vif->ssid_len;
2879 memcpy(p.ssid, vif->ssid, vif->ssid_len); 2882 memcpy(p.ssid, vif->ssid, vif->ssid_len);
2880 p.dot11_auth_mode = vif->dot11_auth_mode; 2883 p.dot11_auth_mode = vif->dot11_auth_mode;
2881 p.ch = cpu_to_le16(info->channel->center_freq); 2884 p.ch = cpu_to_le16(info->chandef.chan->center_freq);
2882 2885
2883 /* Enable uAPSD support by default */ 2886 /* Enable uAPSD support by default */
2884 res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true); 2887 res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
@@ -2909,8 +2912,9 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2909 return res; 2912 return res;
2910 } 2913 }
2911 2914
2912 if (ath6kl_set_htcap(vif, info->channel->band, 2915 if (ath6kl_set_htcap(vif, info->chandef.chan->band,
2913 info->channel_type != NL80211_CHAN_NO_HT)) 2916 cfg80211_get_chandef_type(&info->chandef)
2917 != NL80211_CHAN_NO_HT))
2914 return -EIO; 2918 return -EIO;
2915 2919
2916 /* 2920 /*
@@ -3006,7 +3010,6 @@ static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
3006static int ath6kl_remain_on_channel(struct wiphy *wiphy, 3010static int ath6kl_remain_on_channel(struct wiphy *wiphy,
3007 struct wireless_dev *wdev, 3011 struct wireless_dev *wdev,
3008 struct ieee80211_channel *chan, 3012 struct ieee80211_channel *chan,
3009 enum nl80211_channel_type channel_type,
3010 unsigned int duration, 3013 unsigned int duration,
3011 u64 *cookie) 3014 u64 *cookie)
3012{ 3015{
@@ -3165,10 +3168,8 @@ static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
3165 3168
3166static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 3169static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3167 struct ieee80211_channel *chan, bool offchan, 3170 struct ieee80211_channel *chan, bool offchan,
3168 enum nl80211_channel_type channel_type, 3171 unsigned int wait, const u8 *buf, size_t len,
3169 bool channel_type_valid, unsigned int wait, 3172 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
3170 const u8 *buf, size_t len, bool no_cck,
3171 bool dont_wait_for_ack, u64 *cookie)
3172{ 3173{
3173 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); 3174 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3174 struct ath6kl *ar = ath6kl_priv(vif->ndev); 3175 struct ath6kl *ar = ath6kl_priv(vif->ndev);
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 55ccf9770339..998f8b0f62fd 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -474,7 +474,7 @@ static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap,
474 return -EINVAL; 474 return -EINVAL;
475 } 475 }
476 id = vif->last_roc_id; 476 id = vif->last_roc_id;
477 cfg80211_ready_on_channel(&vif->wdev, id, chan, NL80211_CHAN_NO_HT, 477 cfg80211_ready_on_channel(&vif->wdev, id, chan,
478 dur, GFP_ATOMIC); 478 dur, GFP_ATOMIC);
479 479
480 return 0; 480 return 0;
@@ -513,8 +513,7 @@ static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi,
513 else 513 else
514 id = vif->last_roc_id; /* timeout on uncanceled r-o-c */ 514 id = vif->last_roc_id; /* timeout on uncanceled r-o-c */
515 vif->last_cancel_roc_id = 0; 515 vif->last_cancel_roc_id = 0;
516 cfg80211_remain_on_channel_expired(&vif->wdev, id, chan, 516 cfg80211_remain_on_channel_expired(&vif->wdev, id, chan, GFP_ATOMIC);
517 NL80211_CHAN_NO_HT, GFP_ATOMIC);
518 517
519 return 0; 518 return 0;
520} 519}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 769c134c6618..2044fdb55558 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -1013,8 +1013,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1013 else 1013 else
1014 WL_CONN("No BSSID specified\n"); 1014 WL_CONN("No BSSID specified\n");
1015 1015
1016 if (params->channel) 1016 if (params->chandef.chan)
1017 WL_CONN("channel: %d\n", params->channel->center_freq); 1017 WL_CONN("channel: %d\n", params->chandef.chan->center_freq);
1018 else 1018 else
1019 WL_CONN("no channel specified\n"); 1019 WL_CONN("no channel specified\n");
1020 1020
@@ -1087,12 +1087,12 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1087 } 1087 }
1088 1088
1089 /* Channel */ 1089 /* Channel */
1090 if (params->channel) { 1090 if (params->chandef.chan) {
1091 u32 target_channel; 1091 u32 target_channel;
1092 1092
1093 cfg->channel = 1093 cfg->channel =
1094 ieee80211_frequency_to_channel( 1094 ieee80211_frequency_to_channel(
1095 params->channel->center_freq); 1095 params->chandef.chan->center_freq);
1096 if (params->channel_fixed) { 1096 if (params->channel_fixed) {
1097 /* adding chanspec */ 1097 /* adding chanspec */
1098 brcmf_ch_to_chanspec(cfg->channel, 1098 brcmf_ch_to_chanspec(cfg->channel,
@@ -3506,7 +3506,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3506 s32 bssidx = 0; 3506 s32 bssidx = 0;
3507 3507
3508 WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n", 3508 WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3509 settings->channel_type, settings->beacon_interval, 3509 cfg80211_get_chandef_type(&settings->chandef),
3510 settings->beacon_interval,
3510 settings->dtim_period); 3511 settings->dtim_period);
3511 WL_TRACE("ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n", 3512 WL_TRACE("ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3512 settings->ssid, settings->ssid_len, settings->auth_type, 3513 settings->ssid, settings->ssid_len, settings->auth_type,
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index 8141f91c3725..29c571a56251 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -789,7 +789,6 @@ struct iwl_priv {
789 /* remain-on-channel offload support */ 789 /* remain-on-channel offload support */
790 struct ieee80211_channel *hw_roc_channel; 790 struct ieee80211_channel *hw_roc_channel;
791 struct delayed_work hw_roc_disable_work; 791 struct delayed_work hw_roc_disable_work;
792 enum nl80211_channel_type hw_roc_chantype;
793 int hw_roc_duration; 792 int hw_roc_duration;
794 bool hw_roc_setup, hw_roc_start_notified; 793 bool hw_roc_setup, hw_roc_start_notified;
795 794
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 932ad357edbd..fb959b00b208 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1037,7 +1037,6 @@ done:
1037static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, 1037static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
1038 struct ieee80211_vif *vif, 1038 struct ieee80211_vif *vif,
1039 struct ieee80211_channel *channel, 1039 struct ieee80211_channel *channel,
1040 enum nl80211_channel_type channel_type,
1041 int duration) 1040 int duration)
1042{ 1041{
1043 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1042 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
@@ -1069,7 +1068,6 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
1069 } 1068 }
1070 1069
1071 priv->hw_roc_channel = channel; 1070 priv->hw_roc_channel = channel;
1072 priv->hw_roc_chantype = channel_type;
1073 /* convert from ms to TU */ 1071 /* convert from ms to TU */
1074 priv->hw_roc_duration = DIV_ROUND_UP(1000 * duration, 1024); 1072 priv->hw_roc_duration = DIV_ROUND_UP(1000 * duration, 1024);
1075 priv->hw_roc_start_notified = false; 1073 priv->hw_roc_start_notified = false;
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 1c10b542ab23..ec36868f6fc5 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -436,19 +436,19 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
436 */ 436 */
437 437
438static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy, 438static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy,
439 struct ieee80211_channel *channel, 439 struct cfg80211_chan_def *chandef)
440 enum nl80211_channel_type channel_type)
441{ 440{
442 struct lbs_private *priv = wiphy_priv(wiphy); 441 struct lbs_private *priv = wiphy_priv(wiphy);
443 int ret = -ENOTSUPP; 442 int ret = -ENOTSUPP;
444 443
445 lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d", 444 lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d",
446 channel->center_freq, channel_type); 445 chandef->chan->center_freq,
446 cfg80211_get_chandef_type(chandef));
447 447
448 if (channel_type != NL80211_CHAN_NO_HT) 448 if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT)
449 goto out; 449 goto out;
450 450
451 ret = lbs_set_channel(priv, channel->hw_value); 451 ret = lbs_set_channel(priv, chandef->chan->hw_value);
452 452
453 out: 453 out:
454 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 454 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
@@ -1734,7 +1734,7 @@ static void lbs_join_post(struct lbs_private *priv,
1734 /* Fake DS channel IE */ 1734 /* Fake DS channel IE */
1735 *fake++ = WLAN_EID_DS_PARAMS; 1735 *fake++ = WLAN_EID_DS_PARAMS;
1736 *fake++ = 1; 1736 *fake++ = 1;
1737 *fake++ = params->channel->hw_value; 1737 *fake++ = params->chandef.chan->hw_value;
1738 /* Fake IBSS params IE */ 1738 /* Fake IBSS params IE */
1739 *fake++ = WLAN_EID_IBSS_PARAMS; 1739 *fake++ = WLAN_EID_IBSS_PARAMS;
1740 *fake++ = 2; 1740 *fake++ = 2;
@@ -1755,7 +1755,7 @@ static void lbs_join_post(struct lbs_private *priv,
1755 lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie); 1755 lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie);
1756 1756
1757 bss = cfg80211_inform_bss(priv->wdev->wiphy, 1757 bss = cfg80211_inform_bss(priv->wdev->wiphy,
1758 params->channel, 1758 params->chandef.chan,
1759 bssid, 1759 bssid,
1760 0, 1760 0,
1761 capability, 1761 capability,
@@ -1833,7 +1833,7 @@ static int lbs_ibss_join_existing(struct lbs_private *priv,
1833 cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval); 1833 cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval);
1834 cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS; 1834 cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS;
1835 cmd.bss.ds.header.len = 1; 1835 cmd.bss.ds.header.len = 1;
1836 cmd.bss.ds.channel = params->channel->hw_value; 1836 cmd.bss.ds.channel = params->chandef.chan->hw_value;
1837 cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS; 1837 cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS;
1838 cmd.bss.ibss.header.len = 2; 1838 cmd.bss.ibss.header.len = 2;
1839 cmd.bss.ibss.atimwindow = 0; 1839 cmd.bss.ibss.atimwindow = 0;
@@ -1942,7 +1942,7 @@ static int lbs_ibss_start_new(struct lbs_private *priv,
1942 cmd.ibss.atimwindow = 0; 1942 cmd.ibss.atimwindow = 0;
1943 cmd.ds.header.id = WLAN_EID_DS_PARAMS; 1943 cmd.ds.header.id = WLAN_EID_DS_PARAMS;
1944 cmd.ds.header.len = 1; 1944 cmd.ds.header.len = 1;
1945 cmd.ds.channel = params->channel->hw_value; 1945 cmd.ds.channel = params->chandef.chan->hw_value;
1946 /* Only v8 and below support setting probe delay */ 1946 /* Only v8 and below support setting probe delay */
1947 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) 1947 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8)
1948 cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); 1948 cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
@@ -1987,18 +1987,18 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1987 1987
1988 lbs_deb_enter(LBS_DEB_CFG80211); 1988 lbs_deb_enter(LBS_DEB_CFG80211);
1989 1989
1990 if (!params->channel) { 1990 if (!params->chandef.chan) {
1991 ret = -ENOTSUPP; 1991 ret = -ENOTSUPP;
1992 goto out; 1992 goto out;
1993 } 1993 }
1994 1994
1995 ret = lbs_set_channel(priv, params->channel->hw_value); 1995 ret = lbs_set_channel(priv, params->chandef.chan->hw_value);
1996 if (ret) 1996 if (ret)
1997 goto out; 1997 goto out;
1998 1998
1999 /* Search if someone is beaconing. This assumes that the 1999 /* Search if someone is beaconing. This assumes that the
2000 * bss list is populated already */ 2000 * bss list is populated already */
2001 bss = cfg80211_get_bss(wiphy, params->channel, params->bssid, 2001 bss = cfg80211_get_bss(wiphy, params->chandef.chan, params->bssid,
2002 params->ssid, params->ssid_len, 2002 params->ssid, params->ssid_len,
2003 WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); 2003 WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
2004 2004
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 3baa51f1bb83..2aa8a1aa1184 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -681,7 +681,7 @@ static void mac80211_hwsim_tx_iter(void *_data, u8 *addr,
681 return; 681 return;
682 682
683 if (!hwsim_chans_compat(data->channel, 683 if (!hwsim_chans_compat(data->channel,
684 rcu_dereference(vif->chanctx_conf)->channel)) 684 rcu_dereference(vif->chanctx_conf)->def.chan))
685 return; 685 return;
686 686
687 data->receive = true; 687 data->receive = true;
@@ -832,7 +832,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
832 } else { 832 } else {
833 chanctx_conf = rcu_dereference(txi->control.vif->chanctx_conf); 833 chanctx_conf = rcu_dereference(txi->control.vif->chanctx_conf);
834 if (chanctx_conf) 834 if (chanctx_conf)
835 channel = chanctx_conf->channel; 835 channel = chanctx_conf->def.chan;
836 else 836 else
837 channel = NULL; 837 channel = NULL;
838 } 838 }
@@ -977,7 +977,7 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
977 return; 977 return;
978 978
979 mac80211_hwsim_tx_frame(hw, skb, 979 mac80211_hwsim_tx_frame(hw, skb,
980 rcu_dereference(vif->chanctx_conf)->channel); 980 rcu_dereference(vif->chanctx_conf)->def.chan);
981} 981}
982 982
983 983
@@ -1107,9 +1107,8 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
1107 } 1107 }
1108 1108
1109 if (changed & BSS_CHANGED_HT) { 1109 if (changed & BSS_CHANGED_HT) {
1110 wiphy_debug(hw->wiphy, " HT: op_mode=0x%x, chantype=%s\n", 1110 wiphy_debug(hw->wiphy, " HT: op_mode=0x%x\n",
1111 info->ht_operation_mode, 1111 info->ht_operation_mode);
1112 hwsim_chantypes[info->channel_type]);
1113 } 1112 }
1114 1113
1115 if (changed & BSS_CHANGED_BASIC_RATES) { 1114 if (changed & BSS_CHANGED_BASIC_RATES) {
@@ -1368,7 +1367,6 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
1368 struct cfg80211_scan_request *req) 1367 struct cfg80211_scan_request *req)
1369{ 1368{
1370 struct mac80211_hwsim_data *hwsim = hw->priv; 1369 struct mac80211_hwsim_data *hwsim = hw->priv;
1371 int i;
1372 1370
1373 mutex_lock(&hwsim->mutex); 1371 mutex_lock(&hwsim->mutex);
1374 if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) { 1372 if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) {
@@ -1381,11 +1379,6 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
1381 mutex_unlock(&hwsim->mutex); 1379 mutex_unlock(&hwsim->mutex);
1382 1380
1383 wiphy_debug(hw->wiphy, "hwsim hw_scan request\n"); 1381 wiphy_debug(hw->wiphy, "hwsim hw_scan request\n");
1384 for (i = 0; i < req->n_channels; i++)
1385 printk(KERN_DEBUG "hwsim hw_scan freq %d\n",
1386 req->channels[i]->center_freq);
1387 print_hex_dump(KERN_DEBUG, "scan IEs: ", DUMP_PREFIX_OFFSET,
1388 16, 1, req->ie, req->ie_len, 1);
1389 1382
1390 ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0); 1383 ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0);
1391 1384
@@ -1455,7 +1448,6 @@ static void hw_roc_done(struct work_struct *work)
1455static int mac80211_hwsim_roc(struct ieee80211_hw *hw, 1448static int mac80211_hwsim_roc(struct ieee80211_hw *hw,
1456 struct ieee80211_vif *vif, 1449 struct ieee80211_vif *vif,
1457 struct ieee80211_channel *chan, 1450 struct ieee80211_channel *chan,
1458 enum nl80211_channel_type channel_type,
1459 int duration) 1451 int duration)
1460{ 1452{
1461 struct mac80211_hwsim_data *hwsim = hw->priv; 1453 struct mac80211_hwsim_data *hwsim = hw->priv;
@@ -1498,16 +1490,20 @@ static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw,
1498 struct ieee80211_chanctx_conf *ctx) 1490 struct ieee80211_chanctx_conf *ctx)
1499{ 1491{
1500 hwsim_set_chanctx_magic(ctx); 1492 hwsim_set_chanctx_magic(ctx);
1501 wiphy_debug(hw->wiphy, "add channel context %d MHz/%d\n", 1493 wiphy_debug(hw->wiphy,
1502 ctx->channel->center_freq, ctx->channel_type); 1494 "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
1495 ctx->def.chan->center_freq, ctx->def.width,
1496 ctx->def.center_freq1, ctx->def.center_freq2);
1503 return 0; 1497 return 0;
1504} 1498}
1505 1499
1506static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw, 1500static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw,
1507 struct ieee80211_chanctx_conf *ctx) 1501 struct ieee80211_chanctx_conf *ctx)
1508{ 1502{
1509 wiphy_debug(hw->wiphy, "remove channel context %d MHz/%d\n", 1503 wiphy_debug(hw->wiphy,
1510 ctx->channel->center_freq, ctx->channel_type); 1504 "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
1505 ctx->def.chan->center_freq, ctx->def.width,
1506 ctx->def.center_freq1, ctx->def.center_freq2);
1511 hwsim_check_chanctx_magic(ctx); 1507 hwsim_check_chanctx_magic(ctx);
1512 hwsim_clear_chanctx_magic(ctx); 1508 hwsim_clear_chanctx_magic(ctx);
1513} 1509}
@@ -1517,8 +1513,10 @@ static void mac80211_hwsim_change_chanctx(struct ieee80211_hw *hw,
1517 u32 changed) 1513 u32 changed)
1518{ 1514{
1519 hwsim_check_chanctx_magic(ctx); 1515 hwsim_check_chanctx_magic(ctx);
1520 wiphy_debug(hw->wiphy, "change channel context %#x (%d MHz/%d)\n", 1516 wiphy_debug(hw->wiphy,
1521 changed, ctx->channel->center_freq, ctx->channel_type); 1517 "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
1518 ctx->def.chan->center_freq, ctx->def.width,
1519 ctx->def.center_freq1, ctx->def.center_freq2);
1522} 1520}
1523 1521
1524static int mac80211_hwsim_assign_vif_chanctx(struct ieee80211_hw *hw, 1522static int mac80211_hwsim_assign_vif_chanctx(struct ieee80211_hw *hw,
@@ -1640,7 +1638,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
1640 1638
1641 rcu_read_lock(); 1639 rcu_read_lock();
1642 mac80211_hwsim_tx_frame(data->hw, skb, 1640 mac80211_hwsim_tx_frame(data->hw, skb,
1643 rcu_dereference(vif->chanctx_conf)->channel); 1641 rcu_dereference(vif->chanctx_conf)->def.chan);
1644 rcu_read_unlock(); 1642 rcu_read_unlock();
1645} 1643}
1646 1644
@@ -1672,7 +1670,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
1672 1670
1673 rcu_read_lock(); 1671 rcu_read_lock();
1674 mac80211_hwsim_tx_frame(data->hw, skb, 1672 mac80211_hwsim_tx_frame(data->hw, skb,
1675 rcu_dereference(vif->chanctx_conf)->channel); 1673 rcu_dereference(vif->chanctx_conf)->def.chan);
1676 rcu_read_unlock(); 1674 rcu_read_unlock();
1677} 1675}
1678 1676
@@ -2204,6 +2202,34 @@ static int __init init_mac80211_hwsim(void)
2204 sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 2202 sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
2205 2203
2206 hw->wiphy->bands[band] = sband; 2204 hw->wiphy->bands[band] = sband;
2205
2206 if (channels == 1)
2207 continue;
2208
2209 sband->vht_cap.vht_supported = true;
2210 sband->vht_cap.cap =
2211 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
2212 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ |
2213 IEEE80211_VHT_CAP_RXLDPC |
2214 IEEE80211_VHT_CAP_SHORT_GI_80 |
2215 IEEE80211_VHT_CAP_SHORT_GI_160 |
2216 IEEE80211_VHT_CAP_TXSTBC |
2217 IEEE80211_VHT_CAP_RXSTBC_1 |
2218 IEEE80211_VHT_CAP_RXSTBC_2 |
2219 IEEE80211_VHT_CAP_RXSTBC_3 |
2220 IEEE80211_VHT_CAP_RXSTBC_4 |
2221 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT;
2222 sband->vht_cap.vht_mcs.rx_mcs_map =
2223 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_8 << 0 |
2224 IEEE80211_VHT_MCS_SUPPORT_0_8 << 2 |
2225 IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 |
2226 IEEE80211_VHT_MCS_SUPPORT_0_8 << 6 |
2227 IEEE80211_VHT_MCS_SUPPORT_0_8 << 8 |
2228 IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 |
2229 IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 |
2230 IEEE80211_VHT_MCS_SUPPORT_0_8 << 14);
2231 sband->vht_cap.vht_mcs.tx_mcs_map =
2232 sband->vht_cap.vht_mcs.rx_mcs_map;
2207 } 2233 }
2208 /* By default all radios are belonging to the first group */ 2234 /* By default all radios are belonging to the first group */
2209 data->group = 1; 2235 data->group = 1;
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 41be319665eb..3b1c27712ad9 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -180,10 +180,8 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
180static int 180static int
181mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 181mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
182 struct ieee80211_channel *chan, bool offchan, 182 struct ieee80211_channel *chan, bool offchan,
183 enum nl80211_channel_type channel_type, 183 unsigned int wait, const u8 *buf, size_t len,
184 bool channel_type_valid, unsigned int wait, 184 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
185 const u8 *buf, size_t len, bool no_cck,
186 bool dont_wait_for_ack, u64 *cookie)
187{ 185{
188 struct sk_buff *skb; 186 struct sk_buff *skb;
189 u16 pkt_len; 187 u16 pkt_len;
@@ -253,7 +251,6 @@ static int
253mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy, 251mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy,
254 struct wireless_dev *wdev, 252 struct wireless_dev *wdev,
255 struct ieee80211_channel *chan, 253 struct ieee80211_channel *chan,
256 enum nl80211_channel_type channel_type,
257 unsigned int duration, u64 *cookie) 254 unsigned int duration, u64 *cookie)
258{ 255{
259 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); 256 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
@@ -271,15 +268,14 @@ mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy,
271 } 268 }
272 269
273 ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_SET, chan, 270 ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_SET, chan,
274 &channel_type, duration); 271 duration);
275 272
276 if (!ret) { 273 if (!ret) {
277 *cookie = random32() | 1; 274 *cookie = random32() | 1;
278 priv->roc_cfg.cookie = *cookie; 275 priv->roc_cfg.cookie = *cookie;
279 priv->roc_cfg.chan = *chan; 276 priv->roc_cfg.chan = *chan;
280 priv->roc_cfg.chan_type = channel_type;
281 277
282 cfg80211_ready_on_channel(wdev, *cookie, chan, channel_type, 278 cfg80211_ready_on_channel(wdev, *cookie, chan,
283 duration, GFP_ATOMIC); 279 duration, GFP_ATOMIC);
284 280
285 wiphy_dbg(wiphy, "info: ROC, cookie = 0x%llx\n", *cookie); 281 wiphy_dbg(wiphy, "info: ROC, cookie = 0x%llx\n", *cookie);
@@ -302,13 +298,11 @@ mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
302 return -ENOENT; 298 return -ENOENT;
303 299
304 ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_REMOVE, 300 ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_REMOVE,
305 &priv->roc_cfg.chan, 301 &priv->roc_cfg.chan, 0);
306 &priv->roc_cfg.chan_type, 0);
307 302
308 if (!ret) { 303 if (!ret) {
309 cfg80211_remain_on_channel_expired(wdev, cookie, 304 cfg80211_remain_on_channel_expired(wdev, cookie,
310 &priv->roc_cfg.chan, 305 &priv->roc_cfg.chan,
311 priv->roc_cfg.chan_type,
312 GFP_ATOMIC); 306 GFP_ATOMIC);
313 307
314 memset(&priv->roc_cfg, 0, sizeof(struct mwifiex_roc_cfg)); 308 memset(&priv->roc_cfg, 0, sizeof(struct mwifiex_roc_cfg));
@@ -1297,21 +1291,23 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1297 return -EINVAL; 1291 return -EINVAL;
1298 } 1292 }
1299 1293
1300 bss_cfg->channel = 1294 bss_cfg->channel = ieee80211_frequency_to_channel(
1301 (u8)ieee80211_frequency_to_channel(params->channel->center_freq); 1295 params->chandef.chan->center_freq);
1302 1296
1303 /* Set appropriate bands */ 1297 /* Set appropriate bands */
1304 if (params->channel->band == IEEE80211_BAND_2GHZ) { 1298 if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
1305 bss_cfg->band_cfg = BAND_CONFIG_BG; 1299 bss_cfg->band_cfg = BAND_CONFIG_BG;
1306 1300
1307 if (params->channel_type == NL80211_CHAN_NO_HT) 1301 if (cfg80211_get_chandef_type(&params->chandef) ==
1302 NL80211_CHAN_NO_HT)
1308 config_bands = BAND_B | BAND_G; 1303 config_bands = BAND_B | BAND_G;
1309 else 1304 else
1310 config_bands = BAND_B | BAND_G | BAND_GN; 1305 config_bands = BAND_B | BAND_G | BAND_GN;
1311 } else { 1306 } else {
1312 bss_cfg->band_cfg = BAND_CONFIG_A; 1307 bss_cfg->band_cfg = BAND_CONFIG_A;
1313 1308
1314 if (params->channel_type == NL80211_CHAN_NO_HT) 1309 if (cfg80211_get_chandef_type(&params->chandef) ==
1310 NL80211_CHAN_NO_HT)
1315 config_bands = BAND_A; 1311 config_bands = BAND_A;
1316 else 1312 else
1317 config_bands = BAND_AN | BAND_A; 1313 config_bands = BAND_AN | BAND_A;
@@ -1684,7 +1680,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
1684 int index = 0, i; 1680 int index = 0, i;
1685 u8 config_bands = 0; 1681 u8 config_bands = 0;
1686 1682
1687 if (params->channel->band == IEEE80211_BAND_2GHZ) { 1683 if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
1688 if (!params->basic_rates) { 1684 if (!params->basic_rates) {
1689 config_bands = BAND_B | BAND_G; 1685 config_bands = BAND_B | BAND_G;
1690 } else { 1686 } else {
@@ -1709,10 +1705,12 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
1709 } 1705 }
1710 } 1706 }
1711 1707
1712 if (params->channel_type != NL80211_CHAN_NO_HT) 1708 if (cfg80211_get_chandef_type(&params->chandef) !=
1709 NL80211_CHAN_NO_HT)
1713 config_bands |= BAND_GN; 1710 config_bands |= BAND_GN;
1714 } else { 1711 } else {
1715 if (params->channel_type == NL80211_CHAN_NO_HT) 1712 if (cfg80211_get_chandef_type(&params->chandef) !=
1713 NL80211_CHAN_NO_HT)
1716 config_bands = BAND_A; 1714 config_bands = BAND_A;
1717 else 1715 else
1718 config_bands = BAND_AN | BAND_A; 1716 config_bands = BAND_AN | BAND_A;
@@ -1729,9 +1727,10 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
1729 } 1727 }
1730 1728
1731 adapter->sec_chan_offset = 1729 adapter->sec_chan_offset =
1732 mwifiex_chan_type_to_sec_chan_offset(params->channel_type); 1730 mwifiex_chan_type_to_sec_chan_offset(
1733 priv->adhoc_channel = 1731 cfg80211_get_chandef_type(&params->chandef));
1734 ieee80211_frequency_to_channel(params->channel->center_freq); 1732 priv->adhoc_channel = ieee80211_frequency_to_channel(
1733 params->chandef.chan->center_freq);
1735 1734
1736 wiphy_dbg(wiphy, "info: set ibss band %d, chan %d, chan offset %d\n", 1735 wiphy_dbg(wiphy, "info: set ibss band %d, chan %d, chan offset %d\n",
1737 config_bands, priv->adhoc_channel, adapter->sec_chan_offset); 1736 config_bands, priv->adhoc_channel, adapter->sec_chan_offset);
@@ -1765,7 +1764,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1765 1764
1766 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, 1765 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
1767 params->bssid, priv->bss_mode, 1766 params->bssid, priv->bss_mode,
1768 params->channel, NULL, params->privacy); 1767 params->chandef.chan, NULL,
1768 params->privacy);
1769done: 1769done:
1770 if (!ret) { 1770 if (!ret) {
1771 cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL); 1771 cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index db57dd430e92..1b3cfc821940 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -371,7 +371,6 @@ struct wps {
371struct mwifiex_roc_cfg { 371struct mwifiex_roc_cfg {
372 u64 cookie; 372 u64 cookie;
373 struct ieee80211_channel chan; 373 struct ieee80211_channel chan;
374 enum nl80211_channel_type chan_type;
375}; 374};
376 375
377struct mwifiex_adapter; 376struct mwifiex_adapter;
@@ -1018,7 +1017,6 @@ int mwifiex_get_ver_ext(struct mwifiex_private *priv);
1018 1017
1019int mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action, 1018int mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1020 struct ieee80211_channel *chan, 1019 struct ieee80211_channel *chan,
1021 enum nl80211_channel_type *channel_type,
1022 unsigned int duration); 1020 unsigned int duration);
1023 1021
1024int mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role); 1022int mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role);
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 5b0d71969ba7..41aafc7454ed 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -421,7 +421,6 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
421 cfg80211_remain_on_channel_expired(priv->wdev, 421 cfg80211_remain_on_channel_expired(priv->wdev,
422 priv->roc_cfg.cookie, 422 priv->roc_cfg.cookie,
423 &priv->roc_cfg.chan, 423 &priv->roc_cfg.chan,
424 priv->roc_cfg.chan_type,
425 GFP_ATOMIC); 424 GFP_ATOMIC);
426 425
427 memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg)); 426 memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg));
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index c8b50c70a03d..237c8d2ba9f2 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -1044,7 +1044,6 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv)
1044int 1044int
1045mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action, 1045mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1046 struct ieee80211_channel *chan, 1046 struct ieee80211_channel *chan,
1047 enum nl80211_channel_type *ct,
1048 unsigned int duration) 1047 unsigned int duration)
1049{ 1048{
1050 struct host_cmd_ds_remain_on_chan roc_cfg; 1049 struct host_cmd_ds_remain_on_chan roc_cfg;
@@ -1054,7 +1053,7 @@ mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1054 roc_cfg.action = cpu_to_le16(action); 1053 roc_cfg.action = cpu_to_le16(action);
1055 if (action == HostCmd_ACT_GEN_SET) { 1054 if (action == HostCmd_ACT_GEN_SET) {
1056 roc_cfg.band_cfg = chan->band; 1055 roc_cfg.band_cfg = chan->band;
1057 sc = mwifiex_chan_type_to_sec_chan_offset(*ct); 1056 sc = mwifiex_chan_type_to_sec_chan_offset(NL80211_CHAN_NO_HT);
1058 roc_cfg.band_cfg |= (sc << 2); 1057 roc_cfg.band_cfg |= (sc << 2);
1059 1058
1060 roc_cfg.channel = 1059 roc_cfg.channel =
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
index 7b751fba7e1f..d01edd2c50c5 100644
--- a/drivers/net/wireless/orinoco/cfg.c
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -161,24 +161,23 @@ static int orinoco_scan(struct wiphy *wiphy,
161} 161}
162 162
163static int orinoco_set_monitor_channel(struct wiphy *wiphy, 163static int orinoco_set_monitor_channel(struct wiphy *wiphy,
164 struct ieee80211_channel *chan, 164 struct cfg80211_chan_def *chandef)
165 enum nl80211_channel_type channel_type)
166{ 165{
167 struct orinoco_private *priv = wiphy_priv(wiphy); 166 struct orinoco_private *priv = wiphy_priv(wiphy);
168 int err = 0; 167 int err = 0;
169 unsigned long flags; 168 unsigned long flags;
170 int channel; 169 int channel;
171 170
172 if (!chan) 171 if (!chandef->chan)
173 return -EINVAL; 172 return -EINVAL;
174 173
175 if (channel_type != NL80211_CHAN_NO_HT) 174 if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT)
176 return -EINVAL; 175 return -EINVAL;
177 176
178 if (chan->band != IEEE80211_BAND_2GHZ) 177 if (chandef->chan->band != IEEE80211_BAND_2GHZ)
179 return -EINVAL; 178 return -EINVAL;
180 179
181 channel = ieee80211_freq_to_dsss_chan(chan->center_freq); 180 channel = ieee80211_freq_to_dsss_chan(chandef->chan->center_freq);
182 181
183 if ((channel < 1) || (channel > NUM_CHANNELS) || 182 if ((channel < 1) || (channel > NUM_CHANNELS) ||
184 !(priv->channel_mask & (1 << (channel - 1)))) 183 !(priv->channel_mask & (1 << (channel - 1))))
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 5390af36c064..abe1d039be81 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -2293,7 +2293,7 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
2293{ 2293{
2294 struct rndis_wlan_private *priv = wiphy_priv(wiphy); 2294 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2295 struct usbnet *usbdev = priv->usbdev; 2295 struct usbnet *usbdev = priv->usbdev;
2296 struct ieee80211_channel *channel = params->channel; 2296 struct ieee80211_channel *channel = params->chandef.chan;
2297 struct ndis_80211_ssid ssid; 2297 struct ndis_80211_ssid ssid;
2298 enum nl80211_auth_type auth_type; 2298 enum nl80211_auth_type auth_type;
2299 int ret, alg, length, chan = -1; 2299 int ret, alg, length, chan = -1;
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 380cf1ff6cd1..4f1a05b92d2d 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -3791,7 +3791,7 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
3791 3791
3792 /* Handle HT information change */ 3792 /* Handle HT information change */
3793 if ((changed & BSS_CHANGED_HT) && 3793 if ((changed & BSS_CHANGED_HT) &&
3794 (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { 3794 (bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) {
3795 ret = wl1271_acx_set_ht_information(wl, wlvif, 3795 ret = wl1271_acx_set_ht_information(wl, wlvif,
3796 bss_conf->ht_operation_mode); 3796 bss_conf->ht_operation_mode);
3797 if (ret < 0) { 3797 if (ret < 0) {
@@ -3905,7 +3905,8 @@ sta_not_found:
3905 u32 rates; 3905 u32 rates;
3906 int ieoffset; 3906 int ieoffset;
3907 wlvif->aid = bss_conf->aid; 3907 wlvif->aid = bss_conf->aid;
3908 wlvif->channel_type = bss_conf->channel_type; 3908 wlvif->channel_type =
3909 cfg80211_get_chandef_type(&bss_conf->chandef);
3909 wlvif->beacon_int = bss_conf->beacon_int; 3910 wlvif->beacon_int = bss_conf->beacon_int;
3910 do_join = true; 3911 do_join = true;
3911 set_assoc = true; 3912 set_assoc = true;
@@ -4071,7 +4072,7 @@ sta_not_found:
4071 /* Handle new association with HT. Do this after join. */ 4072 /* Handle new association with HT. Do this after join. */
4072 if (sta_exists) { 4073 if (sta_exists) {
4073 if ((changed & BSS_CHANGED_HT) && 4074 if ((changed & BSS_CHANGED_HT) &&
4074 (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { 4075 (bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) {
4075 ret = wl1271_acx_set_ht_capabilities(wl, 4076 ret = wl1271_acx_set_ht_capabilities(wl,
4076 &sta_ht_cap, 4077 &sta_ht_cap,
4077 true, 4078 true,
@@ -4098,7 +4099,7 @@ sta_not_found:
4098 4099
4099 /* Handle HT information change. Done after join. */ 4100 /* Handle HT information change. Done after join. */
4100 if ((changed & BSS_CHANGED_HT) && 4101 if ((changed & BSS_CHANGED_HT) &&
4101 (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { 4102 (bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) {
4102 ret = wl1271_acx_set_ht_information(wl, wlvif, 4103 ret = wl1271_acx_set_ht_information(wl, wlvif,
4103 bss_conf->ht_operation_mode); 4104 bss_conf->ht_operation_mode);
4104 if (ret < 0) { 4105 if (ret < 0) {
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index d68790903b9e..f9c5a787d350 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -668,6 +668,21 @@ struct ieee80211_meshconf_ie {
668} __attribute__ ((packed)); 668} __attribute__ ((packed));
669 669
670/** 670/**
671 * enum mesh_config_capab_flags - Mesh Configuration IE capability field flags
672 *
673 * @IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS: STA is willing to establish
674 * additional mesh peerings with other mesh STAs
675 * @IEEE80211_MESHCONF_CAPAB_FORWARDING: the STA forwards MSDUs
676 * @IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING: TBTT adjustment procedure
677 * is ongoing
678 */
679enum mesh_config_capab_flags {
680 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS = 0x01,
681 IEEE80211_MESHCONF_CAPAB_FORWARDING = 0x08,
682 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING = 0x20,
683};
684
685/**
671 * struct ieee80211_rann_ie 686 * struct ieee80211_rann_ie
672 * 687 *
673 * This structure refers to "Root Announcement information element" 688 * This structure refers to "Root Announcement information element"
@@ -1148,11 +1163,13 @@ struct ieee80211_ht_operation {
1148 * STA can receive. Rate expressed in units of 1 Mbps. 1163 * STA can receive. Rate expressed in units of 1 Mbps.
1149 * If this field is 0 this value should not be used to 1164 * If this field is 0 this value should not be used to
1150 * consider the highest RX data rate supported. 1165 * consider the highest RX data rate supported.
1166 * The top 3 bits of this field are reserved.
1151 * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams 1167 * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams
1152 * @tx_highest: Indicates highest long GI VHT PPDU data rate 1168 * @tx_highest: Indicates highest long GI VHT PPDU data rate
1153 * STA can transmit. Rate expressed in units of 1 Mbps. 1169 * STA can transmit. Rate expressed in units of 1 Mbps.
1154 * If this field is 0 this value should not be used to 1170 * If this field is 0 this value should not be used to
1155 * consider the highest TX data rate supported. 1171 * consider the highest TX data rate supported.
1172 * The top 3 bits of this field are reserved.
1156 */ 1173 */
1157struct ieee80211_vht_mcs_info { 1174struct ieee80211_vht_mcs_info {
1158 __le16 rx_mcs_map; 1175 __le16 rx_mcs_map;
@@ -1162,6 +1179,27 @@ struct ieee80211_vht_mcs_info {
1162} __packed; 1179} __packed;
1163 1180
1164/** 1181/**
1182 * enum ieee80211_vht_mcs_support - VHT MCS support definitions
1183 * @IEEE80211_VHT_MCS_SUPPORT_0_7: MCSes 0-7 are supported for the
1184 * number of streams
1185 * @IEEE80211_VHT_MCS_SUPPORT_0_8: MCSes 0-8 are supported
1186 * @IEEE80211_VHT_MCS_SUPPORT_0_9: MCSes 0-9 are supported
1187 * @IEEE80211_VHT_MCS_NOT_SUPPORTED: This number of streams isn't supported
1188 *
1189 * These definitions are used in each 2-bit subfield of the @rx_mcs_map
1190 * and @tx_mcs_map fields of &struct ieee80211_vht_mcs_info, which are
1191 * both split into 8 subfields by number of streams. These values indicate
1192 * which MCSes are supported for the number of streams the value appears
1193 * for.
1194 */
1195enum ieee80211_vht_mcs_support {
1196 IEEE80211_VHT_MCS_SUPPORT_0_7 = 0,
1197 IEEE80211_VHT_MCS_SUPPORT_0_8 = 1,
1198 IEEE80211_VHT_MCS_SUPPORT_0_9 = 2,
1199 IEEE80211_VHT_MCS_NOT_SUPPORTED = 3,
1200};
1201
1202/**
1165 * struct ieee80211_vht_cap - VHT capabilities 1203 * struct ieee80211_vht_cap - VHT capabilities
1166 * 1204 *
1167 * This structure is the "VHT capabilities element" as 1205 * This structure is the "VHT capabilities element" as
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 8a1aec54e68f..e78db2cf3d1b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -306,6 +306,88 @@ struct key_params {
306}; 306};
307 307
308/** 308/**
309 * struct cfg80211_chan_def - channel definition
310 * @chan: the (control) channel
311 * @width: channel width
312 * @center_freq1: center frequency of first segment
313 * @center_freq2: center frequency of second segment
314 * (only with 80+80 MHz)
315 */
316struct cfg80211_chan_def {
317 struct ieee80211_channel *chan;
318 enum nl80211_chan_width width;
319 u32 center_freq1;
320 u32 center_freq2;
321};
322
323/**
324 * cfg80211_get_chandef_type - return old channel type from chandef
325 * @chandef: the channel definition
326 *
327 * Returns the old channel type (NOHT, HT20, HT40+/-) from a given
328 * chandef, which must have a bandwidth allowing this conversion.
329 */
330static inline enum nl80211_channel_type
331cfg80211_get_chandef_type(const struct cfg80211_chan_def *chandef)
332{
333 switch (chandef->width) {
334 case NL80211_CHAN_WIDTH_20_NOHT:
335 return NL80211_CHAN_NO_HT;
336 case NL80211_CHAN_WIDTH_20:
337 return NL80211_CHAN_HT20;
338 case NL80211_CHAN_WIDTH_40:
339 if (chandef->center_freq1 > chandef->chan->center_freq)
340 return NL80211_CHAN_HT40PLUS;
341 return NL80211_CHAN_HT40MINUS;
342 default:
343 WARN_ON(1);
344 return NL80211_CHAN_NO_HT;
345 }
346}
347
348/**
349 * cfg80211_chandef_create - create channel definition using channel type
350 * @chandef: the channel definition struct to fill
351 * @channel: the control channel
352 * @chantype: the channel type
353 *
354 * Given a channel type, create a channel definition.
355 */
356void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
357 struct ieee80211_channel *channel,
358 enum nl80211_channel_type chantype);
359
360/**
361 * cfg80211_chandef_identical - check if two channel definitions are identical
362 * @chandef1: first channel definition
363 * @chandef2: second channel definition
364 *
365 * Returns %true if the channels defined by the channel definitions are
366 * identical, %false otherwise.
367 */
368static inline bool
369cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1,
370 const struct cfg80211_chan_def *chandef2)
371{
372 return (chandef1->chan == chandef2->chan &&
373 chandef1->width == chandef2->width &&
374 chandef1->center_freq1 == chandef2->center_freq1 &&
375 chandef1->center_freq2 == chandef2->center_freq2);
376}
377
378/**
379 * cfg80211_chandef_compatible - check if two channel definitions are compatible
380 * @chandef1: first channel definition
381 * @chandef2: second channel definition
382 *
383 * Returns %NULL if the given channel definitions are incompatible,
384 * chandef1 or chandef2 otherwise.
385 */
386const struct cfg80211_chan_def *
387cfg80211_chandef_compatible(const struct cfg80211_chan_def *chandef1,
388 const struct cfg80211_chan_def *chandef2);
389
390/**
309 * enum survey_info_flags - survey information flags 391 * enum survey_info_flags - survey information flags
310 * 392 *
311 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in 393 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in
@@ -426,8 +508,7 @@ struct cfg80211_beacon_data {
426 * 508 *
427 * Used to configure an AP interface. 509 * Used to configure an AP interface.
428 * 510 *
429 * @channel: the channel to start the AP on 511 * @chandef: defines the channel to use
430 * @channel_type: the channel type to use
431 * @beacon: beacon data 512 * @beacon: beacon data
432 * @beacon_interval: beacon interval 513 * @beacon_interval: beacon interval
433 * @dtim_period: DTIM period 514 * @dtim_period: DTIM period
@@ -441,8 +522,7 @@ struct cfg80211_beacon_data {
441 * @inactivity_timeout: time in seconds to determine station's inactivity. 522 * @inactivity_timeout: time in seconds to determine station's inactivity.
442 */ 523 */
443struct cfg80211_ap_settings { 524struct cfg80211_ap_settings {
444 struct ieee80211_channel *channel; 525 struct cfg80211_chan_def chandef;
445 enum nl80211_channel_type channel_type;
446 526
447 struct cfg80211_beacon_data beacon; 527 struct cfg80211_beacon_data beacon;
448 528
@@ -582,16 +662,24 @@ enum station_info_flags {
582 * Used by the driver to indicate the specific rate transmission 662 * Used by the driver to indicate the specific rate transmission
583 * type for 802.11n transmissions. 663 * type for 802.11n transmissions.
584 * 664 *
585 * @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled 665 * @RATE_INFO_FLAGS_MCS: mcs field filled with HT MCS
586 * @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission 666 * @RATE_INFO_FLAGS_VHT_MCS: mcs field filled with VHT MCS
667 * @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 MHz width transmission
668 * @RATE_INFO_FLAGS_80_MHZ_WIDTH: 80 MHz width transmission
669 * @RATE_INFO_FLAGS_80P80_MHZ_WIDTH: 80+80 MHz width transmission
670 * @RATE_INFO_FLAGS_160_MHZ_WIDTH: 160 MHz width transmission
587 * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval 671 * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval
588 * @RATE_INFO_FLAGS_60G: 60gHz MCS 672 * @RATE_INFO_FLAGS_60G: 60GHz MCS
589 */ 673 */
590enum rate_info_flags { 674enum rate_info_flags {
591 RATE_INFO_FLAGS_MCS = 1<<0, 675 RATE_INFO_FLAGS_MCS = BIT(0),
592 RATE_INFO_FLAGS_40_MHZ_WIDTH = 1<<1, 676 RATE_INFO_FLAGS_VHT_MCS = BIT(1),
593 RATE_INFO_FLAGS_SHORT_GI = 1<<2, 677 RATE_INFO_FLAGS_40_MHZ_WIDTH = BIT(2),
594 RATE_INFO_FLAGS_60G = 1<<3, 678 RATE_INFO_FLAGS_80_MHZ_WIDTH = BIT(3),
679 RATE_INFO_FLAGS_80P80_MHZ_WIDTH = BIT(4),
680 RATE_INFO_FLAGS_160_MHZ_WIDTH = BIT(5),
681 RATE_INFO_FLAGS_SHORT_GI = BIT(6),
682 RATE_INFO_FLAGS_60G = BIT(7),
595}; 683};
596 684
597/** 685/**
@@ -602,11 +690,13 @@ enum rate_info_flags {
602 * @flags: bitflag of flags from &enum rate_info_flags 690 * @flags: bitflag of flags from &enum rate_info_flags
603 * @mcs: mcs index if struct describes a 802.11n bitrate 691 * @mcs: mcs index if struct describes a 802.11n bitrate
604 * @legacy: bitrate in 100kbit/s for 802.11abg 692 * @legacy: bitrate in 100kbit/s for 802.11abg
693 * @nss: number of streams (VHT only)
605 */ 694 */
606struct rate_info { 695struct rate_info {
607 u8 flags; 696 u8 flags;
608 u8 mcs; 697 u8 mcs;
609 u16 legacy; 698 u16 legacy;
699 u8 nss;
610}; 700};
611 701
612/** 702/**
@@ -909,8 +999,7 @@ struct mesh_config {
909 999
910/** 1000/**
911 * struct mesh_setup - 802.11s mesh setup configuration 1001 * struct mesh_setup - 802.11s mesh setup configuration
912 * @channel: the channel to start the mesh network on 1002 * @chandef: defines the channel to use
913 * @channel_type: the channel type to use
914 * @mesh_id: the mesh ID 1003 * @mesh_id: the mesh ID
915 * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes 1004 * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes
916 * @sync_method: which synchronization method to use 1005 * @sync_method: which synchronization method to use
@@ -925,8 +1014,7 @@ struct mesh_config {
925 * These parameters are fixed when the mesh is created. 1014 * These parameters are fixed when the mesh is created.
926 */ 1015 */
927struct mesh_setup { 1016struct mesh_setup {
928 struct ieee80211_channel *channel; 1017 struct cfg80211_chan_def chandef;
929 enum nl80211_channel_type channel_type;
930 const u8 *mesh_id; 1018 const u8 *mesh_id;
931 u8 mesh_id_len; 1019 u8 mesh_id_len;
932 u8 sync_method; 1020 u8 sync_method;
@@ -1266,8 +1354,7 @@ struct cfg80211_disassoc_request {
1266 * @ssid_len: The length of the SSID, will always be non-zero. 1354 * @ssid_len: The length of the SSID, will always be non-zero.
1267 * @bssid: Fixed BSSID requested, maybe be %NULL, if set do not 1355 * @bssid: Fixed BSSID requested, maybe be %NULL, if set do not
1268 * search for IBSSs with a different BSSID. 1356 * search for IBSSs with a different BSSID.
1269 * @channel: The channel to use if no IBSS can be found to join. 1357 * @chandef: defines the channel to use if no other IBSS to join can be found
1270 * @channel_type: channel type (HT mode)
1271 * @channel_fixed: The channel should be fixed -- do not search for 1358 * @channel_fixed: The channel should be fixed -- do not search for
1272 * IBSSs to join on other channels. 1359 * IBSSs to join on other channels.
1273 * @ie: information element(s) to include in the beacon 1360 * @ie: information element(s) to include in the beacon
@@ -1285,8 +1372,7 @@ struct cfg80211_disassoc_request {
1285struct cfg80211_ibss_params { 1372struct cfg80211_ibss_params {
1286 u8 *ssid; 1373 u8 *ssid;
1287 u8 *bssid; 1374 u8 *bssid;
1288 struct ieee80211_channel *channel; 1375 struct cfg80211_chan_def chandef;
1289 enum nl80211_channel_type channel_type;
1290 u8 *ie; 1376 u8 *ie;
1291 u8 ssid_len, ie_len; 1377 u8 ssid_len, ie_len;
1292 u16 beacon_interval; 1378 u16 beacon_interval;
@@ -1728,8 +1814,7 @@ struct cfg80211_ops {
1728 struct ieee80211_channel *chan); 1814 struct ieee80211_channel *chan);
1729 1815
1730 int (*set_monitor_channel)(struct wiphy *wiphy, 1816 int (*set_monitor_channel)(struct wiphy *wiphy,
1731 struct ieee80211_channel *chan, 1817 struct cfg80211_chan_def *chandef);
1732 enum nl80211_channel_type channel_type);
1733 1818
1734 int (*scan)(struct wiphy *wiphy, 1819 int (*scan)(struct wiphy *wiphy,
1735 struct cfg80211_scan_request *request); 1820 struct cfg80211_scan_request *request);
@@ -1791,7 +1876,6 @@ struct cfg80211_ops {
1791 int (*remain_on_channel)(struct wiphy *wiphy, 1876 int (*remain_on_channel)(struct wiphy *wiphy,
1792 struct wireless_dev *wdev, 1877 struct wireless_dev *wdev,
1793 struct ieee80211_channel *chan, 1878 struct ieee80211_channel *chan,
1794 enum nl80211_channel_type channel_type,
1795 unsigned int duration, 1879 unsigned int duration,
1796 u64 *cookie); 1880 u64 *cookie);
1797 int (*cancel_remain_on_channel)(struct wiphy *wiphy, 1881 int (*cancel_remain_on_channel)(struct wiphy *wiphy,
@@ -1800,10 +1884,8 @@ struct cfg80211_ops {
1800 1884
1801 int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev, 1885 int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev,
1802 struct ieee80211_channel *chan, bool offchan, 1886 struct ieee80211_channel *chan, bool offchan,
1803 enum nl80211_channel_type channel_type, 1887 unsigned int wait, const u8 *buf, size_t len,
1804 bool channel_type_valid, unsigned int wait, 1888 bool no_cck, bool dont_wait_for_ack, u64 *cookie);
1805 const u8 *buf, size_t len, bool no_cck,
1806 bool dont_wait_for_ack, u64 *cookie);
1807 int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy, 1889 int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
1808 struct wireless_dev *wdev, 1890 struct wireless_dev *wdev,
1809 u64 cookie); 1891 u64 cookie);
@@ -1858,10 +1940,9 @@ struct cfg80211_ops {
1858 void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev, 1940 void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev,
1859 u32 sset, u8 *data); 1941 u32 sset, u8 *data);
1860 1942
1861 struct ieee80211_channel * 1943 int (*get_channel)(struct wiphy *wiphy,
1862 (*get_channel)(struct wiphy *wiphy,
1863 struct wireless_dev *wdev, 1944 struct wireless_dev *wdev,
1864 enum nl80211_channel_type *type); 1945 struct cfg80211_chan_def *chandef);
1865 1946
1866 int (*start_p2p_device)(struct wiphy *wiphy, 1947 int (*start_p2p_device)(struct wiphy *wiphy,
1867 struct wireless_dev *wdev); 1948 struct wireless_dev *wdev);
@@ -2469,8 +2550,7 @@ struct wireless_dev {
2469 spinlock_t event_lock; 2550 spinlock_t event_lock;
2470 2551
2471 struct cfg80211_internal_bss *current_bss; /* associated / joined */ 2552 struct cfg80211_internal_bss *current_bss; /* associated / joined */
2472 struct ieee80211_channel *preset_chan; 2553 struct cfg80211_chan_def preset_chandef;
2473 enum nl80211_channel_type preset_chantype;
2474 2554
2475 /* for AP and mesh channel tracking */ 2555 /* for AP and mesh channel tracking */
2476 struct ieee80211_channel *channel; 2556 struct ieee80211_channel *channel;
@@ -3350,14 +3430,12 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason,
3350 * @wdev: wireless device 3430 * @wdev: wireless device
3351 * @cookie: the request cookie 3431 * @cookie: the request cookie
3352 * @chan: The current channel (from remain_on_channel request) 3432 * @chan: The current channel (from remain_on_channel request)
3353 * @channel_type: Channel type
3354 * @duration: Duration in milliseconds that the driver intents to remain on the 3433 * @duration: Duration in milliseconds that the driver intents to remain on the
3355 * channel 3434 * channel
3356 * @gfp: allocation flags 3435 * @gfp: allocation flags
3357 */ 3436 */
3358void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie, 3437void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
3359 struct ieee80211_channel *chan, 3438 struct ieee80211_channel *chan,
3360 enum nl80211_channel_type channel_type,
3361 unsigned int duration, gfp_t gfp); 3439 unsigned int duration, gfp_t gfp);
3362 3440
3363/** 3441/**
@@ -3365,12 +3443,10 @@ void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
3365 * @wdev: wireless device 3443 * @wdev: wireless device
3366 * @cookie: the request cookie 3444 * @cookie: the request cookie
3367 * @chan: The current channel (from remain_on_channel request) 3445 * @chan: The current channel (from remain_on_channel request)
3368 * @channel_type: Channel type
3369 * @gfp: allocation flags 3446 * @gfp: allocation flags
3370 */ 3447 */
3371void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie, 3448void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
3372 struct ieee80211_channel *chan, 3449 struct ieee80211_channel *chan,
3373 enum nl80211_channel_type channel_type,
3374 gfp_t gfp); 3450 gfp_t gfp);
3375 3451
3376 3452
@@ -3570,28 +3646,25 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
3570 int freq, int sig_dbm); 3646 int freq, int sig_dbm);
3571 3647
3572/** 3648/**
3573 * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used 3649 * cfg80211_reg_can_beacon - check if beaconing is allowed
3574 * @wiphy: the wiphy 3650 * @wiphy: the wiphy
3575 * @chan: main channel 3651 * @chandef: the channel definition
3576 * @channel_type: HT mode
3577 * 3652 *
3578 * This function returns true if there is no secondary channel or the secondary 3653 * This function returns true if there is no secondary channel or the secondary
3579 * channel can be used for beaconing (i.e. is not a radar channel etc.) 3654 * channel(s) can be used for beaconing (i.e. is not a radar channel etc.)
3580 */ 3655 */
3581bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, 3656bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
3582 struct ieee80211_channel *chan, 3657 struct cfg80211_chan_def *chandef);
3583 enum nl80211_channel_type channel_type);
3584 3658
3585/* 3659/*
3586 * cfg80211_ch_switch_notify - update wdev channel and notify userspace 3660 * cfg80211_ch_switch_notify - update wdev channel and notify userspace
3587 * @dev: the device which switched channels 3661 * @dev: the device which switched channels
3588 * @freq: new channel frequency (in MHz) 3662 * @chandef: the new channel definition
3589 * @type: channel type
3590 * 3663 *
3591 * Acquires wdev_lock, so must only be called from sleepable driver context! 3664 * Acquires wdev_lock, so must only be called from sleepable driver context!
3592 */ 3665 */
3593void cfg80211_ch_switch_notify(struct net_device *dev, int freq, 3666void cfg80211_ch_switch_notify(struct net_device *dev,
3594 enum nl80211_channel_type type); 3667 struct cfg80211_chan_def *chandef);
3595 3668
3596/* 3669/*
3597 * cfg80211_tdls_oper_request - request userspace to perform TDLS operation 3670 * cfg80211_tdls_oper_request - request userspace to perform TDLS operation
@@ -3652,8 +3725,9 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev);
3652 * the data is malformed or the attribute can't be found (respectively), 3725 * the data is malformed or the attribute can't be found (respectively),
3653 * or the length of the found attribute (which can be zero). 3726 * or the length of the found attribute (which can be zero).
3654 */ 3727 */
3655unsigned int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len, 3728int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
3656 u8 attr, u8 *buf, unsigned int bufsize); 3729 enum ieee80211_p2p_attr_id attr,
3730 u8 *buf, unsigned int bufsize);
3657 3731
3658/* Logging, debugging and troubleshooting/diagnostic helpers. */ 3732/* Logging, debugging and troubleshooting/diagnostic helpers. */
3659 3733
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index e1293c7e4d2c..db7680acd0da 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -145,11 +145,11 @@ struct ieee80211_low_level_stats {
145 145
146/** 146/**
147 * enum ieee80211_chanctx_change - change flag for channel context 147 * enum ieee80211_chanctx_change - change flag for channel context
148 * @IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE: The channel type was changed 148 * @IEEE80211_CHANCTX_CHANGE_WIDTH: The channel width changed
149 * @IEEE80211_CHANCTX_CHANGE_RX_CHAINS: The number of RX chains changed 149 * @IEEE80211_CHANCTX_CHANGE_RX_CHAINS: The number of RX chains changed
150 */ 150 */
151enum ieee80211_chanctx_change { 151enum ieee80211_chanctx_change {
152 IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE = BIT(0), 152 IEEE80211_CHANCTX_CHANGE_WIDTH = BIT(0),
153 IEEE80211_CHANCTX_CHANGE_RX_CHAINS = BIT(1), 153 IEEE80211_CHANCTX_CHANGE_RX_CHAINS = BIT(1),
154}; 154};
155 155
@@ -159,8 +159,7 @@ enum ieee80211_chanctx_change {
159 * This is the driver-visible part. The ieee80211_chanctx 159 * This is the driver-visible part. The ieee80211_chanctx
160 * that contains it is visible in mac80211 only. 160 * that contains it is visible in mac80211 only.
161 * 161 *
162 * @channel: the channel to tune to 162 * @def: the channel definition
163 * @channel_type: the channel (HT) type
164 * @rx_chains_static: The number of RX chains that must always be 163 * @rx_chains_static: The number of RX chains that must always be
165 * active on the channel to receive MIMO transmissions 164 * active on the channel to receive MIMO transmissions
166 * @rx_chains_dynamic: The number of RX chains that must be enabled 165 * @rx_chains_dynamic: The number of RX chains that must be enabled
@@ -170,8 +169,7 @@ enum ieee80211_chanctx_change {
170 * sizeof(void *), size is determined in hw information. 169 * sizeof(void *), size is determined in hw information.
171 */ 170 */
172struct ieee80211_chanctx_conf { 171struct ieee80211_chanctx_conf {
173 struct ieee80211_channel *channel; 172 struct cfg80211_chan_def def;
174 enum nl80211_channel_type channel_type;
175 173
176 u8 rx_chains_static, rx_chains_dynamic; 174 u8 rx_chains_static, rx_chains_dynamic;
177 175
@@ -288,9 +286,8 @@ enum ieee80211_rssi_event {
288 * @mcast_rate: per-band multicast rate index + 1 (0: disabled) 286 * @mcast_rate: per-band multicast rate index + 1 (0: disabled)
289 * @bssid: The BSSID for this BSS 287 * @bssid: The BSSID for this BSS
290 * @enable_beacon: whether beaconing should be enabled or not 288 * @enable_beacon: whether beaconing should be enabled or not
291 * @channel_type: Channel type for this BSS -- the hardware might be 289 * @chandef: Channel definition for this BSS -- the hardware might be
292 * configured for HT40+ while this BSS only uses no-HT, for 290 * configured a higher bandwidth than this BSS uses, for example.
293 * example.
294 * @ht_operation_mode: HT operation mode like in &struct ieee80211_ht_operation. 291 * @ht_operation_mode: HT operation mode like in &struct ieee80211_ht_operation.
295 * This field is only valid when the channel type is one of the HT types. 292 * This field is only valid when the channel type is one of the HT types.
296 * @cqm_rssi_thold: Connection quality monitor RSSI threshold, a zero value 293 * @cqm_rssi_thold: Connection quality monitor RSSI threshold, a zero value
@@ -339,7 +336,7 @@ struct ieee80211_bss_conf {
339 u16 ht_operation_mode; 336 u16 ht_operation_mode;
340 s32 cqm_rssi_thold; 337 s32 cqm_rssi_thold;
341 u32 cqm_rssi_hyst; 338 u32 cqm_rssi_hyst;
342 enum nl80211_channel_type channel_type; 339 struct cfg80211_chan_def chandef;
343 __be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN]; 340 __be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN];
344 u8 arp_addr_cnt; 341 u8 arp_addr_cnt;
345 bool arp_filter_enabled; 342 bool arp_filter_enabled;
@@ -502,9 +499,14 @@ enum mac80211_tx_control_flags {
502 * This is set if the current BSS requires ERP protection. 499 * This is set if the current BSS requires ERP protection.
503 * @IEEE80211_TX_RC_USE_SHORT_PREAMBLE: Use short preamble. 500 * @IEEE80211_TX_RC_USE_SHORT_PREAMBLE: Use short preamble.
504 * @IEEE80211_TX_RC_MCS: HT rate. 501 * @IEEE80211_TX_RC_MCS: HT rate.
502 * @IEEE80211_TX_RC_VHT_MCS: VHT MCS rate, in this case the idx field is split
503 * into a higher 4 bits (Nss) and lower 4 bits (MCS number)
505 * @IEEE80211_TX_RC_GREEN_FIELD: Indicates whether this rate should be used in 504 * @IEEE80211_TX_RC_GREEN_FIELD: Indicates whether this rate should be used in
506 * Greenfield mode. 505 * Greenfield mode.
507 * @IEEE80211_TX_RC_40_MHZ_WIDTH: Indicates if the Channel Width should be 40 MHz. 506 * @IEEE80211_TX_RC_40_MHZ_WIDTH: Indicates if the Channel Width should be 40 MHz.
507 * @IEEE80211_TX_RC_80_MHZ_WIDTH: Indicates 80 MHz transmission
508 * @IEEE80211_TX_RC_160_MHZ_WIDTH: Indicates 160 MHz transmission
509 * (80+80 isn't supported yet)
508 * @IEEE80211_TX_RC_DUP_DATA: The frame should be transmitted on both of the 510 * @IEEE80211_TX_RC_DUP_DATA: The frame should be transmitted on both of the
509 * adjacent 20 MHz channels, if the current channel type is 511 * adjacent 20 MHz channels, if the current channel type is
510 * NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS. 512 * NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS.
@@ -515,12 +517,15 @@ enum mac80211_rate_control_flags {
515 IEEE80211_TX_RC_USE_CTS_PROTECT = BIT(1), 517 IEEE80211_TX_RC_USE_CTS_PROTECT = BIT(1),
516 IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(2), 518 IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(2),
517 519
518 /* rate index is an MCS rate number instead of an index */ 520 /* rate index is an HT/VHT MCS instead of an index */
519 IEEE80211_TX_RC_MCS = BIT(3), 521 IEEE80211_TX_RC_MCS = BIT(3),
520 IEEE80211_TX_RC_GREEN_FIELD = BIT(4), 522 IEEE80211_TX_RC_GREEN_FIELD = BIT(4),
521 IEEE80211_TX_RC_40_MHZ_WIDTH = BIT(5), 523 IEEE80211_TX_RC_40_MHZ_WIDTH = BIT(5),
522 IEEE80211_TX_RC_DUP_DATA = BIT(6), 524 IEEE80211_TX_RC_DUP_DATA = BIT(6),
523 IEEE80211_TX_RC_SHORT_GI = BIT(7), 525 IEEE80211_TX_RC_SHORT_GI = BIT(7),
526 IEEE80211_TX_RC_VHT_MCS = BIT(8),
527 IEEE80211_TX_RC_80_MHZ_WIDTH = BIT(9),
528 IEEE80211_TX_RC_160_MHZ_WIDTH = BIT(10),
524}; 529};
525 530
526 531
@@ -563,10 +568,32 @@ enum mac80211_rate_control_flags {
563 */ 568 */
564struct ieee80211_tx_rate { 569struct ieee80211_tx_rate {
565 s8 idx; 570 s8 idx;
566 u8 count; 571 u16 count:5,
567 u8 flags; 572 flags:11;
568} __packed; 573} __packed;
569 574
575#define IEEE80211_MAX_TX_RETRY 31
576
577static inline void ieee80211_rate_set_vht(struct ieee80211_tx_rate *rate,
578 u8 mcs, u8 nss)
579{
580 WARN_ON(mcs & ~0xF);
581 WARN_ON(nss & ~0x7);
582 rate->idx = (nss << 4) | mcs;
583}
584
585static inline u8
586ieee80211_rate_get_vht_mcs(const struct ieee80211_tx_rate *rate)
587{
588 return rate->idx & 0xF;
589}
590
591static inline u8
592ieee80211_rate_get_vht_nss(const struct ieee80211_tx_rate *rate)
593{
594 return rate->idx >> 4;
595}
596
570/** 597/**
571 * struct ieee80211_tx_info - skb transmit information 598 * struct ieee80211_tx_info - skb transmit information
572 * 599 *
@@ -720,7 +747,11 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
720 * (including FCS) was received. 747 * (including FCS) was received.
721 * @RX_FLAG_SHORTPRE: Short preamble was used for this frame 748 * @RX_FLAG_SHORTPRE: Short preamble was used for this frame
722 * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index 749 * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
750 * @RX_FLAG_VHT: VHT MCS was used and rate_index is MCS index
723 * @RX_FLAG_40MHZ: HT40 (40 MHz) was used 751 * @RX_FLAG_40MHZ: HT40 (40 MHz) was used
752 * @RX_FLAG_80MHZ: 80 MHz was used
753 * @RX_FLAG_80P80MHZ: 80+80 MHz was used
754 * @RX_FLAG_160MHZ: 160 MHz was used
724 * @RX_FLAG_SHORT_GI: Short guard interval was used 755 * @RX_FLAG_SHORT_GI: Short guard interval was used
725 * @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present. 756 * @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present.
726 * Valid only for data frames (mainly A-MPDU) 757 * Valid only for data frames (mainly A-MPDU)
@@ -763,6 +794,10 @@ enum mac80211_rx_flags {
763 RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(19), 794 RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(19),
764 RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(20), 795 RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(20),
765 RX_FLAG_MACTIME_END = BIT(21), 796 RX_FLAG_MACTIME_END = BIT(21),
797 RX_FLAG_VHT = BIT(22),
798 RX_FLAG_80MHZ = BIT(23),
799 RX_FLAG_80P80MHZ = BIT(24),
800 RX_FLAG_160MHZ = BIT(25),
766}; 801};
767 802
768/** 803/**
@@ -783,7 +818,8 @@ enum mac80211_rx_flags {
783 * @IEEE80211_HW_SIGNAL_* 818 * @IEEE80211_HW_SIGNAL_*
784 * @antenna: antenna used 819 * @antenna: antenna used
785 * @rate_idx: index of data rate into band's supported rates or MCS index if 820 * @rate_idx: index of data rate into band's supported rates or MCS index if
786 * HT rates are use (RX_FLAG_HT) 821 * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
822 * @vht_nss: number of streams (VHT only)
787 * @flag: %RX_FLAG_* 823 * @flag: %RX_FLAG_*
788 * @rx_flags: internal RX flags for mac80211 824 * @rx_flags: internal RX flags for mac80211
789 * @ampdu_reference: A-MPDU reference number, must be a different value for 825 * @ampdu_reference: A-MPDU reference number, must be a different value for
@@ -806,6 +842,7 @@ struct ieee80211_rx_status {
806 u16 vendor_radiotap_len; 842 u16 vendor_radiotap_len;
807 u16 freq; 843 u16 freq;
808 u8 rate_idx; 844 u8 rate_idx;
845 u8 vht_nss;
809 u8 rx_flags; 846 u8 rx_flags;
810 u8 band; 847 u8 band;
811 u8 antenna; 848 u8 antenna;
@@ -2550,7 +2587,6 @@ struct ieee80211_ops {
2550 int (*remain_on_channel)(struct ieee80211_hw *hw, 2587 int (*remain_on_channel)(struct ieee80211_hw *hw,
2551 struct ieee80211_vif *vif, 2588 struct ieee80211_vif *vif,
2552 struct ieee80211_channel *chan, 2589 struct ieee80211_channel *chan,
2553 enum nl80211_channel_type channel_type,
2554 int duration); 2590 int duration);
2555 int (*cancel_remain_on_channel)(struct ieee80211_hw *hw); 2591 int (*cancel_remain_on_channel)(struct ieee80211_hw *hw);
2556 int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx); 2592 int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx);
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 1a9a819cfab0..33a417481ad8 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -118,8 +118,9 @@
118 * to get a list of all present wiphys. 118 * to get a list of all present wiphys.
119 * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or 119 * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or
120 * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME, 120 * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME,
121 * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ, 121 * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ (and the
122 * %NL80211_ATTR_WIPHY_CHANNEL_TYPE, %NL80211_ATTR_WIPHY_RETRY_SHORT, 122 * attributes determining the channel width; this is used for setting
123 * monitor mode channel), %NL80211_ATTR_WIPHY_RETRY_SHORT,
123 * %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD, 124 * %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
124 * and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD. 125 * and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD.
125 * However, for setting the channel, see %NL80211_CMD_SET_CHANNEL 126 * However, for setting the channel, see %NL80211_CMD_SET_CHANNEL
@@ -171,7 +172,7 @@
171 * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY, 172 * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
172 * %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT. 173 * %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT.
173 * The channel to use can be set on the interface or be given using the 174 * The channel to use can be set on the interface or be given using the
174 * %NL80211_ATTR_WIPHY_FREQ and %NL80211_ATTR_WIPHY_CHANNEL_TYPE attrs. 175 * %NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width.
175 * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP 176 * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP
176 * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface 177 * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface
177 * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP 178 * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP
@@ -401,8 +402,7 @@
401 * a response while being associated to an AP on another channel. 402 * a response while being associated to an AP on another channel.
402 * %NL80211_ATTR_IFINDEX is used to specify which interface (and thus 403 * %NL80211_ATTR_IFINDEX is used to specify which interface (and thus
403 * radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the 404 * radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the
404 * frequency for the operation and %NL80211_ATTR_WIPHY_CHANNEL_TYPE may be 405 * frequency for the operation.
405 * optionally used to specify additional channel parameters.
406 * %NL80211_ATTR_DURATION is used to specify the duration in milliseconds 406 * %NL80211_ATTR_DURATION is used to specify the duration in milliseconds
407 * to remain on the channel. This command is also used as an event to 407 * to remain on the channel. This command is also used as an event to
408 * notify when the requested duration starts (it may take a while for the 408 * notify when the requested duration starts (it may take a while for the
@@ -440,12 +440,11 @@
440 * as an event indicating reception of a frame that was not processed in 440 * as an event indicating reception of a frame that was not processed in
441 * kernel code, but is for us (i.e., which may need to be processed in a 441 * kernel code, but is for us (i.e., which may need to be processed in a
442 * user space application). %NL80211_ATTR_FRAME is used to specify the 442 * user space application). %NL80211_ATTR_FRAME is used to specify the
443 * frame contents (including header). %NL80211_ATTR_WIPHY_FREQ (and 443 * frame contents (including header). %NL80211_ATTR_WIPHY_FREQ is used
444 * optionally %NL80211_ATTR_WIPHY_CHANNEL_TYPE) is used to indicate on 444 * to indicate on which channel the frame is to be transmitted or was
445 * which channel the frame is to be transmitted or was received. If this 445 * received. If this channel is not the current channel (remain-on-channel
446 * channel is not the current channel (remain-on-channel or the 446 * or the operational channel) the device will switch to the given channel
447 * operational channel) the device will switch to the given channel and 447 * and transmit the frame, optionally waiting for a response for the time
448 * transmit the frame, optionally waiting for a response for the time
449 * specified using %NL80211_ATTR_DURATION. When called, this operation 448 * specified using %NL80211_ATTR_DURATION. When called, this operation
450 * returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the 449 * returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the
451 * TX status event pertaining to the TX request. 450 * TX status event pertaining to the TX request.
@@ -473,8 +472,8 @@
473 * command is used as an event to indicate the that a trigger level was 472 * command is used as an event to indicate the that a trigger level was
474 * reached. 473 * reached.
475 * @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ 474 * @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ
476 * and %NL80211_ATTR_WIPHY_CHANNEL_TYPE) the given interface (identifed 475 * and the attributes determining channel width) the given interface
477 * by %NL80211_ATTR_IFINDEX) shall operate on. 476 * (identifed by %NL80211_ATTR_IFINDEX) shall operate on.
478 * In case multiple channels are supported by the device, the mechanism 477 * In case multiple channels are supported by the device, the mechanism
479 * with which it switches channels is implementation-defined. 478 * with which it switches channels is implementation-defined.
480 * When a monitor interface is given, it can only switch channel while 479 * When a monitor interface is given, it can only switch channel while
@@ -568,8 +567,8 @@
568 * 567 *
569 * @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels 568 * @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels
570 * independently of the userspace SME, send this event indicating 569 * independently of the userspace SME, send this event indicating
571 * %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ with 570 * %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ and the
572 * %NL80211_ATTR_WIPHY_CHANNEL_TYPE. 571 * attributes determining channel width.
573 * 572 *
574 * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by 573 * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by
575 * its %NL80211_ATTR_WDEV identifier. It must have been created with 574 * its %NL80211_ATTR_WDEV identifier. It must have been created with
@@ -773,14 +772,26 @@ enum nl80211_commands {
773 * /sys/class/ieee80211/<phyname>/index 772 * /sys/class/ieee80211/<phyname>/index
774 * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming) 773 * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming)
775 * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters 774 * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters
776 * @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz 775 * @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz,
776 * defines the channel together with the (deprecated)
777 * %NL80211_ATTR_WIPHY_CHANNEL_TYPE attribute or the attributes
778 * %NL80211_ATTR_CHANNEL_WIDTH and if needed %NL80211_ATTR_CENTER_FREQ1
779 * and %NL80211_ATTR_CENTER_FREQ2
780 * @NL80211_ATTR_CHANNEL_WIDTH: u32 attribute containing one of the values
781 * of &enum nl80211_chan_width, describing the channel width. See the
782 * documentation of the enum for more information.
783 * @NL80211_ATTR_CENTER_FREQ1: Center frequency of the first part of the
784 * channel, used for anything but 20 MHz bandwidth
785 * @NL80211_ATTR_CENTER_FREQ2: Center frequency of the second part of the
786 * channel, used only for 80+80 MHz bandwidth
777 * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ 787 * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ
778 * if HT20 or HT40 are allowed (i.e., 802.11n disabled if not included): 788 * if HT20 or HT40 are to be used (i.e., HT disabled if not included):
779 * NL80211_CHAN_NO_HT = HT not allowed (i.e., same as not including 789 * NL80211_CHAN_NO_HT = HT not allowed (i.e., same as not including
780 * this attribute) 790 * this attribute)
781 * NL80211_CHAN_HT20 = HT20 only 791 * NL80211_CHAN_HT20 = HT20 only
782 * NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel 792 * NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel
783 * NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel 793 * NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel
794 * This attribute is now deprecated.
784 * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is 795 * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is
785 * less than or equal to the RTS threshold; allowed range: 1..255; 796 * less than or equal to the RTS threshold; allowed range: 1..255;
786 * dot11ShortRetryLimit; u8 797 * dot11ShortRetryLimit; u8
@@ -1555,6 +1566,10 @@ enum nl80211_attrs {
1555 1566
1556 NL80211_ATTR_SCAN_FLAGS, 1567 NL80211_ATTR_SCAN_FLAGS,
1557 1568
1569 NL80211_ATTR_CHANNEL_WIDTH,
1570 NL80211_ATTR_CENTER_FREQ1,
1571 NL80211_ATTR_CENTER_FREQ2,
1572
1558 /* add attributes here, update the policy in nl80211.c */ 1573 /* add attributes here, update the policy in nl80211.c */
1559 1574
1560 __NL80211_ATTR_AFTER_LAST, 1575 __NL80211_ATTR_AFTER_LAST,
@@ -1719,10 +1734,15 @@ struct nl80211_sta_flag_update {
1719 * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved 1734 * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved
1720 * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) 1735 * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s)
1721 * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) 1736 * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8)
1722 * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate 1737 * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 MHz dualchannel bitrate
1723 * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval 1738 * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval
1724 * @NL80211_RATE_INFO_BITRATE32: total bitrate (u32, 100kbit/s) 1739 * @NL80211_RATE_INFO_BITRATE32: total bitrate (u32, 100kbit/s)
1725 * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined 1740 * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined
1741 * @NL80211_RATE_INFO_VHT_MCS: MCS index for VHT (u8)
1742 * @NL80211_RATE_INFO_VHT_NSS: number of streams in VHT (u8)
1743 * @NL80211_RATE_INFO_80_MHZ_WIDTH: 80 MHz VHT rate
1744 * @NL80211_RATE_INFO_80P80_MHZ_WIDTH: 80+80 MHz VHT rate
1745 * @NL80211_RATE_INFO_160_MHZ_WIDTH: 160 MHz VHT rate
1726 * @__NL80211_RATE_INFO_AFTER_LAST: internal use 1746 * @__NL80211_RATE_INFO_AFTER_LAST: internal use
1727 */ 1747 */
1728enum nl80211_rate_info { 1748enum nl80211_rate_info {
@@ -1732,6 +1752,11 @@ enum nl80211_rate_info {
1732 NL80211_RATE_INFO_40_MHZ_WIDTH, 1752 NL80211_RATE_INFO_40_MHZ_WIDTH,
1733 NL80211_RATE_INFO_SHORT_GI, 1753 NL80211_RATE_INFO_SHORT_GI,
1734 NL80211_RATE_INFO_BITRATE32, 1754 NL80211_RATE_INFO_BITRATE32,
1755 NL80211_RATE_INFO_VHT_MCS,
1756 NL80211_RATE_INFO_VHT_NSS,
1757 NL80211_RATE_INFO_80_MHZ_WIDTH,
1758 NL80211_RATE_INFO_80P80_MHZ_WIDTH,
1759 NL80211_RATE_INFO_160_MHZ_WIDTH,
1735 1760
1736 /* keep last */ 1761 /* keep last */
1737 __NL80211_RATE_INFO_AFTER_LAST, 1762 __NL80211_RATE_INFO_AFTER_LAST,
@@ -2440,6 +2465,15 @@ enum nl80211_ac {
2440#define NL80211_TXQ_Q_BE NL80211_AC_BE 2465#define NL80211_TXQ_Q_BE NL80211_AC_BE
2441#define NL80211_TXQ_Q_BK NL80211_AC_BK 2466#define NL80211_TXQ_Q_BK NL80211_AC_BK
2442 2467
2468/**
2469 * enum nl80211_channel_type - channel type
2470 * @NL80211_CHAN_NO_HT: 20 MHz, non-HT channel
2471 * @NL80211_CHAN_HT20: 20 MHz HT channel
2472 * @NL80211_CHAN_HT40MINUS: HT40 channel, secondary channel
2473 * below the control channel
2474 * @NL80211_CHAN_HT40PLUS: HT40 channel, secondary channel
2475 * above the control channel
2476 */
2443enum nl80211_channel_type { 2477enum nl80211_channel_type {
2444 NL80211_CHAN_NO_HT, 2478 NL80211_CHAN_NO_HT,
2445 NL80211_CHAN_HT20, 2479 NL80211_CHAN_HT20,
@@ -2448,6 +2482,32 @@ enum nl80211_channel_type {
2448}; 2482};
2449 2483
2450/** 2484/**
2485 * enum nl80211_chan_width - channel width definitions
2486 *
2487 * These values are used with the %NL80211_ATTR_CHANNEL_WIDTH
2488 * attribute.
2489 *
2490 * @NL80211_CHAN_WIDTH_20_NOHT: 20 MHz, non-HT channel
2491 * @NL80211_CHAN_WIDTH_20: 20 MHz HT channel
2492 * @NL80211_CHAN_WIDTH_40: 40 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
2493 * attribute must be provided as well
2494 * @NL80211_CHAN_WIDTH_80: 80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
2495 * attribute must be provided as well
2496 * @NL80211_CHAN_WIDTH_80P80: 80+80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
2497 * and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well
2498 * @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
2499 * attribute must be provided as well
2500 */
2501enum nl80211_chan_width {
2502 NL80211_CHAN_WIDTH_20_NOHT,
2503 NL80211_CHAN_WIDTH_20,
2504 NL80211_CHAN_WIDTH_40,
2505 NL80211_CHAN_WIDTH_80,
2506 NL80211_CHAN_WIDTH_80P80,
2507 NL80211_CHAN_WIDTH_160,
2508};
2509
2510/**
2451 * enum nl80211_bss - netlink attributes for a BSS 2511 * enum nl80211_bss - netlink attributes for a BSS
2452 * 2512 *
2453 * @__NL80211_BSS_INVALID: invalid 2513 * @__NL80211_BSS_INVALID: invalid
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6733b374c821..4965aa6424ec 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -370,30 +370,32 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
370 return 0; 370 return 0;
371} 371}
372 372
373static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, int idx)
374{
375 enum ieee80211_band band = ieee80211_get_sdata_band(sta->sdata);
376
377 if (!(rate->flags & RATE_INFO_FLAGS_MCS)) {
378 struct ieee80211_supported_band *sband;
379 sband = sta->local->hw.wiphy->bands[band];
380 rate->legacy = sband->bitrates[idx].bitrate;
381 } else
382 rate->mcs = idx;
383}
384
385void sta_set_rate_info_tx(struct sta_info *sta, 373void sta_set_rate_info_tx(struct sta_info *sta,
386 const struct ieee80211_tx_rate *rate, 374 const struct ieee80211_tx_rate *rate,
387 struct rate_info *rinfo) 375 struct rate_info *rinfo)
388{ 376{
389 rinfo->flags = 0; 377 rinfo->flags = 0;
390 if (rate->flags & IEEE80211_TX_RC_MCS) 378 if (rate->flags & IEEE80211_TX_RC_MCS) {
391 rinfo->flags |= RATE_INFO_FLAGS_MCS; 379 rinfo->flags |= RATE_INFO_FLAGS_MCS;
380 rinfo->mcs = rate->idx;
381 } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
382 rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS;
383 rinfo->mcs = ieee80211_rate_get_vht_mcs(rate);
384 rinfo->nss = ieee80211_rate_get_vht_nss(rate);
385 } else {
386 struct ieee80211_supported_band *sband;
387 sband = sta->local->hw.wiphy->bands[
388 ieee80211_get_sdata_band(sta->sdata)];
389 rinfo->legacy = sband->bitrates[rate->idx].bitrate;
390 }
392 if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 391 if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
393 rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 392 rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
393 if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
394 rinfo->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
395 if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
396 rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
394 if (rate->flags & IEEE80211_TX_RC_SHORT_GI) 397 if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
395 rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; 398 rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
396 rate_idx_to_bitrate(rinfo, sta, rate->idx);
397} 399}
398 400
399static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 401static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
@@ -444,13 +446,32 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
444 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); 446 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
445 447
446 sinfo->rxrate.flags = 0; 448 sinfo->rxrate.flags = 0;
447 if (sta->last_rx_rate_flag & RX_FLAG_HT) 449 if (sta->last_rx_rate_flag & RX_FLAG_HT) {
448 sinfo->rxrate.flags |= RATE_INFO_FLAGS_MCS; 450 sinfo->rxrate.flags |= RATE_INFO_FLAGS_MCS;
451 sinfo->rxrate.mcs = sta->last_rx_rate_idx;
452 } else if (sta->last_rx_rate_flag & RX_FLAG_VHT) {
453 sinfo->rxrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
454 sinfo->rxrate.nss = sta->last_rx_rate_vht_nss;
455 sinfo->rxrate.mcs = sta->last_rx_rate_idx;
456 } else {
457 struct ieee80211_supported_band *sband;
458
459 sband = sta->local->hw.wiphy->bands[
460 ieee80211_get_sdata_band(sta->sdata)];
461 sinfo->rxrate.legacy =
462 sband->bitrates[sta->last_rx_rate_idx].bitrate;
463 }
464
449 if (sta->last_rx_rate_flag & RX_FLAG_40MHZ) 465 if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
450 sinfo->rxrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 466 sinfo->rxrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
451 if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI) 467 if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI)
452 sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; 468 sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
453 rate_idx_to_bitrate(&sinfo->rxrate, sta, sta->last_rx_rate_idx); 469 if (sta->last_rx_rate_flag & RX_FLAG_80MHZ)
470 sinfo->rxrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
471 if (sta->last_rx_rate_flag & RX_FLAG_80P80MHZ)
472 sinfo->rxrate.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH;
473 if (sta->last_rx_rate_flag & RX_FLAG_160MHZ)
474 sinfo->rxrate.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
454 475
455 if (ieee80211_vif_is_mesh(&sdata->vif)) { 476 if (ieee80211_vif_is_mesh(&sdata->vif)) {
456#ifdef CONFIG_MAC80211_MESH 477#ifdef CONFIG_MAC80211_MESH
@@ -615,7 +636,7 @@ do_survey:
615 rcu_read_lock(); 636 rcu_read_lock();
616 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 637 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
617 if (chanctx_conf) 638 if (chanctx_conf)
618 channel = chanctx_conf->channel; 639 channel = chanctx_conf->def.chan;
619 else 640 else
620 channel = NULL; 641 channel = NULL;
621 rcu_read_unlock(); 642 rcu_read_unlock();
@@ -735,15 +756,13 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
735} 756}
736 757
737static int ieee80211_set_monitor_channel(struct wiphy *wiphy, 758static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
738 struct ieee80211_channel *chan, 759 struct cfg80211_chan_def *chandef)
739 enum nl80211_channel_type channel_type)
740{ 760{
741 struct ieee80211_local *local = wiphy_priv(wiphy); 761 struct ieee80211_local *local = wiphy_priv(wiphy);
742 struct ieee80211_sub_if_data *sdata; 762 struct ieee80211_sub_if_data *sdata;
743 int ret = 0; 763 int ret = 0;
744 764
745 if (local->monitor_channel == chan && 765 if (cfg80211_chandef_identical(&local->monitor_chandef, chandef))
746 local->monitor_channel_type == channel_type)
747 return 0; 766 return 0;
748 767
749 mutex_lock(&local->iflist_mtx); 768 mutex_lock(&local->iflist_mtx);
@@ -753,20 +772,17 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
753 lockdep_is_held(&local->iflist_mtx)); 772 lockdep_is_held(&local->iflist_mtx));
754 if (sdata) { 773 if (sdata) {
755 ieee80211_vif_release_channel(sdata); 774 ieee80211_vif_release_channel(sdata);
756 ret = ieee80211_vif_use_channel( 775 ret = ieee80211_vif_use_channel(sdata, chandef,
757 sdata, chan, channel_type,
758 IEEE80211_CHANCTX_EXCLUSIVE); 776 IEEE80211_CHANCTX_EXCLUSIVE);
759 } 777 }
760 } else if (local->open_count == local->monitors) { 778 } else if (local->open_count == local->monitors) {
761 local->_oper_channel = chan; 779 local->_oper_channel = chandef->chan;
762 local->_oper_channel_type = channel_type; 780 local->_oper_channel_type = cfg80211_get_chandef_type(chandef);
763 ieee80211_hw_config(local, 0); 781 ieee80211_hw_config(local, 0);
764 } 782 }
765 783
766 if (ret == 0) { 784 if (ret == 0)
767 local->monitor_channel = chan; 785 local->monitor_chandef = *chandef;
768 local->monitor_channel_type = channel_type;
769 }
770 mutex_unlock(&local->iflist_mtx); 786 mutex_unlock(&local->iflist_mtx);
771 787
772 return ret; 788 return ret;
@@ -888,8 +904,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
888 sdata->smps_mode = IEEE80211_SMPS_OFF; 904 sdata->smps_mode = IEEE80211_SMPS_OFF;
889 sdata->needed_rx_chains = sdata->local->rx_chains; 905 sdata->needed_rx_chains = sdata->local->rx_chains;
890 906
891 err = ieee80211_vif_use_channel(sdata, params->channel, 907 err = ieee80211_vif_use_channel(sdata, &params->chandef,
892 params->channel_type,
893 IEEE80211_CHANCTX_SHARED); 908 IEEE80211_CHANCTX_SHARED);
894 if (err) 909 if (err)
895 return err; 910 return err;
@@ -1707,8 +1722,7 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
1707 sdata->smps_mode = IEEE80211_SMPS_OFF; 1722 sdata->smps_mode = IEEE80211_SMPS_OFF;
1708 sdata->needed_rx_chains = sdata->local->rx_chains; 1723 sdata->needed_rx_chains = sdata->local->rx_chains;
1709 1724
1710 err = ieee80211_vif_use_channel(sdata, setup->channel, 1725 err = ieee80211_vif_use_channel(sdata, &setup->chandef,
1711 setup->channel_type,
1712 IEEE80211_CHANCTX_SHARED); 1726 IEEE80211_CHANCTX_SHARED);
1713 if (err) 1727 if (err)
1714 return err; 1728 return err;
@@ -1990,10 +2004,16 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1990 return err; 2004 return err;
1991 } 2005 }
1992 2006
1993 if (changed & WIPHY_PARAM_RETRY_SHORT) 2007 if (changed & WIPHY_PARAM_RETRY_SHORT) {
2008 if (wiphy->retry_short > IEEE80211_MAX_TX_RETRY)
2009 return -EINVAL;
1994 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; 2010 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
1995 if (changed & WIPHY_PARAM_RETRY_LONG) 2011 }
2012 if (changed & WIPHY_PARAM_RETRY_LONG) {
2013 if (wiphy->retry_long > IEEE80211_MAX_TX_RETRY)
2014 return -EINVAL;
1996 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; 2015 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
2016 }
1997 if (changed & 2017 if (changed &
1998 (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG)) 2018 (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG))
1999 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS); 2019 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
@@ -2129,7 +2149,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
2129 * the new value until we associate. 2149 * the new value until we associate.
2130 */ 2150 */
2131 if (!sdata->u.mgd.associated || 2151 if (!sdata->u.mgd.associated ||
2132 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) 2152 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
2133 return 0; 2153 return 0;
2134 2154
2135 ap = sdata->u.mgd.associated->bssid; 2155 ap = sdata->u.mgd.associated->bssid;
@@ -2236,7 +2256,6 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
2236static int ieee80211_start_roc_work(struct ieee80211_local *local, 2256static int ieee80211_start_roc_work(struct ieee80211_local *local,
2237 struct ieee80211_sub_if_data *sdata, 2257 struct ieee80211_sub_if_data *sdata,
2238 struct ieee80211_channel *channel, 2258 struct ieee80211_channel *channel,
2239 enum nl80211_channel_type channel_type,
2240 unsigned int duration, u64 *cookie, 2259 unsigned int duration, u64 *cookie,
2241 struct sk_buff *txskb) 2260 struct sk_buff *txskb)
2242{ 2261{
@@ -2254,7 +2273,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2254 return -ENOMEM; 2273 return -ENOMEM;
2255 2274
2256 roc->chan = channel; 2275 roc->chan = channel;
2257 roc->chan_type = channel_type;
2258 roc->duration = duration; 2276 roc->duration = duration;
2259 roc->req_duration = duration; 2277 roc->req_duration = duration;
2260 roc->frame = txskb; 2278 roc->frame = txskb;
@@ -2287,8 +2305,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2287 if (!duration) 2305 if (!duration)
2288 duration = 10; 2306 duration = 10;
2289 2307
2290 ret = drv_remain_on_channel(local, sdata, channel, channel_type, 2308 ret = drv_remain_on_channel(local, sdata, channel, duration);
2291 duration);
2292 if (ret) { 2309 if (ret) {
2293 kfree(roc); 2310 kfree(roc);
2294 return ret; 2311 return ret;
@@ -2299,8 +2316,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2299 2316
2300 out_check_combine: 2317 out_check_combine:
2301 list_for_each_entry(tmp, &local->roc_list, list) { 2318 list_for_each_entry(tmp, &local->roc_list, list) {
2302 if (tmp->chan != channel || tmp->chan_type != channel_type || 2319 if (tmp->chan != channel || tmp->sdata != sdata)
2303 tmp->sdata != sdata)
2304 continue; 2320 continue;
2305 2321
2306 /* 2322 /*
@@ -2417,7 +2433,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2417static int ieee80211_remain_on_channel(struct wiphy *wiphy, 2433static int ieee80211_remain_on_channel(struct wiphy *wiphy,
2418 struct wireless_dev *wdev, 2434 struct wireless_dev *wdev,
2419 struct ieee80211_channel *chan, 2435 struct ieee80211_channel *chan,
2420 enum nl80211_channel_type channel_type,
2421 unsigned int duration, 2436 unsigned int duration,
2422 u64 *cookie) 2437 u64 *cookie)
2423{ 2438{
@@ -2426,7 +2441,7 @@ static int ieee80211_remain_on_channel(struct wiphy *wiphy,
2426 int ret; 2441 int ret;
2427 2442
2428 mutex_lock(&local->mtx); 2443 mutex_lock(&local->mtx);
2429 ret = ieee80211_start_roc_work(local, sdata, chan, channel_type, 2444 ret = ieee80211_start_roc_work(local, sdata, chan,
2430 duration, cookie, NULL); 2445 duration, cookie, NULL);
2431 mutex_unlock(&local->mtx); 2446 mutex_unlock(&local->mtx);
2432 2447
@@ -2519,10 +2534,8 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
2519 2534
2520static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 2535static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2521 struct ieee80211_channel *chan, bool offchan, 2536 struct ieee80211_channel *chan, bool offchan,
2522 enum nl80211_channel_type channel_type, 2537 unsigned int wait, const u8 *buf, size_t len,
2523 bool channel_type_valid, unsigned int wait, 2538 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
2524 const u8 *buf, size_t len, bool no_cck,
2525 bool dont_wait_for_ack, u64 *cookie)
2526{ 2539{
2527 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 2540 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
2528 struct ieee80211_local *local = sdata->local; 2541 struct ieee80211_local *local = sdata->local;
@@ -2591,14 +2604,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2591 rcu_read_lock(); 2604 rcu_read_lock();
2592 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 2605 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
2593 2606
2594 if (chanctx_conf) { 2607 if (chanctx_conf)
2595 need_offchan = chan != chanctx_conf->channel; 2608 need_offchan = chan != chanctx_conf->def.chan;
2596 if (channel_type_valid && 2609 else
2597 channel_type != chanctx_conf->channel_type)
2598 need_offchan = true;
2599 } else {
2600 need_offchan = true; 2610 need_offchan = true;
2601 }
2602 rcu_read_unlock(); 2611 rcu_read_unlock();
2603 } 2612 }
2604 2613
@@ -2633,7 +2642,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2633 local->hw.offchannel_tx_hw_queue; 2642 local->hw.offchannel_tx_hw_queue;
2634 2643
2635 /* This will handle all kinds of coalescing and immediate TX */ 2644 /* This will handle all kinds of coalescing and immediate TX */
2636 ret = ieee80211_start_roc_work(local, sdata, chan, channel_type, 2645 ret = ieee80211_start_roc_work(local, sdata, chan,
2637 wait, cookie, skb); 2646 wait, cookie, skb);
2638 if (ret) 2647 if (ret)
2639 kfree_skb(skb); 2648 kfree_skb(skb);
@@ -3067,7 +3076,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
3067 rcu_read_unlock(); 3076 rcu_read_unlock();
3068 return -EINVAL; 3077 return -EINVAL;
3069 } 3078 }
3070 band = chanctx_conf->channel->band; 3079 band = chanctx_conf->def.chan->band;
3071 sta = sta_info_get(sdata, peer); 3080 sta = sta_info_get(sdata, peer);
3072 if (sta) { 3081 if (sta) {
3073 qos = test_sta_flag(sta, WLAN_STA_WME); 3082 qos = test_sta_flag(sta, WLAN_STA_WME);
@@ -3124,23 +3133,23 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
3124 return 0; 3133 return 0;
3125} 3134}
3126 3135
3127static struct ieee80211_channel * 3136static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
3128ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, 3137 struct wireless_dev *wdev,
3129 enum nl80211_channel_type *type) 3138 struct cfg80211_chan_def *chandef)
3130{ 3139{
3131 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 3140 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
3132 struct ieee80211_chanctx_conf *chanctx_conf; 3141 struct ieee80211_chanctx_conf *chanctx_conf;
3133 struct ieee80211_channel *chan = NULL; 3142 int ret = -ENODATA;
3134 3143
3135 rcu_read_lock(); 3144 rcu_read_lock();
3136 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 3145 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
3137 if (chanctx_conf) { 3146 if (chanctx_conf) {
3138 *type = chanctx_conf->channel_type; 3147 *chandef = chanctx_conf->def;
3139 chan = chanctx_conf->channel; 3148 ret = 0;
3140 } 3149 }
3141 rcu_read_unlock(); 3150 rcu_read_unlock();
3142 3151
3143 return chan; 3152 return ret;
3144} 3153}
3145 3154
3146#ifdef CONFIG_PM 3155#ifdef CONFIG_PM
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index a2b06d40aebf..53f03120db55 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -8,93 +8,47 @@
8#include "ieee80211_i.h" 8#include "ieee80211_i.h"
9#include "driver-ops.h" 9#include "driver-ops.h"
10 10
11static bool 11static void ieee80211_change_chandef(struct ieee80211_local *local,
12ieee80211_channel_types_are_compatible(enum nl80211_channel_type chantype1, 12 struct ieee80211_chanctx *ctx,
13 enum nl80211_channel_type chantype2, 13 const struct cfg80211_chan_def *chandef)
14 enum nl80211_channel_type *compat)
15{ 14{
16 /* 15 if (cfg80211_chandef_identical(&ctx->conf.def, chandef))
17 * start out with chantype1 being the result,
18 * overwriting later if needed
19 */
20 if (compat)
21 *compat = chantype1;
22
23 switch (chantype1) {
24 case NL80211_CHAN_NO_HT:
25 if (compat)
26 *compat = chantype2;
27 break;
28 case NL80211_CHAN_HT20:
29 /*
30 * allow any change that doesn't go to no-HT
31 * (if it already is no-HT no change is needed)
32 */
33 if (chantype2 == NL80211_CHAN_NO_HT)
34 break;
35 if (compat)
36 *compat = chantype2;
37 break;
38 case NL80211_CHAN_HT40PLUS:
39 case NL80211_CHAN_HT40MINUS:
40 /* allow smaller bandwidth and same */
41 if (chantype2 == NL80211_CHAN_NO_HT)
42 break;
43 if (chantype2 == NL80211_CHAN_HT20)
44 break;
45 if (chantype2 == chantype1)
46 break;
47 return false;
48 }
49
50 return true;
51}
52
53static void ieee80211_change_chantype(struct ieee80211_local *local,
54 struct ieee80211_chanctx *ctx,
55 enum nl80211_channel_type chantype)
56{
57 if (chantype == ctx->conf.channel_type)
58 return; 16 return;
59 17
60 ctx->conf.channel_type = chantype; 18 WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
61 drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE); 19
20 ctx->conf.def = *chandef;
21 drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH);
62 22
63 if (!local->use_chanctx) { 23 if (!local->use_chanctx) {
64 local->_oper_channel_type = chantype; 24 local->_oper_channel_type = cfg80211_get_chandef_type(chandef);
65 ieee80211_hw_config(local, 0); 25 ieee80211_hw_config(local, 0);
66 } 26 }
67} 27}
68 28
69static struct ieee80211_chanctx * 29static struct ieee80211_chanctx *
70ieee80211_find_chanctx(struct ieee80211_local *local, 30ieee80211_find_chanctx(struct ieee80211_local *local,
71 struct ieee80211_channel *channel, 31 const struct cfg80211_chan_def *chandef,
72 enum nl80211_channel_type channel_type,
73 enum ieee80211_chanctx_mode mode) 32 enum ieee80211_chanctx_mode mode)
74{ 33{
75 struct ieee80211_chanctx *ctx; 34 struct ieee80211_chanctx *ctx;
76 enum nl80211_channel_type compat_type;
77 35
78 lockdep_assert_held(&local->chanctx_mtx); 36 lockdep_assert_held(&local->chanctx_mtx);
79 37
80 if (mode == IEEE80211_CHANCTX_EXCLUSIVE) 38 if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
81 return NULL; 39 return NULL;
82 if (WARN_ON(!channel))
83 return NULL;
84 40
85 list_for_each_entry(ctx, &local->chanctx_list, list) { 41 list_for_each_entry(ctx, &local->chanctx_list, list) {
86 compat_type = ctx->conf.channel_type; 42 const struct cfg80211_chan_def *compat;
87 43
88 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) 44 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
89 continue; 45 continue;
90 if (ctx->conf.channel != channel) 46
91 continue; 47 compat = cfg80211_chandef_compatible(&ctx->conf.def, chandef);
92 if (!ieee80211_channel_types_are_compatible(ctx->conf.channel_type, 48 if (!compat)
93 channel_type,
94 &compat_type))
95 continue; 49 continue;
96 50
97 ieee80211_change_chantype(local, ctx, compat_type); 51 ieee80211_change_chandef(local, ctx, compat);
98 52
99 return ctx; 53 return ctx;
100 } 54 }
@@ -104,8 +58,7 @@ ieee80211_find_chanctx(struct ieee80211_local *local,
104 58
105static struct ieee80211_chanctx * 59static struct ieee80211_chanctx *
106ieee80211_new_chanctx(struct ieee80211_local *local, 60ieee80211_new_chanctx(struct ieee80211_local *local,
107 struct ieee80211_channel *channel, 61 const struct cfg80211_chan_def *chandef,
108 enum nl80211_channel_type channel_type,
109 enum ieee80211_chanctx_mode mode) 62 enum ieee80211_chanctx_mode mode)
110{ 63{
111 struct ieee80211_chanctx *ctx; 64 struct ieee80211_chanctx *ctx;
@@ -117,15 +70,15 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
117 if (!ctx) 70 if (!ctx)
118 return ERR_PTR(-ENOMEM); 71 return ERR_PTR(-ENOMEM);
119 72
120 ctx->conf.channel = channel; 73 ctx->conf.def = *chandef;
121 ctx->conf.channel_type = channel_type;
122 ctx->conf.rx_chains_static = 1; 74 ctx->conf.rx_chains_static = 1;
123 ctx->conf.rx_chains_dynamic = 1; 75 ctx->conf.rx_chains_dynamic = 1;
124 ctx->mode = mode; 76 ctx->mode = mode;
125 77
126 if (!local->use_chanctx) { 78 if (!local->use_chanctx) {
127 local->_oper_channel_type = channel_type; 79 local->_oper_channel_type =
128 local->_oper_channel = channel; 80 cfg80211_get_chandef_type(chandef);
81 local->_oper_channel = chandef->chan;
129 ieee80211_hw_config(local, 0); 82 ieee80211_hw_config(local, 0);
130 } else { 83 } else {
131 err = drv_add_chanctx(local, ctx); 84 err = drv_add_chanctx(local, ctx);
@@ -178,41 +131,37 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
178 return 0; 131 return 0;
179} 132}
180 133
181static enum nl80211_channel_type 134static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
182ieee80211_calc_chantype(struct ieee80211_local *local, 135 struct ieee80211_chanctx *ctx)
183 struct ieee80211_chanctx *ctx)
184{ 136{
185 struct ieee80211_chanctx_conf *conf = &ctx->conf; 137 struct ieee80211_chanctx_conf *conf = &ctx->conf;
186 struct ieee80211_sub_if_data *sdata; 138 struct ieee80211_sub_if_data *sdata;
187 enum nl80211_channel_type result = NL80211_CHAN_NO_HT; 139 const struct cfg80211_chan_def *compat = NULL;
188 140
189 lockdep_assert_held(&local->chanctx_mtx); 141 lockdep_assert_held(&local->chanctx_mtx);
190 142
191 rcu_read_lock(); 143 rcu_read_lock();
192 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 144 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
145
193 if (!ieee80211_sdata_running(sdata)) 146 if (!ieee80211_sdata_running(sdata))
194 continue; 147 continue;
195 if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) 148 if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
196 continue; 149 continue;
197 150
198 WARN_ON_ONCE(!ieee80211_channel_types_are_compatible( 151 if (!compat)
199 sdata->vif.bss_conf.channel_type, 152 compat = &sdata->vif.bss_conf.chandef;
200 result, &result)); 153
154 compat = cfg80211_chandef_compatible(
155 &sdata->vif.bss_conf.chandef, compat);
156 if (!compat)
157 break;
201 } 158 }
202 rcu_read_unlock(); 159 rcu_read_unlock();
203 160
204 return result; 161 if (WARN_ON_ONCE(!compat))
205} 162 return;
206
207static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
208 struct ieee80211_chanctx *ctx)
209{
210 enum nl80211_channel_type chantype;
211
212 lockdep_assert_held(&local->chanctx_mtx);
213 163
214 chantype = ieee80211_calc_chantype(local, ctx); 164 ieee80211_change_chandef(local, ctx, compat);
215 ieee80211_change_chantype(local, ctx, chantype);
216} 165}
217 166
218static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata, 167static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
@@ -337,8 +286,7 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
337} 286}
338 287
339int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, 288int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
340 struct ieee80211_channel *channel, 289 const struct cfg80211_chan_def *chandef,
341 enum nl80211_channel_type channel_type,
342 enum ieee80211_chanctx_mode mode) 290 enum ieee80211_chanctx_mode mode)
343{ 291{
344 struct ieee80211_local *local = sdata->local; 292 struct ieee80211_local *local = sdata->local;
@@ -350,15 +298,15 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
350 mutex_lock(&local->chanctx_mtx); 298 mutex_lock(&local->chanctx_mtx);
351 __ieee80211_vif_release_channel(sdata); 299 __ieee80211_vif_release_channel(sdata);
352 300
353 ctx = ieee80211_find_chanctx(local, channel, channel_type, mode); 301 ctx = ieee80211_find_chanctx(local, chandef, mode);
354 if (!ctx) 302 if (!ctx)
355 ctx = ieee80211_new_chanctx(local, channel, channel_type, mode); 303 ctx = ieee80211_new_chanctx(local, chandef, mode);
356 if (IS_ERR(ctx)) { 304 if (IS_ERR(ctx)) {
357 ret = PTR_ERR(ctx); 305 ret = PTR_ERR(ctx);
358 goto out; 306 goto out;
359 } 307 }
360 308
361 sdata->vif.bss_conf.channel_type = channel_type; 309 sdata->vif.bss_conf.chandef = *chandef;
362 310
363 ret = ieee80211_assign_vif_chanctx(sdata, ctx); 311 ret = ieee80211_assign_vif_chanctx(sdata, ctx);
364 if (ret) { 312 if (ret) {
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index ba9bd0ef119a..cbde5cc49a40 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -168,7 +168,6 @@ IEEE80211_IF_FILE(rc_rateidx_mcs_mask_5ghz,
168 168
169IEEE80211_IF_FILE(flags, flags, HEX); 169IEEE80211_IF_FILE(flags, flags, HEX);
170IEEE80211_IF_FILE(state, state, LHEX); 170IEEE80211_IF_FILE(state, state, LHEX);
171IEEE80211_IF_FILE(channel_type, vif.bss_conf.channel_type, DEC);
172IEEE80211_IF_FILE(txpower, vif.bss_conf.txpower, DEC); 171IEEE80211_IF_FILE(txpower, vif.bss_conf.txpower, DEC);
173IEEE80211_IF_FILE(ap_power_level, ap_power_level, DEC); 172IEEE80211_IF_FILE(ap_power_level, ap_power_level, DEC);
174IEEE80211_IF_FILE(user_power_level, user_power_level, DEC); 173IEEE80211_IF_FILE(user_power_level, user_power_level, DEC);
@@ -632,7 +631,6 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
632 631
633 DEBUGFS_ADD(flags); 632 DEBUGFS_ADD(flags);
634 DEBUGFS_ADD(state); 633 DEBUGFS_ADD(state);
635 DEBUGFS_ADD(channel_type);
636 DEBUGFS_ADD(txpower); 634 DEBUGFS_ADD(txpower);
637 DEBUGFS_ADD(user_power_level); 635 DEBUGFS_ADD(user_power_level);
638 DEBUGFS_ADD(ap_power_level); 636 DEBUGFS_ADD(ap_power_level);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 68c27aaf5c93..c6560cc7a9d6 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -738,16 +738,15 @@ static inline int drv_get_antenna(struct ieee80211_local *local,
738static inline int drv_remain_on_channel(struct ieee80211_local *local, 738static inline int drv_remain_on_channel(struct ieee80211_local *local,
739 struct ieee80211_sub_if_data *sdata, 739 struct ieee80211_sub_if_data *sdata,
740 struct ieee80211_channel *chan, 740 struct ieee80211_channel *chan,
741 enum nl80211_channel_type chantype,
742 unsigned int duration) 741 unsigned int duration)
743{ 742{
744 int ret; 743 int ret;
745 744
746 might_sleep(); 745 might_sleep();
747 746
748 trace_drv_remain_on_channel(local, sdata, chan, chantype, duration); 747 trace_drv_remain_on_channel(local, sdata, chan, duration);
749 ret = local->ops->remain_on_channel(&local->hw, &sdata->vif, 748 ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
750 chan, chantype, duration); 749 chan, duration);
751 trace_drv_return_int(local, ret); 750 trace_drv_return_int(local, ret);
752 751
753 return ret; 752 return ret;
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 7aa02da52125..fa862b24a7e0 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -51,7 +51,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
51 struct cfg80211_bss *bss; 51 struct cfg80211_bss *bss;
52 u32 bss_change; 52 u32 bss_change;
53 u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; 53 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
54 enum nl80211_channel_type channel_type; 54 struct cfg80211_chan_def chandef;
55 55
56 lockdep_assert_held(&ifibss->mtx); 56 lockdep_assert_held(&ifibss->mtx);
57 57
@@ -79,12 +79,14 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
79 79
80 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; 80 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
81 81
82 channel_type = ifibss->channel_type; 82 cfg80211_chandef_create(&chandef, chan, ifibss->channel_type);
83 if (!cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) 83 if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
84 channel_type = NL80211_CHAN_HT20; 84 chandef.width = NL80211_CHAN_WIDTH_20;
85 chandef.center_freq1 = chan->center_freq;
86 }
85 87
86 ieee80211_vif_release_channel(sdata); 88 ieee80211_vif_release_channel(sdata);
87 if (ieee80211_vif_use_channel(sdata, chan, channel_type, 89 if (ieee80211_vif_use_channel(sdata, &chandef,
88 ifibss->fixed_channel ? 90 ifibss->fixed_channel ?
89 IEEE80211_CHANCTX_SHARED : 91 IEEE80211_CHANCTX_SHARED :
90 IEEE80211_CHANCTX_EXCLUSIVE)) { 92 IEEE80211_CHANCTX_EXCLUSIVE)) {
@@ -158,7 +160,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
158 ifibss->ie, ifibss->ie_len); 160 ifibss->ie, ifibss->ie_len);
159 161
160 /* add HT capability and information IEs */ 162 /* add HT capability and information IEs */
161 if (channel_type && sband->ht_cap.ht_supported) { 163 if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
164 sband->ht_cap.ht_supported) {
162 pos = skb_put(skb, 4 + 165 pos = skb_put(skb, 4 +
163 sizeof(struct ieee80211_ht_cap) + 166 sizeof(struct ieee80211_ht_cap) +
164 sizeof(struct ieee80211_ht_operation)); 167 sizeof(struct ieee80211_ht_operation));
@@ -170,7 +173,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
170 * keep them at 0 173 * keep them at 0
171 */ 174 */
172 pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, 175 pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap,
173 chan, channel_type, 0); 176 &chandef, 0);
174 } 177 }
175 178
176 if (local->hw.queues >= IEEE80211_NUM_ACS) { 179 if (local->hw.queues >= IEEE80211_NUM_ACS) {
@@ -326,7 +329,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
326 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 329 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
327 if (WARN_ON_ONCE(!chanctx_conf)) 330 if (WARN_ON_ONCE(!chanctx_conf))
328 return NULL; 331 return NULL;
329 band = chanctx_conf->channel->band; 332 band = chanctx_conf->def.chan->band;
330 rcu_read_unlock(); 333 rcu_read_unlock();
331 334
332 sta = sta_info_alloc(sdata, addr, GFP_KERNEL); 335 sta = sta_info_alloc(sdata, addr, GFP_KERNEL);
@@ -374,11 +377,13 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
374 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); 377 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
375 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); 378 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
376 379
377 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
378 return;
379 ibss_dbg(sdata, 380 ibss_dbg(sdata,
380 "RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", 381 "RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n",
381 mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction); 382 mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction);
383
384 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
385 return;
386
382 sta_info_destroy_addr(sdata, mgmt->sa); 387 sta_info_destroy_addr(sdata, mgmt->sa);
383 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); 388 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false);
384 rcu_read_unlock(); 389 rcu_read_unlock();
@@ -473,9 +478,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
473 sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) { 478 sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) {
474 /* we both use HT */ 479 /* we both use HT */
475 struct ieee80211_sta_ht_cap sta_ht_cap_new; 480 struct ieee80211_sta_ht_cap sta_ht_cap_new;
476 enum nl80211_channel_type channel_type = 481 struct cfg80211_chan_def chandef;
477 ieee80211_ht_oper_to_channel_type( 482
478 elems->ht_operation); 483 ieee80211_ht_oper_to_chandef(channel,
484 elems->ht_operation,
485 &chandef);
479 486
480 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, 487 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
481 elems->ht_cap_elem, 488 elems->ht_cap_elem,
@@ -485,9 +492,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
485 * fall back to HT20 if we don't use or use 492 * fall back to HT20 if we don't use or use
486 * the other extension channel 493 * the other extension channel
487 */ 494 */
488 if (!(channel_type == NL80211_CHAN_HT40MINUS || 495 if (chandef.width != NL80211_CHAN_WIDTH_40 ||
489 channel_type == NL80211_CHAN_HT40PLUS) || 496 cfg80211_get_chandef_type(&chandef) !=
490 channel_type != sdata->u.ibss.channel_type) 497 sdata->u.ibss.channel_type)
491 sta_ht_cap_new.cap &= 498 sta_ht_cap_new.cap &=
492 ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; 499 ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
493 500
@@ -611,7 +618,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
611 rcu_read_unlock(); 618 rcu_read_unlock();
612 return; 619 return;
613 } 620 }
614 band = chanctx_conf->channel->band; 621 band = chanctx_conf->def.chan->band;
615 rcu_read_unlock(); 622 rcu_read_unlock();
616 623
617 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); 624 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
@@ -1076,8 +1083,9 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1076 1083
1077 sdata->vif.bss_conf.beacon_int = params->beacon_interval; 1084 sdata->vif.bss_conf.beacon_int = params->beacon_interval;
1078 1085
1079 sdata->u.ibss.channel = params->channel; 1086 sdata->u.ibss.channel = params->chandef.chan;
1080 sdata->u.ibss.channel_type = params->channel_type; 1087 sdata->u.ibss.channel_type =
1088 cfg80211_get_chandef_type(&params->chandef);
1081 sdata->u.ibss.fixed_channel = params->channel_fixed; 1089 sdata->u.ibss.fixed_channel = params->channel_fixed;
1082 1090
1083 if (params->ie) { 1091 if (params->ie) {
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 115117c558aa..5c0d5a6946c1 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -348,7 +348,6 @@ struct ieee80211_roc_work {
348 struct ieee80211_sub_if_data *sdata; 348 struct ieee80211_sub_if_data *sdata;
349 349
350 struct ieee80211_channel *chan; 350 struct ieee80211_channel *chan;
351 enum nl80211_channel_type chan_type;
352 351
353 bool started, abort, hw_begun, notified; 352 bool started, abort, hw_begun, notified;
354 353
@@ -364,7 +363,7 @@ enum ieee80211_sta_flags {
364 IEEE80211_STA_BEACON_POLL = BIT(0), 363 IEEE80211_STA_BEACON_POLL = BIT(0),
365 IEEE80211_STA_CONNECTION_POLL = BIT(1), 364 IEEE80211_STA_CONNECTION_POLL = BIT(1),
366 IEEE80211_STA_CONTROL_PORT = BIT(2), 365 IEEE80211_STA_CONTROL_PORT = BIT(2),
367 IEEE80211_STA_DISABLE_11N = BIT(4), 366 IEEE80211_STA_DISABLE_HT = BIT(4),
368 IEEE80211_STA_CSA_RECEIVED = BIT(5), 367 IEEE80211_STA_CSA_RECEIVED = BIT(5),
369 IEEE80211_STA_MFP_ENABLED = BIT(6), 368 IEEE80211_STA_MFP_ENABLED = BIT(6),
370 IEEE80211_STA_UAPSD_ENABLED = BIT(7), 369 IEEE80211_STA_UAPSD_ENABLED = BIT(7),
@@ -800,7 +799,7 @@ ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata)
800 rcu_read_lock(); 799 rcu_read_lock();
801 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 800 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
802 if (!WARN_ON(!chanctx_conf)) 801 if (!WARN_ON(!chanctx_conf))
803 band = chanctx_conf->channel->band; 802 band = chanctx_conf->def.chan->band;
804 rcu_read_unlock(); 803 rcu_read_unlock();
805 804
806 return band; 805 return band;
@@ -1048,7 +1047,6 @@ struct ieee80211_local {
1048 1047
1049 /* Temporary remain-on-channel for off-channel operations */ 1048 /* Temporary remain-on-channel for off-channel operations */
1050 struct ieee80211_channel *tmp_channel; 1049 struct ieee80211_channel *tmp_channel;
1051 enum nl80211_channel_type tmp_channel_type;
1052 1050
1053 /* channel contexts */ 1051 /* channel contexts */
1054 struct list_head chanctx_list; 1052 struct list_head chanctx_list;
@@ -1158,8 +1156,7 @@ struct ieee80211_local {
1158 1156
1159 /* virtual monitor interface */ 1157 /* virtual monitor interface */
1160 struct ieee80211_sub_if_data __rcu *monitor_sdata; 1158 struct ieee80211_sub_if_data __rcu *monitor_sdata;
1161 struct ieee80211_channel *monitor_channel; 1159 struct cfg80211_chan_def monitor_chandef;
1162 enum nl80211_channel_type monitor_channel_type;
1163}; 1160};
1164 1161
1165static inline struct ieee80211_sub_if_data * 1162static inline struct ieee80211_sub_if_data *
@@ -1518,7 +1515,7 @@ static inline void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata,
1518 } 1515 }
1519 1516
1520 __ieee80211_tx_skb_tid_band(sdata, skb, tid, 1517 __ieee80211_tx_skb_tid_band(sdata, skb, tid,
1521 chanctx_conf->channel->band); 1518 chanctx_conf->def.chan->band);
1522 rcu_read_unlock(); 1519 rcu_read_unlock();
1523} 1520}
1524 1521
@@ -1607,8 +1604,7 @@ size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
1607u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, 1604u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1608 u16 cap); 1605 u16 cap);
1609u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, 1606u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1610 struct ieee80211_channel *channel, 1607 const struct cfg80211_chan_def *chandef,
1611 enum nl80211_channel_type channel_type,
1612 u16 prot_mode); 1608 u16 prot_mode);
1613u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, 1609u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
1614 u32 cap); 1610 u32 cap);
@@ -1620,13 +1616,13 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
1620 enum ieee80211_band band); 1616 enum ieee80211_band band);
1621 1617
1622/* channel management */ 1618/* channel management */
1623enum nl80211_channel_type 1619void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,
1624ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper); 1620 struct ieee80211_ht_operation *ht_oper,
1621 struct cfg80211_chan_def *chandef);
1625 1622
1626int __must_check 1623int __must_check
1627ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, 1624ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
1628 struct ieee80211_channel *channel, 1625 const struct cfg80211_chan_def *chandef,
1629 enum nl80211_channel_type channel_type,
1630 enum ieee80211_chanctx_mode mode); 1626 enum ieee80211_chanctx_mode mode);
1631void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); 1627void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
1632 1628
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 80ce90b29d9d..5331662489f7 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -54,7 +54,7 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
54 return false; 54 return false;
55 } 55 }
56 56
57 power = chanctx_conf->channel->max_power; 57 power = chanctx_conf->def.chan->max_power;
58 rcu_read_unlock(); 58 rcu_read_unlock();
59 59
60 if (sdata->user_power_level != IEEE80211_UNSET_POWER_LEVEL) 60 if (sdata->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
@@ -415,8 +415,7 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
415 goto out_unlock; 415 goto out_unlock;
416 } 416 }
417 417
418 ret = ieee80211_vif_use_channel(sdata, local->monitor_channel, 418 ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef,
419 local->monitor_channel_type,
420 IEEE80211_CHANCTX_EXCLUSIVE); 419 IEEE80211_CHANCTX_EXCLUSIVE);
421 if (ret) { 420 if (ret) {
422 drv_remove_interface(local, sdata); 421 drv_remove_interface(local, sdata);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index da2f41610125..f5e4c1f24bf2 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -115,7 +115,7 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
115 channel_type = NL80211_CHAN_NO_HT; 115 channel_type = NL80211_CHAN_NO_HT;
116 } else if (local->tmp_channel) { 116 } else if (local->tmp_channel) {
117 chan = local->tmp_channel; 117 chan = local->tmp_channel;
118 channel_type = local->tmp_channel_type; 118 channel_type = NL80211_CHAN_NO_HT;
119 } else { 119 } else {
120 chan = local->_oper_channel; 120 chan = local->_oper_channel;
121 channel_type = local->_oper_channel_type; 121 channel_type = local->_oper_channel_type;
@@ -798,10 +798,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
798 local->_oper_channel = &sband->channels[0]; 798 local->_oper_channel = &sband->channels[0];
799 local->hw.conf.channel_type = NL80211_CHAN_NO_HT; 799 local->hw.conf.channel_type = NL80211_CHAN_NO_HT;
800 } 800 }
801 if (!local->monitor_channel) { 801 cfg80211_chandef_create(&local->monitor_chandef,
802 local->monitor_channel = &sband->channels[0]; 802 &sband->channels[0],
803 local->monitor_channel_type = NL80211_CHAN_NO_HT; 803 NL80211_CHAN_NO_HT);
804 }
805 channels += sband->n_channels; 804 channels += sband->n_channels;
806 805
807 if (max_bitrates < sband->n_bitrates) 806 if (max_bitrates < sband->n_bitrates)
@@ -884,10 +883,22 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
884 if (supp_ht) 883 if (supp_ht)
885 local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); 884 local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap);
886 885
887 if (supp_vht) 886 if (supp_vht) {
888 local->scan_ies_len += 887 local->scan_ies_len +=
889 2 + sizeof(struct ieee80211_vht_cap); 888 2 + sizeof(struct ieee80211_vht_cap);
890 889
890 /*
891 * (for now at least), drivers wanting to use VHT must
892 * support channel contexts, as they contain all the
893 * necessary VHT information and the global hw config
894 * doesn't (yet)
895 */
896 if (WARN_ON(!local->use_chanctx)) {
897 result = -EINVAL;
898 goto fail_wiphy_register;
899 }
900 }
901
891 if (!local->ops->hw_scan) { 902 if (!local->ops->hw_scan) {
892 /* For hw_scan, driver needs to set these up. */ 903 /* For hw_scan, driver needs to set these up. */
893 local->hw.wiphy->max_scan_ssids = 4; 904 local->hw.wiphy->max_scan_ssids = 4;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index a350cab4b339..1bf03f9ff3ba 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -76,7 +76,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
76 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 76 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
77 struct ieee80211_local *local = sdata->local; 77 struct ieee80211_local *local = sdata->local;
78 u32 basic_rates = 0; 78 u32 basic_rates = 0;
79 enum nl80211_channel_type sta_channel_type = NL80211_CHAN_NO_HT; 79 struct cfg80211_chan_def sta_chan_def;
80 80
81 /* 81 /*
82 * As support for each feature is added, check for matching 82 * As support for each feature is added, check for matching
@@ -103,17 +103,11 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
103 if (sdata->vif.bss_conf.basic_rates != basic_rates) 103 if (sdata->vif.bss_conf.basic_rates != basic_rates)
104 goto mismatch; 104 goto mismatch;
105 105
106 if (ie->ht_operation) 106 ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan,
107 sta_channel_type = 107 ie->ht_operation, &sta_chan_def);
108 ieee80211_ht_oper_to_channel_type(ie->ht_operation); 108
109 109 if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef,
110 /* Disallow HT40+/- mismatch */ 110 &sta_chan_def))
111 if (ie->ht_operation &&
112 (sdata->vif.bss_conf.channel_type == NL80211_CHAN_HT40MINUS ||
113 sdata->vif.bss_conf.channel_type == NL80211_CHAN_HT40PLUS) &&
114 (sta_channel_type == NL80211_CHAN_HT40MINUS ||
115 sta_channel_type == NL80211_CHAN_HT40PLUS) &&
116 sdata->vif.bss_conf.channel_type != sta_channel_type)
117 goto mismatch; 111 goto mismatch;
118 112
119 return true; 113 return true;
@@ -129,7 +123,7 @@ mismatch:
129bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie) 123bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie)
130{ 124{
131 return (ie->mesh_config->meshconf_cap & 125 return (ie->mesh_config->meshconf_cap &
132 MESHCONF_CAPAB_ACCEPT_PLINKS) != 0; 126 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS) != 0;
133} 127}
134 128
135/** 129/**
@@ -269,11 +263,11 @@ mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
269 neighbors = (neighbors > 15) ? 15 : neighbors; 263 neighbors = (neighbors > 15) ? 15 : neighbors;
270 *pos++ = neighbors << 1; 264 *pos++ = neighbors << 1;
271 /* Mesh capability */ 265 /* Mesh capability */
272 *pos = MESHCONF_CAPAB_FORWARDING; 266 *pos = IEEE80211_MESHCONF_CAPAB_FORWARDING;
273 *pos |= ifmsh->accepting_plinks ? 267 *pos |= ifmsh->accepting_plinks ?
274 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; 268 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
275 *pos++ |= ifmsh->adjusting_tbtt ? 269 *pos++ |= ifmsh->adjusting_tbtt ?
276 MESHCONF_CAPAB_TBTT_ADJUSTING : 0x00; 270 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING : 0x00;
277 *pos++ = 0x00; 271 *pos++ = 0x00;
278 272
279 return 0; 273 return 0;
@@ -368,7 +362,7 @@ int mesh_add_ds_params_ie(struct sk_buff *skb,
368 rcu_read_unlock(); 362 rcu_read_unlock();
369 return -EINVAL; 363 return -EINVAL;
370 } 364 }
371 chan = chanctx_conf->channel; 365 chan = chanctx_conf->def.chan;
372 rcu_read_unlock(); 366 rcu_read_unlock();
373 367
374 sband = local->hw.wiphy->bands[chan->band]; 368 sband = local->hw.wiphy->bands[chan->band];
@@ -392,7 +386,7 @@ int mesh_add_ht_cap_ie(struct sk_buff *skb,
392 386
393 sband = local->hw.wiphy->bands[band]; 387 sband = local->hw.wiphy->bands[band];
394 if (!sband->ht_cap.ht_supported || 388 if (!sband->ht_cap.ht_supported ||
395 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) 389 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
396 return 0; 390 return 0;
397 391
398 if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap)) 392 if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap))
@@ -411,7 +405,7 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
411 struct ieee80211_chanctx_conf *chanctx_conf; 405 struct ieee80211_chanctx_conf *chanctx_conf;
412 struct ieee80211_channel *channel; 406 struct ieee80211_channel *channel;
413 enum nl80211_channel_type channel_type = 407 enum nl80211_channel_type channel_type =
414 sdata->vif.bss_conf.channel_type; 408 cfg80211_get_chandef_type(&sdata->vif.bss_conf.chandef);
415 struct ieee80211_supported_band *sband; 409 struct ieee80211_supported_band *sband;
416 struct ieee80211_sta_ht_cap *ht_cap; 410 struct ieee80211_sta_ht_cap *ht_cap;
417 u8 *pos; 411 u8 *pos;
@@ -422,7 +416,7 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
422 rcu_read_unlock(); 416 rcu_read_unlock();
423 return -EINVAL; 417 return -EINVAL;
424 } 418 }
425 channel = chanctx_conf->channel; 419 channel = chanctx_conf->def.chan;
426 rcu_read_unlock(); 420 rcu_read_unlock();
427 421
428 sband = local->hw.wiphy->bands[channel->band]; 422 sband = local->hw.wiphy->bands[channel->band];
@@ -435,7 +429,7 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
435 return -ENOMEM; 429 return -ENOMEM;
436 430
437 pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_operation)); 431 pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_operation));
438 ieee80211_ie_build_ht_oper(pos, ht_cap, channel, channel_type, 432 ieee80211_ie_build_ht_oper(pos, ht_cap, &sdata->vif.bss_conf.chandef,
439 sdata->vif.bss_conf.ht_operation_mode); 433 sdata->vif.bss_conf.ht_operation_mode);
440 434
441 return 0; 435 return 0;
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 9285f3f67e66..7c9215fb2ac8 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -19,20 +19,6 @@
19/* Data structures */ 19/* Data structures */
20 20
21/** 21/**
22 * enum mesh_config_capab_flags - mesh config IE capability flags
23 *
24 * @MESHCONF_CAPAB_ACCEPT_PLINKS: STA is willing to establish
25 * additional mesh peerings with other mesh STAs
26 * @MESHCONF_CAPAB_FORWARDING: the STA forwards MSDUs
27 * @MESHCONF_CAPAB_TBTT_ADJUSTING: TBTT adjustment procedure is ongoing
28 */
29enum mesh_config_capab_flags {
30 MESHCONF_CAPAB_ACCEPT_PLINKS = BIT(0),
31 MESHCONF_CAPAB_FORWARDING = BIT(3),
32 MESHCONF_CAPAB_TBTT_ADJUSTING = BIT(5),
33};
34
35/**
36 * enum mesh_path_flags - mac80211 mesh path flags 22 * enum mesh_path_flags - mac80211 mesh path flags
37 * 23 *
38 * 24 *
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 234fe755968b..ca52dfdd5375 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -19,12 +19,6 @@
19#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \ 19#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
20 jiffies + HZ * t / 1000)) 20 jiffies + HZ * t / 1000))
21 21
22#define dot11MeshMaxRetries(s) (s->u.mesh.mshcfg.dot11MeshMaxRetries)
23#define dot11MeshRetryTimeout(s) (s->u.mesh.mshcfg.dot11MeshRetryTimeout)
24#define dot11MeshConfirmTimeout(s) (s->u.mesh.mshcfg.dot11MeshConfirmTimeout)
25#define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout)
26#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
27
28/* We only need a valid sta if user configured a minimum rssi_threshold. */ 22/* We only need a valid sta if user configured a minimum rssi_threshold. */
29#define rssi_threshold_check(sta, sdata) \ 23#define rssi_threshold_check(sta, sdata) \
30 (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\ 24 (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\
@@ -117,7 +111,7 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
117 u16 ht_opmode; 111 u16 ht_opmode;
118 bool non_ht_sta = false, ht20_sta = false; 112 bool non_ht_sta = false, ht20_sta = false;
119 113
120 if (sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) 114 if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
121 return 0; 115 return 0;
122 116
123 rcu_read_lock(); 117 rcu_read_lock();
@@ -126,14 +120,14 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
126 sta->plink_state != NL80211_PLINK_ESTAB) 120 sta->plink_state != NL80211_PLINK_ESTAB)
127 continue; 121 continue;
128 122
129 switch (sta->ch_type) { 123 switch (sta->ch_width) {
130 case NL80211_CHAN_NO_HT: 124 case NL80211_CHAN_WIDTH_20_NOHT:
131 mpl_dbg(sdata, 125 mpl_dbg(sdata,
132 "mesh_plink %pM: nonHT sta (%pM) is present\n", 126 "mesh_plink %pM: nonHT sta (%pM) is present\n",
133 sdata->vif.addr, sta->sta.addr); 127 sdata->vif.addr, sta->sta.addr);
134 non_ht_sta = true; 128 non_ht_sta = true;
135 goto out; 129 goto out;
136 case NL80211_CHAN_HT20: 130 case NL80211_CHAN_WIDTH_20:
137 mpl_dbg(sdata, 131 mpl_dbg(sdata,
138 "mesh_plink %pM: HT20 sta (%pM) is present\n", 132 "mesh_plink %pM: HT20 sta (%pM) is present\n",
139 sdata->vif.addr, sta->sta.addr); 133 sdata->vif.addr, sta->sta.addr);
@@ -148,7 +142,7 @@ out:
148 if (non_ht_sta) 142 if (non_ht_sta)
149 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED; 143 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
150 else if (ht20_sta && 144 else if (ht20_sta &&
151 sdata->vif.bss_conf.channel_type > NL80211_CHAN_HT20) 145 sdata->vif.bss_conf.chandef.width > NL80211_CHAN_WIDTH_20)
152 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ; 146 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
153 else 147 else
154 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE; 148 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
@@ -378,7 +372,7 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
378 372
379 sta->sta.supp_rates[band] = rates; 373 sta->sta.supp_rates[band] = rates;
380 if (elems->ht_cap_elem && 374 if (elems->ht_cap_elem &&
381 sdata->vif.bss_conf.channel_type != NL80211_CHAN_NO_HT) 375 sdata->vif.bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
382 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, 376 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
383 elems->ht_cap_elem, 377 elems->ht_cap_elem,
384 &sta->sta.ht_cap); 378 &sta->sta.ht_cap);
@@ -386,12 +380,15 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
386 memset(&sta->sta.ht_cap, 0, sizeof(sta->sta.ht_cap)); 380 memset(&sta->sta.ht_cap, 0, sizeof(sta->sta.ht_cap));
387 381
388 if (elems->ht_operation) { 382 if (elems->ht_operation) {
383 struct cfg80211_chan_def chandef;
384
389 if (!(elems->ht_operation->ht_param & 385 if (!(elems->ht_operation->ht_param &
390 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) 386 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
391 sta->sta.ht_cap.cap &= 387 sta->sta.ht_cap.cap &=
392 ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; 388 ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
393 sta->ch_type = 389 ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan,
394 ieee80211_ht_oper_to_channel_type(elems->ht_operation); 390 elems->ht_operation, &chandef);
391 sta->ch_width = chandef.width;
395 } 392 }
396 393
397 rate_control_rate_init(sta); 394 rate_control_rate_init(sta);
@@ -430,6 +427,7 @@ static void mesh_plink_timer(unsigned long data)
430 struct sta_info *sta; 427 struct sta_info *sta;
431 __le16 llid, plid, reason; 428 __le16 llid, plid, reason;
432 struct ieee80211_sub_if_data *sdata; 429 struct ieee80211_sub_if_data *sdata;
430 struct mesh_config *mshcfg;
433 431
434 /* 432 /*
435 * This STA is valid because sta_info_destroy() will 433 * This STA is valid because sta_info_destroy() will
@@ -456,12 +454,13 @@ static void mesh_plink_timer(unsigned long data)
456 llid = sta->llid; 454 llid = sta->llid;
457 plid = sta->plid; 455 plid = sta->plid;
458 sdata = sta->sdata; 456 sdata = sta->sdata;
457 mshcfg = &sdata->u.mesh.mshcfg;
459 458
460 switch (sta->plink_state) { 459 switch (sta->plink_state) {
461 case NL80211_PLINK_OPN_RCVD: 460 case NL80211_PLINK_OPN_RCVD:
462 case NL80211_PLINK_OPN_SNT: 461 case NL80211_PLINK_OPN_SNT:
463 /* retry timer */ 462 /* retry timer */
464 if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { 463 if (sta->plink_retries < mshcfg->dot11MeshMaxRetries) {
465 u32 rand; 464 u32 rand;
466 mpl_dbg(sta->sdata, 465 mpl_dbg(sta->sdata,
467 "Mesh plink for %pM (retry, timeout): %d %d\n", 466 "Mesh plink for %pM (retry, timeout): %d %d\n",
@@ -484,7 +483,7 @@ static void mesh_plink_timer(unsigned long data)
484 if (!reason) 483 if (!reason)
485 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT); 484 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
486 sta->plink_state = NL80211_PLINK_HOLDING; 485 sta->plink_state = NL80211_PLINK_HOLDING;
487 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 486 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
488 spin_unlock_bh(&sta->lock); 487 spin_unlock_bh(&sta->lock);
489 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 488 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
490 sta->sta.addr, llid, plid, reason); 489 sta->sta.addr, llid, plid, reason);
@@ -543,7 +542,7 @@ int mesh_plink_open(struct sta_info *sta)
543 return -EBUSY; 542 return -EBUSY;
544 } 543 }
545 sta->plink_state = NL80211_PLINK_OPN_SNT; 544 sta->plink_state = NL80211_PLINK_OPN_SNT;
546 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 545 mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout);
547 spin_unlock_bh(&sta->lock); 546 spin_unlock_bh(&sta->lock);
548 mpl_dbg(sdata, 547 mpl_dbg(sdata,
549 "Mesh plink: starting establishment with %pM\n", 548 "Mesh plink: starting establishment with %pM\n",
@@ -570,6 +569,7 @@ void mesh_plink_block(struct sta_info *sta)
570void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, 569void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt,
571 size_t len, struct ieee80211_rx_status *rx_status) 570 size_t len, struct ieee80211_rx_status *rx_status)
572{ 571{
572 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
573 struct ieee802_11_elems elems; 573 struct ieee802_11_elems elems;
574 struct sta_info *sta; 574 struct sta_info *sta;
575 enum plink_event event; 575 enum plink_event event;
@@ -777,7 +777,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
777 sta->plid = plid; 777 sta->plid = plid;
778 get_random_bytes(&llid, 2); 778 get_random_bytes(&llid, 2);
779 sta->llid = llid; 779 sta->llid = llid;
780 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 780 mesh_plink_timer_set(sta,
781 mshcfg->dot11MeshRetryTimeout);
781 spin_unlock_bh(&sta->lock); 782 spin_unlock_bh(&sta->lock);
782 mesh_plink_frame_tx(sdata, 783 mesh_plink_frame_tx(sdata,
783 WLAN_SP_MESH_PEERING_OPEN, 784 WLAN_SP_MESH_PEERING_OPEN,
@@ -803,7 +804,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
803 sta->reason = reason; 804 sta->reason = reason;
804 sta->plink_state = NL80211_PLINK_HOLDING; 805 sta->plink_state = NL80211_PLINK_HOLDING;
805 if (!mod_plink_timer(sta, 806 if (!mod_plink_timer(sta,
806 dot11MeshHoldingTimeout(sdata))) 807 mshcfg->dot11MeshHoldingTimeout))
807 sta->ignore_plink_timer = true; 808 sta->ignore_plink_timer = true;
808 809
809 llid = sta->llid; 810 llid = sta->llid;
@@ -825,7 +826,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
825 case CNF_ACPT: 826 case CNF_ACPT:
826 sta->plink_state = NL80211_PLINK_CNF_RCVD; 827 sta->plink_state = NL80211_PLINK_CNF_RCVD;
827 if (!mod_plink_timer(sta, 828 if (!mod_plink_timer(sta,
828 dot11MeshConfirmTimeout(sdata))) 829 mshcfg->dot11MeshConfirmTimeout))
829 sta->ignore_plink_timer = true; 830 sta->ignore_plink_timer = true;
830 831
831 spin_unlock_bh(&sta->lock); 832 spin_unlock_bh(&sta->lock);
@@ -847,7 +848,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
847 sta->reason = reason; 848 sta->reason = reason;
848 sta->plink_state = NL80211_PLINK_HOLDING; 849 sta->plink_state = NL80211_PLINK_HOLDING;
849 if (!mod_plink_timer(sta, 850 if (!mod_plink_timer(sta,
850 dot11MeshHoldingTimeout(sdata))) 851 mshcfg->dot11MeshHoldingTimeout))
851 sta->ignore_plink_timer = true; 852 sta->ignore_plink_timer = true;
852 853
853 llid = sta->llid; 854 llid = sta->llid;
@@ -888,7 +889,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
888 sta->reason = reason; 889 sta->reason = reason;
889 sta->plink_state = NL80211_PLINK_HOLDING; 890 sta->plink_state = NL80211_PLINK_HOLDING;
890 if (!mod_plink_timer(sta, 891 if (!mod_plink_timer(sta,
891 dot11MeshHoldingTimeout(sdata))) 892 mshcfg->dot11MeshHoldingTimeout))
892 sta->ignore_plink_timer = true; 893 sta->ignore_plink_timer = true;
893 894
894 llid = sta->llid; 895 llid = sta->llid;
@@ -923,7 +924,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
923 changed |= __mesh_plink_deactivate(sta); 924 changed |= __mesh_plink_deactivate(sta);
924 sta->plink_state = NL80211_PLINK_HOLDING; 925 sta->plink_state = NL80211_PLINK_HOLDING;
925 llid = sta->llid; 926 llid = sta->llid;
926 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 927 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
927 spin_unlock_bh(&sta->lock); 928 spin_unlock_bh(&sta->lock);
928 changed |= mesh_set_ht_prot_mode(sdata); 929 changed |= mesh_set_ht_prot_mode(sdata);
929 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 930 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c
index 9c6ea9cfe1b3..0f40086cce18 100644
--- a/net/mac80211/mesh_sync.c
+++ b/net/mac80211/mesh_sync.c
@@ -43,7 +43,7 @@ struct sync_method {
43static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie) 43static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie)
44{ 44{
45 return (ie->mesh_config->meshconf_cap & 45 return (ie->mesh_config->meshconf_cap &
46 MESHCONF_CAPAB_TBTT_ADJUSTING) != 0; 46 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING) != 0;
47} 47}
48 48
49void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata) 49void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 61614461e089..d2a4f78b4b0f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -191,17 +191,19 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
191 rcu_read_unlock(); 191 rcu_read_unlock();
192 return 0; 192 return 0;
193 } 193 }
194 chan = chanctx_conf->channel; 194 chan = chanctx_conf->def.chan;
195 rcu_read_unlock(); 195 rcu_read_unlock();
196 sband = local->hw.wiphy->bands[chan->band]; 196 sband = local->hw.wiphy->bands[chan->band];
197 197
198 switch (sdata->vif.bss_conf.channel_type) { 198 switch (sdata->vif.bss_conf.chandef.width) {
199 case NL80211_CHAN_HT40PLUS: 199 case NL80211_CHAN_WIDTH_40:
200 if (chan->flags & IEEE80211_CHAN_NO_HT40PLUS) 200 if (sdata->vif.bss_conf.chandef.chan->center_freq >
201 sdata->vif.bss_conf.chandef.center_freq1 &&
202 chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
201 disable_40 = true; 203 disable_40 = true;
202 break; 204 if (sdata->vif.bss_conf.chandef.chan->center_freq <
203 case NL80211_CHAN_HT40MINUS: 205 sdata->vif.bss_conf.chandef.center_freq1 &&
204 if (chan->flags & IEEE80211_CHAN_NO_HT40MINUS) 206 chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
205 disable_40 = true; 207 disable_40 = true;
206 break; 208 break;
207 default: 209 default:
@@ -381,7 +383,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
381 rcu_read_unlock(); 383 rcu_read_unlock();
382 return; 384 return;
383 } 385 }
384 chan = chanctx_conf->channel; 386 chan = chanctx_conf->def.chan;
385 rcu_read_unlock(); 387 rcu_read_unlock();
386 sband = local->hw.wiphy->bands[chan->band]; 388 sband = local->hw.wiphy->bands[chan->band];
387 389
@@ -541,7 +543,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
541 offset = noffset; 543 offset = noffset;
542 } 544 }
543 545
544 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 546 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
545 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, 547 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param,
546 sband, chan, sdata->smps_mode); 548 sband, chan, sdata->smps_mode);
547 549
@@ -1528,8 +1530,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1528 changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; 1530 changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
1529 ieee80211_bss_info_change_notify(sdata, changed); 1531 ieee80211_bss_info_change_notify(sdata, changed);
1530 1532
1531 ieee80211_vif_release_channel(sdata);
1532
1533 /* disassociated - set to defaults now */ 1533 /* disassociated - set to defaults now */
1534 ieee80211_set_wmm_default(sdata, false); 1534 ieee80211_set_wmm_default(sdata, false);
1535 1535
@@ -1539,6 +1539,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1539 del_timer_sync(&sdata->u.mgd.chswitch_timer); 1539 del_timer_sync(&sdata->u.mgd.chswitch_timer);
1540 1540
1541 sdata->u.mgd.timers_running = 0; 1541 sdata->u.mgd.timers_running = 0;
1542
1543 ifmgd->flags = 0;
1544 ieee80211_vif_release_channel(sdata);
1542} 1545}
1543 1546
1544void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 1547void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -1864,6 +1867,7 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
1864 1867
1865 memset(sdata->u.mgd.bssid, 0, ETH_ALEN); 1868 memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
1866 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); 1869 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
1870 sdata->u.mgd.flags = 0;
1867 ieee80211_vif_release_channel(sdata); 1871 ieee80211_vif_release_channel(sdata);
1868 } 1872 }
1869 1873
@@ -2106,6 +2110,7 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
2106 2110
2107 memset(sdata->u.mgd.bssid, 0, ETH_ALEN); 2111 memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
2108 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); 2112 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
2113 sdata->u.mgd.flags = 0;
2109 ieee80211_vif_release_channel(sdata); 2114 ieee80211_vif_release_channel(sdata);
2110 } 2115 }
2111 2116
@@ -2170,7 +2175,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2170 2175
2171 sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)]; 2176 sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
2172 2177
2173 if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 2178 if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
2174 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, 2179 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
2175 elems.ht_cap_elem, &sta->sta.ht_cap); 2180 elems.ht_cap_elem, &sta->sta.ht_cap);
2176 2181
@@ -2222,7 +2227,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2222 changed |= BSS_CHANGED_QOS; 2227 changed |= BSS_CHANGED_QOS;
2223 2228
2224 if (elems.ht_operation && elems.wmm_param && 2229 if (elems.ht_operation && elems.wmm_param &&
2225 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 2230 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
2226 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation, 2231 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation,
2227 cbss->bssid, false); 2232 cbss->bssid, false);
2228 2233
@@ -2473,11 +2478,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2473 return; 2478 return;
2474 } 2479 }
2475 2480
2476 if (rx_status->freq != chanctx_conf->channel->center_freq) { 2481 if (rx_status->freq != chanctx_conf->def.chan->center_freq) {
2477 rcu_read_unlock(); 2482 rcu_read_unlock();
2478 return; 2483 return;
2479 } 2484 }
2480 chan = chanctx_conf->channel; 2485 chan = chanctx_conf->def.chan;
2481 rcu_read_unlock(); 2486 rcu_read_unlock();
2482 2487
2483 if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon && 2488 if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon &&
@@ -2658,7 +2663,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2658 2663
2659 2664
2660 if (elems.ht_cap_elem && elems.ht_operation && elems.wmm_param && 2665 if (elems.ht_cap_elem && elems.ht_operation && elems.wmm_param &&
2661 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 2666 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
2662 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation, 2667 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation,
2663 bssid, true); 2668 bssid, true);
2664 2669
@@ -3188,6 +3193,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3188 const u8 *ht_oper_ie; 3193 const u8 *ht_oper_ie;
3189 const struct ieee80211_ht_operation *ht_oper = NULL; 3194 const struct ieee80211_ht_operation *ht_oper = NULL;
3190 struct ieee80211_supported_band *sband; 3195 struct ieee80211_supported_band *sband;
3196 struct cfg80211_chan_def chandef;
3191 3197
3192 sband = local->hw.wiphy->bands[cbss->channel->band]; 3198 sband = local->hw.wiphy->bands[cbss->channel->band];
3193 3199
@@ -3219,12 +3225,10 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3219 ht_cfreq, ht_oper->primary_chan, 3225 ht_cfreq, ht_oper->primary_chan,
3220 cbss->channel->band); 3226 cbss->channel->band);
3221 ht_oper = NULL; 3227 ht_oper = NULL;
3222 } else {
3223 channel_type = NL80211_CHAN_HT20;
3224 } 3228 }
3225 } 3229 }
3226 3230
3227 if (ht_oper && sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { 3231 if (ht_oper) {
3228 /* 3232 /*
3229 * cfg80211 already verified that the channel itself can 3233 * cfg80211 already verified that the channel itself can
3230 * be used, but it didn't check that we can do the right 3234 * be used, but it didn't check that we can do the right
@@ -3237,19 +3241,26 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3237 3241
3238 channel_type = NL80211_CHAN_HT20; 3242 channel_type = NL80211_CHAN_HT20;
3239 3243
3240 switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { 3244 if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
3241 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: 3245 switch (ht_oper->ht_param &
3242 if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40PLUS) 3246 IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
3243 ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; 3247 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
3244 else 3248 if (cbss->channel->flags &
3245 channel_type = NL80211_CHAN_HT40PLUS; 3249 IEEE80211_CHAN_NO_HT40PLUS)
3246 break; 3250 ifmgd->flags |=
3247 case IEEE80211_HT_PARAM_CHA_SEC_BELOW: 3251 IEEE80211_STA_DISABLE_40MHZ;
3248 if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40MINUS) 3252 else
3249 ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; 3253 channel_type = NL80211_CHAN_HT40PLUS;
3250 else 3254 break;
3251 channel_type = NL80211_CHAN_HT40MINUS; 3255 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
3252 break; 3256 if (cbss->channel->flags &
3257 IEEE80211_CHAN_NO_HT40MINUS)
3258 ifmgd->flags |=
3259 IEEE80211_STA_DISABLE_40MHZ;
3260 else
3261 channel_type = NL80211_CHAN_HT40MINUS;
3262 break;
3263 }
3253 } 3264 }
3254 3265
3255 ht_cap_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, 3266 ht_cap_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
@@ -3262,13 +3273,15 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3262 sdata->needed_rx_chains = min(chains, local->rx_chains); 3273 sdata->needed_rx_chains = min(chains, local->rx_chains);
3263 } else { 3274 } else {
3264 sdata->needed_rx_chains = 1; 3275 sdata->needed_rx_chains = 1;
3276 sdata->u.mgd.flags |= IEEE80211_STA_DISABLE_HT;
3265 } 3277 }
3266 3278
3267 /* will change later if needed */ 3279 /* will change later if needed */
3268 sdata->smps_mode = IEEE80211_SMPS_OFF; 3280 sdata->smps_mode = IEEE80211_SMPS_OFF;
3269 3281
3270 ieee80211_vif_release_channel(sdata); 3282 ieee80211_vif_release_channel(sdata);
3271 return ieee80211_vif_use_channel(sdata, cbss->channel, channel_type, 3283 cfg80211_chandef_create(&chandef, cbss->channel, channel_type);
3284 return ieee80211_vif_use_channel(sdata, &chandef,
3272 IEEE80211_CHANCTX_SHARED); 3285 IEEE80211_CHANCTX_SHARED);
3273} 3286}
3274 3287
@@ -3530,13 +3543,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3530 3543
3531 /* prepare assoc data */ 3544 /* prepare assoc data */
3532 3545
3533 /*
3534 * keep only the 40 MHz disable bit set as it might have
3535 * been set during authentication already, all other bits
3536 * should be reset for a new connection
3537 */
3538 ifmgd->flags &= IEEE80211_STA_DISABLE_40MHZ;
3539
3540 ifmgd->beacon_crc_valid = false; 3546 ifmgd->beacon_crc_valid = false;
3541 3547
3542 /* 3548 /*
@@ -3550,7 +3556,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3550 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || 3556 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
3551 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || 3557 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
3552 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) { 3558 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) {
3553 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3559 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3554 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; 3560 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
3555 netdev_info(sdata->dev, 3561 netdev_info(sdata->dev,
3556 "disabling HT/VHT due to WEP/TKIP use\n"); 3562 "disabling HT/VHT due to WEP/TKIP use\n");
@@ -3558,7 +3564,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3558 } 3564 }
3559 3565
3560 if (req->flags & ASSOC_REQ_DISABLE_HT) { 3566 if (req->flags & ASSOC_REQ_DISABLE_HT) {
3561 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3567 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3562 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; 3568 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
3563 } 3569 }
3564 3570
@@ -3566,7 +3572,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3566 sband = local->hw.wiphy->bands[req->bss->channel->band]; 3572 sband = local->hw.wiphy->bands[req->bss->channel->band];
3567 if (!sband->ht_cap.ht_supported || 3573 if (!sband->ht_cap.ht_supported ||
3568 local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) { 3574 local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) {
3569 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3575 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3570 if (!bss->wmm_used) 3576 if (!bss->wmm_used)
3571 netdev_info(sdata->dev, 3577 netdev_info(sdata->dev,
3572 "disabling HT as WMM/QoS is not supported by the AP\n"); 3578 "disabling HT as WMM/QoS is not supported by the AP\n");
@@ -3611,7 +3617,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3611 assoc_data->ap_ht_param = 3617 assoc_data->ap_ht_param =
3612 ((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param; 3618 ((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param;
3613 else 3619 else
3614 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3620 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3615 3621
3616 if (bss->wmm_used && bss->uapsd_supported && 3622 if (bss->wmm_used && bss->uapsd_supported &&
3617 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { 3623 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 7f8a36510813..5abddfe3e101 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -205,8 +205,8 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc)
205 } 205 }
206 } else { 206 } else {
207 cfg80211_ready_on_channel(&roc->sdata->wdev, roc->cookie, 207 cfg80211_ready_on_channel(&roc->sdata->wdev, roc->cookie,
208 roc->chan, roc->chan_type, 208 roc->chan, roc->req_duration,
209 roc->req_duration, GFP_KERNEL); 209 GFP_KERNEL);
210 } 210 }
211 211
212 roc->notified = true; 212 roc->notified = true;
@@ -284,7 +284,6 @@ void ieee80211_start_next_roc(struct ieee80211_local *local)
284 duration = 10; 284 duration = 10;
285 285
286 ret = drv_remain_on_channel(local, roc->sdata, roc->chan, 286 ret = drv_remain_on_channel(local, roc->sdata, roc->chan,
287 roc->chan_type,
288 duration); 287 duration);
289 288
290 roc->started = true; 289 roc->started = true;
@@ -321,7 +320,7 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
321 if (!roc->mgmt_tx_cookie) 320 if (!roc->mgmt_tx_cookie)
322 cfg80211_remain_on_channel_expired(&roc->sdata->wdev, 321 cfg80211_remain_on_channel_expired(&roc->sdata->wdev,
323 roc->cookie, roc->chan, 322 roc->cookie, roc->chan,
324 roc->chan_type, GFP_KERNEL); 323 GFP_KERNEL);
325 324
326 list_for_each_entry_safe(dep, tmp, &roc->dependents, list) 325 list_for_each_entry_safe(dep, tmp, &roc->dependents, list)
327 ieee80211_roc_notify_destroy(dep); 326 ieee80211_roc_notify_destroy(dep);
@@ -359,7 +358,6 @@ void ieee80211_sw_roc_work(struct work_struct *work)
359 ieee80211_recalc_idle(local); 358 ieee80211_recalc_idle(local);
360 359
361 local->tmp_channel = roc->chan; 360 local->tmp_channel = roc->chan;
362 local->tmp_channel_type = roc->chan_type;
363 ieee80211_hw_config(local, 0); 361 ieee80211_hw_config(local, 0);
364 362
365 /* tell userspace or send frame */ 363 /* tell userspace or send frame */
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 3313c117b322..dd88381c53b7 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -391,7 +391,7 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
391 return; 391 return;
392 392
393 /* if HT BSS, and we handle a data frame, also try HT rates */ 393 /* if HT BSS, and we handle a data frame, also try HT rates */
394 if (txrc->bss_conf->channel_type == NL80211_CHAN_NO_HT) 394 if (txrc->bss_conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
395 return; 395 return;
396 396
397 fc = hdr->frame_control; 397 fc = hdr->frame_control;
@@ -408,8 +408,7 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
408 408
409 alt_rate.flags |= IEEE80211_TX_RC_MCS; 409 alt_rate.flags |= IEEE80211_TX_RC_MCS;
410 410
411 if ((txrc->bss_conf->channel_type == NL80211_CHAN_HT40MINUS) || 411 if (txrc->bss_conf->chandef.width == NL80211_CHAN_WIDTH_40)
412 (txrc->bss_conf->channel_type == NL80211_CHAN_HT40PLUS))
413 alt_rate.flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; 412 alt_rate.flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
414 413
415 if (rate_idx_match_mcs_mask(&alt_rate, mcs_mask)) { 414 if (rate_idx_match_mcs_mask(&alt_rate, mcs_mask)) {
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index ec198ef6aa8a..301386dabf88 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -65,7 +65,7 @@ static inline void rate_control_rate_init(struct sta_info *sta)
65 return; 65 return;
66 } 66 }
67 67
68 sband = local->hw.wiphy->bands[chanctx_conf->channel->band]; 68 sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
69 rcu_read_unlock(); 69 rcu_read_unlock();
70 70
71 ref->ops->rate_init(ref->priv, sband, ista, priv_sta); 71 ref->ops->rate_init(ref->priv, sband, ista, priv_sta);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index ec15a4929f7a..825f33cf7bbc 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -62,13 +62,16 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
62static inline int should_drop_frame(struct sk_buff *skb, int present_fcs_len) 62static inline int should_drop_frame(struct sk_buff *skb, int present_fcs_len)
63{ 63{
64 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 64 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
65 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 65 struct ieee80211_hdr *hdr;
66
67 hdr = (void *)(skb->data + status->vendor_radiotap_len);
66 68
67 if (status->flag & (RX_FLAG_FAILED_FCS_CRC | 69 if (status->flag & (RX_FLAG_FAILED_FCS_CRC |
68 RX_FLAG_FAILED_PLCP_CRC | 70 RX_FLAG_FAILED_PLCP_CRC |
69 RX_FLAG_AMPDU_IS_ZEROLEN)) 71 RX_FLAG_AMPDU_IS_ZEROLEN))
70 return 1; 72 return 1;
71 if (unlikely(skb->len < 16 + present_fcs_len)) 73 if (unlikely(skb->len < 16 + present_fcs_len +
74 status->vendor_radiotap_len))
72 return 1; 75 return 1;
73 if (ieee80211_is_ctl(hdr->frame_control) && 76 if (ieee80211_is_ctl(hdr->frame_control) &&
74 !ieee80211_is_pspoll(hdr->frame_control) && 77 !ieee80211_is_pspoll(hdr->frame_control) &&
@@ -190,7 +193,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
190 pos++; 193 pos++;
191 194
192 /* IEEE80211_RADIOTAP_RATE */ 195 /* IEEE80211_RADIOTAP_RATE */
193 if (!rate || status->flag & RX_FLAG_HT) { 196 if (!rate || status->flag & (RX_FLAG_HT | RX_FLAG_VHT)) {
194 /* 197 /*
195 * Without rate information don't add it. If we have, 198 * Without rate information don't add it. If we have,
196 * MCS information is a separate field in radiotap, 199 * MCS information is a separate field in radiotap,
@@ -210,7 +213,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
210 if (status->band == IEEE80211_BAND_5GHZ) 213 if (status->band == IEEE80211_BAND_5GHZ)
211 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ, 214 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ,
212 pos); 215 pos);
213 else if (status->flag & RX_FLAG_HT) 216 else if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT))
214 put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ, 217 put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ,
215 pos); 218 pos);
216 else if (rate && rate->flags & IEEE80211_RATE_ERP_G) 219 else if (rate && rate->flags & IEEE80211_RATE_ERP_G)
@@ -341,8 +344,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
341 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) 344 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
342 present_fcs_len = FCS_LEN; 345 present_fcs_len = FCS_LEN;
343 346
344 /* make sure hdr->frame_control is on the linear part */ 347 /* ensure hdr->frame_control and vendor radiotap data are in skb head */
345 if (!pskb_may_pull(origskb, 2)) { 348 if (!pskb_may_pull(origskb, 2 + status->vendor_radiotap_len)) {
346 dev_kfree_skb(origskb); 349 dev_kfree_skb(origskb);
347 return NULL; 350 return NULL;
348 } 351 }
@@ -1338,17 +1341,22 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1338 1341
1339 /* 1342 /*
1340 * Update last_rx only for IBSS packets which are for the current 1343 * Update last_rx only for IBSS packets which are for the current
1341 * BSSID to avoid keeping the current IBSS network alive in cases 1344 * BSSID and for station already AUTHORIZED to avoid keeping the
1342 * where other STAs start using different BSSID. 1345 * current IBSS network alive in cases where other STAs start
1346 * using different BSSID. This will also give the station another
1347 * chance to restart the authentication/authorization in case
1348 * something went wrong the first time.
1343 */ 1349 */
1344 if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) { 1350 if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) {
1345 u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, 1351 u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len,
1346 NL80211_IFTYPE_ADHOC); 1352 NL80211_IFTYPE_ADHOC);
1347 if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid)) { 1353 if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid) &&
1354 test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
1348 sta->last_rx = jiffies; 1355 sta->last_rx = jiffies;
1349 if (ieee80211_is_data(hdr->frame_control)) { 1356 if (ieee80211_is_data(hdr->frame_control)) {
1350 sta->last_rx_rate_idx = status->rate_idx; 1357 sta->last_rx_rate_idx = status->rate_idx;
1351 sta->last_rx_rate_flag = status->flag; 1358 sta->last_rx_rate_flag = status->flag;
1359 sta->last_rx_rate_vht_nss = status->vht_nss;
1352 } 1360 }
1353 } 1361 }
1354 } else if (!is_multicast_ether_addr(hdr->addr1)) { 1362 } else if (!is_multicast_ether_addr(hdr->addr1)) {
@@ -1360,6 +1368,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1360 if (ieee80211_is_data(hdr->frame_control)) { 1368 if (ieee80211_is_data(hdr->frame_control)) {
1361 sta->last_rx_rate_idx = status->rate_idx; 1369 sta->last_rx_rate_idx = status->rate_idx;
1362 sta->last_rx_rate_flag = status->flag; 1370 sta->last_rx_rate_flag = status->flag;
1371 sta->last_rx_rate_vht_nss = status->vht_nss;
1363 } 1372 }
1364 } 1373 }
1365 1374
@@ -2703,7 +2712,8 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
2703 status = IEEE80211_SKB_RXCB((rx->skb)); 2712 status = IEEE80211_SKB_RXCB((rx->skb));
2704 2713
2705 sband = rx->local->hw.wiphy->bands[status->band]; 2714 sband = rx->local->hw.wiphy->bands[status->band];
2706 if (!(status->flag & RX_FLAG_HT)) 2715 if (!(status->flag & RX_FLAG_HT) &&
2716 !(status->flag & RX_FLAG_VHT))
2707 rate = &sband->bitrates[status->rate_idx]; 2717 rate = &sband->bitrates[status->rate_idx];
2708 2718
2709 ieee80211_rx_cooked_monitor(rx, rate); 2719 ieee80211_rx_cooked_monitor(rx, rate);
@@ -2870,8 +2880,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
2870 status->rx_flags &= ~IEEE80211_RX_RA_MATCH; 2880 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2871 } else if (!rx->sta) { 2881 } else if (!rx->sta) {
2872 int rate_idx; 2882 int rate_idx;
2873 if (status->flag & RX_FLAG_HT) 2883 if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT))
2874 rate_idx = 0; /* TODO: HT rates */ 2884 rate_idx = 0; /* TODO: HT/VHT rates */
2875 else 2885 else
2876 rate_idx = status->rate_idx; 2886 rate_idx = status->rate_idx;
2877 ieee80211_ibss_rx_no_sta(sdata, bssid, hdr->addr2, 2887 ieee80211_ibss_rx_no_sta(sdata, bssid, hdr->addr2,
@@ -3147,6 +3157,13 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
3147 status->rate_idx, 3157 status->rate_idx,
3148 status->rate_idx)) 3158 status->rate_idx))
3149 goto drop; 3159 goto drop;
3160 } else if (status->flag & RX_FLAG_VHT) {
3161 if (WARN_ONCE(status->rate_idx > 9 ||
3162 !status->vht_nss ||
3163 status->vht_nss > 8,
3164 "Rate marked as a VHT rate but data is invalid: MCS: %d, NSS: %d\n",
3165 status->rate_idx, status->vht_nss))
3166 goto drop;
3150 } else { 3167 } else {
3151 if (WARN_ON(status->rate_idx >= sband->n_bitrates)) 3168 if (WARN_ON(status->rate_idx >= sband->n_bitrates))
3152 goto drop; 3169 goto drop;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 8e9bb168b73b..f3340279aba3 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -174,7 +174,6 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
174 u8 *elements; 174 u8 *elements;
175 struct ieee80211_channel *channel; 175 struct ieee80211_channel *channel;
176 size_t baselen; 176 size_t baselen;
177 int freq;
178 bool beacon; 177 bool beacon;
179 struct ieee802_11_elems elems; 178 struct ieee802_11_elems elems;
180 179
@@ -209,13 +208,7 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
209 208
210 ieee802_11_parse_elems(elements, skb->len - baselen, &elems); 209 ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
211 210
212 if (elems.ds_params && elems.ds_params_len == 1) 211 channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq);
213 freq = ieee80211_channel_to_frequency(elems.ds_params[0],
214 rx_status->band);
215 else
216 freq = rx_status->freq;
217
218 channel = ieee80211_get_channel(local->hw.wiphy, freq);
219 212
220 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) 213 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
221 return; 214 return;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index e6e5cb586ac0..f3e502502fee 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1092,7 +1092,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata,
1092 return; 1092 return;
1093 } 1093 }
1094 1094
1095 ieee80211_xmit(sdata, skb, chanctx_conf->channel->band); 1095 ieee80211_xmit(sdata, skb, chanctx_conf->def.chan->band);
1096 rcu_read_unlock(); 1096 rcu_read_unlock();
1097} 1097}
1098 1098
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 776f3d0b4a47..6835cea4e402 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -227,6 +227,7 @@ struct sta_ampdu_mlme {
227 * "the" transmit rate 227 * "the" transmit rate
228 * @last_rx_rate_idx: rx status rate index of the last data packet 228 * @last_rx_rate_idx: rx status rate index of the last data packet
229 * @last_rx_rate_flag: rx status flag of the last data packet 229 * @last_rx_rate_flag: rx status flag of the last data packet
230 * @last_rx_rate_vht_nss: rx status nss of last data packet
230 * @lock: used for locking all fields that require locking, see comments 231 * @lock: used for locking all fields that require locking, see comments
231 * in the header file. 232 * in the header file.
232 * @drv_unblock_wk: used for driver PS unblocking 233 * @drv_unblock_wk: used for driver PS unblocking
@@ -272,7 +273,7 @@ struct sta_ampdu_mlme {
272 * @t_offset: timing offset relative to this host 273 * @t_offset: timing offset relative to this host
273 * @t_offset_setpoint: reference timing offset of this sta to be used when 274 * @t_offset_setpoint: reference timing offset of this sta to be used when
274 * calculating clockdrift 275 * calculating clockdrift
275 * @ch_type: peer's channel type 276 * @ch_width: peer's channel width
276 * @debugfs: debug filesystem info 277 * @debugfs: debug filesystem info
277 * @dead: set to true when sta is unlinked 278 * @dead: set to true when sta is unlinked
278 * @uploaded: set to true when sta is uploaded to the driver 279 * @uploaded: set to true when sta is uploaded to the driver
@@ -343,7 +344,8 @@ struct sta_info {
343 unsigned long tx_fragments; 344 unsigned long tx_fragments;
344 struct ieee80211_tx_rate last_tx_rate; 345 struct ieee80211_tx_rate last_tx_rate;
345 int last_rx_rate_idx; 346 int last_rx_rate_idx;
346 int last_rx_rate_flag; 347 u32 last_rx_rate_flag;
348 u8 last_rx_rate_vht_nss;
347 u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; 349 u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
348 350
349 /* 351 /*
@@ -368,7 +370,7 @@ struct sta_info {
368 struct timer_list plink_timer; 370 struct timer_list plink_timer;
369 s64 t_offset; 371 s64 t_offset;
370 s64 t_offset_setpoint; 372 s64 t_offset_setpoint;
371 enum nl80211_channel_type ch_type; 373 enum nl80211_chan_width ch_width;
372#endif 374#endif
373 375
374#ifdef CONFIG_MAC80211_DEBUGFS 376#ifdef CONFIG_MAC80211_DEBUGFS
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index e9579b7a2cd0..a8270b441a6f 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -28,16 +28,21 @@
28#define VIF_PR_FMT " vif:%s(%d%s)" 28#define VIF_PR_FMT " vif:%s(%d%s)"
29#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" 29#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : ""
30 30
31#define CHANCTX_ENTRY __field(int, freq) \ 31#define CHANCTX_ENTRY __field(u32, control_freq) \
32 __field(int, chantype) \ 32 __field(u32, chan_width) \
33 __field(u32, center_freq1) \
34 __field(u32, center_freq2) \
33 __field(u8, rx_chains_static) \ 35 __field(u8, rx_chains_static) \
34 __field(u8, rx_chains_dynamic) 36 __field(u8, rx_chains_dynamic)
35#define CHANCTX_ASSIGN __entry->freq = ctx->conf.channel->center_freq; \ 37#define CHANCTX_ASSIGN __entry->control_freq = ctx->conf.def.chan->center_freq;\
36 __entry->chantype = ctx->conf.channel_type; \ 38 __entry->chan_width = ctx->conf.def.width; \
39 __entry->center_freq1 = ctx->conf.def.center_freq1; \
40 __entry->center_freq2 = ctx->conf.def.center_freq2; \
37 __entry->rx_chains_static = ctx->conf.rx_chains_static; \ 41 __entry->rx_chains_static = ctx->conf.rx_chains_static; \
38 __entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic 42 __entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic
39#define CHANCTX_PR_FMT " freq:%d MHz chantype:%d chains:%d/%d" 43#define CHANCTX_PR_FMT " control:%d MHz width:%d center: %d/%d MHz chains:%d/%d"
40#define CHANCTX_PR_ARG __entry->freq, __entry->chantype, \ 44#define CHANCTX_PR_ARG __entry->control_freq, __entry->chan_width, \
45 __entry->center_freq1, __entry->center_freq2, \
41 __entry->rx_chains_static, __entry->rx_chains_dynamic 46 __entry->rx_chains_static, __entry->rx_chains_dynamic
42 47
43 48
@@ -334,7 +339,8 @@ TRACE_EVENT(drv_bss_info_changed,
334 __field(u16, ht_operation_mode) 339 __field(u16, ht_operation_mode)
335 __field(s32, cqm_rssi_thold); 340 __field(s32, cqm_rssi_thold);
336 __field(s32, cqm_rssi_hyst); 341 __field(s32, cqm_rssi_hyst);
337 __field(u32, channel_type); 342 __field(u32, channel_width);
343 __field(u32, channel_cfreq1);
338 __dynamic_array(u32, arp_addr_list, info->arp_addr_cnt); 344 __dynamic_array(u32, arp_addr_list, info->arp_addr_cnt);
339 __field(bool, arp_filter_enabled); 345 __field(bool, arp_filter_enabled);
340 __field(bool, qos); 346 __field(bool, qos);
@@ -370,7 +376,8 @@ TRACE_EVENT(drv_bss_info_changed,
370 __entry->ht_operation_mode = info->ht_operation_mode; 376 __entry->ht_operation_mode = info->ht_operation_mode;
371 __entry->cqm_rssi_thold = info->cqm_rssi_thold; 377 __entry->cqm_rssi_thold = info->cqm_rssi_thold;
372 __entry->cqm_rssi_hyst = info->cqm_rssi_hyst; 378 __entry->cqm_rssi_hyst = info->cqm_rssi_hyst;
373 __entry->channel_type = info->channel_type; 379 __entry->channel_width = info->chandef.width;
380 __entry->channel_cfreq1 = info->chandef.center_freq1;
374 memcpy(__get_dynamic_array(arp_addr_list), info->arp_addr_list, 381 memcpy(__get_dynamic_array(arp_addr_list), info->arp_addr_list,
375 sizeof(u32) * info->arp_addr_cnt); 382 sizeof(u32) * info->arp_addr_cnt);
376 __entry->arp_filter_enabled = info->arp_filter_enabled; 383 __entry->arp_filter_enabled = info->arp_filter_enabled;
@@ -1022,15 +1029,14 @@ TRACE_EVENT(drv_remain_on_channel,
1022 TP_PROTO(struct ieee80211_local *local, 1029 TP_PROTO(struct ieee80211_local *local,
1023 struct ieee80211_sub_if_data *sdata, 1030 struct ieee80211_sub_if_data *sdata,
1024 struct ieee80211_channel *chan, 1031 struct ieee80211_channel *chan,
1025 enum nl80211_channel_type chantype, unsigned int duration), 1032 unsigned int duration),
1026 1033
1027 TP_ARGS(local, sdata, chan, chantype, duration), 1034 TP_ARGS(local, sdata, chan, duration),
1028 1035
1029 TP_STRUCT__entry( 1036 TP_STRUCT__entry(
1030 LOCAL_ENTRY 1037 LOCAL_ENTRY
1031 VIF_ENTRY 1038 VIF_ENTRY
1032 __field(int, center_freq) 1039 __field(int, center_freq)
1033 __field(int, channel_type)
1034 __field(unsigned int, duration) 1040 __field(unsigned int, duration)
1035 ), 1041 ),
1036 1042
@@ -1038,7 +1044,6 @@ TRACE_EVENT(drv_remain_on_channel,
1038 LOCAL_ASSIGN; 1044 LOCAL_ASSIGN;
1039 VIF_ASSIGN; 1045 VIF_ASSIGN;
1040 __entry->center_freq = chan->center_freq; 1046 __entry->center_freq = chan->center_freq;
1041 __entry->channel_type = chantype;
1042 __entry->duration = duration; 1047 __entry->duration = duration;
1043 ), 1048 ),
1044 1049
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 04076250264b..d287a4f2c01b 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1676,7 +1676,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1676 if (!chanctx_conf) 1676 if (!chanctx_conf)
1677 goto fail_rcu; 1677 goto fail_rcu;
1678 1678
1679 chan = chanctx_conf->channel; 1679 chan = chanctx_conf->def.chan;
1680 1680
1681 /* 1681 /*
1682 * Frame injection is not allowed if beaconing is not allowed 1682 * Frame injection is not allowed if beaconing is not allowed
@@ -1779,7 +1779,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1779 chanctx_conf = rcu_dereference(ap_sdata->vif.chanctx_conf); 1779 chanctx_conf = rcu_dereference(ap_sdata->vif.chanctx_conf);
1780 if (!chanctx_conf) 1780 if (!chanctx_conf)
1781 goto fail_rcu; 1781 goto fail_rcu;
1782 band = chanctx_conf->channel->band; 1782 band = chanctx_conf->def.chan->band;
1783 if (sta) 1783 if (sta)
1784 break; 1784 break;
1785 /* fall through */ 1785 /* fall through */
@@ -1794,7 +1794,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1794 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 1794 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1795 if (!chanctx_conf) 1795 if (!chanctx_conf)
1796 goto fail_rcu; 1796 goto fail_rcu;
1797 band = chanctx_conf->channel->band; 1797 band = chanctx_conf->def.chan->band;
1798 break; 1798 break;
1799 case NL80211_IFTYPE_WDS: 1799 case NL80211_IFTYPE_WDS:
1800 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); 1800 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
@@ -1871,7 +1871,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1871 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 1871 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1872 if (!chanctx_conf) 1872 if (!chanctx_conf)
1873 goto fail_rcu; 1873 goto fail_rcu;
1874 band = chanctx_conf->channel->band; 1874 band = chanctx_conf->def.chan->band;
1875 break; 1875 break;
1876#endif 1876#endif
1877 case NL80211_IFTYPE_STATION: 1877 case NL80211_IFTYPE_STATION:
@@ -1930,7 +1930,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1930 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 1930 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1931 if (!chanctx_conf) 1931 if (!chanctx_conf)
1932 goto fail_rcu; 1932 goto fail_rcu;
1933 band = chanctx_conf->channel->band; 1933 band = chanctx_conf->def.chan->band;
1934 break; 1934 break;
1935 case NL80211_IFTYPE_ADHOC: 1935 case NL80211_IFTYPE_ADHOC:
1936 /* DA SA BSSID */ 1936 /* DA SA BSSID */
@@ -1941,7 +1941,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1941 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 1941 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1942 if (!chanctx_conf) 1942 if (!chanctx_conf)
1943 goto fail_rcu; 1943 goto fail_rcu;
1944 band = chanctx_conf->channel->band; 1944 band = chanctx_conf->def.chan->band;
1945 break; 1945 break;
1946 default: 1946 default:
1947 goto fail_rcu; 1947 goto fail_rcu;
@@ -2194,7 +2194,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
2194 return true; 2194 return true;
2195 } 2195 }
2196 result = ieee80211_tx(sdata, skb, true, 2196 result = ieee80211_tx(sdata, skb, true,
2197 chanctx_conf->channel->band); 2197 chanctx_conf->def.chan->band);
2198 } else { 2198 } else {
2199 struct sk_buff_head skbs; 2199 struct sk_buff_head skbs;
2200 2200
@@ -2458,7 +2458,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2458 *pos++ = WLAN_EID_SSID; 2458 *pos++ = WLAN_EID_SSID;
2459 *pos++ = 0x0; 2459 *pos++ = 0x0;
2460 2460
2461 band = chanctx_conf->channel->band; 2461 band = chanctx_conf->def.chan->band;
2462 2462
2463 if (ieee80211_add_srates_ie(sdata, skb, true, band) || 2463 if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
2464 mesh_add_ds_params_ie(skb, sdata) || 2464 mesh_add_ds_params_ie(skb, sdata) ||
@@ -2477,7 +2477,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2477 goto out; 2477 goto out;
2478 } 2478 }
2479 2479
2480 band = chanctx_conf->channel->band; 2480 band = chanctx_conf->def.chan->band;
2481 2481
2482 info = IEEE80211_SKB_CB(skb); 2482 info = IEEE80211_SKB_CB(skb);
2483 2483
@@ -2757,7 +2757,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
2757 info = IEEE80211_SKB_CB(skb); 2757 info = IEEE80211_SKB_CB(skb);
2758 2758
2759 tx.flags |= IEEE80211_TX_PS_BUFFERED; 2759 tx.flags |= IEEE80211_TX_PS_BUFFERED;
2760 info->band = chanctx_conf->channel->band; 2760 info->band = chanctx_conf->def.chan->band;
2761 2761
2762 if (invoke_tx_handlers(&tx)) 2762 if (invoke_tx_handlers(&tx))
2763 skb = NULL; 2763 skb = NULL;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 9b99916f384f..08132ff98155 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -898,7 +898,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
898 rcu_read_lock(); 898 rcu_read_lock();
899 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 899 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
900 use_11b = (chanctx_conf && 900 use_11b = (chanctx_conf &&
901 chanctx_conf->channel->band == IEEE80211_BAND_2GHZ) && 901 chanctx_conf->def.chan->band == IEEE80211_BAND_2GHZ) &&
902 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE); 902 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE);
903 rcu_read_unlock(); 903 rcu_read_unlock();
904 904
@@ -991,7 +991,7 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
991 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 991 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
992 992
993 if (chanctx_conf && 993 if (chanctx_conf &&
994 chanctx_conf->channel->band == IEEE80211_BAND_2GHZ && 994 chanctx_conf->def.chan->band == IEEE80211_BAND_2GHZ &&
995 have_higher_than_11mbit) 995 have_higher_than_11mbit)
996 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; 996 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
997 else 997 else
@@ -1873,8 +1873,7 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
1873} 1873}
1874 1874
1875u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, 1875u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1876 struct ieee80211_channel *channel, 1876 const struct cfg80211_chan_def *chandef,
1877 enum nl80211_channel_type channel_type,
1878 u16 prot_mode) 1877 u16 prot_mode)
1879{ 1878{
1880 struct ieee80211_ht_operation *ht_oper; 1879 struct ieee80211_ht_operation *ht_oper;
@@ -1882,23 +1881,25 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1882 *pos++ = WLAN_EID_HT_OPERATION; 1881 *pos++ = WLAN_EID_HT_OPERATION;
1883 *pos++ = sizeof(struct ieee80211_ht_operation); 1882 *pos++ = sizeof(struct ieee80211_ht_operation);
1884 ht_oper = (struct ieee80211_ht_operation *)pos; 1883 ht_oper = (struct ieee80211_ht_operation *)pos;
1885 ht_oper->primary_chan = 1884 ht_oper->primary_chan = ieee80211_frequency_to_channel(
1886 ieee80211_frequency_to_channel(channel->center_freq); 1885 chandef->chan->center_freq);
1887 switch (channel_type) { 1886 switch (chandef->width) {
1888 case NL80211_CHAN_HT40MINUS: 1887 case NL80211_CHAN_WIDTH_160:
1889 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW; 1888 case NL80211_CHAN_WIDTH_80P80:
1890 break; 1889 case NL80211_CHAN_WIDTH_80:
1891 case NL80211_CHAN_HT40PLUS: 1890 case NL80211_CHAN_WIDTH_40:
1892 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; 1891 if (chandef->center_freq1 > chandef->chan->center_freq)
1892 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
1893 else
1894 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
1893 break; 1895 break;
1894 case NL80211_CHAN_HT20:
1895 default: 1896 default:
1896 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE; 1897 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
1897 break; 1898 break;
1898 } 1899 }
1899 if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 && 1900 if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 &&
1900 channel_type != NL80211_CHAN_NO_HT && 1901 chandef->width != NL80211_CHAN_WIDTH_20_NOHT &&
1901 channel_type != NL80211_CHAN_HT20) 1902 chandef->width != NL80211_CHAN_WIDTH_20)
1902 ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; 1903 ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
1903 1904
1904 ht_oper->operation_mode = cpu_to_le16(prot_mode); 1905 ht_oper->operation_mode = cpu_to_le16(prot_mode);
@@ -1912,13 +1913,17 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1912 return pos + sizeof(struct ieee80211_ht_operation); 1913 return pos + sizeof(struct ieee80211_ht_operation);
1913} 1914}
1914 1915
1915enum nl80211_channel_type 1916void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,
1916ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper) 1917 struct ieee80211_ht_operation *ht_oper,
1918 struct cfg80211_chan_def *chandef)
1917{ 1919{
1918 enum nl80211_channel_type channel_type; 1920 enum nl80211_channel_type channel_type;
1919 1921
1920 if (!ht_oper) 1922 if (!ht_oper) {
1921 return NL80211_CHAN_NO_HT; 1923 cfg80211_chandef_create(chandef, control_chan,
1924 NL80211_CHAN_NO_HT);
1925 return;
1926 }
1922 1927
1923 switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { 1928 switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
1924 case IEEE80211_HT_PARAM_CHA_SEC_NONE: 1929 case IEEE80211_HT_PARAM_CHA_SEC_NONE:
@@ -1934,7 +1939,7 @@ ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper)
1934 channel_type = NL80211_CHAN_NO_HT; 1939 channel_type = NL80211_CHAN_NO_HT;
1935 } 1940 }
1936 1941
1937 return channel_type; 1942 cfg80211_chandef_create(chandef, control_chan, channel_type);
1938} 1943}
1939 1944
1940int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, 1945int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
@@ -2066,6 +2071,20 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
2066 ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 2071 ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
2067 if (status->flag & RX_FLAG_SHORT_GI) 2072 if (status->flag & RX_FLAG_SHORT_GI)
2068 ri.flags |= RATE_INFO_FLAGS_SHORT_GI; 2073 ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
2074 } else if (status->flag & RX_FLAG_VHT) {
2075 ri.flags |= RATE_INFO_FLAGS_VHT_MCS;
2076 ri.mcs = status->rate_idx;
2077 ri.nss = status->vht_nss;
2078 if (status->flag & RX_FLAG_40MHZ)
2079 ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
2080 if (status->flag & RX_FLAG_80MHZ)
2081 ri.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
2082 if (status->flag & RX_FLAG_80P80MHZ)
2083 ri.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH;
2084 if (status->flag & RX_FLAG_160MHZ)
2085 ri.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
2086 if (status->flag & RX_FLAG_SHORT_GI)
2087 ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
2069 } else { 2088 } else {
2070 struct ieee80211_supported_band *sband; 2089 struct ieee80211_supported_band *sband;
2071 2090
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index cea06e9f26f4..906f00cd6d2f 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -160,31 +160,37 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
160 return ieee80211_downgrade_queue(sdata, skb); 160 return ieee80211_downgrade_queue(sdata, skb);
161} 161}
162 162
163/**
164 * ieee80211_set_qos_hdr - Fill in the QoS header if there is one.
165 *
166 * @sdata: local subif
167 * @skb: packet to be updated
168 */
163void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, 169void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
164 struct sk_buff *skb) 170 struct sk_buff *skb)
165{ 171{
166 struct ieee80211_hdr *hdr = (void *)skb->data; 172 struct ieee80211_hdr *hdr = (void *)skb->data;
167 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 173 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
174 u8 *p;
175 u8 ack_policy, tid;
168 176
169 /* Fill in the QoS header if there is one. */ 177 if (!ieee80211_is_data_qos(hdr->frame_control))
170 if (ieee80211_is_data_qos(hdr->frame_control)) { 178 return;
171 u8 *p = ieee80211_get_qos_ctl(hdr);
172 u8 ack_policy, tid;
173
174 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
175 179
176 /* preserve EOSP bit */ 180 p = ieee80211_get_qos_ctl(hdr);
177 ack_policy = *p & IEEE80211_QOS_CTL_EOSP; 181 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
178 182
179 if (is_multicast_ether_addr(hdr->addr1) || 183 /* preserve EOSP bit */
180 sdata->noack_map & BIT(tid)) { 184 ack_policy = *p & IEEE80211_QOS_CTL_EOSP;
181 ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK;
182 info->flags |= IEEE80211_TX_CTL_NO_ACK;
183 }
184 185
185 /* qos header is 2 bytes */ 186 if (is_multicast_ether_addr(hdr->addr1) ||
186 *p++ = ack_policy | tid; 187 sdata->noack_map & BIT(tid)) {
187 *p = ieee80211_vif_is_mesh(&sdata->vif) ? 188 ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK;
188 (IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT >> 8) : 0; 189 info->flags |= IEEE80211_TX_CTL_NO_ACK;
189 } 190 }
191
192 /* qos header is 2 bytes */
193 *p++ = ack_policy | tid;
194 *p = ieee80211_vif_is_mesh(&sdata->vif) ?
195 (IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT >> 8) : 0;
190} 196}
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 48febd2160ba..bf2dfd54ff3b 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -11,96 +11,264 @@
11#include "core.h" 11#include "core.h"
12#include "rdev-ops.h" 12#include "rdev-ops.h"
13 13
14struct ieee80211_channel * 14void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
15rdev_freq_to_chan(struct cfg80211_registered_device *rdev, 15 struct ieee80211_channel *chan,
16 int freq, enum nl80211_channel_type channel_type) 16 enum nl80211_channel_type chan_type)
17{ 17{
18 struct ieee80211_channel *chan; 18 if (WARN_ON(!chan))
19 struct ieee80211_sta_ht_cap *ht_cap; 19 return;
20 20
21 chan = ieee80211_get_channel(&rdev->wiphy, freq); 21 chandef->chan = chan;
22 chandef->center_freq2 = 0;
22 23
23 /* Primary channel not allowed */ 24 switch (chan_type) {
24 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) 25 case NL80211_CHAN_NO_HT:
25 return NULL; 26 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
27 chandef->center_freq1 = chan->center_freq;
28 break;
29 case NL80211_CHAN_HT20:
30 chandef->width = NL80211_CHAN_WIDTH_20;
31 chandef->center_freq1 = chan->center_freq;
32 break;
33 case NL80211_CHAN_HT40PLUS:
34 chandef->width = NL80211_CHAN_WIDTH_40;
35 chandef->center_freq1 = chan->center_freq + 10;
36 break;
37 case NL80211_CHAN_HT40MINUS:
38 chandef->width = NL80211_CHAN_WIDTH_40;
39 chandef->center_freq1 = chan->center_freq - 10;
40 break;
41 default:
42 WARN_ON(1);
43 }
44}
45EXPORT_SYMBOL(cfg80211_chandef_create);
26 46
27 if (channel_type == NL80211_CHAN_HT40MINUS && 47bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef)
28 chan->flags & IEEE80211_CHAN_NO_HT40MINUS) 48{
29 return NULL; 49 u32 control_freq;
30 else if (channel_type == NL80211_CHAN_HT40PLUS &&
31 chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
32 return NULL;
33 50
34 ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap; 51 if (!chandef->chan)
52 return false;
35 53
36 if (channel_type != NL80211_CHAN_NO_HT) { 54 control_freq = chandef->chan->center_freq;
37 if (!ht_cap->ht_supported)
38 return NULL;
39 55
40 if (channel_type != NL80211_CHAN_HT20 && 56 switch (chandef->width) {
41 (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) || 57 case NL80211_CHAN_WIDTH_20:
42 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)) 58 case NL80211_CHAN_WIDTH_20_NOHT:
43 return NULL; 59 if (chandef->center_freq1 != control_freq)
60 return false;
61 if (chandef->center_freq2)
62 return false;
63 break;
64 case NL80211_CHAN_WIDTH_40:
65 if (chandef->center_freq1 != control_freq + 10 &&
66 chandef->center_freq1 != control_freq - 10)
67 return false;
68 if (chandef->center_freq2)
69 return false;
70 break;
71 case NL80211_CHAN_WIDTH_80P80:
72 if (chandef->center_freq1 != control_freq + 30 &&
73 chandef->center_freq1 != control_freq + 10 &&
74 chandef->center_freq1 != control_freq - 10 &&
75 chandef->center_freq1 != control_freq - 30)
76 return false;
77 if (!chandef->center_freq2)
78 return false;
79 break;
80 case NL80211_CHAN_WIDTH_80:
81 if (chandef->center_freq1 != control_freq + 30 &&
82 chandef->center_freq1 != control_freq + 10 &&
83 chandef->center_freq1 != control_freq - 10 &&
84 chandef->center_freq1 != control_freq - 30)
85 return false;
86 if (chandef->center_freq2)
87 return false;
88 break;
89 case NL80211_CHAN_WIDTH_160:
90 if (chandef->center_freq1 != control_freq + 70 &&
91 chandef->center_freq1 != control_freq + 50 &&
92 chandef->center_freq1 != control_freq + 30 &&
93 chandef->center_freq1 != control_freq + 10 &&
94 chandef->center_freq1 != control_freq - 10 &&
95 chandef->center_freq1 != control_freq - 30 &&
96 chandef->center_freq1 != control_freq - 50 &&
97 chandef->center_freq1 != control_freq - 70)
98 return false;
99 if (chandef->center_freq2)
100 return false;
101 break;
102 default:
103 return false;
44 } 104 }
45 105
46 return chan; 106 return true;
47} 107}
48 108
49bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, 109static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
50 struct ieee80211_channel *chan, 110 int *pri40, int *pri80)
51 enum nl80211_channel_type channel_type)
52{ 111{
53 struct ieee80211_channel *sec_chan; 112 int tmp;
54 int diff;
55
56 trace_cfg80211_can_beacon_sec_chan(wiphy, chan, channel_type);
57 113
58 switch (channel_type) { 114 switch (c->width) {
59 case NL80211_CHAN_HT40PLUS: 115 case NL80211_CHAN_WIDTH_40:
60 diff = 20; 116 *pri40 = c->center_freq1;
117 *pri80 = 0;
61 break; 118 break;
62 case NL80211_CHAN_HT40MINUS: 119 case NL80211_CHAN_WIDTH_80:
63 diff = -20; 120 case NL80211_CHAN_WIDTH_80P80:
121 *pri80 = c->center_freq1;
122 /* n_P20 */
123 tmp = (30 + c->chan->center_freq - c->center_freq1)/20;
124 /* n_P40 */
125 tmp /= 2;
126 /* freq_P40 */
127 *pri40 = c->center_freq1 - 20 + 40 * tmp;
128 break;
129 case NL80211_CHAN_WIDTH_160:
130 /* n_P20 */
131 tmp = (70 + c->chan->center_freq - c->center_freq1)/20;
132 /* n_P40 */
133 tmp /= 2;
134 /* freq_P40 */
135 *pri40 = c->center_freq1 - 60 + 40 * tmp;
136 /* n_P80 */
137 tmp /= 2;
138 *pri80 = c->center_freq1 - 40 + 80 * tmp;
64 break; 139 break;
65 default: 140 default:
66 trace_cfg80211_return_bool(true); 141 WARN_ON_ONCE(1);
67 return true;
68 } 142 }
143}
144
145const struct cfg80211_chan_def *
146cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
147 const struct cfg80211_chan_def *c2)
148{
149 u32 c1_pri40, c1_pri80, c2_pri40, c2_pri80;
69 150
70 sec_chan = ieee80211_get_channel(wiphy, chan->center_freq + diff); 151 /* If they are identical, return */
71 if (!sec_chan) { 152 if (cfg80211_chandef_identical(c1, c2))
153 return c1;
154
155 /* otherwise, must have same control channel */
156 if (c1->chan != c2->chan)
157 return NULL;
158
159 /*
160 * If they have the same width, but aren't identical,
161 * then they can't be compatible.
162 */
163 if (c1->width == c2->width)
164 return NULL;
165
166 if (c1->width == NL80211_CHAN_WIDTH_20_NOHT ||
167 c1->width == NL80211_CHAN_WIDTH_20)
168 return c2;
169
170 if (c2->width == NL80211_CHAN_WIDTH_20_NOHT ||
171 c2->width == NL80211_CHAN_WIDTH_20)
172 return c1;
173
174 chandef_primary_freqs(c1, &c1_pri40, &c1_pri80);
175 chandef_primary_freqs(c2, &c2_pri40, &c2_pri80);
176
177 if (c1_pri40 != c2_pri40)
178 return NULL;
179
180 WARN_ON(!c1_pri80 && !c2_pri80);
181 if (c1_pri80 && c2_pri80 && c1_pri80 != c2_pri80)
182 return NULL;
183
184 if (c1->width > c2->width)
185 return c1;
186 return c2;
187}
188EXPORT_SYMBOL(cfg80211_chandef_compatible);
189
190bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
191 u32 center_freq, u32 bandwidth,
192 u32 prohibited_flags)
193{
194 struct ieee80211_channel *c;
195 u32 freq;
196
197 for (freq = center_freq - bandwidth/2 + 10;
198 freq <= center_freq + bandwidth/2 - 10;
199 freq += 20) {
200 c = ieee80211_get_channel(wiphy, freq);
201 if (!c || c->flags & prohibited_flags)
202 return false;
203 }
204
205 return true;
206}
207
208static bool cfg80211_check_beacon_chans(struct wiphy *wiphy,
209 u32 center_freq, u32 bw)
210{
211 return cfg80211_secondary_chans_ok(wiphy, center_freq, bw,
212 IEEE80211_CHAN_DISABLED |
213 IEEE80211_CHAN_PASSIVE_SCAN |
214 IEEE80211_CHAN_NO_IBSS |
215 IEEE80211_CHAN_RADAR);
216}
217
218bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
219 struct cfg80211_chan_def *chandef)
220{
221 u32 width;
222 bool res;
223
224 trace_cfg80211_reg_can_beacon(wiphy, chandef);
225
226 if (WARN_ON(!cfg80211_chan_def_valid(chandef))) {
72 trace_cfg80211_return_bool(false); 227 trace_cfg80211_return_bool(false);
73 return false; 228 return false;
74 } 229 }
75 230
76 /* we'll need a DFS capability later */ 231 switch (chandef->width) {
77 if (sec_chan->flags & (IEEE80211_CHAN_DISABLED | 232 case NL80211_CHAN_WIDTH_20_NOHT:
78 IEEE80211_CHAN_PASSIVE_SCAN | 233 case NL80211_CHAN_WIDTH_20:
79 IEEE80211_CHAN_NO_IBSS | 234 width = 20;
80 IEEE80211_CHAN_RADAR)) { 235 break;
236 case NL80211_CHAN_WIDTH_40:
237 width = 40;
238 break;
239 case NL80211_CHAN_WIDTH_80:
240 case NL80211_CHAN_WIDTH_80P80:
241 width = 80;
242 break;
243 case NL80211_CHAN_WIDTH_160:
244 width = 160;
245 break;
246 default:
247 WARN_ON_ONCE(1);
81 trace_cfg80211_return_bool(false); 248 trace_cfg80211_return_bool(false);
82 return false; 249 return false;
83 } 250 }
84 trace_cfg80211_return_bool(true); 251
85 return true; 252 res = cfg80211_check_beacon_chans(wiphy, chandef->center_freq1, width);
253
254 if (res && chandef->center_freq2)
255 res = cfg80211_check_beacon_chans(wiphy, chandef->center_freq2,
256 width);
257
258 trace_cfg80211_return_bool(res);
259 return res;
86} 260}
87EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan); 261EXPORT_SYMBOL(cfg80211_reg_can_beacon);
88 262
89int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, 263int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
90 int freq, enum nl80211_channel_type chantype) 264 struct cfg80211_chan_def *chandef)
91{ 265{
92 struct ieee80211_channel *chan;
93
94 if (!rdev->ops->set_monitor_channel) 266 if (!rdev->ops->set_monitor_channel)
95 return -EOPNOTSUPP; 267 return -EOPNOTSUPP;
96 if (!cfg80211_has_monitors_only(rdev)) 268 if (!cfg80211_has_monitors_only(rdev))
97 return -EBUSY; 269 return -EBUSY;
98 270
99 chan = rdev_freq_to_chan(rdev, freq, chantype); 271 return rdev_set_monitor_channel(rdev, chandef);
100 if (!chan)
101 return -EINVAL;
102
103 return rdev_set_monitor_channel(rdev, chan, chantype);
104} 272}
105 273
106void 274void
diff --git a/net/wireless/core.h b/net/wireless/core.h
index e53831c876bb..a0c8decf6a47 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -309,9 +309,9 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
309 const struct mesh_config *conf); 309 const struct mesh_config *conf);
310int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 310int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
311 struct net_device *dev); 311 struct net_device *dev);
312int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, 312int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
313 struct wireless_dev *wdev, int freq, 313 struct wireless_dev *wdev,
314 enum nl80211_channel_type channel_type); 314 struct cfg80211_chan_def *chandef);
315 315
316/* AP */ 316/* AP */
317int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, 317int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
@@ -378,10 +378,8 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
378int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, 378int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
379 struct wireless_dev *wdev, 379 struct wireless_dev *wdev,
380 struct ieee80211_channel *chan, bool offchan, 380 struct ieee80211_channel *chan, bool offchan,
381 enum nl80211_channel_type channel_type, 381 unsigned int wait, const u8 *buf, size_t len,
382 bool channel_type_valid, unsigned int wait, 382 bool no_cck, bool dont_wait_for_ack, u64 *cookie);
383 const u8 *buf, size_t len, bool no_cck,
384 bool dont_wait_for_ack, u64 *cookie);
385void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa, 383void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
386 const struct ieee80211_ht_cap *ht_capa_mask); 384 const struct ieee80211_ht_cap *ht_capa_mask);
387 385
@@ -472,11 +470,8 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
472 struct ieee80211_channel **chan, 470 struct ieee80211_channel **chan,
473 enum cfg80211_chan_mode *chanmode); 471 enum cfg80211_chan_mode *chanmode);
474 472
475struct ieee80211_channel *
476rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
477 int freq, enum nl80211_channel_type channel_type);
478int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, 473int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
479 int freq, enum nl80211_channel_type chantype); 474 struct cfg80211_chan_def *chandef);
480 475
481int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, 476int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
482 const u8 *rates, unsigned int n_rates, 477 const u8 *rates, unsigned int n_rates,
@@ -488,6 +483,12 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
488void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, 483void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
489 enum nl80211_iftype iftype, int num); 484 enum nl80211_iftype iftype, int num);
490 485
486bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef);
487
488bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
489 u32 center_freq, u32 bandwidth,
490 u32 prohibited_flags);
491
491#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 492#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10
492 493
493#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS 494#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 27941d5db72b..9b9551e4a6f9 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -100,9 +100,9 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
100 * 11a for maximum compatibility. 100 * 11a for maximum compatibility.
101 */ 101 */
102 struct ieee80211_supported_band *sband = 102 struct ieee80211_supported_band *sband =
103 rdev->wiphy.bands[params->channel->band]; 103 rdev->wiphy.bands[params->chandef.chan->band];
104 int j; 104 int j;
105 u32 flag = params->channel->band == IEEE80211_BAND_5GHZ ? 105 u32 flag = params->chandef.chan->band == IEEE80211_BAND_5GHZ ?
106 IEEE80211_RATE_MANDATORY_A : 106 IEEE80211_RATE_MANDATORY_A :
107 IEEE80211_RATE_MANDATORY_B; 107 IEEE80211_RATE_MANDATORY_B;
108 108
@@ -118,11 +118,11 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
118 118
119 wdev->ibss_fixed = params->channel_fixed; 119 wdev->ibss_fixed = params->channel_fixed;
120#ifdef CONFIG_CFG80211_WEXT 120#ifdef CONFIG_CFG80211_WEXT
121 wdev->wext.ibss.channel = params->channel; 121 wdev->wext.ibss.chandef = params->chandef;
122#endif 122#endif
123 wdev->sme_state = CFG80211_SME_CONNECTING; 123 wdev->sme_state = CFG80211_SME_CONNECTING;
124 124
125 err = cfg80211_can_use_chan(rdev, wdev, params->channel, 125 err = cfg80211_can_use_chan(rdev, wdev, params->chandef.chan,
126 params->channel_fixed 126 params->channel_fixed
127 ? CHAN_MODE_SHARED 127 ? CHAN_MODE_SHARED
128 : CHAN_MODE_EXCLUSIVE); 128 : CHAN_MODE_EXCLUSIVE);
@@ -251,7 +251,9 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
251 wdev->wext.ibss.beacon_interval = 100; 251 wdev->wext.ibss.beacon_interval = 100;
252 252
253 /* try to find an IBSS channel if none requested ... */ 253 /* try to find an IBSS channel if none requested ... */
254 if (!wdev->wext.ibss.channel) { 254 if (!wdev->wext.ibss.chandef.chan) {
255 wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
256
255 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 257 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
256 struct ieee80211_supported_band *sband; 258 struct ieee80211_supported_band *sband;
257 struct ieee80211_channel *chan; 259 struct ieee80211_channel *chan;
@@ -266,15 +268,15 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
266 continue; 268 continue;
267 if (chan->flags & IEEE80211_CHAN_DISABLED) 269 if (chan->flags & IEEE80211_CHAN_DISABLED)
268 continue; 270 continue;
269 wdev->wext.ibss.channel = chan; 271 wdev->wext.ibss.chandef.chan = chan;
270 break; 272 break;
271 } 273 }
272 274
273 if (wdev->wext.ibss.channel) 275 if (wdev->wext.ibss.chandef.chan)
274 break; 276 break;
275 } 277 }
276 278
277 if (!wdev->wext.ibss.channel) 279 if (!wdev->wext.ibss.chandef.chan)
278 return -EINVAL; 280 return -EINVAL;
279 } 281 }
280 282
@@ -336,7 +338,7 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
336 return -EINVAL; 338 return -EINVAL;
337 } 339 }
338 340
339 if (wdev->wext.ibss.channel == chan) 341 if (wdev->wext.ibss.chandef.chan == chan)
340 return 0; 342 return 0;
341 343
342 wdev_lock(wdev); 344 wdev_lock(wdev);
@@ -349,7 +351,8 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
349 return err; 351 return err;
350 352
351 if (chan) { 353 if (chan) {
352 wdev->wext.ibss.channel = chan; 354 wdev->wext.ibss.chandef.chan = chan;
355 wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
353 wdev->wext.ibss.channel_fixed = true; 356 wdev->wext.ibss.channel_fixed = true;
354 } else { 357 } else {
355 /* cfg80211_ibss_wext_join will pick one if needed */ 358 /* cfg80211_ibss_wext_join will pick one if needed */
@@ -379,8 +382,8 @@ int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
379 wdev_lock(wdev); 382 wdev_lock(wdev);
380 if (wdev->current_bss) 383 if (wdev->current_bss)
381 chan = wdev->current_bss->pub.channel; 384 chan = wdev->current_bss->pub.channel;
382 else if (wdev->wext.ibss.channel) 385 else if (wdev->wext.ibss.chandef.chan)
383 chan = wdev->wext.ibss.channel; 386 chan = wdev->wext.ibss.chandef.chan;
384 wdev_unlock(wdev); 387 wdev_unlock(wdev);
385 388
386 if (chan) { 389 if (chan) {
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 966cfc4cd79d..3ee5a7282283 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -73,8 +73,6 @@ const struct mesh_config default_mesh_config = {
73 73
74const struct mesh_setup default_mesh_setup = { 74const struct mesh_setup default_mesh_setup = {
75 /* cfg80211_join_mesh() will pick a channel if needed */ 75 /* cfg80211_join_mesh() will pick a channel if needed */
76 .channel = NULL,
77 .channel_type = NL80211_CHAN_NO_HT,
78 .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, 76 .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET,
79 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, 77 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
80 .path_metric = IEEE80211_PATH_METRIC_AIRTIME, 78 .path_metric = IEEE80211_PATH_METRIC_AIRTIME,
@@ -111,13 +109,12 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
111 if (!rdev->ops->join_mesh) 109 if (!rdev->ops->join_mesh)
112 return -EOPNOTSUPP; 110 return -EOPNOTSUPP;
113 111
114 if (!setup->channel) { 112 if (!setup->chandef.chan) {
115 /* if no channel explicitly given, use preset channel */ 113 /* if no channel explicitly given, use preset channel */
116 setup->channel = wdev->preset_chan; 114 setup->chandef = wdev->preset_chandef;
117 setup->channel_type = wdev->preset_chantype;
118 } 115 }
119 116
120 if (!setup->channel) { 117 if (!setup->chandef.chan) {
121 /* if we don't have that either, use the first usable channel */ 118 /* if we don't have that either, use the first usable channel */
122 enum ieee80211_band band; 119 enum ieee80211_band band;
123 120
@@ -137,26 +134,25 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
137 IEEE80211_CHAN_DISABLED | 134 IEEE80211_CHAN_DISABLED |
138 IEEE80211_CHAN_RADAR)) 135 IEEE80211_CHAN_RADAR))
139 continue; 136 continue;
140 setup->channel = chan; 137 setup->chandef.chan = chan;
141 break; 138 break;
142 } 139 }
143 140
144 if (setup->channel) 141 if (setup->chandef.chan)
145 break; 142 break;
146 } 143 }
147 144
148 /* no usable channel ... */ 145 /* no usable channel ... */
149 if (!setup->channel) 146 if (!setup->chandef.chan)
150 return -EINVAL; 147 return -EINVAL;
151 148
152 setup->channel_type = NL80211_CHAN_NO_HT; 149 setup->chandef.width = NL80211_CHAN_WIDTH_20_NOHT;;
153 } 150 }
154 151
155 if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, setup->channel, 152 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
156 setup->channel_type))
157 return -EINVAL; 153 return -EINVAL;
158 154
159 err = cfg80211_can_use_chan(rdev, wdev, setup->channel, 155 err = cfg80211_can_use_chan(rdev, wdev, setup->chandef.chan,
160 CHAN_MODE_SHARED); 156 CHAN_MODE_SHARED);
161 if (err) 157 if (err)
162 return err; 158 return err;
@@ -165,7 +161,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
165 if (!err) { 161 if (!err) {
166 memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); 162 memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
167 wdev->mesh_id_len = setup->mesh_id_len; 163 wdev->mesh_id_len = setup->mesh_id_len;
168 wdev->channel = setup->channel; 164 wdev->channel = setup->chandef.chan;
169 } 165 }
170 166
171 return err; 167 return err;
@@ -188,20 +184,12 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
188 return err; 184 return err;
189} 185}
190 186
191int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, 187int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
192 struct wireless_dev *wdev, int freq, 188 struct wireless_dev *wdev,
193 enum nl80211_channel_type channel_type) 189 struct cfg80211_chan_def *chandef)
194{ 190{
195 struct ieee80211_channel *channel;
196 int err; 191 int err;
197 192
198 channel = rdev_freq_to_chan(rdev, freq, channel_type);
199 if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy,
200 channel,
201 channel_type)) {
202 return -EINVAL;
203 }
204
205 /* 193 /*
206 * Workaround for libertas (only!), it puts the interface 194 * Workaround for libertas (only!), it puts the interface
207 * into mesh mode but doesn't implement join_mesh. Instead, 195 * into mesh mode but doesn't implement join_mesh. Instead,
@@ -210,21 +198,21 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
210 * compatible with 802.11 mesh. 198 * compatible with 802.11 mesh.
211 */ 199 */
212 if (rdev->ops->libertas_set_mesh_channel) { 200 if (rdev->ops->libertas_set_mesh_channel) {
213 if (channel_type != NL80211_CHAN_NO_HT) 201 if (chandef->width != NL80211_CHAN_WIDTH_20_NOHT)
214 return -EINVAL; 202 return -EINVAL;
215 203
216 if (!netif_running(wdev->netdev)) 204 if (!netif_running(wdev->netdev))
217 return -ENETDOWN; 205 return -ENETDOWN;
218 206
219 err = cfg80211_can_use_chan(rdev, wdev, channel, 207 err = cfg80211_can_use_chan(rdev, wdev, chandef->chan,
220 CHAN_MODE_SHARED); 208 CHAN_MODE_SHARED);
221 if (err) 209 if (err)
222 return err; 210 return err;
223 211
224 err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev, 212 err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev,
225 channel); 213 chandef->chan);
226 if (!err) 214 if (!err)
227 wdev->channel = channel; 215 wdev->channel = chandef->chan;
228 216
229 return err; 217 return err;
230 } 218 }
@@ -232,8 +220,7 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
232 if (wdev->mesh_id_len) 220 if (wdev->mesh_id_len)
233 return -EBUSY; 221 return -EBUSY;
234 222
235 wdev->preset_chan = channel; 223 wdev->preset_chandef = *chandef;
236 wdev->preset_chantype = channel_type;
237 return 0; 224 return 0;
238} 225}
239 226
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 4bfd14f7c592..5e8123ee63fd 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -579,31 +579,25 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
579 579
580void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie, 580void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
581 struct ieee80211_channel *chan, 581 struct ieee80211_channel *chan,
582 enum nl80211_channel_type channel_type,
583 unsigned int duration, gfp_t gfp) 582 unsigned int duration, gfp_t gfp)
584{ 583{
585 struct wiphy *wiphy = wdev->wiphy; 584 struct wiphy *wiphy = wdev->wiphy;
586 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 585 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
587 586
588 trace_cfg80211_ready_on_channel(wdev, cookie, chan, channel_type, 587 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
589 duration); 588 nl80211_send_remain_on_channel(rdev, wdev, cookie, chan, duration, gfp);
590 nl80211_send_remain_on_channel(rdev, wdev, cookie, chan, channel_type,
591 duration, gfp);
592} 589}
593EXPORT_SYMBOL(cfg80211_ready_on_channel); 590EXPORT_SYMBOL(cfg80211_ready_on_channel);
594 591
595void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie, 592void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
596 struct ieee80211_channel *chan, 593 struct ieee80211_channel *chan,
597 enum nl80211_channel_type channel_type,
598 gfp_t gfp) 594 gfp_t gfp)
599{ 595{
600 struct wiphy *wiphy = wdev->wiphy; 596 struct wiphy *wiphy = wdev->wiphy;
601 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 597 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
602 598
603 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan, 599 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
604 channel_type); 600 nl80211_send_remain_on_channel_cancel(rdev, wdev, cookie, chan, gfp);
605 nl80211_send_remain_on_channel_cancel(rdev, wdev, cookie, chan,
606 channel_type, gfp);
607} 601}
608EXPORT_SYMBOL(cfg80211_remain_on_channel_expired); 602EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
609 603
@@ -758,10 +752,8 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
758int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, 752int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
759 struct wireless_dev *wdev, 753 struct wireless_dev *wdev,
760 struct ieee80211_channel *chan, bool offchan, 754 struct ieee80211_channel *chan, bool offchan,
761 enum nl80211_channel_type channel_type, 755 unsigned int wait, const u8 *buf, size_t len,
762 bool channel_type_valid, unsigned int wait, 756 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
763 const u8 *buf, size_t len, bool no_cck,
764 bool dont_wait_for_ack, u64 *cookie)
765{ 757{
766 const struct ieee80211_mgmt *mgmt; 758 const struct ieee80211_mgmt *mgmt;
767 u16 stype; 759 u16 stype;
@@ -855,7 +847,6 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
855 847
856 /* Transmit the Action frame as requested by user space */ 848 /* Transmit the Action frame as requested by user space */
857 return rdev_mgmt_tx(rdev, wdev, chan, offchan, 849 return rdev_mgmt_tx(rdev, wdev, chan, offchan,
858 channel_type, channel_type_valid,
859 wait, buf, len, no_cck, dont_wait_for_ack, 850 wait, buf, len, no_cck, dont_wait_for_ack,
860 cookie); 851 cookie);
861} 852}
@@ -997,15 +988,14 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
997} 988}
998EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); 989EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
999 990
1000void cfg80211_ch_switch_notify(struct net_device *dev, int freq, 991void cfg80211_ch_switch_notify(struct net_device *dev,
1001 enum nl80211_channel_type type) 992 struct cfg80211_chan_def *chandef)
1002{ 993{
1003 struct wireless_dev *wdev = dev->ieee80211_ptr; 994 struct wireless_dev *wdev = dev->ieee80211_ptr;
1004 struct wiphy *wiphy = wdev->wiphy; 995 struct wiphy *wiphy = wdev->wiphy;
1005 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 996 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
1006 struct ieee80211_channel *chan;
1007 997
1008 trace_cfg80211_ch_switch_notify(dev, freq, type); 998 trace_cfg80211_ch_switch_notify(dev, chandef);
1009 999
1010 wdev_lock(wdev); 1000 wdev_lock(wdev);
1011 1001
@@ -1013,12 +1003,8 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
1013 wdev->iftype != NL80211_IFTYPE_P2P_GO)) 1003 wdev->iftype != NL80211_IFTYPE_P2P_GO))
1014 goto out; 1004 goto out;
1015 1005
1016 chan = rdev_freq_to_chan(rdev, freq, type); 1006 wdev->channel = chandef->chan;
1017 if (WARN_ON(!chan)) 1007 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
1018 goto out;
1019
1020 wdev->channel = chan;
1021 nl80211_ch_switch_notify(rdev, dev, freq, type, GFP_KERNEL);
1022out: 1008out:
1023 wdev_unlock(wdev); 1009 wdev_unlock(wdev);
1024 return; 1010 return;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4c427fa5c450..d038fa45ecd1 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -223,8 +223,13 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
223 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, 223 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
224 .len = 20-1 }, 224 .len = 20-1 },
225 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED }, 225 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
226
226 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 }, 227 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
227 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 }, 228 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
229 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
230 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
231 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
232
228 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 }, 233 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
229 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 }, 234 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
230 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 }, 235 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
@@ -1360,51 +1365,139 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
1360 wdev->iftype == NL80211_IFTYPE_P2P_GO; 1365 wdev->iftype == NL80211_IFTYPE_P2P_GO;
1361} 1366}
1362 1367
1363static bool nl80211_valid_channel_type(struct genl_info *info, 1368static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
1364 enum nl80211_channel_type *channel_type) 1369 struct genl_info *info,
1370 struct cfg80211_chan_def *chandef)
1365{ 1371{
1366 enum nl80211_channel_type tmp; 1372 struct ieee80211_sta_ht_cap *ht_cap;
1373 struct ieee80211_sta_vht_cap *vht_cap;
1374 u32 control_freq, width;
1367 1375
1368 if (!info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) 1376 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
1369 return false; 1377 return -EINVAL;
1370 1378
1371 tmp = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); 1379 control_freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
1372 if (tmp != NL80211_CHAN_NO_HT &&
1373 tmp != NL80211_CHAN_HT20 &&
1374 tmp != NL80211_CHAN_HT40PLUS &&
1375 tmp != NL80211_CHAN_HT40MINUS)
1376 return false;
1377 1380
1378 if (channel_type) 1381 chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
1379 *channel_type = tmp; 1382 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
1383 chandef->center_freq1 = control_freq;
1384 chandef->center_freq2 = 0;
1380 1385
1381 return true; 1386 /* Primary channel not allowed */
1387 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED)
1388 return -EINVAL;
1389
1390 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
1391 enum nl80211_channel_type chantype;
1392
1393 chantype = nla_get_u32(
1394 info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
1395
1396 switch (chantype) {
1397 case NL80211_CHAN_NO_HT:
1398 case NL80211_CHAN_HT20:
1399 case NL80211_CHAN_HT40PLUS:
1400 case NL80211_CHAN_HT40MINUS:
1401 cfg80211_chandef_create(chandef, chandef->chan,
1402 chantype);
1403 break;
1404 default:
1405 return -EINVAL;
1406 }
1407 } else if (info->attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
1408 chandef->width =
1409 nla_get_u32(info->attrs[NL80211_ATTR_CHANNEL_WIDTH]);
1410 if (info->attrs[NL80211_ATTR_CENTER_FREQ1])
1411 chandef->center_freq1 =
1412 nla_get_u32(
1413 info->attrs[NL80211_ATTR_CENTER_FREQ1]);
1414 if (info->attrs[NL80211_ATTR_CENTER_FREQ2])
1415 chandef->center_freq2 =
1416 nla_get_u32(
1417 info->attrs[NL80211_ATTR_CENTER_FREQ2]);
1418 }
1419
1420 ht_cap = &rdev->wiphy.bands[chandef->chan->band]->ht_cap;
1421 vht_cap = &rdev->wiphy.bands[chandef->chan->band]->vht_cap;
1422
1423 if (!cfg80211_chan_def_valid(chandef))
1424 return -EINVAL;
1425
1426 switch (chandef->width) {
1427 case NL80211_CHAN_WIDTH_20:
1428 if (!ht_cap->ht_supported)
1429 return -EINVAL;
1430 case NL80211_CHAN_WIDTH_20_NOHT:
1431 width = 20;
1432 break;
1433 case NL80211_CHAN_WIDTH_40:
1434 width = 40;
1435 /* quick early regulatory check */
1436 if (chandef->center_freq1 < control_freq &&
1437 chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
1438 return -EINVAL;
1439 if (chandef->center_freq1 > control_freq &&
1440 chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
1441 return -EINVAL;
1442 if (!ht_cap->ht_supported)
1443 return -EINVAL;
1444 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
1445 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
1446 return -EINVAL;
1447 break;
1448 case NL80211_CHAN_WIDTH_80:
1449 width = 80;
1450 if (!vht_cap->vht_supported)
1451 return -EINVAL;
1452 break;
1453 case NL80211_CHAN_WIDTH_80P80:
1454 width = 80;
1455 if (!vht_cap->vht_supported)
1456 return -EINVAL;
1457 if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
1458 return -EINVAL;
1459 break;
1460 case NL80211_CHAN_WIDTH_160:
1461 width = 160;
1462 if (!vht_cap->vht_supported)
1463 return -EINVAL;
1464 if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ))
1465 return -EINVAL;
1466 break;
1467 default:
1468 return -EINVAL;
1469 }
1470
1471 if (!cfg80211_secondary_chans_ok(&rdev->wiphy, chandef->center_freq1,
1472 width, IEEE80211_CHAN_DISABLED))
1473 return -EINVAL;
1474 if (chandef->center_freq2 &&
1475 !cfg80211_secondary_chans_ok(&rdev->wiphy, chandef->center_freq2,
1476 width, IEEE80211_CHAN_DISABLED))
1477 return -EINVAL;
1478
1479 /* TODO: missing regulatory check on bandwidth */
1480
1481 return 0;
1382} 1482}
1383 1483
1384static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, 1484static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1385 struct wireless_dev *wdev, 1485 struct wireless_dev *wdev,
1386 struct genl_info *info) 1486 struct genl_info *info)
1387{ 1487{
1388 struct ieee80211_channel *channel; 1488 struct cfg80211_chan_def chandef;
1389 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
1390 u32 freq;
1391 int result; 1489 int result;
1392 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR; 1490 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
1393 1491
1394 if (wdev) 1492 if (wdev)
1395 iftype = wdev->iftype; 1493 iftype = wdev->iftype;
1396 1494
1397 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
1398 return -EINVAL;
1399
1400 if (!nl80211_can_set_dev_channel(wdev)) 1495 if (!nl80211_can_set_dev_channel(wdev))
1401 return -EOPNOTSUPP; 1496 return -EOPNOTSUPP;
1402 1497
1403 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 1498 result = nl80211_parse_chandef(rdev, info, &chandef);
1404 !nl80211_valid_channel_type(info, &channel_type)) 1499 if (result)
1405 return -EINVAL; 1500 return result;
1406
1407 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
1408 1501
1409 mutex_lock(&rdev->devlist_mtx); 1502 mutex_lock(&rdev->devlist_mtx);
1410 switch (iftype) { 1503 switch (iftype) {
@@ -1414,22 +1507,18 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1414 result = -EBUSY; 1507 result = -EBUSY;
1415 break; 1508 break;
1416 } 1509 }
1417 channel = rdev_freq_to_chan(rdev, freq, channel_type); 1510 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef)) {
1418 if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy,
1419 channel,
1420 channel_type)) {
1421 result = -EINVAL; 1511 result = -EINVAL;
1422 break; 1512 break;
1423 } 1513 }
1424 wdev->preset_chan = channel; 1514 wdev->preset_chandef = chandef;
1425 wdev->preset_chantype = channel_type;
1426 result = 0; 1515 result = 0;
1427 break; 1516 break;
1428 case NL80211_IFTYPE_MESH_POINT: 1517 case NL80211_IFTYPE_MESH_POINT:
1429 result = cfg80211_set_mesh_freq(rdev, wdev, freq, channel_type); 1518 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
1430 break; 1519 break;
1431 case NL80211_IFTYPE_MONITOR: 1520 case NL80211_IFTYPE_MONITOR:
1432 result = cfg80211_set_monitor_channel(rdev, freq, channel_type); 1521 result = cfg80211_set_monitor_channel(rdev, &chandef);
1433 break; 1522 break;
1434 default: 1523 default:
1435 result = -EINVAL; 1524 result = -EINVAL;
@@ -1749,6 +1838,35 @@ static inline u64 wdev_id(struct wireless_dev *wdev)
1749 ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32); 1838 ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32);
1750} 1839}
1751 1840
1841static int nl80211_send_chandef(struct sk_buff *msg,
1842 struct cfg80211_chan_def *chandef)
1843{
1844 WARN_ON(!cfg80211_chan_def_valid(chandef));
1845
1846 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
1847 chandef->chan->center_freq))
1848 return -ENOBUFS;
1849 switch (chandef->width) {
1850 case NL80211_CHAN_WIDTH_20_NOHT:
1851 case NL80211_CHAN_WIDTH_20:
1852 case NL80211_CHAN_WIDTH_40:
1853 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
1854 cfg80211_get_chandef_type(chandef)))
1855 return -ENOBUFS;
1856 break;
1857 default:
1858 break;
1859 }
1860 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
1861 return -ENOBUFS;
1862 if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
1863 return -ENOBUFS;
1864 if (chandef->center_freq2 &&
1865 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
1866 return -ENOBUFS;
1867 return 0;
1868}
1869
1752static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags, 1870static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
1753 struct cfg80211_registered_device *rdev, 1871 struct cfg80211_registered_device *rdev,
1754 struct wireless_dev *wdev) 1872 struct wireless_dev *wdev)
@@ -1775,16 +1893,14 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
1775 goto nla_put_failure; 1893 goto nla_put_failure;
1776 1894
1777 if (rdev->ops->get_channel) { 1895 if (rdev->ops->get_channel) {
1778 struct ieee80211_channel *chan; 1896 int ret;
1779 enum nl80211_channel_type channel_type; 1897 struct cfg80211_chan_def chandef;
1780 1898
1781 chan = rdev_get_channel(rdev, wdev, &channel_type); 1899 ret = rdev_get_channel(rdev, wdev, &chandef);
1782 if (chan && 1900 if (ret == 0) {
1783 (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, 1901 if (nl80211_send_chandef(msg, &chandef))
1784 chan->center_freq) || 1902 goto nla_put_failure;
1785 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, 1903 }
1786 channel_type)))
1787 goto nla_put_failure;
1788 } 1904 }
1789 1905
1790 if (wdev->ssid_len) { 1906 if (wdev->ssid_len) {
@@ -2492,11 +2608,10 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
2492 wdev->iftype != NL80211_IFTYPE_P2P_GO) 2608 wdev->iftype != NL80211_IFTYPE_P2P_GO)
2493 continue; 2609 continue;
2494 2610
2495 if (!wdev->preset_chan) 2611 if (!wdev->preset_chandef.chan)
2496 continue; 2612 continue;
2497 2613
2498 params->channel = wdev->preset_chan; 2614 params->chandef = wdev->preset_chandef;
2499 params->channel_type = wdev->preset_chantype;
2500 ret = true; 2615 ret = true;
2501 break; 2616 break;
2502 } 2617 }
@@ -2618,30 +2733,19 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2618 } 2733 }
2619 2734
2620 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 2735 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
2621 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 2736 err = nl80211_parse_chandef(rdev, info, &params.chandef);
2622 2737 if (err)
2623 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 2738 return err;
2624 !nl80211_valid_channel_type(info, &channel_type)) 2739 } else if (wdev->preset_chandef.chan) {
2625 return -EINVAL; 2740 params.chandef = wdev->preset_chandef;
2626
2627 params.channel = rdev_freq_to_chan(rdev,
2628 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
2629 channel_type);
2630 if (!params.channel)
2631 return -EINVAL;
2632 params.channel_type = channel_type;
2633 } else if (wdev->preset_chan) {
2634 params.channel = wdev->preset_chan;
2635 params.channel_type = wdev->preset_chantype;
2636 } else if (!nl80211_get_ap_channel(rdev, &params)) 2741 } else if (!nl80211_get_ap_channel(rdev, &params))
2637 return -EINVAL; 2742 return -EINVAL;
2638 2743
2639 if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel, 2744 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
2640 params.channel_type))
2641 return -EINVAL; 2745 return -EINVAL;
2642 2746
2643 mutex_lock(&rdev->devlist_mtx); 2747 mutex_lock(&rdev->devlist_mtx);
2644 err = cfg80211_can_use_chan(rdev, wdev, params.channel, 2748 err = cfg80211_can_use_chan(rdev, wdev, params.chandef.chan,
2645 CHAN_MODE_SHARED); 2749 CHAN_MODE_SHARED);
2646 mutex_unlock(&rdev->devlist_mtx); 2750 mutex_unlock(&rdev->devlist_mtx);
2647 2751
@@ -2650,10 +2754,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2650 2754
2651 err = rdev_start_ap(rdev, dev, &params); 2755 err = rdev_start_ap(rdev, dev, &params);
2652 if (!err) { 2756 if (!err) {
2653 wdev->preset_chan = params.channel; 2757 wdev->preset_chandef = params.chandef;
2654 wdev->preset_chantype = params.channel_type;
2655 wdev->beacon_interval = params.beacon_interval; 2758 wdev->beacon_interval = params.beacon_interval;
2656 wdev->channel = params.channel; 2759 wdev->channel = params.chandef.chan;
2657 wdev->ssid_len = params.ssid_len; 2760 wdev->ssid_len = params.ssid_len;
2658 memcpy(wdev->ssid, params.ssid, wdev->ssid_len); 2761 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
2659 } 2762 }
@@ -2787,29 +2890,52 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
2787 2890
2788 rate = nla_nest_start(msg, attr); 2891 rate = nla_nest_start(msg, attr);
2789 if (!rate) 2892 if (!rate)
2790 goto nla_put_failure; 2893 return false;
2791 2894
2792 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */ 2895 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
2793 bitrate = cfg80211_calculate_bitrate(info); 2896 bitrate = cfg80211_calculate_bitrate(info);
2794 /* report 16-bit bitrate only if we can */ 2897 /* report 16-bit bitrate only if we can */
2795 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0; 2898 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
2796 if ((bitrate > 0 && 2899 if (bitrate > 0 &&
2797 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate)) || 2900 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
2798 (bitrate_compat > 0 && 2901 return false;
2799 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat)) || 2902 if (bitrate_compat > 0 &&
2800 ((info->flags & RATE_INFO_FLAGS_MCS) && 2903 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
2801 nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) || 2904 return false;
2802 ((info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) && 2905
2803 nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) || 2906 if (info->flags & RATE_INFO_FLAGS_MCS) {
2804 ((info->flags & RATE_INFO_FLAGS_SHORT_GI) && 2907 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
2805 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))) 2908 return false;
2806 goto nla_put_failure; 2909 if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
2910 nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
2911 return false;
2912 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
2913 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
2914 return false;
2915 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
2916 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
2917 return false;
2918 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
2919 return false;
2920 if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
2921 nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
2922 return false;
2923 if (info->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH &&
2924 nla_put_flag(msg, NL80211_RATE_INFO_80_MHZ_WIDTH))
2925 return false;
2926 if (info->flags & RATE_INFO_FLAGS_80P80_MHZ_WIDTH &&
2927 nla_put_flag(msg, NL80211_RATE_INFO_80P80_MHZ_WIDTH))
2928 return false;
2929 if (info->flags & RATE_INFO_FLAGS_160_MHZ_WIDTH &&
2930 nla_put_flag(msg, NL80211_RATE_INFO_160_MHZ_WIDTH))
2931 return false;
2932 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
2933 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
2934 return false;
2935 }
2807 2936
2808 nla_nest_end(msg, rate); 2937 nla_nest_end(msg, rate);
2809 return true; 2938 return true;
2810
2811nla_put_failure:
2812 return false;
2813} 2939}
2814 2940
2815static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, 2941static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
@@ -5330,8 +5456,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5330 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 5456 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
5331 return -EINVAL; 5457 return -EINVAL;
5332 5458
5333 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] || 5459 if (!info->attrs[NL80211_ATTR_SSID] ||
5334 !info->attrs[NL80211_ATTR_SSID] ||
5335 !nla_len(info->attrs[NL80211_ATTR_SSID])) 5460 !nla_len(info->attrs[NL80211_ATTR_SSID]))
5336 return -EINVAL; 5461 return -EINVAL;
5337 5462
@@ -5366,35 +5491,17 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5366 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 5491 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
5367 } 5492 }
5368 5493
5369 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { 5494 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
5370 enum nl80211_channel_type channel_type; 5495 if (err)
5371 5496 return err;
5372 if (!nl80211_valid_channel_type(info, &channel_type))
5373 return -EINVAL;
5374
5375 if (channel_type != NL80211_CHAN_NO_HT &&
5376 !(wiphy->features & NL80211_FEATURE_HT_IBSS))
5377 return -EINVAL;
5378
5379 ibss.channel_type = channel_type;
5380 } else {
5381 ibss.channel_type = NL80211_CHAN_NO_HT;
5382 }
5383 5497
5384 ibss.channel = rdev_freq_to_chan(rdev, 5498 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef))
5385 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
5386 ibss.channel_type);
5387 if (!ibss.channel ||
5388 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
5389 ibss.channel->flags & IEEE80211_CHAN_DISABLED)
5390 return -EINVAL; 5499 return -EINVAL;
5391 5500
5392 /* Both channels should be able to initiate communication */ 5501 if (ibss.chandef.width > NL80211_CHAN_WIDTH_40)
5393 if ((ibss.channel_type == NL80211_CHAN_HT40PLUS ||
5394 ibss.channel_type == NL80211_CHAN_HT40MINUS) &&
5395 !cfg80211_can_beacon_sec_chan(&rdev->wiphy, ibss.channel,
5396 ibss.channel_type))
5397 return -EINVAL; 5502 return -EINVAL;
5503 if (ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
5504 !(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
5398 5505
5399 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; 5506 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
5400 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; 5507 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
@@ -5405,7 +5512,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5405 int n_rates = 5512 int n_rates =
5406 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); 5513 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5407 struct ieee80211_supported_band *sband = 5514 struct ieee80211_supported_band *sband =
5408 wiphy->bands[ibss.channel->band]; 5515 wiphy->bands[ibss.chandef.chan->band];
5409 5516
5410 err = ieee80211_get_ratemask(sband, rates, n_rates, 5517 err = ieee80211_get_ratemask(sband, rates, n_rates,
5411 &ibss.basic_rates); 5518 &ibss.basic_rates);
@@ -5427,7 +5534,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5427 if (IS_ERR(connkeys)) 5534 if (IS_ERR(connkeys))
5428 return PTR_ERR(connkeys); 5535 return PTR_ERR(connkeys);
5429 5536
5430 if ((ibss.channel_type != NL80211_CHAN_NO_HT) && no_ht) { 5537 if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
5538 no_ht) {
5431 kfree(connkeys); 5539 kfree(connkeys);
5432 return -EINVAL; 5540 return -EINVAL;
5433 } 5541 }
@@ -5948,12 +6056,11 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
5948{ 6056{
5949 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6057 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5950 struct wireless_dev *wdev = info->user_ptr[1]; 6058 struct wireless_dev *wdev = info->user_ptr[1];
5951 struct ieee80211_channel *chan; 6059 struct cfg80211_chan_def chandef;
5952 struct sk_buff *msg; 6060 struct sk_buff *msg;
5953 void *hdr; 6061 void *hdr;
5954 u64 cookie; 6062 u64 cookie;
5955 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 6063 u32 duration;
5956 u32 freq, duration;
5957 int err; 6064 int err;
5958 6065
5959 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] || 6066 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
@@ -5974,14 +6081,9 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
5974 duration > rdev->wiphy.max_remain_on_channel_duration) 6081 duration > rdev->wiphy.max_remain_on_channel_duration)
5975 return -EINVAL; 6082 return -EINVAL;
5976 6083
5977 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 6084 err = nl80211_parse_chandef(rdev, info, &chandef);
5978 !nl80211_valid_channel_type(info, &channel_type)) 6085 if (err)
5979 return -EINVAL; 6086 return err;
5980
5981 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
5982 chan = rdev_freq_to_chan(rdev, freq, channel_type);
5983 if (chan == NULL)
5984 return -EINVAL;
5985 6087
5986 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6088 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5987 if (!msg) 6089 if (!msg)
@@ -5995,8 +6097,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
5995 goto free_msg; 6097 goto free_msg;
5996 } 6098 }
5997 6099
5998 err = rdev_remain_on_channel(rdev, wdev, chan, channel_type, duration, 6100 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
5999 &cookie); 6101 duration, &cookie);
6000 6102
6001 if (err) 6103 if (err)
6002 goto free_msg; 6104 goto free_msg;
@@ -6215,10 +6317,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6215{ 6317{
6216 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6318 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6217 struct wireless_dev *wdev = info->user_ptr[1]; 6319 struct wireless_dev *wdev = info->user_ptr[1];
6218 struct ieee80211_channel *chan; 6320 struct cfg80211_chan_def chandef;
6219 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
6220 bool channel_type_valid = false;
6221 u32 freq;
6222 int err; 6321 int err;
6223 void *hdr = NULL; 6322 void *hdr = NULL;
6224 u64 cookie; 6323 u64 cookie;
@@ -6228,8 +6327,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6228 6327
6229 dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK]; 6328 dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
6230 6329
6231 if (!info->attrs[NL80211_ATTR_FRAME] || 6330 if (!info->attrs[NL80211_ATTR_FRAME])
6232 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
6233 return -EINVAL; 6331 return -EINVAL;
6234 6332
6235 if (!rdev->ops->mgmt_tx) 6333 if (!rdev->ops->mgmt_tx)
@@ -6264,12 +6362,6 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6264 6362
6265 } 6363 }
6266 6364
6267 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
6268 if (!nl80211_valid_channel_type(info, &channel_type))
6269 return -EINVAL;
6270 channel_type_valid = true;
6271 }
6272
6273 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; 6365 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
6274 6366
6275 if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) 6367 if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
@@ -6277,10 +6369,9 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6277 6369
6278 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); 6370 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
6279 6371
6280 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); 6372 err = nl80211_parse_chandef(rdev, info, &chandef);
6281 chan = rdev_freq_to_chan(rdev, freq, channel_type); 6373 if (err)
6282 if (chan == NULL) 6374 return err;
6283 return -EINVAL;
6284 6375
6285 if (!dont_wait_for_ack) { 6376 if (!dont_wait_for_ack) {
6286 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6377 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
@@ -6296,8 +6387,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6296 } 6387 }
6297 } 6388 }
6298 6389
6299 err = cfg80211_mlme_mgmt_tx(rdev, wdev, chan, offchan, channel_type, 6390 err = cfg80211_mlme_mgmt_tx(rdev, wdev, chandef.chan, offchan, wait,
6300 channel_type_valid, wait,
6301 nla_data(info->attrs[NL80211_ATTR_FRAME]), 6391 nla_data(info->attrs[NL80211_ATTR_FRAME]),
6302 nla_len(info->attrs[NL80211_ATTR_FRAME]), 6392 nla_len(info->attrs[NL80211_ATTR_FRAME]),
6303 no_cck, dont_wait_for_ack, &cookie); 6393 no_cck, dont_wait_for_ack, &cookie);
@@ -6561,21 +6651,12 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
6561 } 6651 }
6562 6652
6563 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 6653 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
6564 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 6654 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
6565 6655 if (err)
6566 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 6656 return err;
6567 !nl80211_valid_channel_type(info, &channel_type))
6568 return -EINVAL;
6569
6570 setup.channel = rdev_freq_to_chan(rdev,
6571 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
6572 channel_type);
6573 if (!setup.channel)
6574 return -EINVAL;
6575 setup.channel_type = channel_type;
6576 } else { 6657 } else {
6577 /* cfg80211_join_mesh() will sort it out */ 6658 /* cfg80211_join_mesh() will sort it out */
6578 setup.channel = NULL; 6659 setup.chandef.chan = NULL;
6579 } 6660 }
6580 6661
6581 return cfg80211_join_mesh(rdev, dev, &setup, &cfg); 6662 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
@@ -8395,7 +8476,6 @@ static void nl80211_send_remain_on_chan_event(
8395 int cmd, struct cfg80211_registered_device *rdev, 8476 int cmd, struct cfg80211_registered_device *rdev,
8396 struct wireless_dev *wdev, u64 cookie, 8477 struct wireless_dev *wdev, u64 cookie,
8397 struct ieee80211_channel *chan, 8478 struct ieee80211_channel *chan,
8398 enum nl80211_channel_type channel_type,
8399 unsigned int duration, gfp_t gfp) 8479 unsigned int duration, gfp_t gfp)
8400{ 8480{
8401 struct sk_buff *msg; 8481 struct sk_buff *msg;
@@ -8416,7 +8496,8 @@ static void nl80211_send_remain_on_chan_event(
8416 wdev->netdev->ifindex)) || 8496 wdev->netdev->ifindex)) ||
8417 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) || 8497 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
8418 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) || 8498 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
8419 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, channel_type) || 8499 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
8500 NL80211_CHAN_NO_HT) ||
8420 nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) 8501 nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
8421 goto nla_put_failure; 8502 goto nla_put_failure;
8422 8503
@@ -8438,23 +8519,20 @@ static void nl80211_send_remain_on_chan_event(
8438void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev, 8519void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
8439 struct wireless_dev *wdev, u64 cookie, 8520 struct wireless_dev *wdev, u64 cookie,
8440 struct ieee80211_channel *chan, 8521 struct ieee80211_channel *chan,
8441 enum nl80211_channel_type channel_type,
8442 unsigned int duration, gfp_t gfp) 8522 unsigned int duration, gfp_t gfp)
8443{ 8523{
8444 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL, 8524 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
8445 rdev, wdev, cookie, chan, 8525 rdev, wdev, cookie, chan,
8446 channel_type, duration, gfp); 8526 duration, gfp);
8447} 8527}
8448 8528
8449void nl80211_send_remain_on_channel_cancel( 8529void nl80211_send_remain_on_channel_cancel(
8450 struct cfg80211_registered_device *rdev, 8530 struct cfg80211_registered_device *rdev,
8451 struct wireless_dev *wdev, 8531 struct wireless_dev *wdev,
8452 u64 cookie, struct ieee80211_channel *chan, 8532 u64 cookie, struct ieee80211_channel *chan, gfp_t gfp)
8453 enum nl80211_channel_type channel_type, gfp_t gfp)
8454{ 8533{
8455 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, 8534 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
8456 rdev, wdev, cookie, chan, 8535 rdev, wdev, cookie, chan, 0, gfp);
8457 channel_type, 0, gfp);
8458} 8536}
8459 8537
8460void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, 8538void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
@@ -8810,8 +8888,8 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
8810} 8888}
8811 8889
8812void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, 8890void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
8813 struct net_device *netdev, int freq, 8891 struct net_device *netdev,
8814 enum nl80211_channel_type type, gfp_t gfp) 8892 struct cfg80211_chan_def *chandef, gfp_t gfp)
8815{ 8893{
8816 struct sk_buff *msg; 8894 struct sk_buff *msg;
8817 void *hdr; 8895 void *hdr;
@@ -8826,9 +8904,10 @@ void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
8826 return; 8904 return;
8827 } 8905 }
8828 8906
8829 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || 8907 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
8830 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) || 8908 goto nla_put_failure;
8831 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, type)) 8909
8910 if (nl80211_send_chandef(msg, chandef))
8832 goto nla_put_failure; 8911 goto nla_put_failure;
8833 8912
8834 genlmsg_end(msg, hdr); 8913 genlmsg_end(msg, hdr);
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index f6153516068c..2acba8477e9d 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -76,13 +76,11 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
76void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev, 76void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
77 struct wireless_dev *wdev, u64 cookie, 77 struct wireless_dev *wdev, u64 cookie,
78 struct ieee80211_channel *chan, 78 struct ieee80211_channel *chan,
79 enum nl80211_channel_type channel_type,
80 unsigned int duration, gfp_t gfp); 79 unsigned int duration, gfp_t gfp);
81void nl80211_send_remain_on_channel_cancel( 80void nl80211_send_remain_on_channel_cancel(
82 struct cfg80211_registered_device *rdev, 81 struct cfg80211_registered_device *rdev,
83 struct wireless_dev *wdev, 82 struct wireless_dev *wdev,
84 u64 cookie, struct ieee80211_channel *chan, 83 u64 cookie, struct ieee80211_channel *chan, gfp_t gfp);
85 enum nl80211_channel_type channel_type, gfp_t gfp);
86 84
87void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, 85void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
88 struct net_device *dev, const u8 *mac_addr, 86 struct net_device *dev, const u8 *mac_addr,
@@ -129,8 +127,8 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
129 const u8 *bssid, bool preauth, gfp_t gfp); 127 const u8 *bssid, bool preauth, gfp_t gfp);
130 128
131void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, 129void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
132 struct net_device *dev, int freq, 130 struct net_device *dev,
133 enum nl80211_channel_type type, gfp_t gfp); 131 struct cfg80211_chan_def *chandef, gfp_t gfp);
134 132
135bool nl80211_unexpected_frame(struct net_device *dev, 133bool nl80211_unexpected_frame(struct net_device *dev,
136 const u8 *addr, gfp_t gfp); 134 const u8 *addr, gfp_t gfp);
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 6e5fa659068d..6c0c8191f837 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -359,12 +359,11 @@ rdev_libertas_set_mesh_channel(struct cfg80211_registered_device *rdev,
359 359
360static inline int 360static inline int
361rdev_set_monitor_channel(struct cfg80211_registered_device *rdev, 361rdev_set_monitor_channel(struct cfg80211_registered_device *rdev,
362 struct ieee80211_channel *chan, 362 struct cfg80211_chan_def *chandef)
363 enum nl80211_channel_type channel_type)
364{ 363{
365 int ret; 364 int ret;
366 trace_rdev_set_monitor_channel(&rdev->wiphy, chan, channel_type); 365 trace_rdev_set_monitor_channel(&rdev->wiphy, chandef);
367 ret = rdev->ops->set_monitor_channel(&rdev->wiphy, chan, channel_type); 366 ret = rdev->ops->set_monitor_channel(&rdev->wiphy, chandef);
368 trace_rdev_return_int(&rdev->wiphy, ret); 367 trace_rdev_return_int(&rdev->wiphy, ret);
369 return ret; 368 return ret;
370} 369}
@@ -600,14 +599,12 @@ static inline int
600rdev_remain_on_channel(struct cfg80211_registered_device *rdev, 599rdev_remain_on_channel(struct cfg80211_registered_device *rdev,
601 struct wireless_dev *wdev, 600 struct wireless_dev *wdev,
602 struct ieee80211_channel *chan, 601 struct ieee80211_channel *chan,
603 enum nl80211_channel_type channel_type,
604 unsigned int duration, u64 *cookie) 602 unsigned int duration, u64 *cookie)
605{ 603{
606 int ret; 604 int ret;
607 trace_rdev_remain_on_channel(&rdev->wiphy, wdev, chan, channel_type, 605 trace_rdev_remain_on_channel(&rdev->wiphy, wdev, chan, duration);
608 duration);
609 ret = rdev->ops->remain_on_channel(&rdev->wiphy, wdev, chan, 606 ret = rdev->ops->remain_on_channel(&rdev->wiphy, wdev, chan,
610 channel_type, duration, cookie); 607 duration, cookie);
611 trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); 608 trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie);
612 return ret; 609 return ret;
613} 610}
@@ -626,17 +623,15 @@ rdev_cancel_remain_on_channel(struct cfg80211_registered_device *rdev,
626static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev, 623static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev,
627 struct wireless_dev *wdev, 624 struct wireless_dev *wdev,
628 struct ieee80211_channel *chan, bool offchan, 625 struct ieee80211_channel *chan, bool offchan,
629 enum nl80211_channel_type channel_type, 626 unsigned int wait, const u8 *buf, size_t len,
630 bool channel_type_valid, unsigned int wait, 627 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
631 const u8 *buf, size_t len, bool no_cck,
632 bool dont_wait_for_ack, u64 *cookie)
633{ 628{
634 int ret; 629 int ret;
635 trace_rdev_mgmt_tx(&rdev->wiphy, wdev, chan, offchan, channel_type, 630 trace_rdev_mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
636 channel_type_valid, wait, no_cck, dont_wait_for_ack); 631 wait, no_cck, dont_wait_for_ack);
637 ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan, 632 ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
638 channel_type, channel_type_valid, wait, buf, 633 wait, buf, len, no_cck,
639 len, no_cck, dont_wait_for_ack, cookie); 634 dont_wait_for_ack, cookie);
640 trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); 635 trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie);
641 return ret; 636 return ret;
642} 637}
@@ -848,14 +843,17 @@ static inline void rdev_get_et_strings(struct cfg80211_registered_device *rdev,
848 trace_rdev_return_void(&rdev->wiphy); 843 trace_rdev_return_void(&rdev->wiphy);
849} 844}
850 845
851static inline struct ieee80211_channel 846static inline int
852*rdev_get_channel(struct cfg80211_registered_device *rdev, 847rdev_get_channel(struct cfg80211_registered_device *rdev,
853 struct wireless_dev *wdev, enum nl80211_channel_type *type) 848 struct wireless_dev *wdev,
849 struct cfg80211_chan_def *chandef)
854{ 850{
855 struct ieee80211_channel *ret; 851 int ret;
852
856 trace_rdev_get_channel(&rdev->wiphy, wdev); 853 trace_rdev_get_channel(&rdev->wiphy, wdev);
857 ret = rdev->ops->get_channel(&rdev->wiphy, wdev, type); 854 ret = rdev->ops->get_channel(&rdev->wiphy, wdev, chandef);
858 trace_rdev_return_channel(&rdev->wiphy, ret, *type); 855 trace_rdev_return_chandef(&rdev->wiphy, ret, chandef);
856
859 return ret; 857 return ret;
860} 858}
861 859
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 7f97a087f452..9596015975d2 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -771,6 +771,38 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
771 return found; 771 return found;
772} 772}
773 773
774static struct ieee80211_channel *
775cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
776 struct ieee80211_channel *channel)
777{
778 const u8 *tmp;
779 u32 freq;
780 int channel_number = -1;
781
782 tmp = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ie, ielen);
783 if (tmp && tmp[1] == 1) {
784 channel_number = tmp[2];
785 } else {
786 tmp = cfg80211_find_ie(WLAN_EID_HT_OPERATION, ie, ielen);
787 if (tmp && tmp[1] >= sizeof(struct ieee80211_ht_operation)) {
788 struct ieee80211_ht_operation *htop = (void *)(tmp + 2);
789
790 channel_number = htop->primary_chan;
791 }
792 }
793
794 if (channel_number < 0)
795 return channel;
796
797 freq = ieee80211_channel_to_frequency(channel_number, channel->band);
798 channel = ieee80211_get_channel(wiphy, freq);
799 if (!channel)
800 return NULL;
801 if (channel->flags & IEEE80211_CHAN_DISABLED)
802 return NULL;
803 return channel;
804}
805
774struct cfg80211_bss* 806struct cfg80211_bss*
775cfg80211_inform_bss(struct wiphy *wiphy, 807cfg80211_inform_bss(struct wiphy *wiphy,
776 struct ieee80211_channel *channel, 808 struct ieee80211_channel *channel,
@@ -790,6 +822,10 @@ cfg80211_inform_bss(struct wiphy *wiphy,
790 (signal < 0 || signal > 100))) 822 (signal < 0 || signal > 100)))
791 return NULL; 823 return NULL;
792 824
825 channel = cfg80211_get_bss_channel(wiphy, ie, ielen, channel);
826 if (!channel)
827 return NULL;
828
793 res = kzalloc(sizeof(*res) + privsz + ielen, gfp); 829 res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
794 if (!res) 830 if (!res)
795 return NULL; 831 return NULL;
@@ -839,11 +875,13 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
839 s32 signal, gfp_t gfp) 875 s32 signal, gfp_t gfp)
840{ 876{
841 struct cfg80211_internal_bss *res; 877 struct cfg80211_internal_bss *res;
842
843 size_t ielen = len - offsetof(struct ieee80211_mgmt, 878 size_t ielen = len - offsetof(struct ieee80211_mgmt,
844 u.probe_resp.variable); 879 u.probe_resp.variable);
845 size_t privsz; 880 size_t privsz;
846 881
882 BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
883 offsetof(struct ieee80211_mgmt, u.beacon.variable));
884
847 trace_cfg80211_inform_bss_frame(wiphy, channel, mgmt, len, signal); 885 trace_cfg80211_inform_bss_frame(wiphy, channel, mgmt, len, signal);
848 886
849 if (WARN_ON(!mgmt)) 887 if (WARN_ON(!mgmt))
@@ -861,6 +899,11 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
861 899
862 privsz = wiphy->bss_priv_size; 900 privsz = wiphy->bss_priv_size;
863 901
902 channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable,
903 ielen, channel);
904 if (!channel)
905 return NULL;
906
864 res = kzalloc(sizeof(*res) + privsz + ielen, gfp); 907 res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
865 if (!res) 908 if (!res)
866 return NULL; 909 return NULL;
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index f264c20a7090..2134576f426e 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -20,29 +20,26 @@
20#define MAC_PR_FMT "%pM" 20#define MAC_PR_FMT "%pM"
21#define MAC_PR_ARG(entry_mac) (__entry->entry_mac) 21#define MAC_PR_ARG(entry_mac) (__entry->entry_mac)
22 22
23#define WIPHY_ENTRY MAC_ENTRY(wiphy_mac) 23#define MAXNAME 32
24#define WIPHY_ASSIGN MAC_ASSIGN(wiphy_mac, wiphy->perm_addr) 24#define WIPHY_ENTRY __array(char, wiphy_name, 32)
25#define WIPHY_PR_FMT "wiphy " MAC_PR_FMT 25#define WIPHY_ASSIGN strlcpy(__entry->wiphy_name, wiphy_name(wiphy), MAXNAME)
26#define WIPHY_PR_ARG MAC_PR_ARG(wiphy_mac) 26#define WIPHY_PR_FMT "%s"
27 27#define WIPHY_PR_ARG __entry->wiphy_name
28#define WDEV_ENTRY __field(u32, id) 28
29#define WDEV_ASSIGN (__entry->id) = (wdev ? wdev->identifier : 0) 29#define WDEV_ENTRY __field(u32, id)
30#define WDEV_PR_FMT ", wdev id: %u" 30#define WDEV_ASSIGN (__entry->id) = (wdev ? wdev->identifier : 0)
31#define WDEV_PR_ARG (__entry->id) 31#define WDEV_PR_FMT "wdev(%u)"
32 32#define WDEV_PR_ARG (__entry->id)
33#define NETDEV_ENTRY __array(char, name, IFNAMSIZ) \ 33
34 MAC_ENTRY(netdev_addr) \ 34#define NETDEV_ENTRY __array(char, name, IFNAMSIZ) \
35 __field(int, ifindex) 35 __field(int, ifindex)
36#define NETDEV_ASSIGN \ 36#define NETDEV_ASSIGN \
37 do { \ 37 do { \
38 memcpy(__entry->name, netdev->name, IFNAMSIZ); \ 38 memcpy(__entry->name, netdev->name, IFNAMSIZ); \
39 MAC_ASSIGN(netdev_addr, netdev->dev_addr); \
40 (__entry->ifindex) = (netdev->ifindex); \ 39 (__entry->ifindex) = (netdev->ifindex); \
41 } while (0) 40 } while (0)
42#define NETDEV_PR_FMT ", netdev - name: %s, addr: " MAC_PR_FMT \ 41#define NETDEV_PR_FMT "netdev:%s(%d)"
43 ", intf index: %d" 42#define NETDEV_PR_ARG __entry->name, __entry->ifindex
44#define NETDEV_PR_ARG (__entry->name), MAC_PR_ARG(netdev_addr), \
45 (__entry->ifindex)
46 43
47#define MESH_CFG_ENTRY __field(u16, dot11MeshRetryTimeout) \ 44#define MESH_CFG_ENTRY __field(u16, dot11MeshRetryTimeout) \
48 __field(u16, dot11MeshConfirmTimeout) \ 45 __field(u16, dot11MeshConfirmTimeout) \
@@ -123,9 +120,37 @@
123 __entry->center_freq = 0; \ 120 __entry->center_freq = 0; \
124 } \ 121 } \
125 } while (0) 122 } while (0)
126#define CHAN_PR_FMT ", band: %d, freq: %u" 123#define CHAN_PR_FMT "band: %d, freq: %u"
127#define CHAN_PR_ARG __entry->band, __entry->center_freq 124#define CHAN_PR_ARG __entry->band, __entry->center_freq
128 125
126#define CHAN_DEF_ENTRY __field(enum ieee80211_band, band) \
127 __field(u32, control_freq) \
128 __field(u32, width) \
129 __field(u32, center_freq1) \
130 __field(u32, center_freq2)
131#define CHAN_DEF_ASSIGN(chandef) \
132 do { \
133 if ((chandef) && (chandef)->chan) { \
134 __entry->band = (chandef)->chan->band; \
135 __entry->control_freq = \
136 (chandef)->chan->center_freq; \
137 __entry->width = (chandef)->width; \
138 __entry->center_freq1 = (chandef)->center_freq1;\
139 __entry->center_freq2 = (chandef)->center_freq2;\
140 } else { \
141 __entry->band = 0; \
142 __entry->control_freq = 0; \
143 __entry->width = 0; \
144 __entry->center_freq1 = 0; \
145 __entry->center_freq2 = 0; \
146 } \
147 } while (0)
148#define CHAN_DEF_PR_FMT \
149 "band: %d, control freq: %u, width: %d, cf1: %u, cf2: %u"
150#define CHAN_DEF_PR_ARG __entry->band, __entry->control_freq, \
151 __entry->width, __entry->center_freq1, \
152 __entry->center_freq2
153
129#define SINFO_ENTRY __field(int, generation) \ 154#define SINFO_ENTRY __field(int, generation) \
130 __field(u32, connected_time) \ 155 __field(u32, connected_time) \
131 __field(u32, inactive_time) \ 156 __field(u32, inactive_time) \
@@ -313,7 +338,7 @@ DECLARE_EVENT_CLASS(wiphy_wdev_evt,
313 WIPHY_ASSIGN; 338 WIPHY_ASSIGN;
314 WDEV_ASSIGN; 339 WDEV_ASSIGN;
315 ), 340 ),
316 TP_printk(WIPHY_PR_FMT WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG) 341 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG)
317); 342);
318 343
319DEFINE_EVENT(wiphy_wdev_evt, rdev_return_wdev, 344DEFINE_EVENT(wiphy_wdev_evt, rdev_return_wdev,
@@ -340,7 +365,7 @@ TRACE_EVENT(rdev_change_virtual_intf,
340 NETDEV_ASSIGN; 365 NETDEV_ASSIGN;
341 __entry->type = type; 366 __entry->type = type;
342 ), 367 ),
343 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", type: %d", 368 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", type: %d",
344 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->type) 369 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->type)
345); 370);
346 371
@@ -362,7 +387,7 @@ DECLARE_EVENT_CLASS(key_handle,
362 __entry->key_index = key_index; 387 __entry->key_index = key_index;
363 __entry->pairwise = pairwise; 388 __entry->pairwise = pairwise;
364 ), 389 ),
365 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key_index: %u, pairwise: %s, mac addr: " MAC_PR_FMT, 390 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key_index: %u, pairwise: %s, mac addr: " MAC_PR_FMT,
366 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index, 391 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index,
367 BOOL_TO_STR(__entry->pairwise), MAC_PR_ARG(mac_addr)) 392 BOOL_TO_STR(__entry->pairwise), MAC_PR_ARG(mac_addr))
368); 393);
@@ -403,7 +428,7 @@ TRACE_EVENT(rdev_set_default_key,
403 __entry->unicast = unicast; 428 __entry->unicast = unicast;
404 __entry->multicast = multicast; 429 __entry->multicast = multicast;
405 ), 430 ),
406 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key index: %u, unicast: %s, multicast: %s", 431 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key index: %u, unicast: %s, multicast: %s",
407 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index, 432 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index,
408 BOOL_TO_STR(__entry->unicast), 433 BOOL_TO_STR(__entry->unicast),
409 BOOL_TO_STR(__entry->multicast)) 434 BOOL_TO_STR(__entry->multicast))
@@ -422,7 +447,7 @@ TRACE_EVENT(rdev_set_default_mgmt_key,
422 NETDEV_ASSIGN; 447 NETDEV_ASSIGN;
423 __entry->key_index = key_index; 448 __entry->key_index = key_index;
424 ), 449 ),
425 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key index: %u", 450 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key index: %u",
426 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index) 451 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index)
427); 452);
428 453
@@ -433,7 +458,7 @@ TRACE_EVENT(rdev_start_ap,
433 TP_STRUCT__entry( 458 TP_STRUCT__entry(
434 WIPHY_ENTRY 459 WIPHY_ENTRY
435 NETDEV_ENTRY 460 NETDEV_ENTRY
436 CHAN_ENTRY 461 CHAN_DEF_ENTRY
437 __field(int, beacon_interval) 462 __field(int, beacon_interval)
438 __field(int, dtim_period) 463 __field(int, dtim_period)
439 __array(char, ssid, IEEE80211_MAX_SSID_LEN + 1) 464 __array(char, ssid, IEEE80211_MAX_SSID_LEN + 1)
@@ -446,7 +471,7 @@ TRACE_EVENT(rdev_start_ap,
446 TP_fast_assign( 471 TP_fast_assign(
447 WIPHY_ASSIGN; 472 WIPHY_ASSIGN;
448 NETDEV_ASSIGN; 473 NETDEV_ASSIGN;
449 CHAN_ASSIGN(settings->channel); 474 CHAN_DEF_ASSIGN(&settings->chandef);
450 __entry->beacon_interval = settings->beacon_interval; 475 __entry->beacon_interval = settings->beacon_interval;
451 __entry->dtim_period = settings->dtim_period; 476 __entry->dtim_period = settings->dtim_period;
452 __entry->hidden_ssid = settings->hidden_ssid; 477 __entry->hidden_ssid = settings->hidden_ssid;
@@ -457,11 +482,11 @@ TRACE_EVENT(rdev_start_ap,
457 memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1); 482 memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1);
458 memcpy(__entry->ssid, settings->ssid, settings->ssid_len); 483 memcpy(__entry->ssid, settings->ssid, settings->ssid_len);
459 ), 484 ),
460 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", AP settings - ssid: %s, " 485 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", AP settings - ssid: %s, "
461 CHAN_PR_FMT ", beacon interval: %d, dtim period: %d, " 486 CHAN_DEF_PR_FMT ", beacon interval: %d, dtim period: %d, "
462 "hidden ssid: %d, wpa versions: %u, privacy: %s, " 487 "hidden ssid: %d, wpa versions: %u, privacy: %s, "
463 "auth type: %d, inactivity timeout: %d", 488 "auth type: %d, inactivity timeout: %d",
464 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ssid, CHAN_PR_ARG, 489 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ssid, CHAN_DEF_PR_ARG,
465 __entry->beacon_interval, __entry->dtim_period, 490 __entry->beacon_interval, __entry->dtim_period,
466 __entry->hidden_ssid, __entry->wpa_ver, 491 __entry->hidden_ssid, __entry->wpa_ver,
467 BOOL_TO_STR(__entry->privacy), __entry->auth_type, 492 BOOL_TO_STR(__entry->privacy), __entry->auth_type,
@@ -510,7 +535,7 @@ TRACE_EVENT(rdev_change_beacon,
510 info->probe_resp, info->probe_resp_len); 535 info->probe_resp, info->probe_resp_len);
511 } 536 }
512 ), 537 ),
513 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG) 538 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG)
514); 539);
515 540
516DECLARE_EVENT_CLASS(wiphy_netdev_evt, 541DECLARE_EVENT_CLASS(wiphy_netdev_evt,
@@ -524,7 +549,7 @@ DECLARE_EVENT_CLASS(wiphy_netdev_evt,
524 WIPHY_ASSIGN; 549 WIPHY_ASSIGN;
525 NETDEV_ASSIGN; 550 NETDEV_ASSIGN;
526 ), 551 ),
527 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG) 552 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG)
528); 553);
529 554
530DEFINE_EVENT(wiphy_netdev_evt, rdev_stop_ap, 555DEFINE_EVENT(wiphy_netdev_evt, rdev_stop_ap,
@@ -602,7 +627,7 @@ DECLARE_EVENT_CLASS(station_add_change,
602 memcpy(__entry->ht_capa, params->ht_capa, 627 memcpy(__entry->ht_capa, params->ht_capa,
603 sizeof(struct ieee80211_ht_cap)); 628 sizeof(struct ieee80211_ht_cap));
604 ), 629 ),
605 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", station mac: " MAC_PR_FMT 630 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT
606 ", station flags mask: %u, station flags set: %u, " 631 ", station flags mask: %u, station flags set: %u, "
607 "station modify mask: %u, listen interval: %d, aid: %u, " 632 "station modify mask: %u, listen interval: %d, aid: %u, "
608 "plink action: %u, plink state: %u, uapsd queues: %u", 633 "plink action: %u, plink state: %u, uapsd queues: %u",
@@ -638,7 +663,7 @@ DECLARE_EVENT_CLASS(wiphy_netdev_mac_evt,
638 NETDEV_ASSIGN; 663 NETDEV_ASSIGN;
639 MAC_ASSIGN(sta_mac, mac); 664 MAC_ASSIGN(sta_mac, mac);
640 ), 665 ),
641 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", mac: " MAC_PR_FMT, 666 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", mac: " MAC_PR_FMT,
642 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac)) 667 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac))
643); 668);
644 669
@@ -678,7 +703,7 @@ TRACE_EVENT(rdev_dump_station,
678 MAC_ASSIGN(sta_mac, mac); 703 MAC_ASSIGN(sta_mac, mac);
679 __entry->idx = idx; 704 __entry->idx = idx;
680 ), 705 ),
681 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", station mac: " MAC_PR_FMT ", idx: %d", 706 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT ", idx: %d",
682 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac), 707 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac),
683 __entry->idx) 708 __entry->idx)
684); 709);
@@ -716,7 +741,7 @@ DECLARE_EVENT_CLASS(mpath_evt,
716 MAC_ASSIGN(dst, dst); 741 MAC_ASSIGN(dst, dst);
717 MAC_ASSIGN(next_hop, next_hop); 742 MAC_ASSIGN(next_hop, next_hop);
718 ), 743 ),
719 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", destination: " MAC_PR_FMT ", next hop: " MAC_PR_FMT, 744 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", destination: " MAC_PR_FMT ", next hop: " MAC_PR_FMT,
720 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(dst), 745 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(dst),
721 MAC_PR_ARG(next_hop)) 746 MAC_PR_ARG(next_hop))
722); 747);
@@ -757,7 +782,7 @@ TRACE_EVENT(rdev_dump_mpath,
757 MAC_ASSIGN(next_hop, next_hop); 782 MAC_ASSIGN(next_hop, next_hop);
758 __entry->idx = idx; 783 __entry->idx = idx;
759 ), 784 ),
760 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", index: %d, destination: " 785 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: "
761 MAC_PR_FMT ", next hop: " MAC_PR_FMT, 786 MAC_PR_FMT ", next hop: " MAC_PR_FMT,
762 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst), 787 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst),
763 MAC_PR_ARG(next_hop)) 788 MAC_PR_ARG(next_hop))
@@ -834,7 +859,7 @@ TRACE_EVENT(rdev_update_mesh_config,
834 MESH_CFG_ASSIGN; 859 MESH_CFG_ASSIGN;
835 __entry->mask = mask; 860 __entry->mask = mask;
836 ), 861 ),
837 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", mask: %u", 862 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", mask: %u",
838 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->mask) 863 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->mask)
839); 864);
840 865
@@ -853,7 +878,7 @@ TRACE_EVENT(rdev_join_mesh,
853 NETDEV_ASSIGN; 878 NETDEV_ASSIGN;
854 MESH_CFG_ASSIGN; 879 MESH_CFG_ASSIGN;
855 ), 880 ),
856 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, 881 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT,
857 WIPHY_PR_ARG, NETDEV_PR_ARG) 882 WIPHY_PR_ARG, NETDEV_PR_ARG)
858); 883);
859 884
@@ -879,7 +904,7 @@ TRACE_EVENT(rdev_change_bss,
879 __entry->ap_isolate = params->ap_isolate; 904 __entry->ap_isolate = params->ap_isolate;
880 __entry->ht_opmode = params->ht_opmode; 905 __entry->ht_opmode = params->ht_opmode;
881 ), 906 ),
882 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", use cts prot: %d, " 907 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", use cts prot: %d, "
883 "use short preamble: %d, use short slot time: %d, " 908 "use short preamble: %d, use short slot time: %d, "
884 "ap isolate: %d, ht opmode: %d", 909 "ap isolate: %d, ht opmode: %d",
885 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->use_cts_prot, 910 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->use_cts_prot,
@@ -909,7 +934,7 @@ TRACE_EVENT(rdev_set_txq_params,
909 __entry->cwmax = params->cwmax; 934 __entry->cwmax = params->cwmax;
910 __entry->aifs = params->aifs; 935 __entry->aifs = params->aifs;
911 ), 936 ),
912 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", ac: %d, txop: %u, cwmin: %u, cwmax: %u, aifs: %u", 937 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", ac: %d, txop: %u, cwmin: %u, cwmax: %u, aifs: %u",
913 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ac, __entry->txop, 938 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ac, __entry->txop,
914 __entry->cwmin, __entry->cwmax, __entry->aifs) 939 __entry->cwmin, __entry->cwmax, __entry->aifs)
915); 940);
@@ -928,26 +953,24 @@ TRACE_EVENT(rdev_libertas_set_mesh_channel,
928 NETDEV_ASSIGN; 953 NETDEV_ASSIGN;
929 CHAN_ASSIGN(chan); 954 CHAN_ASSIGN(chan);
930 ), 955 ),
931 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT CHAN_PR_FMT, WIPHY_PR_ARG, 956 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_PR_FMT, WIPHY_PR_ARG,
932 NETDEV_PR_ARG, CHAN_PR_ARG) 957 NETDEV_PR_ARG, CHAN_PR_ARG)
933); 958);
934 959
935TRACE_EVENT(rdev_set_monitor_channel, 960TRACE_EVENT(rdev_set_monitor_channel,
936 TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *chan, 961 TP_PROTO(struct wiphy *wiphy,
937 enum nl80211_channel_type chan_type), 962 struct cfg80211_chan_def *chandef),
938 TP_ARGS(wiphy, chan, chan_type), 963 TP_ARGS(wiphy, chandef),
939 TP_STRUCT__entry( 964 TP_STRUCT__entry(
940 WIPHY_ENTRY 965 WIPHY_ENTRY
941 CHAN_ENTRY 966 CHAN_DEF_ENTRY
942 __field(enum nl80211_channel_type, chan_type)
943 ), 967 ),
944 TP_fast_assign( 968 TP_fast_assign(
945 WIPHY_ASSIGN; 969 WIPHY_ASSIGN;
946 CHAN_ASSIGN(chan); 970 CHAN_DEF_ASSIGN(chandef);
947 __entry->chan_type = chan_type;
948 ), 971 ),
949 TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel type : %d", 972 TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
950 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->chan_type) 973 WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
951); 974);
952 975
953TRACE_EVENT(rdev_auth, 976TRACE_EVENT(rdev_auth,
@@ -969,7 +992,7 @@ TRACE_EVENT(rdev_auth,
969 memset(__entry->bssid, 0, ETH_ALEN); 992 memset(__entry->bssid, 0, ETH_ALEN);
970 __entry->auth_type = req->auth_type; 993 __entry->auth_type = req->auth_type;
971 ), 994 ),
972 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", auth type: %d, bssid: " MAC_PR_FMT, 995 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", auth type: %d, bssid: " MAC_PR_FMT,
973 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->auth_type, 996 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->auth_type,
974 MAC_PR_ARG(bssid)) 997 MAC_PR_ARG(bssid))
975); 998);
@@ -997,7 +1020,7 @@ TRACE_EVENT(rdev_assoc,
997 __entry->use_mfp = req->use_mfp; 1020 __entry->use_mfp = req->use_mfp;
998 __entry->flags = req->flags; 1021 __entry->flags = req->flags;
999 ), 1022 ),
1000 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT 1023 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
1001 ", previous bssid: " MAC_PR_FMT ", use mfp: %s, flags: %u", 1024 ", previous bssid: " MAC_PR_FMT ", use mfp: %s, flags: %u",
1002 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), 1025 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid),
1003 MAC_PR_ARG(prev_bssid), BOOL_TO_STR(__entry->use_mfp), 1026 MAC_PR_ARG(prev_bssid), BOOL_TO_STR(__entry->use_mfp),
@@ -1020,7 +1043,7 @@ TRACE_EVENT(rdev_deauth,
1020 MAC_ASSIGN(bssid, req->bssid); 1043 MAC_ASSIGN(bssid, req->bssid);
1021 __entry->reason_code = req->reason_code; 1044 __entry->reason_code = req->reason_code;
1022 ), 1045 ),
1023 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", reason: %u", 1046 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", reason: %u",
1024 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), 1047 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid),
1025 __entry->reason_code) 1048 __entry->reason_code)
1026); 1049);
@@ -1046,7 +1069,7 @@ TRACE_EVENT(rdev_disassoc,
1046 __entry->reason_code = req->reason_code; 1069 __entry->reason_code = req->reason_code;
1047 __entry->local_state_change = req->local_state_change; 1070 __entry->local_state_change = req->local_state_change;
1048 ), 1071 ),
1049 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT 1072 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
1050 ", reason: %u, local state change: %s", 1073 ", reason: %u, local state change: %s",
1051 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), 1074 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid),
1052 __entry->reason_code, 1075 __entry->reason_code,
@@ -1067,7 +1090,7 @@ TRACE_EVENT(rdev_mgmt_tx_cancel_wait,
1067 WDEV_ASSIGN; 1090 WDEV_ASSIGN;
1068 __entry->cookie = cookie; 1091 __entry->cookie = cookie;
1069 ), 1092 ),
1070 TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", cookie: %llu ", 1093 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", cookie: %llu ",
1071 WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie) 1094 WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie)
1072); 1095);
1073 1096
@@ -1087,7 +1110,7 @@ TRACE_EVENT(rdev_set_power_mgmt,
1087 __entry->enabled = enabled; 1110 __entry->enabled = enabled;
1088 __entry->timeout = timeout; 1111 __entry->timeout = timeout;
1089 ), 1112 ),
1090 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", %senabled, timeout: %d ", 1113 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", %senabled, timeout: %d ",
1091 WIPHY_PR_ARG, NETDEV_PR_ARG, 1114 WIPHY_PR_ARG, NETDEV_PR_ARG,
1092 __entry->enabled ? "" : "not ", __entry->timeout) 1115 __entry->enabled ? "" : "not ", __entry->timeout)
1093); 1116);
@@ -1117,7 +1140,7 @@ TRACE_EVENT(rdev_connect,
1117 __entry->wpa_versions = sme->crypto.wpa_versions; 1140 __entry->wpa_versions = sme->crypto.wpa_versions;
1118 __entry->flags = sme->flags; 1141 __entry->flags = sme->flags;
1119 ), 1142 ),
1120 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT 1143 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
1121 ", ssid: %s, auth type: %d, privacy: %s, wpa versions: %u, " 1144 ", ssid: %s, auth type: %d, privacy: %s, wpa versions: %u, "
1122 "flags: %u", 1145 "flags: %u",
1123 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid, 1146 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid,
@@ -1142,7 +1165,7 @@ TRACE_EVENT(rdev_set_cqm_rssi_config,
1142 __entry->rssi_thold = rssi_thold; 1165 __entry->rssi_thold = rssi_thold;
1143 __entry->rssi_hyst = rssi_hyst; 1166 __entry->rssi_hyst = rssi_hyst;
1144 ), 1167 ),
1145 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT 1168 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT
1146 ", rssi_thold: %d, rssi_hyst: %u ", 1169 ", rssi_thold: %d, rssi_hyst: %u ",
1147 WIPHY_PR_ARG, NETDEV_PR_ARG, 1170 WIPHY_PR_ARG, NETDEV_PR_ARG,
1148 __entry->rssi_thold, __entry->rssi_hyst) 1171 __entry->rssi_thold, __entry->rssi_hyst)
@@ -1166,7 +1189,7 @@ TRACE_EVENT(rdev_set_cqm_txe_config,
1166 __entry->pkts = pkts; 1189 __entry->pkts = pkts;
1167 __entry->intvl = intvl; 1190 __entry->intvl = intvl;
1168 ), 1191 ),
1169 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", rate: %u, packets: %u, interval: %u", 1192 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", rate: %u, packets: %u, interval: %u",
1170 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->rate, __entry->pkts, 1193 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->rate, __entry->pkts,
1171 __entry->intvl) 1194 __entry->intvl)
1172); 1195);
@@ -1185,7 +1208,7 @@ TRACE_EVENT(rdev_disconnect,
1185 NETDEV_ASSIGN; 1208 NETDEV_ASSIGN;
1186 __entry->reason_code = reason_code; 1209 __entry->reason_code = reason_code;
1187 ), 1210 ),
1188 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", reason code: %u", WIPHY_PR_ARG, 1211 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", reason code: %u", WIPHY_PR_ARG,
1189 NETDEV_PR_ARG, __entry->reason_code) 1212 NETDEV_PR_ARG, __entry->reason_code)
1190); 1213);
1191 1214
@@ -1206,7 +1229,7 @@ TRACE_EVENT(rdev_join_ibss,
1206 memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1); 1229 memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1);
1207 memcpy(__entry->ssid, params->ssid, params->ssid_len); 1230 memcpy(__entry->ssid, params->ssid, params->ssid_len);
1208 ), 1231 ),
1209 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", ssid: %s", 1232 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", ssid: %s",
1210 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid) 1233 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid)
1211); 1234);
1212 1235
@@ -1246,7 +1269,7 @@ TRACE_EVENT(rdev_set_tx_power,
1246 __entry->type = type; 1269 __entry->type = type;
1247 __entry->mbm = mbm; 1270 __entry->mbm = mbm;
1248 ), 1271 ),
1249 TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", type: %d, mbm: %d", 1272 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", type: %u, mbm: %d",
1250 WIPHY_PR_ARG, WDEV_PR_ARG,__entry->type, __entry->mbm) 1273 WIPHY_PR_ARG, WDEV_PR_ARG,__entry->type, __entry->mbm)
1251); 1274);
1252 1275
@@ -1307,7 +1330,7 @@ TRACE_EVENT(rdev_set_bitrate_mask,
1307 NETDEV_ASSIGN; 1330 NETDEV_ASSIGN;
1308 MAC_ASSIGN(peer, peer); 1331 MAC_ASSIGN(peer, peer);
1309 ), 1332 ),
1310 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", peer: " MAC_PR_FMT, 1333 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT,
1311 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer)) 1334 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer))
1312); 1335);
1313 1336
@@ -1327,7 +1350,7 @@ TRACE_EVENT(rdev_mgmt_frame_register,
1327 __entry->frame_type = frame_type; 1350 __entry->frame_type = frame_type;
1328 __entry->reg = reg; 1351 __entry->reg = reg;
1329 ), 1352 ),
1330 TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", frame_type: %u, reg: %s ", 1353 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", frame_type: 0x%.2x, reg: %s ",
1331 WIPHY_PR_ARG, WDEV_PR_ARG, __entry->frame_type, 1354 WIPHY_PR_ARG, WDEV_PR_ARG, __entry->frame_type,
1332 __entry->reg ? "true" : "false") 1355 __entry->reg ? "true" : "false")
1333); 1356);
@@ -1413,7 +1436,7 @@ TRACE_EVENT(rdev_sched_scan_start,
1413 WIPHY_ASSIGN; 1436 WIPHY_ASSIGN;
1414 NETDEV_ASSIGN; 1437 NETDEV_ASSIGN;
1415 ), 1438 ),
1416 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, 1439 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT,
1417 WIPHY_PR_ARG, NETDEV_PR_ARG) 1440 WIPHY_PR_ARG, NETDEV_PR_ARG)
1418); 1441);
1419 1442
@@ -1441,7 +1464,7 @@ TRACE_EVENT(rdev_tdls_mgmt,
1441 __entry->status_code = status_code; 1464 __entry->status_code = status_code;
1442 memcpy(__get_dynamic_array(buf), buf, len); 1465 memcpy(__get_dynamic_array(buf), buf, len);
1443 ), 1466 ),
1444 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT ", action_code: %u, " 1467 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, "
1445 "dialog_token: %u, status_code: %u, buf: %#.2x ", 1468 "dialog_token: %u, status_code: %u, buf: %#.2x ",
1446 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), 1469 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer),
1447 __entry->action_code, __entry->dialog_token, 1470 __entry->action_code, __entry->dialog_token,
@@ -1461,7 +1484,7 @@ TRACE_EVENT(rdev_dump_survey,
1461 NETDEV_ASSIGN; 1484 NETDEV_ASSIGN;
1462 __entry->idx = idx; 1485 __entry->idx = idx;
1463 ), 1486 ),
1464 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", index: %d", 1487 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d",
1465 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx) 1488 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx)
1466); 1489);
1467 1490
@@ -1518,7 +1541,7 @@ TRACE_EVENT(rdev_tdls_oper,
1518 MAC_ASSIGN(peer, peer); 1541 MAC_ASSIGN(peer, peer);
1519 __entry->oper = oper; 1542 __entry->oper = oper;
1520 ), 1543 ),
1521 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT ", oper: %d", 1544 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", oper: %d",
1522 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->oper) 1545 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->oper)
1523); 1546);
1524 1547
@@ -1536,7 +1559,7 @@ DECLARE_EVENT_CLASS(rdev_pmksa,
1536 NETDEV_ASSIGN; 1559 NETDEV_ASSIGN;
1537 MAC_ASSIGN(bssid, pmksa->bssid); 1560 MAC_ASSIGN(bssid, pmksa->bssid);
1538 ), 1561 ),
1539 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT, 1562 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT,
1540 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid)) 1563 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid))
1541); 1564);
1542 1565
@@ -1554,7 +1577,7 @@ TRACE_EVENT(rdev_probe_client,
1554 NETDEV_ASSIGN; 1577 NETDEV_ASSIGN;
1555 MAC_ASSIGN(peer, peer); 1578 MAC_ASSIGN(peer, peer);
1556 ), 1579 ),
1557 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT, 1580 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT,
1558 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer)) 1581 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer))
1559); 1582);
1560 1583
@@ -1573,25 +1596,22 @@ DEFINE_EVENT(rdev_pmksa, rdev_del_pmksa,
1573TRACE_EVENT(rdev_remain_on_channel, 1596TRACE_EVENT(rdev_remain_on_channel,
1574 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, 1597 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
1575 struct ieee80211_channel *chan, 1598 struct ieee80211_channel *chan,
1576 enum nl80211_channel_type channel_type, unsigned int duration), 1599 unsigned int duration),
1577 TP_ARGS(wiphy, wdev, chan, channel_type, duration), 1600 TP_ARGS(wiphy, wdev, chan, duration),
1578 TP_STRUCT__entry( 1601 TP_STRUCT__entry(
1579 WIPHY_ENTRY 1602 WIPHY_ENTRY
1580 WDEV_ENTRY 1603 WDEV_ENTRY
1581 CHAN_ENTRY 1604 CHAN_ENTRY
1582 __field(enum nl80211_channel_type, channel_type)
1583 __field(unsigned int, duration) 1605 __field(unsigned int, duration)
1584 ), 1606 ),
1585 TP_fast_assign( 1607 TP_fast_assign(
1586 WIPHY_ASSIGN; 1608 WIPHY_ASSIGN;
1587 WDEV_ASSIGN; 1609 WDEV_ASSIGN;
1588 CHAN_ASSIGN(chan); 1610 CHAN_ASSIGN(chan);
1589 __entry->channel_type = channel_type;
1590 __entry->duration = duration; 1611 __entry->duration = duration;
1591 ), 1612 ),
1592 TP_printk(WIPHY_PR_FMT WDEV_PR_FMT CHAN_PR_FMT ", channel type: %d, duration: %u", 1613 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", duration: %u",
1593 WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG, __entry->channel_type, 1614 WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG, __entry->duration)
1594 __entry->duration)
1595); 1615);
1596 1616
1597TRACE_EVENT(rdev_return_int_cookie, 1617TRACE_EVENT(rdev_return_int_cookie,
@@ -1624,25 +1644,20 @@ TRACE_EVENT(rdev_cancel_remain_on_channel,
1624 WDEV_ASSIGN; 1644 WDEV_ASSIGN;
1625 __entry->cookie = cookie; 1645 __entry->cookie = cookie;
1626 ), 1646 ),
1627 TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", cookie: %llu", 1647 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", cookie: %llu",
1628 WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie) 1648 WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie)
1629); 1649);
1630 1650
1631TRACE_EVENT(rdev_mgmt_tx, 1651TRACE_EVENT(rdev_mgmt_tx,
1632 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, 1652 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
1633 struct ieee80211_channel *chan, bool offchan, 1653 struct ieee80211_channel *chan, bool offchan,
1634 enum nl80211_channel_type channel_type, 1654 unsigned int wait, bool no_cck, bool dont_wait_for_ack),
1635 bool channel_type_valid, unsigned int wait, bool no_cck, 1655 TP_ARGS(wiphy, wdev, chan, offchan, wait, no_cck, dont_wait_for_ack),
1636 bool dont_wait_for_ack),
1637 TP_ARGS(wiphy, wdev, chan, offchan, channel_type, channel_type_valid,
1638 wait, no_cck, dont_wait_for_ack),
1639 TP_STRUCT__entry( 1656 TP_STRUCT__entry(
1640 WIPHY_ENTRY 1657 WIPHY_ENTRY
1641 WDEV_ENTRY 1658 WDEV_ENTRY
1642 CHAN_ENTRY 1659 CHAN_ENTRY
1643 __field(bool, offchan) 1660 __field(bool, offchan)
1644 __field(enum nl80211_channel_type, channel_type)
1645 __field(bool, channel_type_valid)
1646 __field(unsigned int, wait) 1661 __field(unsigned int, wait)
1647 __field(bool, no_cck) 1662 __field(bool, no_cck)
1648 __field(bool, dont_wait_for_ack) 1663 __field(bool, dont_wait_for_ack)
@@ -1652,18 +1667,14 @@ TRACE_EVENT(rdev_mgmt_tx,
1652 WDEV_ASSIGN; 1667 WDEV_ASSIGN;
1653 CHAN_ASSIGN(chan); 1668 CHAN_ASSIGN(chan);
1654 __entry->offchan = offchan; 1669 __entry->offchan = offchan;
1655 __entry->channel_type = channel_type;
1656 __entry->channel_type_valid = channel_type_valid;
1657 __entry->wait = wait; 1670 __entry->wait = wait;
1658 __entry->no_cck = no_cck; 1671 __entry->no_cck = no_cck;
1659 __entry->dont_wait_for_ack = dont_wait_for_ack; 1672 __entry->dont_wait_for_ack = dont_wait_for_ack;
1660 ), 1673 ),
1661 TP_printk(WIPHY_PR_FMT WDEV_PR_FMT CHAN_PR_FMT ", offchan: %s, " 1674 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", offchan: %s,"
1662 "channel type: %d, channel type valid: %s, wait: %u, " 1675 " wait: %u, no cck: %s, dont wait for ack: %s",
1663 "no cck: %s, dont wait for ack: %s",
1664 WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG, 1676 WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG,
1665 BOOL_TO_STR(__entry->offchan), __entry->channel_type, 1677 BOOL_TO_STR(__entry->offchan), __entry->wait,
1666 BOOL_TO_STR(__entry->channel_type_valid), __entry->wait,
1667 BOOL_TO_STR(__entry->no_cck), 1678 BOOL_TO_STR(__entry->no_cck),
1668 BOOL_TO_STR(__entry->dont_wait_for_ack)) 1679 BOOL_TO_STR(__entry->dont_wait_for_ack))
1669); 1680);
@@ -1682,7 +1693,7 @@ TRACE_EVENT(rdev_set_noack_map,
1682 NETDEV_ASSIGN; 1693 NETDEV_ASSIGN;
1683 __entry->noack_map = noack_map; 1694 __entry->noack_map = noack_map;
1684 ), 1695 ),
1685 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", noack_map: %u", 1696 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", noack_map: %u",
1686 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map) 1697 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map)
1687); 1698);
1688 1699
@@ -1699,7 +1710,7 @@ TRACE_EVENT(rdev_get_et_sset_count,
1699 NETDEV_ASSIGN; 1710 NETDEV_ASSIGN;
1700 __entry->sset = sset; 1711 __entry->sset = sset;
1701 ), 1712 ),
1702 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", sset: %d", 1713 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %d",
1703 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset) 1714 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset)
1704); 1715);
1705 1716
@@ -1716,7 +1727,7 @@ TRACE_EVENT(rdev_get_et_strings,
1716 NETDEV_ASSIGN; 1727 NETDEV_ASSIGN;
1717 __entry->sset = sset; 1728 __entry->sset = sset;
1718 ), 1729 ),
1719 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", sset: %u", 1730 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %u",
1720 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset) 1731 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset)
1721); 1732);
1722 1733
@@ -1725,22 +1736,25 @@ DEFINE_EVENT(wiphy_wdev_evt, rdev_get_channel,
1725 TP_ARGS(wiphy, wdev) 1736 TP_ARGS(wiphy, wdev)
1726); 1737);
1727 1738
1728TRACE_EVENT(rdev_return_channel, 1739TRACE_EVENT(rdev_return_chandef,
1729 TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *chan, 1740 TP_PROTO(struct wiphy *wiphy, int ret,
1730 enum nl80211_channel_type type), 1741 struct cfg80211_chan_def *chandef),
1731 TP_ARGS(wiphy, chan, type), 1742 TP_ARGS(wiphy, ret, chandef),
1732 TP_STRUCT__entry( 1743 TP_STRUCT__entry(
1733 WIPHY_ENTRY 1744 WIPHY_ENTRY
1734 CHAN_ENTRY 1745 __field(int, ret)
1735 __field(enum nl80211_channel_type, type) 1746 CHAN_DEF_ENTRY
1736 ), 1747 ),
1737 TP_fast_assign( 1748 TP_fast_assign(
1738 WIPHY_ASSIGN; 1749 WIPHY_ASSIGN;
1739 CHAN_ASSIGN(chan); 1750 if (ret == 0)
1740 __entry->type = type; 1751 CHAN_DEF_ASSIGN(chandef);
1752 else
1753 CHAN_DEF_ASSIGN((struct cfg80211_chan_def *)NULL);
1754 __entry->ret = ret;
1741 ), 1755 ),
1742 TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel type: %d", 1756 TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT ", ret: %d",
1743 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->type) 1757 WIPHY_PR_ARG, CHAN_DEF_PR_ARG, __entry->ret)
1744); 1758);
1745 1759
1746DEFINE_EVENT(wiphy_wdev_evt, rdev_start_p2p_device, 1760DEFINE_EVENT(wiphy_wdev_evt, rdev_start_p2p_device,
@@ -1819,7 +1833,7 @@ TRACE_EVENT(cfg80211_send_rx_assoc,
1819 MAC_ASSIGN(bssid, bss->bssid); 1833 MAC_ASSIGN(bssid, bss->bssid);
1820 CHAN_ASSIGN(bss->channel); 1834 CHAN_ASSIGN(bss->channel);
1821 ), 1835 ),
1822 TP_printk(NETDEV_PR_FMT MAC_PR_FMT CHAN_PR_FMT, 1836 TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", " CHAN_PR_FMT,
1823 NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG) 1837 NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
1824); 1838);
1825 1839
@@ -1886,7 +1900,7 @@ TRACE_EVENT(cfg80211_michael_mic_failure,
1886 __entry->key_id = key_id; 1900 __entry->key_id = key_id;
1887 memcpy(__entry->tsc, tsc, 6); 1901 memcpy(__entry->tsc, tsc, 6);
1888 ), 1902 ),
1889 TP_printk(NETDEV_PR_FMT MAC_PR_FMT ", key type: %d, key id: %d, tsc: %pm", 1903 TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", key type: %d, key id: %d, tsc: %pm",
1890 NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->key_type, 1904 NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->key_type,
1891 __entry->key_id, __entry->tsc) 1905 __entry->key_id, __entry->tsc)
1892); 1906);
@@ -1894,47 +1908,41 @@ TRACE_EVENT(cfg80211_michael_mic_failure,
1894TRACE_EVENT(cfg80211_ready_on_channel, 1908TRACE_EVENT(cfg80211_ready_on_channel,
1895 TP_PROTO(struct wireless_dev *wdev, u64 cookie, 1909 TP_PROTO(struct wireless_dev *wdev, u64 cookie,
1896 struct ieee80211_channel *chan, 1910 struct ieee80211_channel *chan,
1897 enum nl80211_channel_type channel_type, unsigned int duration), 1911 unsigned int duration),
1898 TP_ARGS(wdev, cookie, chan, channel_type, duration), 1912 TP_ARGS(wdev, cookie, chan, duration),
1899 TP_STRUCT__entry( 1913 TP_STRUCT__entry(
1900 WDEV_ENTRY 1914 WDEV_ENTRY
1901 __field(u64, cookie) 1915 __field(u64, cookie)
1902 CHAN_ENTRY 1916 CHAN_ENTRY
1903 __field(enum nl80211_channel_type, channel_type)
1904 __field(unsigned int, duration) 1917 __field(unsigned int, duration)
1905 ), 1918 ),
1906 TP_fast_assign( 1919 TP_fast_assign(
1907 WDEV_ASSIGN; 1920 WDEV_ASSIGN;
1908 __entry->cookie = cookie; 1921 __entry->cookie = cookie;
1909 CHAN_ASSIGN(chan); 1922 CHAN_ASSIGN(chan);
1910 __entry->channel_type = channel_type;
1911 __entry->duration = duration; 1923 __entry->duration = duration;
1912 ), 1924 ),
1913 TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT ", channel type: %d, duration: %u", 1925 TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT ", duration: %u",
1914 WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG, 1926 WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG,
1915 __entry->channel_type, __entry->duration) 1927 __entry->duration)
1916); 1928);
1917 1929
1918TRACE_EVENT(cfg80211_ready_on_channel_expired, 1930TRACE_EVENT(cfg80211_ready_on_channel_expired,
1919 TP_PROTO(struct wireless_dev *wdev, u64 cookie, 1931 TP_PROTO(struct wireless_dev *wdev, u64 cookie,
1920 struct ieee80211_channel *chan, 1932 struct ieee80211_channel *chan),
1921 enum nl80211_channel_type channel_type), 1933 TP_ARGS(wdev, cookie, chan),
1922 TP_ARGS(wdev, cookie, chan, channel_type),
1923 TP_STRUCT__entry( 1934 TP_STRUCT__entry(
1924 WDEV_ENTRY 1935 WDEV_ENTRY
1925 __field(u64, cookie) 1936 __field(u64, cookie)
1926 CHAN_ENTRY 1937 CHAN_ENTRY
1927 __field(enum nl80211_channel_type, channel_type)
1928 ), 1938 ),
1929 TP_fast_assign( 1939 TP_fast_assign(
1930 WDEV_ASSIGN; 1940 WDEV_ASSIGN;
1931 __entry->cookie = cookie; 1941 __entry->cookie = cookie;
1932 CHAN_ASSIGN(chan); 1942 CHAN_ASSIGN(chan);
1933 __entry->channel_type = channel_type;
1934 ), 1943 ),
1935 TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT ", channel type: %d", 1944 TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT,
1936 WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG, 1945 WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG)
1937 __entry->channel_type)
1938); 1946);
1939 1947
1940TRACE_EVENT(cfg80211_new_sta, 1948TRACE_EVENT(cfg80211_new_sta,
@@ -1951,7 +1959,7 @@ TRACE_EVENT(cfg80211_new_sta,
1951 MAC_ASSIGN(mac_addr, mac_addr); 1959 MAC_ASSIGN(mac_addr, mac_addr);
1952 SINFO_ASSIGN; 1960 SINFO_ASSIGN;
1953 ), 1961 ),
1954 TP_printk(NETDEV_PR_FMT MAC_PR_FMT, 1962 TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT,
1955 NETDEV_PR_ARG, MAC_PR_ARG(mac_addr)) 1963 NETDEV_PR_ARG, MAC_PR_ARG(mac_addr))
1956); 1964);
1957 1965
@@ -2010,40 +2018,35 @@ TRACE_EVENT(cfg80211_cqm_rssi_notify,
2010 NETDEV_PR_ARG, __entry->rssi_event) 2018 NETDEV_PR_ARG, __entry->rssi_event)
2011); 2019);
2012 2020
2013TRACE_EVENT(cfg80211_can_beacon_sec_chan, 2021TRACE_EVENT(cfg80211_reg_can_beacon,
2014 TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, 2022 TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef),
2015 enum nl80211_channel_type channel_type), 2023 TP_ARGS(wiphy, chandef),
2016 TP_ARGS(wiphy, channel, channel_type),
2017 TP_STRUCT__entry( 2024 TP_STRUCT__entry(
2018 WIPHY_ENTRY 2025 WIPHY_ENTRY
2019 CHAN_ENTRY 2026 CHAN_DEF_ENTRY
2020 __field(enum nl80211_channel_type, channel_type)
2021 ), 2027 ),
2022 TP_fast_assign( 2028 TP_fast_assign(
2023 WIPHY_ASSIGN; 2029 WIPHY_ASSIGN;
2024 CHAN_ASSIGN(channel); 2030 CHAN_DEF_ASSIGN(chandef);
2025 __entry->channel_type = channel_type;
2026 ), 2031 ),
2027 TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel_type: %d", 2032 TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
2028 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->channel_type) 2033 WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
2029); 2034);
2030 2035
2031TRACE_EVENT(cfg80211_ch_switch_notify, 2036TRACE_EVENT(cfg80211_ch_switch_notify,
2032 TP_PROTO(struct net_device *netdev, int freq, 2037 TP_PROTO(struct net_device *netdev,
2033 enum nl80211_channel_type type), 2038 struct cfg80211_chan_def *chandef),
2034 TP_ARGS(netdev, freq, type), 2039 TP_ARGS(netdev, chandef),
2035 TP_STRUCT__entry( 2040 TP_STRUCT__entry(
2036 NETDEV_ENTRY 2041 NETDEV_ENTRY
2037 __field(int, freq) 2042 CHAN_DEF_ENTRY
2038 __field(enum nl80211_channel_type, type)
2039 ), 2043 ),
2040 TP_fast_assign( 2044 TP_fast_assign(
2041 NETDEV_ASSIGN; 2045 NETDEV_ASSIGN;
2042 __entry->freq = freq; 2046 CHAN_DEF_ASSIGN(chandef);
2043 __entry->type = type;
2044 ), 2047 ),
2045 TP_printk(NETDEV_PR_FMT ", freq: %d, type: %d", NETDEV_PR_ARG, 2048 TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT,
2046 __entry->freq, __entry->type) 2049 NETDEV_PR_ARG, CHAN_DEF_PR_ARG)
2047); 2050);
2048 2051
2049DECLARE_EVENT_CLASS(cfg80211_rx_evt, 2052DECLARE_EVENT_CLASS(cfg80211_rx_evt,
@@ -2057,7 +2060,7 @@ DECLARE_EVENT_CLASS(cfg80211_rx_evt,
2057 NETDEV_ASSIGN; 2060 NETDEV_ASSIGN;
2058 MAC_ASSIGN(addr, addr); 2061 MAC_ASSIGN(addr, addr);
2059 ), 2062 ),
2060 TP_printk(NETDEV_PR_FMT MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr)) 2063 TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr))
2061); 2064);
2062 2065
2063DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined, 2066DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined,
@@ -2091,7 +2094,7 @@ TRACE_EVENT(cfg80211_probe_status,
2091 __entry->cookie = cookie; 2094 __entry->cookie = cookie;
2092 __entry->acked = acked; 2095 __entry->acked = acked;
2093 ), 2096 ),
2094 TP_printk(NETDEV_PR_FMT MAC_PR_FMT ", cookie: %llu, acked: %s", 2097 TP_printk(NETDEV_PR_FMT " addr:" MAC_PR_FMT ", cookie: %llu, acked: %s",
2095 NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->cookie, 2098 NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->cookie,
2096 BOOL_TO_STR(__entry->acked)) 2099 BOOL_TO_STR(__entry->acked))
2097); 2100);
@@ -2241,7 +2244,7 @@ TRACE_EVENT(cfg80211_get_bss,
2241 __entry->capa_mask = capa_mask; 2244 __entry->capa_mask = capa_mask;
2242 __entry->capa_val = capa_val; 2245 __entry->capa_val = capa_val;
2243 ), 2246 ),
2244 TP_printk(WIPHY_PR_FMT CHAN_PR_FMT MAC_PR_FMT ", buf: %#.2x, " 2247 TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT ", " MAC_PR_FMT ", buf: %#.2x, "
2245 "capa_mask: %d, capa_val: %u", WIPHY_PR_ARG, CHAN_PR_ARG, 2248 "capa_mask: %d, capa_val: %u", WIPHY_PR_ARG, CHAN_PR_ARG,
2246 MAC_PR_ARG(bssid), ((u8 *)__get_dynamic_array(ssid))[0], 2249 MAC_PR_ARG(bssid), ((u8 *)__get_dynamic_array(ssid))[0],
2247 __entry->capa_mask, __entry->capa_val) 2250 __entry->capa_mask, __entry->capa_val)
@@ -2265,7 +2268,7 @@ TRACE_EVENT(cfg80211_inform_bss_frame,
2265 memcpy(__get_dynamic_array(mgmt), mgmt, len); 2268 memcpy(__get_dynamic_array(mgmt), mgmt, len);
2266 __entry->signal = signal; 2269 __entry->signal = signal;
2267 ), 2270 ),
2268 TP_printk(WIPHY_PR_FMT CHAN_PR_FMT "signal: %d", 2271 TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT "signal: %d",
2269 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->signal) 2272 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->signal)
2270); 2273);
2271 2274
@@ -2280,7 +2283,7 @@ DECLARE_EVENT_CLASS(cfg80211_bss_evt,
2280 MAC_ASSIGN(bssid, pub->bssid); 2283 MAC_ASSIGN(bssid, pub->bssid);
2281 CHAN_ASSIGN(pub->channel); 2284 CHAN_ASSIGN(pub->channel);
2282 ), 2285 ),
2283 TP_printk(MAC_PR_FMT CHAN_PR_FMT, MAC_PR_ARG(bssid), CHAN_PR_ARG) 2286 TP_printk(MAC_PR_FMT ", " CHAN_PR_FMT, MAC_PR_ARG(bssid), CHAN_PR_ARG)
2284); 2287);
2285 2288
2286DEFINE_EVENT(cfg80211_bss_evt, cfg80211_return_bss, 2289DEFINE_EVENT(cfg80211_bss_evt, cfg80211_return_bss,
diff --git a/net/wireless/util.c b/net/wireless/util.c
index b99f01cda1f6..3cce6e486219 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -944,14 +944,86 @@ static u32 cfg80211_calculate_bitrate_60g(struct rate_info *rate)
944 return __mcs2bitrate[rate->mcs]; 944 return __mcs2bitrate[rate->mcs];
945} 945}
946 946
947static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate)
948{
949 static const u32 base[4][10] = {
950 { 6500000,
951 13000000,
952 19500000,
953 26000000,
954 39000000,
955 52000000,
956 58500000,
957 65000000,
958 78000000,
959 0,
960 },
961 { 13500000,
962 27000000,
963 40500000,
964 54000000,
965 81000000,
966 108000000,
967 121500000,
968 135000000,
969 162000000,
970 180000000,
971 },
972 { 29300000,
973 58500000,
974 87800000,
975 117000000,
976 175500000,
977 234000000,
978 263300000,
979 292500000,
980 351000000,
981 390000000,
982 },
983 { 58500000,
984 117000000,
985 175500000,
986 234000000,
987 351000000,
988 468000000,
989 526500000,
990 585000000,
991 702000000,
992 780000000,
993 },
994 };
995 u32 bitrate;
996 int idx;
997
998 if (WARN_ON_ONCE(rate->mcs > 9))
999 return 0;
1000
1001 idx = rate->flags & (RATE_INFO_FLAGS_160_MHZ_WIDTH |
1002 RATE_INFO_FLAGS_80P80_MHZ_WIDTH) ? 3 :
1003 rate->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH ? 2 :
1004 rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH ? 1 : 0;
1005
1006 bitrate = base[idx][rate->mcs];
1007 bitrate *= rate->nss;
1008
1009 if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
1010 bitrate = (bitrate / 9) * 10;
1011
1012 /* do NOT round down here */
1013 return (bitrate + 50000) / 100000;
1014}
1015
947u32 cfg80211_calculate_bitrate(struct rate_info *rate) 1016u32 cfg80211_calculate_bitrate(struct rate_info *rate)
948{ 1017{
949 int modulation, streams, bitrate; 1018 int modulation, streams, bitrate;
950 1019
951 if (!(rate->flags & RATE_INFO_FLAGS_MCS)) 1020 if (!(rate->flags & RATE_INFO_FLAGS_MCS) &&
1021 !(rate->flags & RATE_INFO_FLAGS_VHT_MCS))
952 return rate->legacy; 1022 return rate->legacy;
953 if (rate->flags & RATE_INFO_FLAGS_60G) 1023 if (rate->flags & RATE_INFO_FLAGS_60G)
954 return cfg80211_calculate_bitrate_60g(rate); 1024 return cfg80211_calculate_bitrate_60g(rate);
1025 if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
1026 return cfg80211_calculate_bitrate_vht(rate);
955 1027
956 /* the formula below does only work for MCS values smaller than 32 */ 1028 /* the formula below does only work for MCS values smaller than 32 */
957 if (WARN_ON_ONCE(rate->mcs >= 32)) 1029 if (WARN_ON_ONCE(rate->mcs >= 32))
@@ -980,8 +1052,9 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate)
980} 1052}
981EXPORT_SYMBOL(cfg80211_calculate_bitrate); 1053EXPORT_SYMBOL(cfg80211_calculate_bitrate);
982 1054
983unsigned int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len, 1055int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
984 u8 attr, u8 *buf, unsigned int bufsize) 1056 enum ieee80211_p2p_attr_id attr,
1057 u8 *buf, unsigned int bufsize)
985{ 1058{
986 u8 *out = buf; 1059 u8 *out = buf;
987 u16 attr_remaining = 0; 1060 u16 attr_remaining = 0;
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 742ab6ec4c9d..f9680c9cf9b3 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -784,6 +784,9 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
784{ 784{
785 struct wireless_dev *wdev = dev->ieee80211_ptr; 785 struct wireless_dev *wdev = dev->ieee80211_ptr;
786 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 786 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
787 struct cfg80211_chan_def chandef = {
788 .width = NL80211_CHAN_WIDTH_20_NOHT,
789 };
787 int freq, err; 790 int freq, err;
788 791
789 switch (wdev->iftype) { 792 switch (wdev->iftype) {
@@ -797,8 +800,12 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
797 return freq; 800 return freq;
798 if (freq == 0) 801 if (freq == 0)
799 return -EINVAL; 802 return -EINVAL;
803 chandef.center_freq1 = freq;
804 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
805 if (!chandef.chan)
806 return -EINVAL;
800 mutex_lock(&rdev->devlist_mtx); 807 mutex_lock(&rdev->devlist_mtx);
801 err = cfg80211_set_monitor_channel(rdev, freq, NL80211_CHAN_NO_HT); 808 err = cfg80211_set_monitor_channel(rdev, &chandef);
802 mutex_unlock(&rdev->devlist_mtx); 809 mutex_unlock(&rdev->devlist_mtx);
803 return err; 810 return err;
804 case NL80211_IFTYPE_MESH_POINT: 811 case NL80211_IFTYPE_MESH_POINT:
@@ -807,9 +814,12 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
807 return freq; 814 return freq;
808 if (freq == 0) 815 if (freq == 0)
809 return -EINVAL; 816 return -EINVAL;
817 chandef.center_freq1 = freq;
818 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
819 if (!chandef.chan)
820 return -EINVAL;
810 mutex_lock(&rdev->devlist_mtx); 821 mutex_lock(&rdev->devlist_mtx);
811 err = cfg80211_set_mesh_freq(rdev, wdev, freq, 822 err = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
812 NL80211_CHAN_NO_HT);
813 mutex_unlock(&rdev->devlist_mtx); 823 mutex_unlock(&rdev->devlist_mtx);
814 return err; 824 return err;
815 default: 825 default:
@@ -823,8 +833,8 @@ static int cfg80211_wext_giwfreq(struct net_device *dev,
823{ 833{
824 struct wireless_dev *wdev = dev->ieee80211_ptr; 834 struct wireless_dev *wdev = dev->ieee80211_ptr;
825 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 835 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
826 struct ieee80211_channel *chan; 836 struct cfg80211_chan_def chandef;
827 enum nl80211_channel_type channel_type; 837 int ret;
828 838
829 switch (wdev->iftype) { 839 switch (wdev->iftype) {
830 case NL80211_IFTYPE_STATION: 840 case NL80211_IFTYPE_STATION:
@@ -835,10 +845,10 @@ static int cfg80211_wext_giwfreq(struct net_device *dev,
835 if (!rdev->ops->get_channel) 845 if (!rdev->ops->get_channel)
836 return -EINVAL; 846 return -EINVAL;
837 847
838 chan = rdev_get_channel(rdev, wdev, &channel_type); 848 ret = rdev_get_channel(rdev, wdev, &chandef);
839 if (!chan) 849 if (ret)
840 return -EINVAL; 850 return ret;
841 freq->m = chan->center_freq; 851 freq->m = chandef.chan->center_freq;
842 freq->e = 6; 852 freq->e = 6;
843 return 0; 853 return 0;
844 default: 854 default:
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 1f773f668d1a..873af63187c0 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -119,7 +119,16 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
119 * channel we disconnected above and reconnect below. 119 * channel we disconnected above and reconnect below.
120 */ 120 */
121 if (chan && !wdev->wext.connect.ssid_len) { 121 if (chan && !wdev->wext.connect.ssid_len) {
122 err = cfg80211_set_monitor_channel(rdev, freq, NL80211_CHAN_NO_HT); 122 struct cfg80211_chan_def chandef = {
123 .width = NL80211_CHAN_WIDTH_20_NOHT,
124 .center_freq1 = freq,
125 };
126
127 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
128 if (chandef.chan)
129 err = cfg80211_set_monitor_channel(rdev, &chandef);
130 else
131 err = -EINVAL;
123 goto out; 132 goto out;
124 } 133 }
125 134