linux/Documentation/networking/regulatory.txt
<<
>>
Prefs
   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
  22Userspace gets a regulatory domain in the kernel by having
  23a userspace agent build it and send it via nl80211. Only
  24expected regulatory domains will be respected by the kernel.
  25
  26A currently available userspace agent which can accomplish this
  27is CRDA - central regulatory domain agent. Its documented here:
  28
  29http://wireless.kernel.org/en/developers/Regulatory/CRDA
  30
  31Essentially the kernel will send a udev event when it knows
  32it needs a new regulatory domain. A udev rule can be put in place
  33to trigger crda to send the respective regulatory domain for a
  34specific ISO/IEC 3166 alpha2.
  35
  36Below is an example udev rule which can be used:
  37
  38# Example file, should be put in /etc/udev/rules.d/regulatory.rules
  39KERNEL=="regulatory*", ACTION=="change", SUBSYSTEM=="platform", RUN+="/sbin/crda"
  40
  41The alpha2 is passed as an environment variable under the variable COUNTRY.
  42
  43Who asks for regulatory domains?
  44--------------------------------
  45
  46* Users
  47
  48Users can use iw:
  49
  50http://wireless.kernel.org/en/users/Documentation/iw
  51
  52An example:
  53
  54  # set regulatory domain to "Costa Rica"
  55  iw reg set CR
  56
  57This will request the kernel to set the regulatory domain to
  58the specificied alpha2. The kernel in turn will then ask userspace
  59to provide a regulatory domain for the alpha2 specified by the user
  60by sending a uevent.
  61
  62* Wireless subsystems for Country Information elements
  63
  64The kernel will send a uevent to inform userspace a new
  65regulatory domain is required. More on this to be added
  66as its integration is added.
  67
  68* Drivers
  69
  70If drivers determine they need a specific regulatory domain
  71set they can inform the wireless core using regulatory_hint().
  72They have two options -- they either provide an alpha2 so that
  73crda can provide back a regulatory domain for that country or
  74they can build their own regulatory domain based on internal
  75custom knowledge so the wireless core can respect it.
  76
  77*Most* drivers will rely on the first mechanism of providing a
  78regulatory hint with an alpha2. For these drivers there is an additional
  79check that can be used to ensure compliance based on custom EEPROM
  80regulatory data. This additional check can be used by drivers by
  81registering on its struct wiphy a reg_notifier() callback. This notifier
  82is called when the core's regulatory domain has been changed. The driver
  83can 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
  85internal EEPROM data. Devices drivers wishing to be capable of world
  86roaming should use this callback. More on world roaming will be
  87added to this document when its support is enabled.
  88
  89Device drivers who provide their own built regulatory domain
  90do not need a callback as the channels registered by them are
  91the only ones that will be allowed and therefore *additional*
  92channels cannot be enabled.
  93
  94Example code - drivers hinting an alpha2:
  95------------------------------------------
  96
  97This example comes from the zd1211rw device driver. You can start
  98by having a mapping of your device's EEPROM country/regulatory
  99domain value to a specific alpha2 as follows:
 100
 101static 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
 110Then you can define a routine to map your read EEPROM value to an alpha2,
 111as follows:
 112
 113static 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
 128Lastly, you can then hint to the core of your discovered alpha2, if a match
 129was found. You need to do this after you have registered your wiphy. You
 130are expected to do this during initialization.
 131
 132        r = zd_reg2alpha2(mac->regdomain, alpha2);
 133        if (!r)
 134                regulatory_hint(hw->wiphy, alpha2);
 135
 136Example 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
 141If you have regulatory information you can obtain from your
 142driver and you *need* to use this we let you build a regulatory domain
 143structure and pass it to the wireless core. To do this you should
 144kmalloc() a structure big enough to hold your regulatory domain
 145structure and you should then fill it with your data. Finally you simply
 146call regulatory_hint() with the regulatory domain structure in it.
 147
 148Bellow is a simple example, with a regulatory domain cached using the stack.
 149Your implementation may vary (read EEPROM cache instead, for example).
 150
 151Example cache of some regulatory domain
 152
 153struct 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
 170Then 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);
 191
 192Statically compiled regulatory database
 193---------------------------------------
 194
 195In most situations the userland solution using CRDA as described
 196above is the preferred solution.  However in some cases a set of
 197rules built into the kernel itself may be desirable.  To account
 198for this situation, a configuration option has been provided
 199(i.e. CONFIG_CFG80211_INTERNAL_REGDB).  With this option enabled,
 200the wireless database information contained in net/wireless/db.txt is
 201used to generate a data structure encoded in net/wireless/regdb.c.
 202That option also enables code in net/wireless/reg.c which queries
 203the data in regdb.c as an alternative to using CRDA.
 204
 205The file net/wireless/db.txt should be kept up-to-date with the db.txt
 206file available in the git repository here:
 207
 208    git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-regdb.git
 209
 210Again, most users in most situations should be using the CRDA package
 211provided with their distribution, and in most other situations users
 212should be building and using CRDA on their own rather than using
 213this option.  If you are not absolutely sure that you should be using
 214CONFIG_CFG80211_INTERNAL_REGDB then _DO_NOT_USE_IT_.
 215
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.