aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-11-08 15:25:48 -0500
committerJohannes Berg <johannes.berg@intel.com>2012-11-26 06:42:58 -0500
commit683b6d3b31a51956ea540df00abb0b78894924c1 (patch)
tree558e0f316b56368ab259755cb4eeaeb40331853d
parentfe4b31810c06cc6518fb193efb9b3c3289b55832 (diff)
cfg80211: pass a channel definition struct
Instead of passing a channel pointer and channel type to all functions and driver methods, pass a new channel definition struct. Right now, this struct contains just the control channel and channel type, but for VHT this will change. Also, add a small inline cfg80211_get_chandef_type() so that drivers don't need to use the _type field of the new structure all the time, which will change. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c22
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c11
-rw-r--r--drivers/net/wireless/libertas/cfg.c24
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c30
-rw-r--r--drivers/net/wireless/orinoco/cfg.c11
-rw-r--r--drivers/net/wireless/rndis_wlan.c2
-rw-r--r--include/net/cfg80211.h65
-rw-r--r--net/mac80211/cfg.c43
-rw-r--r--net/mac80211/ibss.c21
-rw-r--r--net/wireless/chan.c59
-rw-r--r--net/wireless/core.h11
-rw-r--r--net/wireless/ibss.c27
-rw-r--r--net/wireless/mesh.c49
-rw-r--r--net/wireless/mlme.c15
-rw-r--r--net/wireless/nl80211.c253
-rw-r--r--net/wireless/nl80211.h4
-rw-r--r--net/wireless/rdev-ops.h22
-rw-r--r--net/wireless/trace.h100
-rw-r--r--net/wireless/wext-compat.c26
-rw-r--r--net/wireless/wext-sme.c10
20 files changed, 403 insertions, 402 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 74091d33ed6c..c0cc2e59fe6c 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1093,15 +1093,20 @@ out:
1093void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, 1093void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
1094 enum wmi_phy_mode mode) 1094 enum wmi_phy_mode mode)
1095{ 1095{
1096 enum nl80211_channel_type type; 1096 struct cfg80211_chan_def chandef;
1097 1097
1098 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, 1098 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1099 "channel switch notify nw_type %d freq %d mode %d\n", 1099 "channel switch notify nw_type %d freq %d mode %d\n",
1100 vif->nw_type, freq, mode); 1100 vif->nw_type, freq, mode);
1101 1101
1102 type = (mode == WMI_11G_HT20) ? NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT; 1102 chandef.chan = ieee80211_get_channel(vif->ar->wiphy, freq);
1103 if (WARN_ON(!chandef.chan))
1104 return;
1105
1106 chandef._type = (mode == WMI_11G_HT20) ?
1107 NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT;
1103 1108
1104 cfg80211_ch_switch_notify(vif->ndev, freq, type); 1109 cfg80211_ch_switch_notify(vif->ndev, &chandef);
1105} 1110}
1106 1111
1107static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, 1112static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
@@ -1613,8 +1618,8 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1613 vif->ssid_len = ibss_param->ssid_len; 1618 vif->ssid_len = ibss_param->ssid_len;
1614 memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len); 1619 memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
1615 1620
1616 if (ibss_param->channel) 1621 if (ibss_param->chandef.chan)
1617 vif->ch_hint = ibss_param->channel->center_freq; 1622 vif->ch_hint = ibss_param->chandef.chan->center_freq;
1618 1623
1619 if (ibss_param->channel_fixed) { 1624 if (ibss_param->channel_fixed) {
1620 /* 1625 /*
@@ -2856,7 +2861,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2856 p.ssid_len = vif->ssid_len; 2861 p.ssid_len = vif->ssid_len;
2857 memcpy(p.ssid, vif->ssid, vif->ssid_len); 2862 memcpy(p.ssid, vif->ssid, vif->ssid_len);
2858 p.dot11_auth_mode = vif->dot11_auth_mode; 2863 p.dot11_auth_mode = vif->dot11_auth_mode;
2859 p.ch = cpu_to_le16(info->channel->center_freq); 2864 p.ch = cpu_to_le16(info->chandef.chan->center_freq);
2860 2865
2861 /* Enable uAPSD support by default */ 2866 /* Enable uAPSD support by default */
2862 res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true); 2867 res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
@@ -2880,8 +2885,9 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2880 return res; 2885 return res;
2881 } 2886 }
2882 2887
2883 if (ath6kl_set_htcap(vif, info->channel->band, 2888 if (ath6kl_set_htcap(vif, info->chandef.chan->band,
2884 info->channel_type != NL80211_CHAN_NO_HT)) 2889 cfg80211_get_chandef_type(&info->chandef)
2890 != NL80211_CHAN_NO_HT))
2885 return -EIO; 2891 return -EIO;
2886 2892
2887 /* 2893 /*
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 904c94121c13..b596ca4f22bd 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -1212,8 +1212,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1212 else 1212 else
1213 WL_CONN("No BSSID specified\n"); 1213 WL_CONN("No BSSID specified\n");
1214 1214
1215 if (params->channel) 1215 if (params->chandef.chan)
1216 WL_CONN("channel: %d\n", params->channel->center_freq); 1216 WL_CONN("channel: %d\n", params->chandef.chan->center_freq);
1217 else 1217 else
1218 WL_CONN("no channel specified\n"); 1218 WL_CONN("no channel specified\n");
1219 1219
@@ -1286,12 +1286,12 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1286 } 1286 }
1287 1287
1288 /* Channel */ 1288 /* Channel */
1289 if (params->channel) { 1289 if (params->chandef.chan) {
1290 u32 target_channel; 1290 u32 target_channel;
1291 1291
1292 cfg->channel = 1292 cfg->channel =
1293 ieee80211_frequency_to_channel( 1293 ieee80211_frequency_to_channel(
1294 params->channel->center_freq); 1294 params->chandef.chan->center_freq);
1295 if (params->channel_fixed) { 1295 if (params->channel_fixed) {
1296 /* adding chanspec */ 1296 /* adding chanspec */
1297 brcmf_ch_to_chanspec(cfg->channel, 1297 brcmf_ch_to_chanspec(cfg->channel,
@@ -3938,7 +3938,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3938 s32 bssidx = 0; 3938 s32 bssidx = 0;
3939 3939
3940 WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n", 3940 WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3941 settings->channel_type, settings->beacon_interval, 3941 cfg80211_get_chandef_type(&settings->chandef),
3942 settings->beacon_interval,
3942 settings->dtim_period); 3943 settings->dtim_period);
3943 WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n", 3944 WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n",
3944 settings->ssid, settings->ssid_len, settings->auth_type, 3945 settings->ssid, settings->ssid_len, settings->auth_type,
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 1c10b542ab23..ec36868f6fc5 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -436,19 +436,19 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
436 */ 436 */
437 437
438static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy, 438static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy,
439 struct ieee80211_channel *channel, 439 struct cfg80211_chan_def *chandef)
440 enum nl80211_channel_type channel_type)
441{ 440{
442 struct lbs_private *priv = wiphy_priv(wiphy); 441 struct lbs_private *priv = wiphy_priv(wiphy);
443 int ret = -ENOTSUPP; 442 int ret = -ENOTSUPP;
444 443
445 lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d", 444 lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d",
446 channel->center_freq, channel_type); 445 chandef->chan->center_freq,
446 cfg80211_get_chandef_type(chandef));
447 447
448 if (channel_type != NL80211_CHAN_NO_HT) 448 if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT)
449 goto out; 449 goto out;
450 450
451 ret = lbs_set_channel(priv, channel->hw_value); 451 ret = lbs_set_channel(priv, chandef->chan->hw_value);
452 452
453 out: 453 out:
454 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 454 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
@@ -1734,7 +1734,7 @@ static void lbs_join_post(struct lbs_private *priv,
1734 /* Fake DS channel IE */ 1734 /* Fake DS channel IE */
1735 *fake++ = WLAN_EID_DS_PARAMS; 1735 *fake++ = WLAN_EID_DS_PARAMS;
1736 *fake++ = 1; 1736 *fake++ = 1;
1737 *fake++ = params->channel->hw_value; 1737 *fake++ = params->chandef.chan->hw_value;
1738 /* Fake IBSS params IE */ 1738 /* Fake IBSS params IE */
1739 *fake++ = WLAN_EID_IBSS_PARAMS; 1739 *fake++ = WLAN_EID_IBSS_PARAMS;
1740 *fake++ = 2; 1740 *fake++ = 2;
@@ -1755,7 +1755,7 @@ static void lbs_join_post(struct lbs_private *priv,
1755 lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie); 1755 lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie);
1756 1756
1757 bss = cfg80211_inform_bss(priv->wdev->wiphy, 1757 bss = cfg80211_inform_bss(priv->wdev->wiphy,
1758 params->channel, 1758 params->chandef.chan,
1759 bssid, 1759 bssid,
1760 0, 1760 0,
1761 capability, 1761 capability,
@@ -1833,7 +1833,7 @@ static int lbs_ibss_join_existing(struct lbs_private *priv,
1833 cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval); 1833 cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval);
1834 cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS; 1834 cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS;
1835 cmd.bss.ds.header.len = 1; 1835 cmd.bss.ds.header.len = 1;
1836 cmd.bss.ds.channel = params->channel->hw_value; 1836 cmd.bss.ds.channel = params->chandef.chan->hw_value;
1837 cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS; 1837 cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS;
1838 cmd.bss.ibss.header.len = 2; 1838 cmd.bss.ibss.header.len = 2;
1839 cmd.bss.ibss.atimwindow = 0; 1839 cmd.bss.ibss.atimwindow = 0;
@@ -1942,7 +1942,7 @@ static int lbs_ibss_start_new(struct lbs_private *priv,
1942 cmd.ibss.atimwindow = 0; 1942 cmd.ibss.atimwindow = 0;
1943 cmd.ds.header.id = WLAN_EID_DS_PARAMS; 1943 cmd.ds.header.id = WLAN_EID_DS_PARAMS;
1944 cmd.ds.header.len = 1; 1944 cmd.ds.header.len = 1;
1945 cmd.ds.channel = params->channel->hw_value; 1945 cmd.ds.channel = params->chandef.chan->hw_value;
1946 /* Only v8 and below support setting probe delay */ 1946 /* Only v8 and below support setting probe delay */
1947 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) 1947 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8)
1948 cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); 1948 cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
@@ -1987,18 +1987,18 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1987 1987
1988 lbs_deb_enter(LBS_DEB_CFG80211); 1988 lbs_deb_enter(LBS_DEB_CFG80211);
1989 1989
1990 if (!params->channel) { 1990 if (!params->chandef.chan) {
1991 ret = -ENOTSUPP; 1991 ret = -ENOTSUPP;
1992 goto out; 1992 goto out;
1993 } 1993 }
1994 1994
1995 ret = lbs_set_channel(priv, params->channel->hw_value); 1995 ret = lbs_set_channel(priv, params->chandef.chan->hw_value);
1996 if (ret) 1996 if (ret)
1997 goto out; 1997 goto out;
1998 1998
1999 /* Search if someone is beaconing. This assumes that the 1999 /* Search if someone is beaconing. This assumes that the
2000 * bss list is populated already */ 2000 * bss list is populated already */
2001 bss = cfg80211_get_bss(wiphy, params->channel, params->bssid, 2001 bss = cfg80211_get_bss(wiphy, params->chandef.chan, params->bssid,
2002 params->ssid, params->ssid_len, 2002 params->ssid, params->ssid_len,
2003 WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); 2003 WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
2004 2004
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index f69190b492aa..42be612faf0f 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1291,21 +1291,23 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1291 return -EINVAL; 1291 return -EINVAL;
1292 } 1292 }
1293 1293
1294 bss_cfg->channel = 1294 bss_cfg->channel = ieee80211_frequency_to_channel(
1295 (u8)ieee80211_frequency_to_channel(params->channel->center_freq); 1295 params->chandef.chan->center_freq);
1296 1296
1297 /* Set appropriate bands */ 1297 /* Set appropriate bands */
1298 if (params->channel->band == IEEE80211_BAND_2GHZ) { 1298 if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
1299 bss_cfg->band_cfg = BAND_CONFIG_BG; 1299 bss_cfg->band_cfg = BAND_CONFIG_BG;
1300 1300
1301 if (params->channel_type == NL80211_CHAN_NO_HT) 1301 if (cfg80211_get_chandef_type(&params->chandef) ==
1302 NL80211_CHAN_NO_HT)
1302 config_bands = BAND_B | BAND_G; 1303 config_bands = BAND_B | BAND_G;
1303 else 1304 else
1304 config_bands = BAND_B | BAND_G | BAND_GN; 1305 config_bands = BAND_B | BAND_G | BAND_GN;
1305 } else { 1306 } else {
1306 bss_cfg->band_cfg = BAND_CONFIG_A; 1307 bss_cfg->band_cfg = BAND_CONFIG_A;
1307 1308
1308 if (params->channel_type == NL80211_CHAN_NO_HT) 1309 if (cfg80211_get_chandef_type(&params->chandef) ==
1310 NL80211_CHAN_NO_HT)
1309 config_bands = BAND_A; 1311 config_bands = BAND_A;
1310 else 1312 else
1311 config_bands = BAND_AN | BAND_A; 1313 config_bands = BAND_AN | BAND_A;
@@ -1678,7 +1680,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
1678 int index = 0, i; 1680 int index = 0, i;
1679 u8 config_bands = 0; 1681 u8 config_bands = 0;
1680 1682
1681 if (params->channel->band == IEEE80211_BAND_2GHZ) { 1683 if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
1682 if (!params->basic_rates) { 1684 if (!params->basic_rates) {
1683 config_bands = BAND_B | BAND_G; 1685 config_bands = BAND_B | BAND_G;
1684 } else { 1686 } else {
@@ -1703,10 +1705,12 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
1703 } 1705 }
1704 } 1706 }
1705 1707
1706 if (params->channel_type != NL80211_CHAN_NO_HT) 1708 if (cfg80211_get_chandef_type(&params->chandef) !=
1709 NL80211_CHAN_NO_HT)
1707 config_bands |= BAND_GN; 1710 config_bands |= BAND_GN;
1708 } else { 1711 } else {
1709 if (params->channel_type == NL80211_CHAN_NO_HT) 1712 if (cfg80211_get_chandef_type(&params->chandef) !=
1713 NL80211_CHAN_NO_HT)
1710 config_bands = BAND_A; 1714 config_bands = BAND_A;
1711 else 1715 else
1712 config_bands = BAND_AN | BAND_A; 1716 config_bands = BAND_AN | BAND_A;
@@ -1723,9 +1727,10 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
1723 } 1727 }
1724 1728
1725 adapter->sec_chan_offset = 1729 adapter->sec_chan_offset =
1726 mwifiex_chan_type_to_sec_chan_offset(params->channel_type); 1730 mwifiex_chan_type_to_sec_chan_offset(
1727 priv->adhoc_channel = 1731 cfg80211_get_chandef_type(&params->chandef));
1728 ieee80211_frequency_to_channel(params->channel->center_freq); 1732 priv->adhoc_channel = ieee80211_frequency_to_channel(
1733 params->chandef.chan->center_freq);
1729 1734
1730 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",
1731 config_bands, priv->adhoc_channel, adapter->sec_chan_offset); 1736 config_bands, priv->adhoc_channel, adapter->sec_chan_offset);
@@ -1759,7 +1764,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1759 1764
1760 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, 1765 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
1761 params->bssid, priv->bss_mode, 1766 params->bssid, priv->bss_mode,
1762 params->channel, NULL, params->privacy); 1767 params->chandef.chan, NULL,
1768 params->privacy);
1763done: 1769done:
1764 if (!ret) { 1770 if (!ret) {
1765 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/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
index 7b751fba7e1f..d01edd2c50c5 100644
--- a/drivers/net/wireless/orinoco/cfg.c
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -161,24 +161,23 @@ static int orinoco_scan(struct wiphy *wiphy,
161} 161}
162 162
163static int orinoco_set_monitor_channel(struct wiphy *wiphy, 163static int orinoco_set_monitor_channel(struct wiphy *wiphy,
164 struct ieee80211_channel *chan, 164 struct cfg80211_chan_def *chandef)
165 enum nl80211_channel_type channel_type)
166{ 165{
167 struct orinoco_private *priv = wiphy_priv(wiphy); 166 struct orinoco_private *priv = wiphy_priv(wiphy);
168 int err = 0; 167 int err = 0;
169 unsigned long flags; 168 unsigned long flags;
170 int channel; 169 int channel;
171 170
172 if (!chan) 171 if (!chandef->chan)
173 return -EINVAL; 172 return -EINVAL;
174 173
175 if (channel_type != NL80211_CHAN_NO_HT) 174 if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT)
176 return -EINVAL; 175 return -EINVAL;
177 176
178 if (chan->band != IEEE80211_BAND_2GHZ) 177 if (chandef->chan->band != IEEE80211_BAND_2GHZ)
179 return -EINVAL; 178 return -EINVAL;
180 179
181 channel = ieee80211_freq_to_dsss_chan(chan->center_freq); 180 channel = ieee80211_freq_to_dsss_chan(chandef->chan->center_freq);
182 181
183 if ((channel < 1) || (channel > NUM_CHANNELS) || 182 if ((channel < 1) || (channel > NUM_CHANNELS) ||
184 !(priv->channel_mask & (1 << (channel - 1)))) 183 !(priv->channel_mask & (1 << (channel - 1))))
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 5390af36c064..abe1d039be81 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -2293,7 +2293,7 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
2293{ 2293{
2294 struct rndis_wlan_private *priv = wiphy_priv(wiphy); 2294 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2295 struct usbnet *usbdev = priv->usbdev; 2295 struct usbnet *usbdev = priv->usbdev;
2296 struct ieee80211_channel *channel = params->channel; 2296 struct ieee80211_channel *channel = params->chandef.chan;
2297 struct ndis_80211_ssid ssid; 2297 struct ndis_80211_ssid ssid;
2298 enum nl80211_auth_type auth_type; 2298 enum nl80211_auth_type auth_type;
2299 int ret, alg, length, chan = -1; 2299 int ret, alg, length, chan = -1;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1effe0682d28..86f777af79e8 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -306,6 +306,23 @@ struct key_params {
306}; 306};
307 307
308/** 308/**
309 * struct cfg80211_chan_def - channel definition
310 * @chan: the (control) channel
311 * @_type: the channel type, don't use this field,
312 * use cfg80211_get_chandef_type() if needed.
313 */
314struct cfg80211_chan_def {
315 struct ieee80211_channel *chan;
316 enum nl80211_channel_type _type;
317};
318
319static inline enum nl80211_channel_type
320cfg80211_get_chandef_type(const struct cfg80211_chan_def *chandef)
321{
322 return chandef->_type;
323}
324
325/**
309 * enum survey_info_flags - survey information flags 326 * enum survey_info_flags - survey information flags
310 * 327 *
311 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in 328 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in
@@ -426,8 +443,7 @@ struct cfg80211_beacon_data {
426 * 443 *
427 * Used to configure an AP interface. 444 * Used to configure an AP interface.
428 * 445 *
429 * @channel: the channel to start the AP on 446 * @chandef: defines the channel to use
430 * @channel_type: the channel type to use
431 * @beacon: beacon data 447 * @beacon: beacon data
432 * @beacon_interval: beacon interval 448 * @beacon_interval: beacon interval
433 * @dtim_period: DTIM period 449 * @dtim_period: DTIM period
@@ -441,8 +457,7 @@ struct cfg80211_beacon_data {
441 * @inactivity_timeout: time in seconds to determine station's inactivity. 457 * @inactivity_timeout: time in seconds to determine station's inactivity.
442 */ 458 */
443struct cfg80211_ap_settings { 459struct cfg80211_ap_settings {
444 struct ieee80211_channel *channel; 460 struct cfg80211_chan_def chandef;
445 enum nl80211_channel_type channel_type;
446 461
447 struct cfg80211_beacon_data beacon; 462 struct cfg80211_beacon_data beacon;
448 463
@@ -909,8 +924,7 @@ struct mesh_config {
909 924
910/** 925/**
911 * struct mesh_setup - 802.11s mesh setup configuration 926 * struct mesh_setup - 802.11s mesh setup configuration
912 * @channel: the channel to start the mesh network on 927 * @chandef: defines the channel to use
913 * @channel_type: the channel type to use
914 * @mesh_id: the mesh ID 928 * @mesh_id: the mesh ID
915 * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes 929 * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes
916 * @sync_method: which synchronization method to use 930 * @sync_method: which synchronization method to use
@@ -925,8 +939,7 @@ struct mesh_config {
925 * These parameters are fixed when the mesh is created. 939 * These parameters are fixed when the mesh is created.
926 */ 940 */
927struct mesh_setup { 941struct mesh_setup {
928 struct ieee80211_channel *channel; 942 struct cfg80211_chan_def chandef;
929 enum nl80211_channel_type channel_type;
930 const u8 *mesh_id; 943 const u8 *mesh_id;
931 u8 mesh_id_len; 944 u8 mesh_id_len;
932 u8 sync_method; 945 u8 sync_method;
@@ -1266,8 +1279,7 @@ struct cfg80211_disassoc_request {
1266 * @ssid_len: The length of the SSID, will always be non-zero. 1279 * @ssid_len: The length of the SSID, will always be non-zero.
1267 * @bssid: Fixed BSSID requested, maybe be %NULL, if set do not 1280 * @bssid: Fixed BSSID requested, maybe be %NULL, if set do not
1268 * search for IBSSs with a different BSSID. 1281 * search for IBSSs with a different BSSID.
1269 * @channel: The channel to use if no IBSS can be found to join. 1282 * @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 1283 * @channel_fixed: The channel should be fixed -- do not search for
1272 * IBSSs to join on other channels. 1284 * IBSSs to join on other channels.
1273 * @ie: information element(s) to include in the beacon 1285 * @ie: information element(s) to include in the beacon
@@ -1285,8 +1297,7 @@ struct cfg80211_disassoc_request {
1285struct cfg80211_ibss_params { 1297struct cfg80211_ibss_params {
1286 u8 *ssid; 1298 u8 *ssid;
1287 u8 *bssid; 1299 u8 *bssid;
1288 struct ieee80211_channel *channel; 1300 struct cfg80211_chan_def chandef;
1289 enum nl80211_channel_type channel_type;
1290 u8 *ie; 1301 u8 *ie;
1291 u8 ssid_len, ie_len; 1302 u8 ssid_len, ie_len;
1292 u16 beacon_interval; 1303 u16 beacon_interval;
@@ -1728,8 +1739,7 @@ struct cfg80211_ops {
1728 struct ieee80211_channel *chan); 1739 struct ieee80211_channel *chan);
1729 1740
1730 int (*set_monitor_channel)(struct wiphy *wiphy, 1741 int (*set_monitor_channel)(struct wiphy *wiphy,
1731 struct ieee80211_channel *chan, 1742 struct cfg80211_chan_def *chandef);
1732 enum nl80211_channel_type channel_type);
1733 1743
1734 int (*scan)(struct wiphy *wiphy, 1744 int (*scan)(struct wiphy *wiphy,
1735 struct cfg80211_scan_request *request); 1745 struct cfg80211_scan_request *request);
@@ -1855,10 +1865,9 @@ struct cfg80211_ops {
1855 void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev, 1865 void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev,
1856 u32 sset, u8 *data); 1866 u32 sset, u8 *data);
1857 1867
1858 struct ieee80211_channel * 1868 int (*get_channel)(struct wiphy *wiphy,
1859 (*get_channel)(struct wiphy *wiphy,
1860 struct wireless_dev *wdev, 1869 struct wireless_dev *wdev,
1861 enum nl80211_channel_type *type); 1870 struct cfg80211_chan_def *chandef);
1862 1871
1863 int (*start_p2p_device)(struct wiphy *wiphy, 1872 int (*start_p2p_device)(struct wiphy *wiphy,
1864 struct wireless_dev *wdev); 1873 struct wireless_dev *wdev);
@@ -2466,8 +2475,7 @@ struct wireless_dev {
2466 spinlock_t event_lock; 2475 spinlock_t event_lock;
2467 2476
2468 struct cfg80211_internal_bss *current_bss; /* associated / joined */ 2477 struct cfg80211_internal_bss *current_bss; /* associated / joined */
2469 struct ieee80211_channel *preset_chan; 2478 struct cfg80211_chan_def preset_chandef;
2470 enum nl80211_channel_type preset_chantype;
2471 2479
2472 /* for AP and mesh channel tracking */ 2480 /* for AP and mesh channel tracking */
2473 struct ieee80211_channel *channel; 2481 struct ieee80211_channel *channel;
@@ -3563,28 +3571,25 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
3563 int freq, int sig_dbm); 3571 int freq, int sig_dbm);
3564 3572
3565/** 3573/**
3566 * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used 3574 * cfg80211_reg_can_beacon - check if beaconing is allowed
3567 * @wiphy: the wiphy 3575 * @wiphy: the wiphy
3568 * @chan: main channel 3576 * @chandef: the channel definition
3569 * @channel_type: HT mode
3570 * 3577 *
3571 * This function returns true if there is no secondary channel or the secondary 3578 * This function returns true if there is no secondary channel or the secondary
3572 * channel can be used for beaconing (i.e. is not a radar channel etc.) 3579 * channel(s) can be used for beaconing (i.e. is not a radar channel etc.)
3573 */ 3580 */
3574bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, 3581bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
3575 struct ieee80211_channel *chan, 3582 struct cfg80211_chan_def *chandef);
3576 enum nl80211_channel_type channel_type);
3577 3583
3578/* 3584/*
3579 * cfg80211_ch_switch_notify - update wdev channel and notify userspace 3585 * cfg80211_ch_switch_notify - update wdev channel and notify userspace
3580 * @dev: the device which switched channels 3586 * @dev: the device which switched channels
3581 * @freq: new channel frequency (in MHz) 3587 * @chandef: the new channel definition
3582 * @type: channel type
3583 * 3588 *
3584 * Acquires wdev_lock, so must only be called from sleepable driver context! 3589 * Acquires wdev_lock, so must only be called from sleepable driver context!
3585 */ 3590 */
3586void cfg80211_ch_switch_notify(struct net_device *dev, int freq, 3591void cfg80211_ch_switch_notify(struct net_device *dev,
3587 enum nl80211_channel_type type); 3592 struct cfg80211_chan_def *chandef);
3588 3593
3589/* 3594/*
3590 * cfg80211_tdls_oper_request - request userspace to perform TDLS operation 3595 * cfg80211_tdls_oper_request - request userspace to perform TDLS operation
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ac0241e3539b..fbb2d072cb9e 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -735,14 +735,16 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
735} 735}
736 736
737static int ieee80211_set_monitor_channel(struct wiphy *wiphy, 737static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
738 struct ieee80211_channel *chan, 738 struct cfg80211_chan_def *chandef)
739 enum nl80211_channel_type channel_type)
740{ 739{
741 struct ieee80211_local *local = wiphy_priv(wiphy); 740 struct ieee80211_local *local = wiphy_priv(wiphy);
742 struct ieee80211_sub_if_data *sdata; 741 struct ieee80211_sub_if_data *sdata;
742 enum nl80211_channel_type channel_type;
743 int ret = 0; 743 int ret = 0;
744 744
745 if (local->monitor_channel == chan && 745 channel_type = cfg80211_get_chandef_type(chandef);
746
747 if (local->monitor_channel == chandef->chan &&
746 local->monitor_channel_type == channel_type) 748 local->monitor_channel_type == channel_type)
747 return 0; 749 return 0;
748 750
@@ -754,17 +756,17 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
754 if (sdata) { 756 if (sdata) {
755 ieee80211_vif_release_channel(sdata); 757 ieee80211_vif_release_channel(sdata);
756 ret = ieee80211_vif_use_channel( 758 ret = ieee80211_vif_use_channel(
757 sdata, chan, channel_type, 759 sdata, chandef->chan, channel_type,
758 IEEE80211_CHANCTX_EXCLUSIVE); 760 IEEE80211_CHANCTX_EXCLUSIVE);
759 } 761 }
760 } else if (local->open_count == local->monitors) { 762 } else if (local->open_count == local->monitors) {
761 local->_oper_channel = chan; 763 local->_oper_channel = chandef->chan;
762 local->_oper_channel_type = channel_type; 764 local->_oper_channel_type = channel_type;
763 ieee80211_hw_config(local, 0); 765 ieee80211_hw_config(local, 0);
764 } 766 }
765 767
766 if (ret == 0) { 768 if (ret == 0) {
767 local->monitor_channel = chan; 769 local->monitor_channel = chandef->chan;
768 local->monitor_channel_type = channel_type; 770 local->monitor_channel_type = channel_type;
769 } 771 }
770 mutex_unlock(&local->iflist_mtx); 772 mutex_unlock(&local->iflist_mtx);
@@ -888,9 +890,10 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
888 sdata->smps_mode = IEEE80211_SMPS_OFF; 890 sdata->smps_mode = IEEE80211_SMPS_OFF;
889 sdata->needed_rx_chains = sdata->local->rx_chains; 891 sdata->needed_rx_chains = sdata->local->rx_chains;
890 892
891 err = ieee80211_vif_use_channel(sdata, params->channel, 893 err = ieee80211_vif_use_channel(
892 params->channel_type, 894 sdata, params->chandef.chan,
893 IEEE80211_CHANCTX_SHARED); 895 cfg80211_get_chandef_type(&params->chandef),
896 IEEE80211_CHANCTX_SHARED);
894 if (err) 897 if (err)
895 return err; 898 return err;
896 899
@@ -1707,9 +1710,10 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
1707 sdata->smps_mode = IEEE80211_SMPS_OFF; 1710 sdata->smps_mode = IEEE80211_SMPS_OFF;
1708 sdata->needed_rx_chains = sdata->local->rx_chains; 1711 sdata->needed_rx_chains = sdata->local->rx_chains;
1709 1712
1710 err = ieee80211_vif_use_channel(sdata, setup->channel, 1713 err = ieee80211_vif_use_channel(
1711 setup->channel_type, 1714 sdata, setup->chandef.chan,
1712 IEEE80211_CHANCTX_SHARED); 1715 cfg80211_get_chandef_type(&setup->chandef),
1716 IEEE80211_CHANCTX_SHARED);
1713 if (err) 1717 if (err)
1714 return err; 1718 return err;
1715 1719
@@ -3110,23 +3114,24 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
3110 return 0; 3114 return 0;
3111} 3115}
3112 3116
3113static struct ieee80211_channel * 3117static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
3114ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, 3118 struct wireless_dev *wdev,
3115 enum nl80211_channel_type *type) 3119 struct cfg80211_chan_def *chandef)
3116{ 3120{
3117 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 3121 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
3118 struct ieee80211_chanctx_conf *chanctx_conf; 3122 struct ieee80211_chanctx_conf *chanctx_conf;
3119 struct ieee80211_channel *chan = NULL; 3123 int ret = -ENODATA;
3120 3124
3121 rcu_read_lock(); 3125 rcu_read_lock();
3122 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 3126 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
3123 if (chanctx_conf) { 3127 if (chanctx_conf) {
3124 *type = chanctx_conf->channel_type; 3128 chandef->chan = chanctx_conf->channel;
3125 chan = chanctx_conf->channel; 3129 chandef->_type = chanctx_conf->channel_type;
3130 ret = 0;
3126 } 3131 }
3127 rcu_read_unlock(); 3132 rcu_read_unlock();
3128 3133
3129 return chan; 3134 return ret;
3130} 3135}
3131 3136
3132#ifdef CONFIG_PM 3137#ifdef CONFIG_PM
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 845973b67a73..bed616fd97e9 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,13 @@ 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 chandef.chan = chan;
83 if (!cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) 83 chandef._type = ifibss->channel_type;
84 channel_type = NL80211_CHAN_HT20; 84 if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef))
85 chandef._type = NL80211_CHAN_HT20;
85 86
86 ieee80211_vif_release_channel(sdata); 87 ieee80211_vif_release_channel(sdata);
87 if (ieee80211_vif_use_channel(sdata, chan, channel_type, 88 if (ieee80211_vif_use_channel(sdata, chan, chandef._type,
88 ifibss->fixed_channel ? 89 ifibss->fixed_channel ?
89 IEEE80211_CHANCTX_SHARED : 90 IEEE80211_CHANCTX_SHARED :
90 IEEE80211_CHANCTX_EXCLUSIVE)) { 91 IEEE80211_CHANCTX_EXCLUSIVE)) {
@@ -158,7 +159,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
158 ifibss->ie, ifibss->ie_len); 159 ifibss->ie, ifibss->ie_len);
159 160
160 /* add HT capability and information IEs */ 161 /* add HT capability and information IEs */
161 if (channel_type && sband->ht_cap.ht_supported) { 162 if (chandef._type != NL80211_CHAN_NO_HT &&
163 sband->ht_cap.ht_supported) {
162 pos = skb_put(skb, 4 + 164 pos = skb_put(skb, 4 +
163 sizeof(struct ieee80211_ht_cap) + 165 sizeof(struct ieee80211_ht_cap) +
164 sizeof(struct ieee80211_ht_operation)); 166 sizeof(struct ieee80211_ht_operation));
@@ -170,7 +172,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
170 * keep them at 0 172 * keep them at 0
171 */ 173 */
172 pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, 174 pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap,
173 chan, channel_type, 0); 175 chan, chandef._type, 0);
174 } 176 }
175 177
176 if (local->hw.queues >= IEEE80211_NUM_ACS) { 178 if (local->hw.queues >= IEEE80211_NUM_ACS) {
@@ -1078,8 +1080,9 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1078 1080
1079 sdata->vif.bss_conf.beacon_int = params->beacon_interval; 1081 sdata->vif.bss_conf.beacon_int = params->beacon_interval;
1080 1082
1081 sdata->u.ibss.channel = params->channel; 1083 sdata->u.ibss.channel = params->chandef.chan;
1082 sdata->u.ibss.channel_type = params->channel_type; 1084 sdata->u.ibss.channel_type =
1085 cfg80211_get_chandef_type(&params->chandef);
1083 sdata->u.ibss.fixed_channel = params->channel_fixed; 1086 sdata->u.ibss.fixed_channel = params->channel_fixed;
1084 1087
1085 if (params->ie) { 1088 if (params->ie) {
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 48febd2160ba..e834422de40a 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -11,51 +11,15 @@
11#include "core.h" 11#include "core.h"
12#include "rdev-ops.h" 12#include "rdev-ops.h"
13 13
14struct ieee80211_channel * 14bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
15rdev_freq_to_chan(struct cfg80211_registered_device *rdev, 15 struct cfg80211_chan_def *chandef)
16 int freq, enum nl80211_channel_type channel_type)
17{
18 struct ieee80211_channel *chan;
19 struct ieee80211_sta_ht_cap *ht_cap;
20
21 chan = ieee80211_get_channel(&rdev->wiphy, freq);
22
23 /* Primary channel not allowed */
24 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
25 return NULL;
26
27 if (channel_type == NL80211_CHAN_HT40MINUS &&
28 chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
29 return NULL;
30 else if (channel_type == NL80211_CHAN_HT40PLUS &&
31 chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
32 return NULL;
33
34 ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
35
36 if (channel_type != NL80211_CHAN_NO_HT) {
37 if (!ht_cap->ht_supported)
38 return NULL;
39
40 if (channel_type != NL80211_CHAN_HT20 &&
41 (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
42 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT))
43 return NULL;
44 }
45
46 return chan;
47}
48
49bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
50 struct ieee80211_channel *chan,
51 enum nl80211_channel_type channel_type)
52{ 16{
53 struct ieee80211_channel *sec_chan; 17 struct ieee80211_channel *sec_chan;
54 int diff; 18 int diff;
55 19
56 trace_cfg80211_can_beacon_sec_chan(wiphy, chan, channel_type); 20 trace_cfg80211_reg_can_beacon(wiphy, chandef);
57 21
58 switch (channel_type) { 22 switch (chandef->_type) {
59 case NL80211_CHAN_HT40PLUS: 23 case NL80211_CHAN_HT40PLUS:
60 diff = 20; 24 diff = 20;
61 break; 25 break;
@@ -67,7 +31,8 @@ bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
67 return true; 31 return true;
68 } 32 }
69 33
70 sec_chan = ieee80211_get_channel(wiphy, chan->center_freq + diff); 34 sec_chan = ieee80211_get_channel(wiphy,
35 chandef->chan->center_freq + diff);
71 if (!sec_chan) { 36 if (!sec_chan) {
72 trace_cfg80211_return_bool(false); 37 trace_cfg80211_return_bool(false);
73 return false; 38 return false;
@@ -84,23 +49,17 @@ bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
84 trace_cfg80211_return_bool(true); 49 trace_cfg80211_return_bool(true);
85 return true; 50 return true;
86} 51}
87EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan); 52EXPORT_SYMBOL(cfg80211_reg_can_beacon);
88 53
89int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, 54int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
90 int freq, enum nl80211_channel_type chantype) 55 struct cfg80211_chan_def *chandef)
91{ 56{
92 struct ieee80211_channel *chan;
93
94 if (!rdev->ops->set_monitor_channel) 57 if (!rdev->ops->set_monitor_channel)
95 return -EOPNOTSUPP; 58 return -EOPNOTSUPP;
96 if (!cfg80211_has_monitors_only(rdev)) 59 if (!cfg80211_has_monitors_only(rdev))
97 return -EBUSY; 60 return -EBUSY;
98 61
99 chan = rdev_freq_to_chan(rdev, freq, chantype); 62 return rdev_set_monitor_channel(rdev, chandef);
100 if (!chan)
101 return -EINVAL;
102
103 return rdev_set_monitor_channel(rdev, chan, chantype);
104} 63}
105 64
106void 65void
diff --git a/net/wireless/core.h b/net/wireless/core.h
index b0a09cf56e06..6183a0d25b8b 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -309,9 +309,9 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
309 const struct mesh_config *conf); 309 const struct mesh_config *conf);
310int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 310int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
311 struct net_device *dev); 311 struct net_device *dev);
312int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, 312int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
313 struct wireless_dev *wdev, int freq, 313 struct wireless_dev *wdev,
314 enum nl80211_channel_type channel_type); 314 struct cfg80211_chan_def *chandef);
315 315
316/* AP */ 316/* AP */
317int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, 317int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
@@ -470,11 +470,8 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
470 struct ieee80211_channel **chan, 470 struct ieee80211_channel **chan,
471 enum cfg80211_chan_mode *chanmode); 471 enum cfg80211_chan_mode *chanmode);
472 472
473struct ieee80211_channel *
474rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
475 int freq, enum nl80211_channel_type channel_type);
476int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, 473int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
477 int freq, enum nl80211_channel_type chantype); 474 struct cfg80211_chan_def *chandef);
478 475
479int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, 476int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
480 const u8 *rates, unsigned int n_rates, 477 const u8 *rates, unsigned int n_rates,
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 27941d5db72b..ccc8865dfadb 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._type = NL80211_CHAN_NO_HT;
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._type = NL80211_CHAN_NO_HT;
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..12b5a570a306 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -73,8 +73,6 @@ const struct mesh_config default_mesh_config = {
73 73
74const struct mesh_setup default_mesh_setup = { 74const struct mesh_setup default_mesh_setup = {
75 /* cfg80211_join_mesh() will pick a channel if needed */ 75 /* cfg80211_join_mesh() will pick a channel if needed */
76 .channel = NULL,
77 .channel_type = NL80211_CHAN_NO_HT,
78 .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, 76 .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET,
79 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, 77 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
80 .path_metric = IEEE80211_PATH_METRIC_AIRTIME, 78 .path_metric = IEEE80211_PATH_METRIC_AIRTIME,
@@ -111,13 +109,12 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
111 if (!rdev->ops->join_mesh) 109 if (!rdev->ops->join_mesh)
112 return -EOPNOTSUPP; 110 return -EOPNOTSUPP;
113 111
114 if (!setup->channel) { 112 if (!setup->chandef.chan) {
115 /* if no channel explicitly given, use preset channel */ 113 /* if no channel explicitly given, use preset channel */
116 setup->channel = wdev->preset_chan; 114 setup->chandef = wdev->preset_chandef;
117 setup->channel_type = wdev->preset_chantype;
118 } 115 }
119 116
120 if (!setup->channel) { 117 if (!setup->chandef.chan) {
121 /* if we don't have that either, use the first usable channel */ 118 /* if we don't have that either, use the first usable channel */
122 enum ieee80211_band band; 119 enum ieee80211_band band;
123 120
@@ -137,26 +134,25 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
137 IEEE80211_CHAN_DISABLED | 134 IEEE80211_CHAN_DISABLED |
138 IEEE80211_CHAN_RADAR)) 135 IEEE80211_CHAN_RADAR))
139 continue; 136 continue;
140 setup->channel = chan; 137 setup->chandef.chan = chan;
141 break; 138 break;
142 } 139 }
143 140
144 if (setup->channel) 141 if (setup->chandef.chan)
145 break; 142 break;
146 } 143 }
147 144
148 /* no usable channel ... */ 145 /* no usable channel ... */
149 if (!setup->channel) 146 if (!setup->chandef.chan)
150 return -EINVAL; 147 return -EINVAL;
151 148
152 setup->channel_type = NL80211_CHAN_NO_HT; 149 setup->chandef._type = NL80211_CHAN_NO_HT;
153 } 150 }
154 151
155 if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, setup->channel, 152 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
156 setup->channel_type))
157 return -EINVAL; 153 return -EINVAL;
158 154
159 err = cfg80211_can_use_chan(rdev, wdev, setup->channel, 155 err = cfg80211_can_use_chan(rdev, wdev, setup->chandef.chan,
160 CHAN_MODE_SHARED); 156 CHAN_MODE_SHARED);
161 if (err) 157 if (err)
162 return err; 158 return err;
@@ -165,7 +161,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
165 if (!err) { 161 if (!err) {
166 memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); 162 memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
167 wdev->mesh_id_len = setup->mesh_id_len; 163 wdev->mesh_id_len = setup->mesh_id_len;
168 wdev->channel = setup->channel; 164 wdev->channel = setup->chandef.chan;
169 } 165 }
170 166
171 return err; 167 return err;
@@ -188,20 +184,12 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
188 return err; 184 return err;
189} 185}
190 186
191int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, 187int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
192 struct wireless_dev *wdev, int freq, 188 struct wireless_dev *wdev,
193 enum nl80211_channel_type channel_type) 189 struct cfg80211_chan_def *chandef)
194{ 190{
195 struct ieee80211_channel *channel;
196 int err; 191 int err;
197 192
198 channel = rdev_freq_to_chan(rdev, freq, channel_type);
199 if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy,
200 channel,
201 channel_type)) {
202 return -EINVAL;
203 }
204
205 /* 193 /*
206 * Workaround for libertas (only!), it puts the interface 194 * Workaround for libertas (only!), it puts the interface
207 * into mesh mode but doesn't implement join_mesh. Instead, 195 * into mesh mode but doesn't implement join_mesh. Instead,
@@ -210,21 +198,21 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
210 * compatible with 802.11 mesh. 198 * compatible with 802.11 mesh.
211 */ 199 */
212 if (rdev->ops->libertas_set_mesh_channel) { 200 if (rdev->ops->libertas_set_mesh_channel) {
213 if (channel_type != NL80211_CHAN_NO_HT) 201 if (chandef->_type != NL80211_CHAN_NO_HT)
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 a9646b53a095..5e8123ee63fd 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -988,15 +988,14 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
988} 988}
989EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); 989EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
990 990
991void cfg80211_ch_switch_notify(struct net_device *dev, int freq, 991void cfg80211_ch_switch_notify(struct net_device *dev,
992 enum nl80211_channel_type type) 992 struct cfg80211_chan_def *chandef)
993{ 993{
994 struct wireless_dev *wdev = dev->ieee80211_ptr; 994 struct wireless_dev *wdev = dev->ieee80211_ptr;
995 struct wiphy *wiphy = wdev->wiphy; 995 struct wiphy *wiphy = wdev->wiphy;
996 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 996 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
997 struct ieee80211_channel *chan;
998 997
999 trace_cfg80211_ch_switch_notify(dev, freq, type); 998 trace_cfg80211_ch_switch_notify(dev, chandef);
1000 999
1001 wdev_lock(wdev); 1000 wdev_lock(wdev);
1002 1001
@@ -1004,12 +1003,8 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
1004 wdev->iftype != NL80211_IFTYPE_P2P_GO)) 1003 wdev->iftype != NL80211_IFTYPE_P2P_GO))
1005 goto out; 1004 goto out;
1006 1005
1007 chan = rdev_freq_to_chan(rdev, freq, type); 1006 wdev->channel = chandef->chan;
1008 if (WARN_ON(!chan)) 1007 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
1009 goto out;
1010
1011 wdev->channel = chan;
1012 nl80211_ch_switch_notify(rdev, dev, freq, type, GFP_KERNEL);
1013out: 1008out:
1014 wdev_unlock(wdev); 1009 wdev_unlock(wdev);
1015 return; 1010 return;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e880f4494950..999108cd947c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1381,30 +1381,82 @@ static bool nl80211_valid_channel_type(struct genl_info *info,
1381 return true; 1381 return true;
1382} 1382}
1383 1383
1384static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
1385 struct genl_info *info,
1386 struct cfg80211_chan_def *chandef)
1387{
1388 struct ieee80211_sta_ht_cap *ht_cap;
1389 struct ieee80211_channel *sc;
1390 u32 control_freq;
1391 int offs;
1392
1393 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
1394 return -EINVAL;
1395
1396 control_freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
1397
1398 chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
1399 chandef->_type = NL80211_CHAN_NO_HT;
1400
1401 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
1402 !nl80211_valid_channel_type(info, &chandef->_type))
1403 return -EINVAL;
1404
1405 /* Primary channel not allowed */
1406 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED)
1407 return -EINVAL;
1408
1409 ht_cap = &rdev->wiphy.bands[chandef->chan->band]->ht_cap;
1410
1411 switch (chandef->_type) {
1412 case NL80211_CHAN_NO_HT:
1413 break;
1414 case NL80211_CHAN_HT40MINUS:
1415 if (chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
1416 return -EINVAL;
1417 offs = -20;
1418 /* fall through */
1419 case NL80211_CHAN_HT40PLUS:
1420 if (chandef->_type == NL80211_CHAN_HT40PLUS) {
1421 if (chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
1422 return -EINVAL;
1423 offs = 20;
1424 }
1425 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
1426 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
1427 return -EINVAL;
1428
1429 sc = ieee80211_get_channel(&rdev->wiphy,
1430 chandef->chan->center_freq + offs);
1431 if (!sc || sc->flags & IEEE80211_CHAN_DISABLED)
1432 return -EINVAL;
1433 /* fall through */
1434 case NL80211_CHAN_HT20:
1435 if (!ht_cap->ht_supported)
1436 return -EINVAL;
1437 break;
1438 }
1439
1440 return 0;
1441}
1442
1384static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, 1443static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1385 struct wireless_dev *wdev, 1444 struct wireless_dev *wdev,
1386 struct genl_info *info) 1445 struct genl_info *info)
1387{ 1446{
1388 struct ieee80211_channel *channel; 1447 struct cfg80211_chan_def chandef;
1389 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
1390 u32 freq;
1391 int result; 1448 int result;
1392 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR; 1449 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
1393 1450
1394 if (wdev) 1451 if (wdev)
1395 iftype = wdev->iftype; 1452 iftype = wdev->iftype;
1396 1453
1397 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
1398 return -EINVAL;
1399
1400 if (!nl80211_can_set_dev_channel(wdev)) 1454 if (!nl80211_can_set_dev_channel(wdev))
1401 return -EOPNOTSUPP; 1455 return -EOPNOTSUPP;
1402 1456
1403 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 1457 result = nl80211_parse_chandef(rdev, info, &chandef);
1404 !nl80211_valid_channel_type(info, &channel_type)) 1458 if (result)
1405 return -EINVAL; 1459 return result;
1406
1407 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
1408 1460
1409 mutex_lock(&rdev->devlist_mtx); 1461 mutex_lock(&rdev->devlist_mtx);
1410 switch (iftype) { 1462 switch (iftype) {
@@ -1414,22 +1466,18 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1414 result = -EBUSY; 1466 result = -EBUSY;
1415 break; 1467 break;
1416 } 1468 }
1417 channel = rdev_freq_to_chan(rdev, freq, channel_type); 1469 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; 1470 result = -EINVAL;
1422 break; 1471 break;
1423 } 1472 }
1424 wdev->preset_chan = channel; 1473 wdev->preset_chandef = chandef;
1425 wdev->preset_chantype = channel_type;
1426 result = 0; 1474 result = 0;
1427 break; 1475 break;
1428 case NL80211_IFTYPE_MESH_POINT: 1476 case NL80211_IFTYPE_MESH_POINT:
1429 result = cfg80211_set_mesh_freq(rdev, wdev, freq, channel_type); 1477 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
1430 break; 1478 break;
1431 case NL80211_IFTYPE_MONITOR: 1479 case NL80211_IFTYPE_MONITOR:
1432 result = cfg80211_set_monitor_channel(rdev, freq, channel_type); 1480 result = cfg80211_set_monitor_channel(rdev, &chandef);
1433 break; 1481 break;
1434 default: 1482 default:
1435 result = -EINVAL; 1483 result = -EINVAL;
@@ -1749,6 +1797,17 @@ static inline u64 wdev_id(struct wireless_dev *wdev)
1749 ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32); 1797 ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32);
1750} 1798}
1751 1799
1800static int nl80211_send_chandef(struct sk_buff *msg,
1801 struct cfg80211_chan_def *chandef)
1802{
1803 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
1804 chandef->chan->center_freq))
1805 return -ENOBUFS;
1806 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, chandef->_type))
1807 return -ENOBUFS;
1808 return 0;
1809}
1810
1752static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags, 1811static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
1753 struct cfg80211_registered_device *rdev, 1812 struct cfg80211_registered_device *rdev,
1754 struct wireless_dev *wdev) 1813 struct wireless_dev *wdev)
@@ -1775,16 +1834,14 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
1775 goto nla_put_failure; 1834 goto nla_put_failure;
1776 1835
1777 if (rdev->ops->get_channel) { 1836 if (rdev->ops->get_channel) {
1778 struct ieee80211_channel *chan; 1837 int ret;
1779 enum nl80211_channel_type channel_type; 1838 struct cfg80211_chan_def chandef;
1780 1839
1781 chan = rdev_get_channel(rdev, wdev, &channel_type); 1840 ret = rdev_get_channel(rdev, wdev, &chandef);
1782 if (chan && 1841 if (ret == 0) {
1783 (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, 1842 if (nl80211_send_chandef(msg, &chandef))
1784 chan->center_freq) || 1843 goto nla_put_failure;
1785 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, 1844 }
1786 channel_type)))
1787 goto nla_put_failure;
1788 } 1845 }
1789 1846
1790 if (wdev->ssid_len) { 1847 if (wdev->ssid_len) {
@@ -2492,11 +2549,10 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
2492 wdev->iftype != NL80211_IFTYPE_P2P_GO) 2549 wdev->iftype != NL80211_IFTYPE_P2P_GO)
2493 continue; 2550 continue;
2494 2551
2495 if (!wdev->preset_chan) 2552 if (!wdev->preset_chandef.chan)
2496 continue; 2553 continue;
2497 2554
2498 params->channel = wdev->preset_chan; 2555 params->chandef = wdev->preset_chandef;
2499 params->channel_type = wdev->preset_chantype;
2500 ret = true; 2556 ret = true;
2501 break; 2557 break;
2502 } 2558 }
@@ -2618,30 +2674,19 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2618 } 2674 }
2619 2675
2620 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 2676 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
2621 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 2677 err = nl80211_parse_chandef(rdev, info, &params.chandef);
2622 2678 if (err)
2623 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 2679 return err;
2624 !nl80211_valid_channel_type(info, &channel_type)) 2680 } else if (wdev->preset_chandef.chan) {
2625 return -EINVAL; 2681 params.chandef = wdev->preset_chandef;
2626
2627 params.channel = rdev_freq_to_chan(rdev,
2628 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
2629 channel_type);
2630 if (!params.channel)
2631 return -EINVAL;
2632 params.channel_type = channel_type;
2633 } else if (wdev->preset_chan) {
2634 params.channel = wdev->preset_chan;
2635 params.channel_type = wdev->preset_chantype;
2636 } else if (!nl80211_get_ap_channel(rdev, &params)) 2682 } else if (!nl80211_get_ap_channel(rdev, &params))
2637 return -EINVAL; 2683 return -EINVAL;
2638 2684
2639 if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel, 2685 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
2640 params.channel_type))
2641 return -EINVAL; 2686 return -EINVAL;
2642 2687
2643 mutex_lock(&rdev->devlist_mtx); 2688 mutex_lock(&rdev->devlist_mtx);
2644 err = cfg80211_can_use_chan(rdev, wdev, params.channel, 2689 err = cfg80211_can_use_chan(rdev, wdev, params.chandef.chan,
2645 CHAN_MODE_SHARED); 2690 CHAN_MODE_SHARED);
2646 mutex_unlock(&rdev->devlist_mtx); 2691 mutex_unlock(&rdev->devlist_mtx);
2647 2692
@@ -2650,10 +2695,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2650 2695
2651 err = rdev_start_ap(rdev, dev, &params); 2696 err = rdev_start_ap(rdev, dev, &params);
2652 if (!err) { 2697 if (!err) {
2653 wdev->preset_chan = params.channel; 2698 wdev->preset_chandef = params.chandef;
2654 wdev->preset_chantype = params.channel_type;
2655 wdev->beacon_interval = params.beacon_interval; 2699 wdev->beacon_interval = params.beacon_interval;
2656 wdev->channel = params.channel; 2700 wdev->channel = params.chandef.chan;
2657 wdev->ssid_len = params.ssid_len; 2701 wdev->ssid_len = params.ssid_len;
2658 memcpy(wdev->ssid, params.ssid, wdev->ssid_len); 2702 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
2659 } 2703 }
@@ -5330,8 +5374,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])) 5374 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
5331 return -EINVAL; 5375 return -EINVAL;
5332 5376
5333 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] || 5377 if (!info->attrs[NL80211_ATTR_SSID] ||
5334 !info->attrs[NL80211_ATTR_SSID] ||
5335 !nla_len(info->attrs[NL80211_ATTR_SSID])) 5378 !nla_len(info->attrs[NL80211_ATTR_SSID]))
5336 return -EINVAL; 5379 return -EINVAL;
5337 5380
@@ -5366,34 +5409,11 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5366 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 5409 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
5367 } 5410 }
5368 5411
5369 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { 5412 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
5370 enum nl80211_channel_type channel_type; 5413 if (err)
5371 5414 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
5384 ibss.channel = rdev_freq_to_chan(rdev,
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;
5391 5415
5392 /* Both channels should be able to initiate communication */ 5416 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef))
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; 5417 return -EINVAL;
5398 5418
5399 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; 5419 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
@@ -5405,7 +5425,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5405 int n_rates = 5425 int n_rates =
5406 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); 5426 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5407 struct ieee80211_supported_band *sband = 5427 struct ieee80211_supported_band *sband =
5408 wiphy->bands[ibss.channel->band]; 5428 wiphy->bands[ibss.chandef.chan->band];
5409 5429
5410 err = ieee80211_get_ratemask(sband, rates, n_rates, 5430 err = ieee80211_get_ratemask(sband, rates, n_rates,
5411 &ibss.basic_rates); 5431 &ibss.basic_rates);
@@ -5427,7 +5447,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5427 if (IS_ERR(connkeys)) 5447 if (IS_ERR(connkeys))
5428 return PTR_ERR(connkeys); 5448 return PTR_ERR(connkeys);
5429 5449
5430 if ((ibss.channel_type != NL80211_CHAN_NO_HT) && no_ht) { 5450 if ((ibss.chandef._type != NL80211_CHAN_NO_HT) && no_ht) {
5431 kfree(connkeys); 5451 kfree(connkeys);
5432 return -EINVAL; 5452 return -EINVAL;
5433 } 5453 }
@@ -5948,11 +5968,11 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
5948{ 5968{
5949 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 5969 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5950 struct wireless_dev *wdev = info->user_ptr[1]; 5970 struct wireless_dev *wdev = info->user_ptr[1];
5951 struct ieee80211_channel *chan; 5971 struct cfg80211_chan_def chandef;
5952 struct sk_buff *msg; 5972 struct sk_buff *msg;
5953 void *hdr; 5973 void *hdr;
5954 u64 cookie; 5974 u64 cookie;
5955 u32 freq, duration; 5975 u32 duration;
5956 int err; 5976 int err;
5957 5977
5958 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] || 5978 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
@@ -5973,14 +5993,9 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
5973 duration > rdev->wiphy.max_remain_on_channel_duration) 5993 duration > rdev->wiphy.max_remain_on_channel_duration)
5974 return -EINVAL; 5994 return -EINVAL;
5975 5995
5976 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 5996 err = nl80211_parse_chandef(rdev, info, &chandef);
5977 !nl80211_valid_channel_type(info, NULL)) 5997 if (err)
5978 return -EINVAL; 5998 return err;
5979
5980 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
5981 chan = rdev_freq_to_chan(rdev, freq, NL80211_CHAN_NO_HT);
5982 if (chan == NULL)
5983 return -EINVAL;
5984 5999
5985 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6000 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5986 if (!msg) 6001 if (!msg)
@@ -5994,7 +6009,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
5994 goto free_msg; 6009 goto free_msg;
5995 } 6010 }
5996 6011
5997 err = rdev_remain_on_channel(rdev, wdev, chan, duration, &cookie); 6012 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
6013 duration, &cookie);
5998 6014
5999 if (err) 6015 if (err)
6000 goto free_msg; 6016 goto free_msg;
@@ -6213,8 +6229,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6213{ 6229{
6214 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6230 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6215 struct wireless_dev *wdev = info->user_ptr[1]; 6231 struct wireless_dev *wdev = info->user_ptr[1];
6216 struct ieee80211_channel *chan; 6232 struct cfg80211_chan_def chandef;
6217 u32 freq;
6218 int err; 6233 int err;
6219 void *hdr = NULL; 6234 void *hdr = NULL;
6220 u64 cookie; 6235 u64 cookie;
@@ -6224,8 +6239,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6224 6239
6225 dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK]; 6240 dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
6226 6241
6227 if (!info->attrs[NL80211_ATTR_FRAME] || 6242 if (!info->attrs[NL80211_ATTR_FRAME])
6228 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
6229 return -EINVAL; 6243 return -EINVAL;
6230 6244
6231 if (!rdev->ops->mgmt_tx) 6245 if (!rdev->ops->mgmt_tx)
@@ -6260,10 +6274,6 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6260 6274
6261 } 6275 }
6262 6276
6263 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
6264 !nl80211_valid_channel_type(info, NULL))
6265 return -EINVAL;
6266
6267 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; 6277 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
6268 6278
6269 if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) 6279 if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
@@ -6271,10 +6281,9 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6271 6281
6272 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); 6282 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
6273 6283
6274 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); 6284 err = nl80211_parse_chandef(rdev, info, &chandef);
6275 chan = rdev_freq_to_chan(rdev, freq, NL80211_CHAN_NO_HT); 6285 if (err)
6276 if (chan == NULL) 6286 return err;
6277 return -EINVAL;
6278 6287
6279 if (!dont_wait_for_ack) { 6288 if (!dont_wait_for_ack) {
6280 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6289 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
@@ -6290,7 +6299,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6290 } 6299 }
6291 } 6300 }
6292 6301
6293 err = cfg80211_mlme_mgmt_tx(rdev, wdev, chan, offchan, wait, 6302 err = cfg80211_mlme_mgmt_tx(rdev, wdev, chandef.chan, offchan, wait,
6294 nla_data(info->attrs[NL80211_ATTR_FRAME]), 6303 nla_data(info->attrs[NL80211_ATTR_FRAME]),
6295 nla_len(info->attrs[NL80211_ATTR_FRAME]), 6304 nla_len(info->attrs[NL80211_ATTR_FRAME]),
6296 no_cck, dont_wait_for_ack, &cookie); 6305 no_cck, dont_wait_for_ack, &cookie);
@@ -6554,21 +6563,12 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
6554 } 6563 }
6555 6564
6556 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 6565 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
6557 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 6566 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
6558 6567 if (err)
6559 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 6568 return err;
6560 !nl80211_valid_channel_type(info, &channel_type))
6561 return -EINVAL;
6562
6563 setup.channel = rdev_freq_to_chan(rdev,
6564 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
6565 channel_type);
6566 if (!setup.channel)
6567 return -EINVAL;
6568 setup.channel_type = channel_type;
6569 } else { 6569 } else {
6570 /* cfg80211_join_mesh() will sort it out */ 6570 /* cfg80211_join_mesh() will sort it out */
6571 setup.channel = NULL; 6571 setup.chandef.chan = NULL;
6572 } 6572 }
6573 6573
6574 return cfg80211_join_mesh(rdev, dev, &setup, &cfg); 6574 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
@@ -8800,8 +8800,8 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
8800} 8800}
8801 8801
8802void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, 8802void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
8803 struct net_device *netdev, int freq, 8803 struct net_device *netdev,
8804 enum nl80211_channel_type type, gfp_t gfp) 8804 struct cfg80211_chan_def *chandef, gfp_t gfp)
8805{ 8805{
8806 struct sk_buff *msg; 8806 struct sk_buff *msg;
8807 void *hdr; 8807 void *hdr;
@@ -8816,9 +8816,10 @@ void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
8816 return; 8816 return;
8817 } 8817 }
8818 8818
8819 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || 8819 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
8820 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) || 8820 goto nla_put_failure;
8821 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, type)) 8821
8822 if (nl80211_send_chandef(msg, chandef))
8822 goto nla_put_failure; 8823 goto nla_put_failure;
8823 8824
8824 genlmsg_end(msg, hdr); 8825 genlmsg_end(msg, hdr);
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 7adbd767dbfd..2acba8477e9d 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -127,8 +127,8 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
127 const u8 *bssid, bool preauth, gfp_t gfp); 127 const u8 *bssid, bool preauth, gfp_t gfp);
128 128
129void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, 129void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
130 struct net_device *dev, int freq, 130 struct net_device *dev,
131 enum nl80211_channel_type type, gfp_t gfp); 131 struct cfg80211_chan_def *chandef, gfp_t gfp);
132 132
133bool nl80211_unexpected_frame(struct net_device *dev, 133bool nl80211_unexpected_frame(struct net_device *dev,
134 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 ee54a5aa4381..6c0c8191f837 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -359,12 +359,11 @@ rdev_libertas_set_mesh_channel(struct cfg80211_registered_device *rdev,
359 359
360static inline int 360static inline int
361rdev_set_monitor_channel(struct cfg80211_registered_device *rdev, 361rdev_set_monitor_channel(struct cfg80211_registered_device *rdev,
362 struct ieee80211_channel *chan, 362 struct cfg80211_chan_def *chandef)
363 enum nl80211_channel_type channel_type)
364{ 363{
365 int ret; 364 int ret;
366 trace_rdev_set_monitor_channel(&rdev->wiphy, chan, channel_type); 365 trace_rdev_set_monitor_channel(&rdev->wiphy, chandef);
367 ret = rdev->ops->set_monitor_channel(&rdev->wiphy, chan, channel_type); 366 ret = rdev->ops->set_monitor_channel(&rdev->wiphy, chandef);
368 trace_rdev_return_int(&rdev->wiphy, ret); 367 trace_rdev_return_int(&rdev->wiphy, ret);
369 return ret; 368 return ret;
370} 369}
@@ -844,14 +843,17 @@ static inline void rdev_get_et_strings(struct cfg80211_registered_device *rdev,
844 trace_rdev_return_void(&rdev->wiphy); 843 trace_rdev_return_void(&rdev->wiphy);
845} 844}
846 845
847static inline struct ieee80211_channel 846static inline int
848*rdev_get_channel(struct cfg80211_registered_device *rdev, 847rdev_get_channel(struct cfg80211_registered_device *rdev,
849 struct wireless_dev *wdev, enum nl80211_channel_type *type) 848 struct wireless_dev *wdev,
849 struct cfg80211_chan_def *chandef)
850{ 850{
851 struct ieee80211_channel *ret; 851 int ret;
852
852 trace_rdev_get_channel(&rdev->wiphy, wdev); 853 trace_rdev_get_channel(&rdev->wiphy, wdev);
853 ret = rdev->ops->get_channel(&rdev->wiphy, wdev, type); 854 ret = rdev->ops->get_channel(&rdev->wiphy, wdev, chandef);
854 trace_rdev_return_channel(&rdev->wiphy, ret, *type); 855 trace_rdev_return_chandef(&rdev->wiphy, ret, chandef);
856
855 return ret; 857 return ret;
856} 858}
857 859
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index ed10833f9a3a..1370d52b1393 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -126,6 +126,26 @@
126#define CHAN_PR_FMT ", band: %d, freq: %u" 126#define CHAN_PR_FMT ", band: %d, freq: %u"
127#define CHAN_PR_ARG __entry->band, __entry->center_freq 127#define CHAN_PR_ARG __entry->band, __entry->center_freq
128 128
129#define CHAN_DEF_ENTRY __field(enum ieee80211_band, band) \
130 __field(u16, center_freq) \
131 __field(u32, channel_type)
132#define CHAN_DEF_ASSIGN(chandef) \
133 do { \
134 if ((chandef) && (chandef)->chan) { \
135 __entry->band = (chandef)->chan->band; \
136 __entry->center_freq = \
137 (chandef)->chan->center_freq; \
138 __entry->channel_type = (chandef)->_type; \
139 } else { \
140 __entry->band = 0; \
141 __entry->center_freq = 0; \
142 __entry->channel_type = 0; \
143 } \
144 } while (0)
145#define CHAN_DEF_PR_FMT ", band: %d, freq: %u, chantype: %d"
146#define CHAN_DEF_PR_ARG __entry->band, __entry->center_freq, \
147 __entry->channel_type
148
129#define SINFO_ENTRY __field(int, generation) \ 149#define SINFO_ENTRY __field(int, generation) \
130 __field(u32, connected_time) \ 150 __field(u32, connected_time) \
131 __field(u32, inactive_time) \ 151 __field(u32, inactive_time) \
@@ -433,7 +453,7 @@ TRACE_EVENT(rdev_start_ap,
433 TP_STRUCT__entry( 453 TP_STRUCT__entry(
434 WIPHY_ENTRY 454 WIPHY_ENTRY
435 NETDEV_ENTRY 455 NETDEV_ENTRY
436 CHAN_ENTRY 456 CHAN_DEF_ENTRY
437 __field(int, beacon_interval) 457 __field(int, beacon_interval)
438 __field(int, dtim_period) 458 __field(int, dtim_period)
439 __array(char, ssid, IEEE80211_MAX_SSID_LEN + 1) 459 __array(char, ssid, IEEE80211_MAX_SSID_LEN + 1)
@@ -446,7 +466,7 @@ TRACE_EVENT(rdev_start_ap,
446 TP_fast_assign( 466 TP_fast_assign(
447 WIPHY_ASSIGN; 467 WIPHY_ASSIGN;
448 NETDEV_ASSIGN; 468 NETDEV_ASSIGN;
449 CHAN_ASSIGN(settings->channel); 469 CHAN_DEF_ASSIGN(&settings->chandef);
450 __entry->beacon_interval = settings->beacon_interval; 470 __entry->beacon_interval = settings->beacon_interval;
451 __entry->dtim_period = settings->dtim_period; 471 __entry->dtim_period = settings->dtim_period;
452 __entry->hidden_ssid = settings->hidden_ssid; 472 __entry->hidden_ssid = settings->hidden_ssid;
@@ -458,10 +478,10 @@ TRACE_EVENT(rdev_start_ap,
458 memcpy(__entry->ssid, settings->ssid, settings->ssid_len); 478 memcpy(__entry->ssid, settings->ssid, settings->ssid_len);
459 ), 479 ),
460 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", AP settings - ssid: %s, " 480 TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", AP settings - ssid: %s, "
461 CHAN_PR_FMT ", beacon interval: %d, dtim period: %d, " 481 CHAN_DEF_PR_FMT ", beacon interval: %d, dtim period: %d, "
462 "hidden ssid: %d, wpa versions: %u, privacy: %s, " 482 "hidden ssid: %d, wpa versions: %u, privacy: %s, "
463 "auth type: %d, inactivity timeout: %d", 483 "auth type: %d, inactivity timeout: %d",
464 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ssid, CHAN_PR_ARG, 484 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ssid, CHAN_DEF_PR_ARG,
465 __entry->beacon_interval, __entry->dtim_period, 485 __entry->beacon_interval, __entry->dtim_period,
466 __entry->hidden_ssid, __entry->wpa_ver, 486 __entry->hidden_ssid, __entry->wpa_ver,
467 BOOL_TO_STR(__entry->privacy), __entry->auth_type, 487 BOOL_TO_STR(__entry->privacy), __entry->auth_type,
@@ -933,21 +953,19 @@ TRACE_EVENT(rdev_libertas_set_mesh_channel,
933); 953);
934 954
935TRACE_EVENT(rdev_set_monitor_channel, 955TRACE_EVENT(rdev_set_monitor_channel,
936 TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *chan, 956 TP_PROTO(struct wiphy *wiphy,
937 enum nl80211_channel_type chan_type), 957 struct cfg80211_chan_def *chandef),
938 TP_ARGS(wiphy, chan, chan_type), 958 TP_ARGS(wiphy, chandef),
939 TP_STRUCT__entry( 959 TP_STRUCT__entry(
940 WIPHY_ENTRY 960 WIPHY_ENTRY
941 CHAN_ENTRY 961 CHAN_DEF_ENTRY
942 __field(enum nl80211_channel_type, chan_type)
943 ), 962 ),
944 TP_fast_assign( 963 TP_fast_assign(
945 WIPHY_ASSIGN; 964 WIPHY_ASSIGN;
946 CHAN_ASSIGN(chan); 965 CHAN_DEF_ASSIGN(chandef);
947 __entry->chan_type = chan_type;
948 ), 966 ),
949 TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel type : %d", 967 TP_printk(WIPHY_PR_FMT CHAN_DEF_PR_FMT,
950 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->chan_type) 968 WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
951); 969);
952 970
953TRACE_EVENT(rdev_auth, 971TRACE_EVENT(rdev_auth,
@@ -1713,22 +1731,25 @@ DEFINE_EVENT(wiphy_wdev_evt, rdev_get_channel,
1713 TP_ARGS(wiphy, wdev) 1731 TP_ARGS(wiphy, wdev)
1714); 1732);
1715 1733
1716TRACE_EVENT(rdev_return_channel, 1734TRACE_EVENT(rdev_return_chandef,
1717 TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *chan, 1735 TP_PROTO(struct wiphy *wiphy, int ret,
1718 enum nl80211_channel_type type), 1736 struct cfg80211_chan_def *chandef),
1719 TP_ARGS(wiphy, chan, type), 1737 TP_ARGS(wiphy, ret, chandef),
1720 TP_STRUCT__entry( 1738 TP_STRUCT__entry(
1721 WIPHY_ENTRY 1739 WIPHY_ENTRY
1722 CHAN_ENTRY 1740 __field(int, ret)
1723 __field(enum nl80211_channel_type, type) 1741 CHAN_DEF_ENTRY
1724 ), 1742 ),
1725 TP_fast_assign( 1743 TP_fast_assign(
1726 WIPHY_ASSIGN; 1744 WIPHY_ASSIGN;
1727 CHAN_ASSIGN(chan); 1745 if (ret == 0)
1728 __entry->type = type; 1746 CHAN_DEF_ASSIGN(chandef);
1747 else
1748 CHAN_DEF_ASSIGN((struct cfg80211_chan_def *)NULL);
1749 __entry->ret = ret;
1729 ), 1750 ),
1730 TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel type: %d", 1751 TP_printk(WIPHY_PR_FMT CHAN_DEF_PR_FMT ", ret: %d",
1731 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->type) 1752 WIPHY_PR_ARG, CHAN_DEF_PR_ARG, __entry->ret)
1732); 1753);
1733 1754
1734DEFINE_EVENT(wiphy_wdev_evt, rdev_start_p2p_device, 1755DEFINE_EVENT(wiphy_wdev_evt, rdev_start_p2p_device,
@@ -1992,40 +2013,35 @@ TRACE_EVENT(cfg80211_cqm_rssi_notify,
1992 NETDEV_PR_ARG, __entry->rssi_event) 2013 NETDEV_PR_ARG, __entry->rssi_event)
1993); 2014);
1994 2015
1995TRACE_EVENT(cfg80211_can_beacon_sec_chan, 2016TRACE_EVENT(cfg80211_reg_can_beacon,
1996 TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, 2017 TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef),
1997 enum nl80211_channel_type channel_type), 2018 TP_ARGS(wiphy, chandef),
1998 TP_ARGS(wiphy, channel, channel_type),
1999 TP_STRUCT__entry( 2019 TP_STRUCT__entry(
2000 WIPHY_ENTRY 2020 WIPHY_ENTRY
2001 CHAN_ENTRY 2021 CHAN_DEF_ENTRY
2002 __field(enum nl80211_channel_type, channel_type)
2003 ), 2022 ),
2004 TP_fast_assign( 2023 TP_fast_assign(
2005 WIPHY_ASSIGN; 2024 WIPHY_ASSIGN;
2006 CHAN_ASSIGN(channel); 2025 CHAN_DEF_ASSIGN(chandef);
2007 __entry->channel_type = channel_type;
2008 ), 2026 ),
2009 TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel_type: %d", 2027 TP_printk(WIPHY_PR_FMT CHAN_DEF_PR_FMT,
2010 WIPHY_PR_ARG, CHAN_PR_ARG, __entry->channel_type) 2028 WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
2011); 2029);
2012 2030
2013TRACE_EVENT(cfg80211_ch_switch_notify, 2031TRACE_EVENT(cfg80211_ch_switch_notify,
2014 TP_PROTO(struct net_device *netdev, int freq, 2032 TP_PROTO(struct net_device *netdev,
2015 enum nl80211_channel_type type), 2033 struct cfg80211_chan_def *chandef),
2016 TP_ARGS(netdev, freq, type), 2034 TP_ARGS(netdev, chandef),
2017 TP_STRUCT__entry( 2035 TP_STRUCT__entry(
2018 NETDEV_ENTRY 2036 NETDEV_ENTRY
2019 __field(int, freq) 2037 CHAN_DEF_ENTRY
2020 __field(enum nl80211_channel_type, type)
2021 ), 2038 ),
2022 TP_fast_assign( 2039 TP_fast_assign(
2023 NETDEV_ASSIGN; 2040 NETDEV_ASSIGN;
2024 __entry->freq = freq; 2041 CHAN_DEF_ASSIGN(chandef);
2025 __entry->type = type;
2026 ), 2042 ),
2027 TP_printk(NETDEV_PR_FMT ", freq: %d, type: %d", NETDEV_PR_ARG, 2043 TP_printk(NETDEV_PR_FMT CHAN_DEF_PR_FMT,
2028 __entry->freq, __entry->type) 2044 NETDEV_PR_ARG, CHAN_DEF_PR_ARG)
2029); 2045);
2030 2046
2031DECLARE_EVENT_CLASS(cfg80211_rx_evt, 2047DECLARE_EVENT_CLASS(cfg80211_rx_evt,
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 742ab6ec4c9d..da3307f32362 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 ._type = NL80211_CHAN_NO_HT,
789 };
787 int freq, err; 790 int freq, err;
788 791
789 switch (wdev->iftype) { 792 switch (wdev->iftype) {
@@ -797,8 +800,11 @@ 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.chan = ieee80211_get_channel(&rdev->wiphy, freq);
804 if (!chandef.chan)
805 return -EINVAL;
800 mutex_lock(&rdev->devlist_mtx); 806 mutex_lock(&rdev->devlist_mtx);
801 err = cfg80211_set_monitor_channel(rdev, freq, NL80211_CHAN_NO_HT); 807 err = cfg80211_set_monitor_channel(rdev, &chandef);
802 mutex_unlock(&rdev->devlist_mtx); 808 mutex_unlock(&rdev->devlist_mtx);
803 return err; 809 return err;
804 case NL80211_IFTYPE_MESH_POINT: 810 case NL80211_IFTYPE_MESH_POINT:
@@ -807,9 +813,11 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
807 return freq; 813 return freq;
808 if (freq == 0) 814 if (freq == 0)
809 return -EINVAL; 815 return -EINVAL;
816 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
817 if (!chandef.chan)
818 return -EINVAL;
810 mutex_lock(&rdev->devlist_mtx); 819 mutex_lock(&rdev->devlist_mtx);
811 err = cfg80211_set_mesh_freq(rdev, wdev, freq, 820 err = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
812 NL80211_CHAN_NO_HT);
813 mutex_unlock(&rdev->devlist_mtx); 821 mutex_unlock(&rdev->devlist_mtx);
814 return err; 822 return err;
815 default: 823 default:
@@ -823,8 +831,8 @@ static int cfg80211_wext_giwfreq(struct net_device *dev,
823{ 831{
824 struct wireless_dev *wdev = dev->ieee80211_ptr; 832 struct wireless_dev *wdev = dev->ieee80211_ptr;
825 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 833 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
826 struct ieee80211_channel *chan; 834 struct cfg80211_chan_def chandef;
827 enum nl80211_channel_type channel_type; 835 int ret;
828 836
829 switch (wdev->iftype) { 837 switch (wdev->iftype) {
830 case NL80211_IFTYPE_STATION: 838 case NL80211_IFTYPE_STATION:
@@ -835,10 +843,10 @@ static int cfg80211_wext_giwfreq(struct net_device *dev,
835 if (!rdev->ops->get_channel) 843 if (!rdev->ops->get_channel)
836 return -EINVAL; 844 return -EINVAL;
837 845
838 chan = rdev_get_channel(rdev, wdev, &channel_type); 846 ret = rdev_get_channel(rdev, wdev, &chandef);
839 if (!chan) 847 if (ret)
840 return -EINVAL; 848 return ret;
841 freq->m = chan->center_freq; 849 freq->m = chandef.chan->center_freq;
842 freq->e = 6; 850 freq->e = 6;
843 return 0; 851 return 0;
844 default: 852 default:
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 1f773f668d1a..e6e5dbf2f616 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -119,7 +119,15 @@ 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 ._type = NL80211_CHAN_NO_HT,
124 };
125
126 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
127 if (chandef.chan)
128 err = cfg80211_set_monitor_channel(rdev, &chandef);
129 else
130 err = -EINVAL;
123 goto out; 131 goto out;
124 } 132 }
125 133