aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2008-09-10 02:19:48 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-15 16:48:19 -0400
commitb2e1b30290539b344cbaff0d9da38012e03aa347 (patch)
tree8d021d078c12f3d7b47da4b52a54eff4509daa98 /include
parent63f2c0464875b6ef2132cecb19b2a5abbf061227 (diff)
cfg80211: Add new wireless regulatory infrastructure
This adds the new wireless regulatory infrastructure. The main motiviation behind this was to centralize regulatory code as each driver was implementing their own regulatory solution, and to replace the initial centralized code we have where: * only 3 regulatory domains are supported: US, JP and EU * regulatory domains can only be changed through module parameter * all rules were built statically in the kernel We now have support for regulatory domains for many countries and regulatory domains are now queried through a userspace agent through udev allowing distributions to update regulatory rules without updating the kernel. Each driver can regulatory_hint() a regulatory domain based on either their EEPROM mapped regulatory domain value to a respective ISO/IEC 3166-1 country code or pass an internally built regulatory domain. We also add support to let the user set the regulatory domain through userspace in case of faulty EEPROMs to further help compliance. Support for world roaming will be added soon for cards capable of this. For more information see: http://wireless.kernel.org/en/developers/Regulatory/CRDA For now we leave an option to enable the old module parameter, ieee80211_regdom, and to build the 3 old regdomains statically (US, JP and EU). This option is CONFIG_WIRELESS_OLD_REGULATORY. These old static definitions and the module parameter is being scheduled for removal for 2.6.29. Note that if you use this you won't make use of a world regulatory domain as its pointless. If you leave this option enabled and if CRDA is present and you use US or JP we will try to ask CRDA to update us a regulatory domain for us. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/nl80211.h96
-rw-r--r--include/net/cfg80211.h60
-rw-r--r--include/net/mac80211.h2
-rw-r--r--include/net/wireless.h58
4 files changed, 214 insertions, 2 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 5e51f4e7600b..9bad65400fba 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -92,6 +92,20 @@
92 * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by 92 * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by
93 * %NL80211_ATTR_IFINDEX. 93 * %NL80211_ATTR_IFINDEX.
94 * 94 *
95 * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
96 * after being queried by the kernel. CRDA replies by sending a regulatory
97 * domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
98 * current alpha2 if it found a match. It also provides
99 * NL80211_ATTR_REG_RULE_FLAGS, and a set of regulatory rules. Each
100 * regulatory rule is a nested set of attributes given by
101 * %NL80211_ATTR_REG_RULE_FREQ_[START|END] and
102 * %NL80211_ATTR_FREQ_RANGE_MAX_BW with an attached power rule given by
103 * %NL80211_ATTR_REG_RULE_POWER_MAX_ANT_GAIN and
104 * %NL80211_ATTR_REG_RULE_POWER_MAX_EIRP.
105 * @NL80211_CMD_REQ_SET_REG: ask the wireless core to set the regulatory domain
106 * to the the specified ISO/IEC 3166-1 alpha2 country code. The core will
107 * store this as a valid request and then query userspace for it.
108 *
95 * @NL80211_CMD_MAX: highest used command number 109 * @NL80211_CMD_MAX: highest used command number
96 * @__NL80211_CMD_AFTER_LAST: internal use 110 * @__NL80211_CMD_AFTER_LAST: internal use
97 */ 111 */
@@ -131,7 +145,10 @@ enum nl80211_commands {
131 145
132 NL80211_CMD_SET_BSS, 146 NL80211_CMD_SET_BSS,
133 147
134 /* add commands here */ 148 NL80211_CMD_SET_REG,
149 NL80211_CMD_REQ_SET_REG,
150
151 /* add new commands above here */
135 152
136 /* used to define NL80211_CMD_MAX below */ 153 /* used to define NL80211_CMD_MAX below */
137 __NL80211_CMD_AFTER_LAST, 154 __NL80211_CMD_AFTER_LAST,
@@ -197,10 +214,21 @@ enum nl80211_commands {
197 * info given for %NL80211_CMD_GET_MPATH, nested attribute described at 214 * info given for %NL80211_CMD_GET_MPATH, nested attribute described at
198 * &enum nl80211_mpath_info. 215 * &enum nl80211_mpath_info.
199 * 216 *
200 *
201 * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of 217 * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of
202 * &enum nl80211_mntr_flags. 218 * &enum nl80211_mntr_flags.
203 * 219 *
220 * @NL80211_ATTR_REG_ALPHA2: an ISO-3166-alpha2 country code for which the
221 * current regulatory domain should be set to or is already set to.
222 * For example, 'CR', for Costa Rica. This attribute is used by the kernel
223 * to query the CRDA to retrieve one regulatory domain. This attribute can
224 * also be used by userspace to query the kernel for the currently set
225 * regulatory domain. We chose an alpha2 as that is also used by the
226 * IEEE-802.11d country information element to identify a country.
227 * Users can also simply ask the wireless core to set regulatory domain
228 * to a specific alpha2.
229 * @NL80211_ATTR_REG_RULES: a nested array of regulatory domain regulatory
230 * rules.
231 *
204 * @NL80211_ATTR_BSS_CTS_PROT: whether CTS protection is enabled (u8, 0 or 1) 232 * @NL80211_ATTR_BSS_CTS_PROT: whether CTS protection is enabled (u8, 0 or 1)
205 * @NL80211_ATTR_BSS_SHORT_PREAMBLE: whether short preamble is enabled 233 * @NL80211_ATTR_BSS_SHORT_PREAMBLE: whether short preamble is enabled
206 * (u8, 0 or 1) 234 * (u8, 0 or 1)
@@ -265,6 +293,9 @@ enum nl80211_attrs {
265 293
266 NL80211_ATTR_SUPPORTED_IFTYPES, 294 NL80211_ATTR_SUPPORTED_IFTYPES,
267 295
296 NL80211_ATTR_REG_ALPHA2,
297 NL80211_ATTR_REG_RULES,
298
268 /* add attributes here, update the policy in nl80211.c */ 299 /* add attributes here, update the policy in nl80211.c */
269 300
270 __NL80211_ATTR_AFTER_LAST, 301 __NL80211_ATTR_AFTER_LAST,
@@ -278,6 +309,7 @@ enum nl80211_attrs {
278#define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY 309#define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY
279 310
280#define NL80211_MAX_SUPP_RATES 32 311#define NL80211_MAX_SUPP_RATES 32
312#define NL80211_MAX_SUPP_REG_RULES 32
281#define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0 313#define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0
282#define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 314#define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16
283#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 315#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24
@@ -473,6 +505,66 @@ enum nl80211_bitrate_attr {
473}; 505};
474 506
475/** 507/**
508 * enum nl80211_reg_rule_attr - regulatory rule attributes
509 * @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional
510 * considerations for a given frequency range. These are the
511 * &enum nl80211_reg_rule_flags.
512 * @NL80211_ATTR_FREQ_RANGE_START: starting frequencry for the regulatory
513 * rule in KHz. This is not a center of frequency but an actual regulatory
514 * band edge.
515 * @NL80211_ATTR_FREQ_RANGE_END: ending frequency for the regulatory rule
516 * in KHz. This is not a center a frequency but an actual regulatory
517 * band edge.
518 * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this
519 * frequency range, in KHz.
520 * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain
521 * for a given frequency range. The value is in mBi (100 * dBi).
522 * If you don't have one then don't send this.
523 * @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for
524 * a given frequency range. The value is in mBm (100 * dBm).
525 */
526enum nl80211_reg_rule_attr {
527 __NL80211_REG_RULE_ATTR_INVALID,
528 NL80211_ATTR_REG_RULE_FLAGS,
529
530 NL80211_ATTR_FREQ_RANGE_START,
531 NL80211_ATTR_FREQ_RANGE_END,
532 NL80211_ATTR_FREQ_RANGE_MAX_BW,
533
534 NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
535 NL80211_ATTR_POWER_RULE_MAX_EIRP,
536
537 /* keep last */
538 __NL80211_REG_RULE_ATTR_AFTER_LAST,
539 NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1
540};
541
542/**
543 * enum nl80211_reg_rule_flags - regulatory rule flags
544 *
545 * @NL80211_RRF_NO_OFDM: OFDM modulation not allowed
546 * @NL80211_RRF_NO_CCK: CCK modulation not allowed
547 * @NL80211_RRF_NO_INDOOR: indoor operation not allowed
548 * @NL80211_RRF_NO_OUTDOOR: outdoor operation not allowed
549 * @NL80211_RRF_DFS: DFS support is required to be used
550 * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links
551 * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links
552 * @NL80211_RRF_PASSIVE_SCAN: passive scan is required
553 * @NL80211_RRF_NO_IBSS: no IBSS is allowed
554 */
555enum nl80211_reg_rule_flags {
556 NL80211_RRF_NO_OFDM = 1<<0,
557 NL80211_RRF_NO_CCK = 1<<1,
558 NL80211_RRF_NO_INDOOR = 1<<2,
559 NL80211_RRF_NO_OUTDOOR = 1<<3,
560 NL80211_RRF_DFS = 1<<4,
561 NL80211_RRF_PTP_ONLY = 1<<5,
562 NL80211_RRF_PTMP_ONLY = 1<<6,
563 NL80211_RRF_PASSIVE_SCAN = 1<<7,
564 NL80211_RRF_NO_IBSS = 1<<8,
565};
566
567/**
476 * enum nl80211_mntr_flags - monitor configuration flags 568 * enum nl80211_mntr_flags - monitor configuration flags
477 * 569 *
478 * Monitor configuration flags. 570 * Monitor configuration flags.
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0a72d1e3d3ab..9f40c4d417d7 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -287,6 +287,66 @@ struct bss_parameters {
287 int use_short_slot_time; 287 int use_short_slot_time;
288}; 288};
289 289
290/**
291 * enum reg_set_by - Indicates who is trying to set the regulatory domain
292 * @REGDOM_SET_BY_INIT: regulatory domain was set by initialization. We will be
293 * using a static world regulatory domain by default.
294 * @REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world regulatory domain.
295 * @REGDOM_SET_BY_USER: User asked the wireless core to set the
296 * regulatory domain.
297 * @REGDOM_SET_BY_DRIVER: a wireless drivers has hinted to the wireless core
298 * it thinks its knows the regulatory domain we should be in.
299 * @REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an 802.11 country
300 * information element with regulatory information it thinks we
301 * should consider.
302 */
303enum reg_set_by {
304 REGDOM_SET_BY_INIT,
305 REGDOM_SET_BY_CORE,
306 REGDOM_SET_BY_USER,
307 REGDOM_SET_BY_DRIVER,
308 REGDOM_SET_BY_COUNTRY_IE,
309};
310
311struct ieee80211_freq_range {
312 u32 start_freq_khz;
313 u32 end_freq_khz;
314 u32 max_bandwidth_khz;
315};
316
317struct ieee80211_power_rule {
318 u32 max_antenna_gain;
319 u32 max_eirp;
320};
321
322struct ieee80211_reg_rule {
323 struct ieee80211_freq_range freq_range;
324 struct ieee80211_power_rule power_rule;
325 u32 flags;
326};
327
328struct ieee80211_regdomain {
329 u32 n_reg_rules;
330 char alpha2[2];
331 struct ieee80211_reg_rule reg_rules[];
332};
333
334#define MHZ_TO_KHZ(freq) (freq * 1000)
335#define KHZ_TO_MHZ(freq) (freq / 1000)
336#define DBI_TO_MBI(gain) (gain * 100)
337#define MBI_TO_DBI(gain) (gain / 100)
338#define DBM_TO_MBM(gain) (gain * 100)
339#define MBM_TO_DBM(gain) (gain / 100)
340
341#define REG_RULE(start, end, bw, gain, eirp, reg_flags) { \
342 .freq_range.start_freq_khz = (start) * 1000, \
343 .freq_range.end_freq_khz = (end) * 1000, \
344 .freq_range.max_bandwidth_khz = (bw) * 1000, \
345 .power_rule.max_antenna_gain = (gain) * 100, \
346 .power_rule.max_eirp = (eirp) * 100, \
347 .flags = reg_flags, \
348 }
349
290/* from net/wireless.h */ 350/* from net/wireless.h */
291struct wiphy; 351struct wiphy;
292 352
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index fb9e62211c34..f504e3eca7d3 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -833,6 +833,8 @@ struct ieee80211_hw {
833 s8 max_signal; 833 s8 max_signal;
834}; 834};
835 835
836struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy);
837
836/** 838/**
837 * SET_IEEE80211_DEV - set device for 802.11 hardware 839 * SET_IEEE80211_DEV - set device for 802.11 hardware
838 * 840 *
diff --git a/include/net/wireless.h b/include/net/wireless.h
index 1dc8ec3daa2f..e4378cc6bf8e 100644
--- a/include/net/wireless.h
+++ b/include/net/wireless.h
@@ -60,6 +60,7 @@ enum ieee80211_channel_flags {
60 * with cfg80211. 60 * with cfg80211.
61 * 61 *
62 * @center_freq: center frequency in MHz 62 * @center_freq: center frequency in MHz
63 * @max_bandwidth: maximum allowed bandwidth for this channel, in MHz
63 * @hw_value: hardware-specific value for the channel 64 * @hw_value: hardware-specific value for the channel
64 * @flags: channel flags from &enum ieee80211_channel_flags. 65 * @flags: channel flags from &enum ieee80211_channel_flags.
65 * @orig_flags: channel flags at registration time, used by regulatory 66 * @orig_flags: channel flags at registration time, used by regulatory
@@ -73,6 +74,7 @@ enum ieee80211_channel_flags {
73struct ieee80211_channel { 74struct ieee80211_channel {
74 enum ieee80211_band band; 75 enum ieee80211_band band;
75 u16 center_freq; 76 u16 center_freq;
77 u8 max_bandwidth;
76 u16 hw_value; 78 u16 hw_value;
77 u32 flags; 79 u32 flags;
78 int max_antenna_gain; 80 int max_antenna_gain;
@@ -178,6 +180,7 @@ struct ieee80211_supported_band {
178 * struct wiphy - wireless hardware description 180 * struct wiphy - wireless hardware description
179 * @idx: the wiphy index assigned to this item 181 * @idx: the wiphy index assigned to this item
180 * @class_dev: the class device representing /sys/class/ieee80211/<wiphy-name> 182 * @class_dev: the class device representing /sys/class/ieee80211/<wiphy-name>
183 * @reg_notifier: the driver's regulatory notification callback
181 */ 184 */
182struct wiphy { 185struct wiphy {
183 /* assign these fields before you register the wiphy */ 186 /* assign these fields before you register the wiphy */
@@ -197,6 +200,9 @@ struct wiphy {
197 200
198 struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS]; 201 struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS];
199 202
203 /* Lets us get back the wiphy on the callback */
204 int (*reg_notifier)(struct wiphy *wiphy, enum reg_set_by setby);
205
200 /* fields below are read-only, assigned by cfg80211 */ 206 /* fields below are read-only, assigned by cfg80211 */
201 207
202 /* the item in /sys/class/ieee80211/ points to this, 208 /* the item in /sys/class/ieee80211/ points to this,
@@ -322,6 +328,58 @@ extern int ieee80211_frequency_to_channel(int freq);
322 */ 328 */
323extern struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy, 329extern struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
324 int freq); 330 int freq);
331/**
332 * __regulatory_hint - hint to the wireless core a regulatory domain
333 * @wiphy: if a driver is providing the hint this is the driver's very
334 * own &struct wiphy
335 * @alpha2: the ISO/IEC 3166 alpha2 being claimed the regulatory domain
336 * should be in. If @rd is set this should be NULL
337 * @rd: a complete regulatory domain, if passed the caller need not worry
338 * about freeing it
339 *
340 * The Wireless subsystem can use this function to hint to the wireless core
341 * what it believes should be the current regulatory domain by
342 * giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory
343 * domain should be in or by providing a completely build regulatory domain.
344 *
345 * Returns -EALREADY if *a regulatory domain* has already been set. Note that
346 * this could be by another driver. It is safe for drivers to continue if
347 * -EALREADY is returned, if drivers are not capable of world roaming they
348 * should not register more channels than they support. Right now we only
349 * support listening to the first driver hint. If the driver is capable
350 * of world roaming but wants to respect its own EEPROM mappings for
351 * specific regulatory domains it should register the @reg_notifier callback
352 * on the &struct wiphy. Returns 0 if the hint went through fine or through an
353 * intersection operation. Otherwise a standard error code is returned.
354 *
355 */
356extern int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
357 const char *alpha2, struct ieee80211_regdomain *rd);
358/**
359 * regulatory_hint - driver hint to the wireless core a regulatory domain
360 * @wiphy: the driver's very own &struct wiphy
361 * @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain
362 * should be in. If @rd is set this should be NULL. Note that if you
363 * set this to NULL you should still set rd->alpha2 to some accepted
364 * alpha2.
365 * @rd: a complete regulatory domain provided by the driver. If passed
366 * the driver does not need to worry about freeing it.
367 *
368 * Wireless drivers can use this function to hint to the wireless core
369 * what it believes should be the current regulatory domain by
370 * giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory
371 * domain should be in or by providing a completely build regulatory domain.
372 * If the driver provides an ISO/IEC 3166 alpha2 userspace will be queried
373 * for a regulatory domain structure for the respective country. If
374 * a regulatory domain is build and passed you should set the alpha2
375 * if possible, otherwise set it to the special value of "99" which tells
376 * the wireless core it is unknown. If you pass a built regulatory domain
377 * and we return non zero you are in charge of kfree()'ing the structure.
378 *
379 * See __regulatory_hint() documentation for possible return values.
380 */
381extern int regulatory_hint(struct wiphy *wiphy,
382 const char *alpha2, struct ieee80211_regdomain *rd);
325 383
326/** 384/**
327 * ieee80211_get_channel - get channel struct from wiphy for specified frequency 385 * ieee80211_get_channel - get channel struct from wiphy for specified frequency