diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-11-26 14:46:41 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-11-26 14:46:41 -0500 |
commit | 62c8003ecb973986958e9dade4a7e598349caf48 (patch) | |
tree | 0e831639cd6449c2955234cfc37ef46481c788d1 | |
parent | e4cb3ff9311e0817e65cda7bc53898348aab7527 (diff) | |
parent | ec816087e8978b74c1bd5fae0e335dd97d964e9f (diff) |
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
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: | |||
1074 | void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, | 1074 | void 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 | ||
1088 | static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | 1091 | static 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, | |||
3006 | static int ath6kl_remain_on_channel(struct wiphy *wiphy, | 3010 | static 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 | ||
3166 | static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | 3169 | static 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: | |||
1037 | static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | 1037 | static 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 | ||
438 | static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy, | 438 | static 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) | |||
1455 | static int mac80211_hwsim_roc(struct ieee80211_hw *hw, | 1448 | static 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 | ||
1506 | static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw, | 1500 | static 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 | ||
1524 | static int mac80211_hwsim_assign_vif_chanctx(struct ieee80211_hw *hw, | 1522 | static 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) | |||
180 | static int | 180 | static int |
181 | mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | 181 | mwifiex_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 | |||
253 | mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy, | 251 | mwifiex_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(¶ms->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(¶ms->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(¶ms->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(¶ms->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(¶ms->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); | ||
1769 | done: | 1769 | done: |
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 { | |||
371 | struct mwifiex_roc_cfg { | 371 | struct 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 | ||
377 | struct mwifiex_adapter; | 376 | struct mwifiex_adapter; |
@@ -1018,7 +1017,6 @@ int mwifiex_get_ver_ext(struct mwifiex_private *priv); | |||
1018 | 1017 | ||
1019 | int mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action, | 1018 | int 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 | ||
1024 | int mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role); | 1022 | int 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) | |||
1044 | int | 1044 | int |
1045 | mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action, | 1045 | mwifiex_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 | ||
163 | static int orinoco_set_monitor_channel(struct wiphy *wiphy, | 163 | static 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 | */ | ||
679 | enum 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 | */ |
1157 | struct ieee80211_vht_mcs_info { | 1174 | struct 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 | */ | ||
1195 | enum 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 | */ | ||
316 | struct 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 | */ | ||
330 | static inline enum nl80211_channel_type | ||
331 | cfg80211_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 | */ | ||
356 | void 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 | */ | ||
368 | static inline bool | ||
369 | cfg80211_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 | */ | ||
386 | const struct cfg80211_chan_def * | ||
387 | cfg80211_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 | */ |
443 | struct cfg80211_ap_settings { | 524 | struct 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 | */ |
590 | enum rate_info_flags { | 674 | enum 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 | */ |
606 | struct rate_info { | 695 | struct 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 | */ |
927 | struct mesh_setup { | 1016 | struct 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 { | |||
1285 | struct cfg80211_ibss_params { | 1372 | struct 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 | */ |
3358 | void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie, | 3437 | void 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 | */ |
3371 | void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie, | 3448 | void 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 | */ |
3581 | bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, | 3656 | bool 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 | */ |
3593 | void cfg80211_ch_switch_notify(struct net_device *dev, int freq, | 3666 | void 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 | */ |
3655 | unsigned int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len, | 3728 | int 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 | */ |
151 | enum ieee80211_chanctx_change { | 151 | enum 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 | */ |
172 | struct ieee80211_chanctx_conf { | 171 | struct 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 | */ |
564 | struct ieee80211_tx_rate { | 569 | struct 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 | |||
577 | static 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 | |||
585 | static inline u8 | ||
586 | ieee80211_rate_get_vht_mcs(const struct ieee80211_tx_rate *rate) | ||
587 | { | ||
588 | return rate->idx & 0xF; | ||
589 | } | ||
590 | |||
591 | static inline u8 | ||
592 | ieee80211_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 | */ |
1728 | enum nl80211_rate_info { | 1748 | enum 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 | */ | ||
2443 | enum nl80211_channel_type { | 2477 | enum 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 | */ | ||
2501 | enum 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 | ||
373 | static 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 | |||
385 | void sta_set_rate_info_tx(struct sta_info *sta, | 373 | void 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 | ||
399 | static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | 401 | static 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 | ||
737 | static int ieee80211_set_monitor_channel(struct wiphy *wiphy, | 758 | static 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, ¶ms->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, | |||
2236 | static int ieee80211_start_roc_work(struct ieee80211_local *local, | 2256 | static 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, | |||
2417 | static int ieee80211_remain_on_channel(struct wiphy *wiphy, | 2433 | static 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 | ||
2520 | static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | 2535 | static 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 | ||
3127 | static struct ieee80211_channel * | 3136 | static int ieee80211_cfg_get_channel(struct wiphy *wiphy, |
3128 | ieee80211_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 | ||
11 | static bool | 11 | static void ieee80211_change_chandef(struct ieee80211_local *local, |
12 | ieee80211_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 | |||
53 | static 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 | ||
69 | static struct ieee80211_chanctx * | 29 | static struct ieee80211_chanctx * |
70 | ieee80211_find_chanctx(struct ieee80211_local *local, | 30 | ieee80211_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 | ||
105 | static struct ieee80211_chanctx * | 59 | static struct ieee80211_chanctx * |
106 | ieee80211_new_chanctx(struct ieee80211_local *local, | 60 | ieee80211_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 | ||
181 | static enum nl80211_channel_type | 134 | static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, |
182 | ieee80211_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 | |||
207 | static 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 | ||
218 | static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata, | 167 | static 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 | ||
339 | int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, | 288 | int 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 | ||
169 | IEEE80211_IF_FILE(flags, flags, HEX); | 169 | IEEE80211_IF_FILE(flags, flags, HEX); |
170 | IEEE80211_IF_FILE(state, state, LHEX); | 170 | IEEE80211_IF_FILE(state, state, LHEX); |
171 | IEEE80211_IF_FILE(channel_type, vif.bss_conf.channel_type, DEC); | ||
172 | IEEE80211_IF_FILE(txpower, vif.bss_conf.txpower, DEC); | 171 | IEEE80211_IF_FILE(txpower, vif.bss_conf.txpower, DEC); |
173 | IEEE80211_IF_FILE(ap_power_level, ap_power_level, DEC); | 172 | IEEE80211_IF_FILE(ap_power_level, ap_power_level, DEC); |
174 | IEEE80211_IF_FILE(user_power_level, user_power_level, DEC); | 173 | IEEE80211_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, | |||
738 | static inline int drv_remain_on_channel(struct ieee80211_local *local, | 738 | static 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(¶ms->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 | ||
1165 | static inline struct ieee80211_sub_if_data * | 1162 | static 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); | |||
1607 | u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, | 1604 | u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, |
1608 | u16 cap); | 1605 | u16 cap); |
1609 | u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, | 1606 | u8 *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); |
1613 | u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, | 1609 | u8 *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 */ |
1623 | enum nl80211_channel_type | 1619 | void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan, |
1624 | ieee80211_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 | ||
1626 | int __must_check | 1623 | int __must_check |
1627 | ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, | 1624 | ieee80211_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); |
1631 | void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); | 1627 | void 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: | |||
129 | bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie) | 123 | bool 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 | */ | ||
29 | enum 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) | |||
570 | void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, | 569 | void 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 { | |||
43 | static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie) | 43 | static 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 | ||
49 | void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata) | 49 | void 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 | ||
1544 | void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | 1547 | void 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, | |||
62 | static inline int should_drop_frame(struct sk_buff *skb, int present_fcs_len) | 62 | static 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 | ||
1875 | u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, | 1875 | u8 *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 | ||
1915 | enum nl80211_channel_type | 1916 | void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan, |
1916 | ieee80211_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 | ||
1940 | int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, | 1945 | int 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 | */ | ||
163 | void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, | 169 | void 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 | ||
14 | struct ieee80211_channel * | 14 | void cfg80211_chandef_create(struct cfg80211_chan_def *chandef, |
15 | rdev_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 | } | ||
45 | EXPORT_SYMBOL(cfg80211_chandef_create); | ||
26 | 46 | ||
27 | if (channel_type == NL80211_CHAN_HT40MINUS && | 47 | bool 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 | ||
49 | bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, | 109 | static 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 | |||
145 | const struct cfg80211_chan_def * | ||
146 | cfg80211_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 | } | ||
188 | EXPORT_SYMBOL(cfg80211_chandef_compatible); | ||
189 | |||
190 | bool 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 | |||
208 | static 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 | |||
218 | bool 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 | } |
87 | EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan); | 261 | EXPORT_SYMBOL(cfg80211_reg_can_beacon); |
88 | 262 | ||
89 | int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, | 263 | int 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 | ||
106 | void | 274 | void |
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); |
310 | int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, | 310 | int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, |
311 | struct net_device *dev); | 311 | struct net_device *dev); |
312 | int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, | 312 | int 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 */ |
317 | int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, | 317 | int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, |
@@ -378,10 +378,8 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev); | |||
378 | int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | 378 | int 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); | ||
385 | void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa, | 383 | void 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 | ||
475 | struct ieee80211_channel * | ||
476 | rdev_freq_to_chan(struct cfg80211_registered_device *rdev, | ||
477 | int freq, enum nl80211_channel_type channel_type); | ||
478 | int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, | 473 | int 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 | ||
481 | int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, | 476 | int 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, | |||
488 | void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, | 483 | void 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 | ||
486 | bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef); | ||
487 | |||
488 | bool 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 | ||
74 | const struct mesh_setup default_mesh_setup = { | 74 | const 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 | ||
191 | int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, | 187 | int 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 | ||
580 | void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie, | 580 | void 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 | } |
593 | EXPORT_SYMBOL(cfg80211_ready_on_channel); | 590 | EXPORT_SYMBOL(cfg80211_ready_on_channel); |
594 | 591 | ||
595 | void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie, | 592 | void 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 | } |
608 | EXPORT_SYMBOL(cfg80211_remain_on_channel_expired); | 602 | EXPORT_SYMBOL(cfg80211_remain_on_channel_expired); |
609 | 603 | ||
@@ -758,10 +752,8 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) | |||
758 | int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | 752 | int 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 | } |
998 | EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); | 989 | EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); |
999 | 990 | ||
1000 | void cfg80211_ch_switch_notify(struct net_device *dev, int freq, | 991 | void 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); | ||
1022 | out: | 1008 | out: |
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 | ||
1363 | static bool nl80211_valid_channel_type(struct genl_info *info, | 1368 | static 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 | ||
1384 | static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, | 1484 | static 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 | ||
1841 | static 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 | |||
1752 | static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags, | 1870 | static 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, ¶ms.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, ¶ms)) | 2741 | } else if (!nl80211_get_ap_channel(rdev, ¶ms)) |
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, ¶ms.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, ¶ms); | 2755 | err = rdev_start_ap(rdev, dev, ¶ms); |
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 | |||
2811 | nla_put_failure: | ||
2812 | return false; | ||
2813 | } | 2939 | } |
2814 | 2940 | ||
2815 | static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, | 2941 | static 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( | |||
8438 | void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev, | 8519 | void 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 | ||
8449 | void nl80211_send_remain_on_channel_cancel( | 8529 | void 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 | ||
8460 | void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, | 8538 | void 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 | ||
8812 | void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, | 8890 | void 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, | |||
76 | void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev, | 76 | void 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); |
81 | void nl80211_send_remain_on_channel_cancel( | 80 | void 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 | ||
87 | void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, | 85 | void 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 | ||
131 | void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, | 129 | void 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 | ||
135 | bool nl80211_unexpected_frame(struct net_device *dev, | 133 | bool 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 | ||
360 | static inline int | 360 | static inline int |
361 | rdev_set_monitor_channel(struct cfg80211_registered_device *rdev, | 361 | rdev_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 | |||
600 | rdev_remain_on_channel(struct cfg80211_registered_device *rdev, | 599 | rdev_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, | |||
626 | static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev, | 623 | static 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 | ||
851 | static inline struct ieee80211_channel | 846 | static inline int |
852 | *rdev_get_channel(struct cfg80211_registered_device *rdev, | 847 | rdev_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 | ||
774 | static struct ieee80211_channel * | ||
775 | cfg80211_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 | |||
774 | struct cfg80211_bss* | 806 | struct cfg80211_bss* |
775 | cfg80211_inform_bss(struct wiphy *wiphy, | 807 | cfg80211_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 | ||
319 | DEFINE_EVENT(wiphy_wdev_evt, rdev_return_wdev, | 344 | DEFINE_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 | ||
516 | DECLARE_EVENT_CLASS(wiphy_netdev_evt, | 541 | DECLARE_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 | ||
530 | DEFINE_EVENT(wiphy_netdev_evt, rdev_stop_ap, | 555 | DEFINE_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 | ||
935 | TRACE_EVENT(rdev_set_monitor_channel, | 960 | TRACE_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 | ||
953 | TRACE_EVENT(rdev_auth, | 976 | TRACE_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, | |||
1573 | TRACE_EVENT(rdev_remain_on_channel, | 1596 | TRACE_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 | ||
1597 | TRACE_EVENT(rdev_return_int_cookie, | 1617 | TRACE_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 | ||
1631 | TRACE_EVENT(rdev_mgmt_tx, | 1651 | TRACE_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 | ||
1728 | TRACE_EVENT(rdev_return_channel, | 1739 | TRACE_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 | ||
1746 | DEFINE_EVENT(wiphy_wdev_evt, rdev_start_p2p_device, | 1760 | DEFINE_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, | |||
1894 | TRACE_EVENT(cfg80211_ready_on_channel, | 1908 | TRACE_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 | ||
1918 | TRACE_EVENT(cfg80211_ready_on_channel_expired, | 1930 | TRACE_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 | ||
1940 | TRACE_EVENT(cfg80211_new_sta, | 1948 | TRACE_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 | ||
2013 | TRACE_EVENT(cfg80211_can_beacon_sec_chan, | 2021 | TRACE_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 | ||
2031 | TRACE_EVENT(cfg80211_ch_switch_notify, | 2036 | TRACE_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 | ||
2049 | DECLARE_EVENT_CLASS(cfg80211_rx_evt, | 2052 | DECLARE_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 | ||
2063 | DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined, | 2066 | DEFINE_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 | ||
2286 | DEFINE_EVENT(cfg80211_bss_evt, cfg80211_return_bss, | 2289 | DEFINE_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 | ||
947 | static 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 | |||
947 | u32 cfg80211_calculate_bitrate(struct rate_info *rate) | 1016 | u32 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 | } |
981 | EXPORT_SYMBOL(cfg80211_calculate_bitrate); | 1053 | EXPORT_SYMBOL(cfg80211_calculate_bitrate); |
982 | 1054 | ||
983 | unsigned int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len, | 1055 | int 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 | ||