The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net80211/ieee80211_regdomain.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2005-2007 Sam Leffler, Errno Consulting
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   24  */
   25 
   26 #include <sys/cdefs.h>
   27 __FBSDID("$FreeBSD$");
   28 
   29 /*
   30  * IEEE 802.11 regdomain support.
   31  */
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h> 
   35 #include <sys/kernel.h>
   36  
   37 #include <sys/socket.h>
   38 
   39 #include <net/if.h>
   40 #include <net/if_arp.h>
   41 #include <net/if_dl.h>
   42 #include <net/if_media.h>
   43 #include <net/if_types.h>
   44 #include <net/ethernet.h>
   45 
   46 #include <net80211/ieee80211_var.h>
   47 #include <net80211/ieee80211_regdomain.h>
   48 
   49 void
   50 ieee80211_regdomain_attach(struct ieee80211com *ic)
   51 {
   52         ic->ic_regdomain = 0;                   /* XXX */
   53         ic->ic_countrycode = CTRY_UNITED_STATES;/* XXX */
   54         ic->ic_location = 1+2;                  /* both */
   55 }
   56 
   57 void
   58 ieee80211_regdomain_detach(struct ieee80211com *ic)
   59 {
   60 }
   61 
   62 static void
   63 addchan(struct ieee80211com *ic, int ieee, int flags)
   64 {
   65         struct ieee80211_channel *c;
   66 
   67         c = &ic->ic_channels[ic->ic_nchans++];
   68         c->ic_freq = ieee80211_ieee2mhz(ieee, flags);
   69         c->ic_ieee = ieee;
   70         c->ic_flags = flags;
   71 }
   72 
   73 /*
   74  * Setup the channel list for the specified regulatory domain,
   75  * country code, and operating modes.  This interface is used
   76  * when a driver does not obtain the channel list from another
   77  * source (such as firmware).
   78  */
   79 void
   80 ieee80211_init_channels(struct ieee80211com *ic,
   81         int rd, enum ISOCountryCode cc, int bands, int outdoor, int ecm)
   82 {
   83         int i;
   84 
   85         /* XXX just do something for now */
   86         ic->ic_nchans = 0;
   87         if (isset(&bands, IEEE80211_MODE_11B) ||
   88             isset(&bands, IEEE80211_MODE_11G)) {
   89                 for (i = 1; i <= (ecm ? 14 : 11); i++) {
   90                         if (isset(&bands, IEEE80211_MODE_11B))
   91                                 addchan(ic, i, IEEE80211_CHAN_B);
   92                         if (isset(&bands, IEEE80211_MODE_11G))
   93                                 addchan(ic, i, IEEE80211_CHAN_G);
   94                 }
   95         }
   96         if (isset(&bands, IEEE80211_MODE_11A)) {
   97                 for (i = 36; i <= 64; i += 4)
   98                         addchan(ic, i, IEEE80211_CHAN_A);
   99                 for (i = 100; i <= 140; i += 4)
  100                         addchan(ic, i, IEEE80211_CHAN_A);
  101                 for (i = 149; i <= 161; i += 4)
  102                         addchan(ic, i, IEEE80211_CHAN_A);
  103         }
  104         ic->ic_regdomain = rd;
  105         ic->ic_countrycode = cc;
  106         ic->ic_location = outdoor;
  107 }
  108 
  109 /*
  110  * Add Country Information IE.
  111  */
  112 uint8_t *
  113 ieee80211_add_countryie(uint8_t *frm, struct ieee80211com *ic,
  114         enum ISOCountryCode cc, int location)
  115 {
  116 #define CHAN_UNINTERESTING \
  117     (IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO | \
  118      IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER)
  119         /* XXX what about auto? */
  120         /* flag set of channels to be excluded */
  121         static const int skipflags[IEEE80211_MODE_MAX] = {
  122             CHAN_UNINTERESTING,                         /* MODE_AUTO */
  123             CHAN_UNINTERESTING | IEEE80211_CHAN_2GHZ,   /* MODE_11A */
  124             CHAN_UNINTERESTING | IEEE80211_CHAN_5GHZ,   /* MODE_11B */
  125             CHAN_UNINTERESTING | IEEE80211_CHAN_5GHZ,   /* MODE_11G */
  126             CHAN_UNINTERESTING | IEEE80211_CHAN_OFDM |  /* MODE_FH */
  127                 IEEE80211_CHAN_CCK | IEEE80211_CHAN_DYN,
  128             CHAN_UNINTERESTING | IEEE80211_CHAN_2GHZ,   /* MODE_TURBO_A */
  129             CHAN_UNINTERESTING | IEEE80211_CHAN_5GHZ,   /* MODE_TURBO_G */
  130             CHAN_UNINTERESTING | IEEE80211_CHAN_2GHZ,   /* MODE_STURBO_A */
  131             CHAN_UNINTERESTING | IEEE80211_CHAN_2GHZ,   /* MODE_11NA */
  132             CHAN_UNINTERESTING | IEEE80211_CHAN_5GHZ,   /* MODE_11NG */
  133         };
  134         struct ieee80211_country_ie *ie = (struct ieee80211_country_ie *)frm;
  135         const char *iso_name;
  136         uint8_t nextchan, chans[IEEE80211_CHAN_BYTES];
  137         int i, skip;
  138 
  139         ie->ie = IEEE80211_ELEMID_COUNTRY;
  140         iso_name = ieee80211_cctoiso(cc);
  141         if (iso_name == NULL) {
  142                 if_printf(ic->ic_ifp, "bad country code %d ignored\n", cc);
  143                 iso_name = "  ";
  144         }
  145         ie->cc[0] = iso_name[0];
  146         ie->cc[1] = iso_name[1];
  147         /* 
  148          * Indoor/Outdoor portion of country string.
  149          * NB: this is not quite right, since we should have one of:
  150          *     'I' indoor only
  151          *     'O' outdoor only
  152          *     ' ' all enviroments
  153          */
  154         ie->cc[2] = ((location & 3) == 3 ? ' ' : location & 1 ? 'I' : 'O');
  155 
  156         /* 
  157          * Run-length encoded channel+max tx power info.
  158          */
  159         frm = (uint8_t *)&ie->band[0];
  160         nextchan = 0;                   /* NB: impossible channel # */
  161         memset(chans, 0, sizeof(chans));
  162         skip = skipflags[ic->ic_curmode];
  163         for (i = 0; i < ic->ic_nchans; i++) {
  164                 const struct ieee80211_channel *c = &ic->ic_channels[i];
  165 
  166                 if (isset(chans, c->ic_ieee))           /* suppress dup's */
  167                         continue;
  168                 if (c->ic_flags & skip)                 /* skip band, etc. */
  169                         continue;
  170                 setbit(chans, c->ic_ieee);
  171                 if (c->ic_ieee != nextchan ||
  172                     c->ic_maxregpower != frm[-1]) {     /* new run */
  173                         /* XXX max of 83 runs */
  174                         frm[0] = c->ic_ieee;            /* starting channel # */
  175                         frm[1] = 1;                     /* # channels in run */
  176                         frm[2] = c->ic_maxregpower;     /* tx power cap */
  177                         frm += 3;
  178                         nextchan = c->ic_ieee + 1;      /* overflow? */
  179                 } else {                                /* extend run */
  180                         frm[-2]++;
  181                         nextchan++;
  182                 }
  183         }
  184         ie->len = frm - ie->cc;
  185         if (ie->len & 1) {              /* Zero pad to multiple of 2 */
  186                 ie->len++;
  187                 *frm++ = 0;
  188         }
  189         return frm;
  190 #undef CHAN_UNINTERESTING
  191 }
  192 
  193 /*
  194  * Country Code Table for code-to-string conversion.
  195  */
  196 static const struct {
  197         enum ISOCountryCode iso_code;      
  198         const char*     iso_name;
  199 } country_strings[] = {
  200     { CTRY_DEBUG,               "DB" },         /* NB: nonstandard */
  201     { CTRY_DEFAULT,             "NA" },         /* NB: nonstandard */
  202     { CTRY_ALBANIA,             "AL" },
  203     { CTRY_ALGERIA,             "DZ" },
  204     { CTRY_ARGENTINA,           "AR" },
  205     { CTRY_ARMENIA,             "AM" },
  206     { CTRY_AUSTRALIA,           "AU" },
  207     { CTRY_AUSTRIA,             "AT" },
  208     { CTRY_AZERBAIJAN,          "AZ" },
  209     { CTRY_BAHRAIN,             "BH" },
  210     { CTRY_BELARUS,             "BY" },
  211     { CTRY_BELGIUM,             "BE" },
  212     { CTRY_BELIZE,              "BZ" },
  213     { CTRY_BOLIVIA,             "BO" },
  214     { CTRY_BRAZIL,              "BR" },
  215     { CTRY_BRUNEI_DARUSSALAM,   "BN" },
  216     { CTRY_BULGARIA,            "BG" },
  217     { CTRY_CANADA,              "CA" },
  218     { CTRY_CHILE,               "CL" },
  219     { CTRY_CHINA,               "CN" },
  220     { CTRY_COLOMBIA,            "CO" },
  221     { CTRY_COSTA_RICA,          "CR" },
  222     { CTRY_CROATIA,             "HR" },
  223     { CTRY_CYPRUS,              "CY" },
  224     { CTRY_CZECH,               "CZ" },
  225     { CTRY_DENMARK,             "DK" },
  226     { CTRY_DOMINICAN_REPUBLIC,  "DO" },
  227     { CTRY_ECUADOR,             "EC" },
  228     { CTRY_EGYPT,               "EG" },
  229     { CTRY_EL_SALVADOR,         "SV" },    
  230     { CTRY_ESTONIA,             "EE" },
  231     { CTRY_FINLAND,             "FI" },
  232     { CTRY_FRANCE,              "FR" },
  233     { CTRY_FRANCE2,             "F2" },
  234     { CTRY_GEORGIA,             "GE" },
  235     { CTRY_GERMANY,             "DE" },
  236     { CTRY_GREECE,              "GR" },
  237     { CTRY_GUATEMALA,           "GT" },
  238     { CTRY_HONDURAS,            "HN" },
  239     { CTRY_HONG_KONG,           "HK" },
  240     { CTRY_HUNGARY,             "HU" },
  241     { CTRY_ICELAND,             "IS" },
  242     { CTRY_INDIA,               "IN" },
  243     { CTRY_INDONESIA,           "ID" },
  244     { CTRY_IRAN,                "IR" },
  245     { CTRY_IRELAND,             "IE" },
  246     { CTRY_ISRAEL,              "IL" },
  247     { CTRY_ITALY,               "IT" },
  248     { CTRY_JAMAICA,             "JM" },
  249     { CTRY_JAPAN,               "JP" },
  250     { CTRY_JAPAN1,              "J1" },
  251     { CTRY_JAPAN2,              "J2" },    
  252     { CTRY_JAPAN3,              "J3" },
  253     { CTRY_JAPAN4,              "J4" },
  254     { CTRY_JAPAN5,              "J5" },    
  255     { CTRY_JORDAN,              "JO" },
  256     { CTRY_KAZAKHSTAN,          "KZ" },
  257     { CTRY_KOREA_NORTH,         "KP" },
  258     { CTRY_KOREA_ROC,           "KR" },
  259     { CTRY_KOREA_ROC2,          "K2" },
  260     { CTRY_KUWAIT,              "KW" },
  261     { CTRY_LATVIA,              "LV" },
  262     { CTRY_LEBANON,             "LB" },
  263     { CTRY_LIECHTENSTEIN,       "LI" },
  264     { CTRY_LITHUANIA,           "LT" },
  265     { CTRY_LUXEMBOURG,          "LU" },
  266     { CTRY_MACAU,               "MO" },
  267     { CTRY_MACEDONIA,           "MK" },
  268     { CTRY_MALAYSIA,            "MY" },
  269     { CTRY_MEXICO,              "MX" },
  270     { CTRY_MONACO,              "MC" },
  271     { CTRY_MOROCCO,             "MA" },
  272     { CTRY_NETHERLANDS,         "NL" },
  273     { CTRY_NEW_ZEALAND,         "NZ" },
  274     { CTRY_NORWAY,              "NO" },
  275     { CTRY_OMAN,                "OM" },
  276     { CTRY_PAKISTAN,            "PK" },
  277     { CTRY_PANAMA,              "PA" },
  278     { CTRY_PERU,                "PE" },
  279     { CTRY_PHILIPPINES,         "PH" },
  280     { CTRY_POLAND,              "PL" },
  281     { CTRY_PORTUGAL,            "PT" },
  282     { CTRY_PUERTO_RICO,         "PR" },
  283     { CTRY_QATAR,               "QA" },
  284     { CTRY_ROMANIA,             "RO" },
  285     { CTRY_RUSSIA,              "RU" },
  286     { CTRY_SAUDI_ARABIA,        "SA" },
  287     { CTRY_SINGAPORE,           "SG" },
  288     { CTRY_SLOVAKIA,            "SK" },
  289     { CTRY_SLOVENIA,            "SI" },
  290     { CTRY_SOUTH_AFRICA,        "ZA" },
  291     { CTRY_SPAIN,               "ES" },
  292     { CTRY_SWEDEN,              "SE" },
  293     { CTRY_SWITZERLAND,         "CH" },
  294     { CTRY_SYRIA,               "SY" },
  295     { CTRY_TAIWAN,              "TW" },
  296     { CTRY_THAILAND,            "TH" },
  297     { CTRY_TRINIDAD_Y_TOBAGO,   "TT" },
  298     { CTRY_TUNISIA,             "TN" },
  299     { CTRY_TURKEY,              "TR" },
  300     { CTRY_UKRAINE,             "UA" },
  301     { CTRY_UAE,                 "AE" },
  302     { CTRY_UNITED_KINGDOM,      "GB" },
  303     { CTRY_UNITED_STATES,       "US" },
  304     { CTRY_URUGUAY,             "UY" },
  305     { CTRY_UZBEKISTAN,          "UZ" },    
  306     { CTRY_VENEZUELA,           "VE" },
  307     { CTRY_VIET_NAM,            "VN" },
  308     { CTRY_YEMEN,               "YE" },
  309     { CTRY_ZIMBABWE,            "ZW" }    
  310 };
  311 
  312 const char *
  313 ieee80211_cctoiso(enum ISOCountryCode cc)
  314 {
  315 #define N(a)    (sizeof(a) / sizeof(a[0]))
  316         int i;
  317 
  318         for (i = 0; i < N(country_strings); i++) {
  319                 if (country_strings[i].iso_code == cc)
  320                         return country_strings[i].iso_name;
  321         }
  322         return NULL;
  323 #undef N
  324 }
  325 
  326 int
  327 ieee80211_isotocc(const char iso[2])
  328 {
  329 #define N(a)    (sizeof(a) / sizeof(a[0]))
  330         int i;
  331 
  332         for (i = 0; i < N(country_strings); i++) {
  333                 if (country_strings[i].iso_name[0] == iso[0] &&
  334                     country_strings[i].iso_name[1] == iso[1])
  335                         return country_strings[i].iso_code;
  336         }
  337         return -1;
  338 #undef N
  339 }

Cache object: e308cddde089b979b0a02076d2090ead


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.