~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/networking/regulatory.rst

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php