aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-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
13 files changed, 312 insertions, 328 deletions
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