aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/chan.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-11-22 10:59:45 -0500
committerJohannes Berg <johannes.berg@intel.com>2012-11-27 03:18:25 -0500
commit9f5e8f6efc7c2601136b27d9c7325c245f8fd19a (patch)
tree99e89e550d6687240364659e78ff4276bd12aae2 /net/wireless/chan.c
parentec816087e8978b74c1bd5fae0e335dd97d964e9f (diff)
cfg80211: rework chandef checking and export it
Some of the chandef checking that we do in cfg80211 to check if a channel is supported or not is also needed in mac80211, so rework that a bit and export the functions that are needed. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/chan.c')
-rw-r--r--net/wireless/chan.c92
1 files changed, 63 insertions, 29 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index bf2dfd54ff3b..b5f69831e318 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -44,7 +44,7 @@ void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
44} 44}
45EXPORT_SYMBOL(cfg80211_chandef_create); 45EXPORT_SYMBOL(cfg80211_chandef_create);
46 46
47bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef) 47bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
48{ 48{
49 u32 control_freq; 49 u32 control_freq;
50 50
@@ -105,6 +105,7 @@ bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef)
105 105
106 return true; 106 return true;
107} 107}
108EXPORT_SYMBOL(cfg80211_chandef_valid);
108 109
109static void chandef_primary_freqs(const struct cfg80211_chan_def *c, 110static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
110 int *pri40, int *pri80) 111 int *pri40, int *pri80)
@@ -187,9 +188,9 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
187} 188}
188EXPORT_SYMBOL(cfg80211_chandef_compatible); 189EXPORT_SYMBOL(cfg80211_chandef_compatible);
189 190
190bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, 191static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
191 u32 center_freq, u32 bandwidth, 192 u32 center_freq, u32 bandwidth,
192 u32 prohibited_flags) 193 u32 prohibited_flags)
193{ 194{
194 struct ieee80211_channel *c; 195 struct ieee80211_channel *c;
195 u32 freq; 196 u32 freq;
@@ -205,55 +206,88 @@ bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
205 return true; 206 return true;
206} 207}
207 208
208static bool cfg80211_check_beacon_chans(struct wiphy *wiphy, 209bool cfg80211_chandef_usable(struct wiphy *wiphy,
209 u32 center_freq, u32 bw) 210 const struct cfg80211_chan_def *chandef,
211 u32 prohibited_flags)
210{ 212{
211 return cfg80211_secondary_chans_ok(wiphy, center_freq, bw, 213 struct ieee80211_sta_ht_cap *ht_cap;
212 IEEE80211_CHAN_DISABLED | 214 struct ieee80211_sta_vht_cap *vht_cap;
213 IEEE80211_CHAN_PASSIVE_SCAN | 215 u32 width, control_freq;
214 IEEE80211_CHAN_NO_IBSS |
215 IEEE80211_CHAN_RADAR);
216}
217 216
218bool cfg80211_reg_can_beacon(struct wiphy *wiphy, 217 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
219 struct cfg80211_chan_def *chandef) 218 return false;
220{
221 u32 width;
222 bool res;
223 219
224 trace_cfg80211_reg_can_beacon(wiphy, chandef); 220 ht_cap = &wiphy->bands[chandef->chan->band]->ht_cap;
221 vht_cap = &wiphy->bands[chandef->chan->band]->vht_cap;
225 222
226 if (WARN_ON(!cfg80211_chan_def_valid(chandef))) { 223 control_freq = chandef->chan->center_freq;
227 trace_cfg80211_return_bool(false);
228 return false;
229 }
230 224
231 switch (chandef->width) { 225 switch (chandef->width) {
232 case NL80211_CHAN_WIDTH_20_NOHT:
233 case NL80211_CHAN_WIDTH_20: 226 case NL80211_CHAN_WIDTH_20:
227 if (!ht_cap->ht_supported)
228 return false;
229 case NL80211_CHAN_WIDTH_20_NOHT:
234 width = 20; 230 width = 20;
235 break; 231 break;
236 case NL80211_CHAN_WIDTH_40: 232 case NL80211_CHAN_WIDTH_40:
237 width = 40; 233 width = 40;
234 if (!ht_cap->ht_supported)
235 return false;
236 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
237 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
238 return false;
239 if (chandef->center_freq1 < control_freq &&
240 chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
241 return false;
242 if (chandef->center_freq1 > control_freq &&
243 chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
244 return false;
238 break; 245 break;
239 case NL80211_CHAN_WIDTH_80:
240 case NL80211_CHAN_WIDTH_80P80: 246 case NL80211_CHAN_WIDTH_80P80:
247 if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
248 return false;
249 case NL80211_CHAN_WIDTH_80:
250 if (!vht_cap->vht_supported)
251 return false;
241 width = 80; 252 width = 80;
242 break; 253 break;
243 case NL80211_CHAN_WIDTH_160: 254 case NL80211_CHAN_WIDTH_160:
255 if (!vht_cap->vht_supported)
256 return false;
257 if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ))
258 return false;
244 width = 160; 259 width = 160;
245 break; 260 break;
246 default: 261 default:
247 WARN_ON_ONCE(1); 262 WARN_ON_ONCE(1);
248 trace_cfg80211_return_bool(false);
249 return false; 263 return false;
250 } 264 }
251 265
252 res = cfg80211_check_beacon_chans(wiphy, chandef->center_freq1, width); 266 /* TODO: missing regulatory check on 80/160 bandwidth */
267
268 if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1,
269 width, prohibited_flags))
270 return false;
271
272 if (!chandef->center_freq2)
273 return true;
274 return cfg80211_secondary_chans_ok(wiphy, chandef->center_freq2,
275 width, prohibited_flags);
276}
277EXPORT_SYMBOL(cfg80211_chandef_usable);
278
279bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
280 struct cfg80211_chan_def *chandef)
281{
282 bool res;
283
284 trace_cfg80211_reg_can_beacon(wiphy, chandef);
253 285
254 if (res && chandef->center_freq2) 286 res = cfg80211_chandef_usable(wiphy, chandef,
255 res = cfg80211_check_beacon_chans(wiphy, chandef->center_freq2, 287 IEEE80211_CHAN_DISABLED |
256 width); 288 IEEE80211_CHAN_PASSIVE_SCAN |
289 IEEE80211_CHAN_NO_IBSS |
290 IEEE80211_CHAN_RADAR);
257 291
258 trace_cfg80211_return_bool(res); 292 trace_cfg80211_return_bool(res);
259 return res; 293 return res;