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