Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg...
[linux-2.6] / Documentation / networking / regulatory.txt
1 Linux wireless regulatory documentation
2 ---------------------------------------
3
4 This document gives a brief review over how the Linux wireless
5 regulatory infrastructure works.
6
7 More up to date information can be obtained at the project's web page:
8
9 http://wireless.kernel.org/en/developers/Regulatory
10
11 Keeping regulatory domains in userspace
12 ---------------------------------------
13
14 Due to the dynamic nature of regulatory domains we keep them
15 in userspace and provide a framework for userspace to upload
16 to the kernel one regulatory domain to be used as the central
17 core regulatory domain all wireless devices should adhere to.
18
19 How to get regulatory domains to the kernel
20 -------------------------------------------
21
22 Userspace gets a regulatory domain in the kernel by having
23 a userspace agent build it and send it via nl80211. Only
24 expected regulatory domains will be respected by the kernel.
25
26 A currently available userspace agent which can accomplish this
27 is CRDA - central regulatory domain agent. Its documented here:
28
29 http://wireless.kernel.org/en/developers/Regulatory/CRDA
30
31 Essentially the kernel will send a udev event when it knows
32 it needs a new regulatory domain. A udev rule can be put in place
33 to trigger crda to send the respective regulatory domain for a
34 specific ISO/IEC 3166 alpha2.
35
36 Below is an example udev rule which can be used:
37
38 # Example file, should be put in /etc/udev/rules.d/regulatory.rules
39 KERNEL=="regulatory*", ACTION=="change", SUBSYSTEM=="platform", RUN+="/sbin/crda"
40
41 The alpha2 is passed as an environment variable under the variable COUNTRY.
42
43 Who asks for regulatory domains?
44 --------------------------------
45
46 * Users
47
48 Users can use iw:
49
50 http://wireless.kernel.org/en/users/Documentation/iw
51
52 An example:
53
54   # set regulatory domain to "Costa Rica"
55   iw reg set CR
56
57 This will request the kernel to set the regulatory domain to
58 the specificied alpha2. The kernel in turn will then ask userspace
59 to provide a regulatory domain for the alpha2 specified by the user
60 by sending a uevent.
61
62 * Wireless subsystems for Country Information elements
63
64 The kernel will send a uevent to inform userspace a new
65 regulatory domain is required. More on this to be added
66 as its integration is added.
67
68 * Drivers
69
70 If drivers determine they need a specific regulatory domain
71 set they can inform the wireless core using regulatory_hint().
72 They have two options -- they either provide an alpha2 so that
73 crda can provide back a regulatory domain for that country or
74 they can build their own regulatory domain based on internal
75 custom knowledge so the wireless core can respect it.
76
77 *Most* drivers will rely on the first mechanism of providing a
78 regulatory hint with an alpha2. For these drivers there is an additional
79 check that can be used to ensure compliance based on custom EEPROM
80 regulatory data. This additional check can be used by drivers by
81 registering on its struct wiphy a reg_notifier() callback. This notifier
82 is called when the core's regulatory domain has been changed. The driver
83 can use this to review the changes made and also review who made them
84 (driver, user, country IE) and determine what to allow based on its
85 internal EEPROM data. Devices drivers wishing to be capable of world
86 roaming should use this callback. More on world roaming will be
87 added to this document when its support is enabled.
88
89 Device drivers who provide their own built regulatory domain
90 do not need a callback as the channels registered by them are
91 the only ones that will be allowed and therefore *additional*
92 cannels cannot be enabled.
93
94 Example code - drivers hinting an alpha2:
95 ------------------------------------------
96
97 This example comes from the zd1211rw device driver. You can start
98 by having a mapping of your device's EEPROM country/regulatory
99 domain value to to a specific alpha2 as follows:
100
101 static struct zd_reg_alpha2_map reg_alpha2_map[] = {
102         { ZD_REGDOMAIN_FCC, "US" },
103         { ZD_REGDOMAIN_IC, "CA" },
104         { ZD_REGDOMAIN_ETSI, "DE" }, /* Generic ETSI, use most restrictive */
105         { ZD_REGDOMAIN_JAPAN, "JP" },
106         { ZD_REGDOMAIN_JAPAN_ADD, "JP" },
107         { ZD_REGDOMAIN_SPAIN, "ES" },
108         { ZD_REGDOMAIN_FRANCE, "FR" },
109
110 Then you can define a routine to map your read EEPROM value to an alpha2,
111 as follows:
112
113 static int zd_reg2alpha2(u8 regdomain, char *alpha2)
114 {
115         unsigned int i;
116         struct zd_reg_alpha2_map *reg_map;
117                 for (i = 0; i < ARRAY_SIZE(reg_alpha2_map); i++) {
118                         reg_map = &reg_alpha2_map[i];
119                         if (regdomain == reg_map->reg) {
120                         alpha2[0] = reg_map->alpha2[0];
121                         alpha2[1] = reg_map->alpha2[1];
122                         return 0;
123                 }
124         }
125         return 1;
126 }
127
128 Lastly, you can then hint to the core of your discovered alpha2, if a match
129 was found. You need to do this after you have registered your wiphy. You
130 are expected to do this during initialization.
131
132         r = zd_reg2alpha2(mac->regdomain, alpha2);
133         if (!r)
134                 regulatory_hint(hw->wiphy, alpha2);
135
136 Example code - drivers providing a built in regulatory domain:
137 --------------------------------------------------------------
138
139 [NOTE: This API is not currently available, it can be added when required]
140
141 If you have regulatory information you can obtain from your
142 driver and you *need* to use this we let you build a regulatory domain
143 structure and pass it to the wireless core. To do this you should
144 kmalloc() a structure big enough to hold your regulatory domain
145 structure and you should then fill it with your data. Finally you simply
146 call regulatory_hint() with the regulatory domain structure in it.
147
148 Bellow is a simple example, with a regulatory domain cached using the stack.
149 Your implementation may vary (read EEPROM cache instead, for example).
150
151 Example cache of some regulatory domain
152
153 struct ieee80211_regdomain mydriver_jp_regdom = {
154         .n_reg_rules = 3,
155         .alpha2 =  "JP",
156         //.alpha2 =  "99", /* If I have no alpha2 to map it to */
157         .reg_rules = {
158                 /* IEEE 802.11b/g, channels 1..14 */
159                 REG_RULE(2412-20, 2484+20, 40, 6, 20, 0),
160                 /* IEEE 802.11a, channels 34..48 */
161                 REG_RULE(5170-20, 5240+20, 40, 6, 20,
162                         NL80211_RRF_PASSIVE_SCAN),
163                 /* IEEE 802.11a, channels 52..64 */
164                 REG_RULE(5260-20, 5320+20, 40, 6, 20,
165                         NL80211_RRF_NO_IBSS |
166                         NL80211_RRF_DFS),
167         }
168 };
169
170 Then in some part of your code after your wiphy has been registered:
171
172         struct ieee80211_regdomain *rd;
173         int size_of_regd;
174         int num_rules = mydriver_jp_regdom.n_reg_rules;
175         unsigned int i;
176
177         size_of_regd = sizeof(struct ieee80211_regdomain) +
178                 (num_rules * sizeof(struct ieee80211_reg_rule));
179
180         rd = kzalloc(size_of_regd, GFP_KERNEL);
181         if (!rd)
182                 return -ENOMEM;
183
184         memcpy(rd, &mydriver_jp_regdom, sizeof(struct ieee80211_regdomain));
185
186         for (i=0; i < num_rules; i++)
187                 memcpy(&rd->reg_rules[i],
188                        &mydriver_jp_regdom.reg_rules[i],
189                        sizeof(struct ieee80211_reg_rule));
190         regulatory_struct_hint(rd);