iPXE
ath_regd.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008-2009 Atheros Communications Inc.
00003  *
00004  * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
00005  * Original from Linux kernel 3.0.1
00006  *
00007  * Permission to use, copy, modify, and/or distribute this software for any
00008  * purpose with or without fee is hereby granted, provided that the above
00009  * copyright notice and this permission notice appear in all copies.
00010  *
00011  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00012  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00013  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
00014  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00015  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00016  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00017  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00018  */
00019 
00020 #include "regd.h"
00021 #include "regd_common.h"
00022 
00023 /*
00024  * This is a set of common rules used by our world regulatory domains.
00025  * We have 12 world regulatory domains. To save space we consolidate
00026  * the regulatory domains in 5 structures by frequency and change
00027  * the flags on our reg_notifier() on a case by case basis.
00028  */
00029 
00030 /* Only these channels all allow active scan on all world regulatory domains */
00031 #define ATH9K_2GHZ_CH01_11      REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
00032 
00033 /* We enable active scan on these a case by case basis by regulatory domain */
00034 #define ATH9K_2GHZ_CH12_13      REG_RULE(2467-10, 2472+10, 40, 0, 20,\
00035                                         NL80211_RRF_PASSIVE_SCAN)
00036 #define ATH9K_2GHZ_CH14         REG_RULE(2484-10, 2484+10, 40, 0, 20,\
00037                                 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
00038 
00039 /* We allow IBSS on these on a case by case basis by regulatory domain */
00040 #define ATH9K_5GHZ_5150_5350    REG_RULE(5150-10, 5350+10, 40, 0, 30,\
00041                                 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
00042 #define ATH9K_5GHZ_5470_5850    REG_RULE(5470-10, 5850+10, 40, 0, 30,\
00043                                 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
00044 #define ATH9K_5GHZ_5725_5850    REG_RULE(5725-10, 5850+10, 40, 0, 30,\
00045                                 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
00046 
00047 #define ATH9K_2GHZ_ALL          ATH9K_2GHZ_CH01_11, \
00048                                 ATH9K_2GHZ_CH12_13, \
00049                                 ATH9K_2GHZ_CH14
00050 
00051 #define ATH9K_5GHZ_ALL          ATH9K_5GHZ_5150_5350, \
00052                                 ATH9K_5GHZ_5470_5850
00053 
00054 /* This one skips what we call "mid band" */
00055 #define ATH9K_5GHZ_NO_MIDBAND   ATH9K_5GHZ_5150_5350, \
00056                                 ATH9K_5GHZ_5725_5850
00057 
00058 ///* Can be used for:
00059 // * 0x60, 0x61, 0x62 */
00060 //static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = {
00061 //      .n_reg_rules = 5,
00062 //      .alpha2 =  "99",
00063 //      .reg_rules = {
00064 //              ATH9K_2GHZ_ALL,
00065 //              ATH9K_5GHZ_ALL,
00066 //      }
00067 //};
00068 //
00069 ///* Can be used by 0x63 and 0x65 */
00070 //static const struct ieee80211_regdomain ath_world_regdom_63_65 = {
00071 //      .n_reg_rules = 4,
00072 //      .alpha2 =  "99",
00073 //      .reg_rules = {
00074 //              ATH9K_2GHZ_CH01_11,
00075 //              ATH9K_2GHZ_CH12_13,
00076 //              ATH9K_5GHZ_NO_MIDBAND,
00077 //      }
00078 //};
00079 //
00080 ///* Can be used by 0x64 only */
00081 //static const struct ieee80211_regdomain ath_world_regdom_64 = {
00082 //      .n_reg_rules = 3,
00083 //      .alpha2 =  "99",
00084 //      .reg_rules = {
00085 //              ATH9K_2GHZ_CH01_11,
00086 //              ATH9K_5GHZ_NO_MIDBAND,
00087 //      }
00088 //};
00089 //
00090 ///* Can be used by 0x66 and 0x69 */
00091 //static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
00092 //      .n_reg_rules = 3,
00093 //      .alpha2 =  "99",
00094 //      .reg_rules = {
00095 //              ATH9K_2GHZ_CH01_11,
00096 //              ATH9K_5GHZ_ALL,
00097 //      }
00098 //};
00099 //
00100 ///* Can be used by 0x67, 0x68, 0x6A and 0x6C */
00101 //static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
00102 //      .n_reg_rules = 4,
00103 //      .alpha2 =  "99",
00104 //      .reg_rules = {
00105 //              ATH9K_2GHZ_CH01_11,
00106 //              ATH9K_2GHZ_CH12_13,
00107 //              ATH9K_5GHZ_ALL,
00108 //      }
00109 //};
00110 //
00111 //static inline int is_wwr_sku(u16 regd)
00112 //{
00113 //      return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
00114 //              (((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
00115 //              (regd == WORLD));
00116 //}
00117 //
00118 //static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
00119 //{
00120 //      return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
00121 //}
00122 //
00123 //int ath_is_world_regd(struct ath_regulatory *reg)
00124 //{
00125 //      return is_wwr_sku(ath_regd_get_eepromRD(reg));
00126 //}
00127 //
00128 //static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
00129 //{
00130 //      /* this is the most restrictive */
00131 //      return &ath_world_regdom_64;
00132 //}
00133 //
00134 //static const struct
00135 //ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
00136 //{
00137 //      switch (reg->regpair->regDmnEnum) {
00138 //      case 0x60:
00139 //      case 0x61:
00140 //      case 0x62:
00141 //              return &ath_world_regdom_60_61_62;
00142 //      case 0x63:
00143 //      case 0x65:
00144 //              return &ath_world_regdom_63_65;
00145 //      case 0x64:
00146 //              return &ath_world_regdom_64;
00147 //      case 0x66:
00148 //      case 0x69:
00149 //              return &ath_world_regdom_66_69;
00150 //      case 0x67:
00151 //      case 0x68:
00152 //      case 0x6A:
00153 //      case 0x6C:
00154 //              return &ath_world_regdom_67_68_6A_6C;
00155 //      default:
00156 //              WARN_ON(1);
00157 //              return ath_default_world_regdomain();
00158 //      }
00159 //}
00160 //
00161 //int ath_is_49ghz_allowed(u16 regdomain)
00162 //{
00163 //      /* possibly more */
00164 //      return regdomain == MKK9_MKKC;
00165 //}
00166 //
00167 ///* Frequency is one where radar detection is required */
00168 //static int ath_is_radar_freq(u16 center_freq)
00169 //{
00170 //      return (center_freq >= 5260 && center_freq <= 5700);
00171 //}
00172 //
00173 ///*
00174 // * N.B: These exception rules do not apply radar freqs.
00175 // *
00176 // * - We enable adhoc (or beaconing) if allowed by 11d
00177 // * - We enable active scan if the channel is allowed by 11d
00178 // * - If no country IE has been processed and a we determine we have
00179 // *   received a beacon on a channel we can enable active scan and
00180 // *   adhoc (or beaconing).
00181 // */
00182 //static void
00183 //ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
00184 //                            enum nl80211_reg_initiator initiator)
00185 //{
00186 //      int band;
00187 //      struct ieee80211_supported_band *sband;
00188 //      const struct ieee80211_reg_rule *reg_rule;
00189 //      struct net80211_channel *ch;
00190 //      unsigned int i;
00191 //      u32 bandwidth = 0;
00192 //      int r;
00193 //
00194 //      for (band = 0; band < NET80211_NR_BANDS; band++) {
00195 //
00196 //              if (!wiphy->bands[band])
00197 //                      continue;
00198 //
00199 //              sband = wiphy->bands[band];
00200 //
00201 //              for (i = 0; i < sband->n_channels; i++) {
00202 //
00203 //                      ch = &sband->channels[i];
00204 //
00205 //                      if (ath_is_radar_freq(ch->center_freq) ||
00206 //                          (ch->flags & IEEE80211_CHAN_RADAR))
00207 //                              continue;
00208 //
00209 //                      if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
00210 //                              r = freq_reg_info(wiphy,
00211 //                                                ch->center_freq,
00212 //                                                bandwidth,
00213 //                                                &reg_rule);
00214 //                              if (r)
00215 //                                      continue;
00216 //                              /*
00217 //                               * If 11d had a rule for this channel ensure
00218 //                               * we enable adhoc/beaconing if it allows us to
00219 //                               * use it. Note that we would have disabled it
00220 //                               * by applying our static world regdomain by
00221 //                               * default during init, prior to calling our
00222 //                               * regulatory_hint().
00223 //                               */
00224 //                              if (!(reg_rule->flags &
00225 //                                  NL80211_RRF_NO_IBSS))
00226 //                                      ch->flags &=
00227 //                                        ~IEEE80211_CHAN_NO_IBSS;
00228 //                              if (!(reg_rule->flags &
00229 //                                  NL80211_RRF_PASSIVE_SCAN))
00230 //                                      ch->flags &=
00231 //                                        ~IEEE80211_CHAN_PASSIVE_SCAN;
00232 //                      } else {
00233 //                              if (ch->beacon_found)
00234 //                                      ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
00235 //                                        IEEE80211_CHAN_PASSIVE_SCAN);
00236 //                      }
00237 //              }
00238 //      }
00239 //
00240 //}
00241 //
00242 ///* Allows active scan scan on Ch 12 and 13 */
00243 //static void
00244 //ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
00245 //                              enum nl80211_reg_initiator initiator)
00246 //{
00247 //      struct ieee80211_supported_band *sband;
00248 //      struct net80211_channel *ch;
00249 //      const struct ieee80211_reg_rule *reg_rule;
00250 //      u32 bandwidth = 0;
00251 //      int r;
00252 //
00253 //      sband = wiphy->bands[NET80211_BAND_2GHZ];
00254 //
00255 //      /*
00256 //       * If no country IE has been received always enable active scan
00257 //       * on these channels. This is only done for specific regulatory SKUs
00258 //       */
00259 //      if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
00260 //              ch = &sband->channels[11]; /* CH 12 */
00261 //              if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
00262 //                      ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
00263 //              ch = &sband->channels[12]; /* CH 13 */
00264 //              if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
00265 //                      ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
00266 //              return;
00267 //      }
00268 //
00269 //      /*
00270 //       * If a country IE has been received check its rule for this
00271 //       * channel first before enabling active scan. The passive scan
00272 //       * would have been enforced by the initial processing of our
00273 //       * custom regulatory domain.
00274 //       */
00275 //
00276 //      ch = &sband->channels[11]; /* CH 12 */
00277 //      r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
00278 //      if (!r) {
00279 //              if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
00280 //                      if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
00281 //                              ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
00282 //      }
00283 //
00284 //      ch = &sband->channels[12]; /* CH 13 */
00285 //      r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
00286 //      if (!r) {
00287 //              if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
00288 //                      if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
00289 //                              ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
00290 //      }
00291 //}
00292 //
00293 ///* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
00294 //static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
00295 //{
00296 //      struct ieee80211_supported_band *sband;
00297 //      struct net80211_channel *ch;
00298 //      unsigned int i;
00299 //
00300 //      if (!wiphy->bands[NET80211_BAND_5GHZ])
00301 //              return;
00302 //
00303 //      sband = wiphy->bands[NET80211_BAND_5GHZ];
00304 //
00305 //      for (i = 0; i < sband->n_channels; i++) {
00306 //              ch = &sband->channels[i];
00307 //              if (!ath_is_radar_freq(ch->center_freq))
00308 //                      continue;
00309 //              /* We always enable radar detection/DFS on this
00310 //               * frequency range. Additionally we also apply on
00311 //               * this frequency range:
00312 //               * - If STA mode does not yet have DFS supports disable
00313 //               *   active scanning
00314 //               * - If adhoc mode does not support DFS yet then
00315 //               *   disable adhoc in the frequency.
00316 //               * - If AP mode does not yet support radar detection/DFS
00317 //               *   do not allow AP mode
00318 //               */
00319 //              if (!(ch->flags & IEEE80211_CHAN_DISABLED))
00320 //                      ch->flags |= IEEE80211_CHAN_RADAR |
00321 //                                   IEEE80211_CHAN_NO_IBSS |
00322 //                                   IEEE80211_CHAN_PASSIVE_SCAN;
00323 //      }
00324 //}
00325 //
00326 //static void ath_reg_apply_world_flags(struct wiphy *wiphy,
00327 //                                    enum nl80211_reg_initiator initiator,
00328 //                                    struct ath_regulatory *reg)
00329 //{
00330 //      switch (reg->regpair->regDmnEnum) {
00331 //      case 0x60:
00332 //      case 0x63:
00333 //      case 0x66:
00334 //      case 0x67:
00335 //      case 0x6C:
00336 //              ath_reg_apply_beaconing_flags(wiphy, initiator);
00337 //              break;
00338 //      case 0x68:
00339 //              ath_reg_apply_beaconing_flags(wiphy, initiator);
00340 //              ath_reg_apply_active_scan_flags(wiphy, initiator);
00341 //              break;
00342 //      }
00343 //}
00344 //
00345 //int ath_reg_notifier_apply(struct wiphy *wiphy,
00346 //                         struct regulatory_request *request,
00347 //                         struct ath_regulatory *reg)
00348 //{
00349 //      /* We always apply this */
00350 //      ath_reg_apply_radar_flags(wiphy);
00351 //
00352 //      /*
00353 //       * This would happen when we have sent a custom regulatory request
00354 //       * a world regulatory domain and the scheduler hasn't yet processed
00355 //       * any pending requests in the queue.
00356 //       */
00357 //      if (!request)
00358 //              return 0;
00359 //
00360 //      switch (request->initiator) {
00361 //      case NL80211_REGDOM_SET_BY_DRIVER:
00362 //      case NL80211_REGDOM_SET_BY_CORE:
00363 //      case NL80211_REGDOM_SET_BY_USER:
00364 //              break;
00365 //      case NL80211_REGDOM_SET_BY_COUNTRY_IE:
00366 //              if (ath_is_world_regd(reg))
00367 //                      ath_reg_apply_world_flags(wiphy, request->initiator,
00368 //                                                reg);
00369 //              break;
00370 //      }
00371 //
00372 //      return 0;
00373 //}
00374 //
00375 //static int ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
00376 //{
00377 //      u16 rd = ath_regd_get_eepromRD(reg);
00378 //      int i;
00379 //
00380 //      if (rd & COUNTRY_ERD_FLAG) {
00381 //              /* EEPROM value is a country code */
00382 //              u16 cc = rd & ~COUNTRY_ERD_FLAG;
00383 //              DBG2(
00384 //                     "ath: EEPROM indicates we should expect "
00385 //                      "a country code\n");
00386 //              for (i = 0; i < ARRAY_SIZE(allCountries); i++)
00387 //                      if (allCountries[i].countryCode == cc)
00388 //                              return 1;
00389 //      } else {
00390 //              /* EEPROM value is a regpair value */
00391 //              if (rd != CTRY_DEFAULT)
00392 //                      DBG2("ath: EEPROM indicates we "
00393 //                             "should expect a direct regpair map\n");
00394 //              for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
00395 //                      if (regDomainPairs[i].regDmnEnum == rd)
00396 //                              return 1;
00397 //      }
00398 //      DBG(
00399 //               "ath: invalid regulatory domain/country code 0x%x\n", rd);
00400 //      return 0;
00401 //}
00402 //
00403 ///* EEPROM country code to regpair mapping */
00404 //static struct country_code_to_enum_rd*
00405 //ath_regd_find_country(u16 countryCode)
00406 //{
00407 //      int i;
00408 //
00409 //      for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
00410 //              if (allCountries[i].countryCode == countryCode)
00411 //                      return &allCountries[i];
00412 //      }
00413 //      return NULL;
00414 //}
00415 //
00416 ///* EEPROM rd code to regpair mapping */
00417 //static struct country_code_to_enum_rd*
00418 //ath_regd_find_country_by_rd(int regdmn)
00419 //{
00420 //      int i;
00421 //
00422 //      for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
00423 //              if (allCountries[i].regDmnEnum == regdmn)
00424 //                      return &allCountries[i];
00425 //      }
00426 //      return NULL;
00427 //}
00428 //
00429 ///* Returns the map of the EEPROM set RD to a country code */
00430 //static u16 ath_regd_get_default_country(u16 rd)
00431 //{
00432 //      if (rd & COUNTRY_ERD_FLAG) {
00433 //              struct country_code_to_enum_rd *country = NULL;
00434 //              u16 cc = rd & ~COUNTRY_ERD_FLAG;
00435 //
00436 //              country = ath_regd_find_country(cc);
00437 //              if (country != NULL)
00438 //                      return cc;
00439 //      }
00440 //
00441 //      return CTRY_DEFAULT;
00442 //}
00443 //
00444 //static struct reg_dmn_pair_mapping*
00445 //ath_get_regpair(int regdmn)
00446 //{
00447 //      int i;
00448 //
00449 //      if (regdmn == NO_ENUMRD)
00450 //              return NULL;
00451 //      for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
00452 //              if (regDomainPairs[i].regDmnEnum == regdmn)
00453 //                      return &regDomainPairs[i];
00454 //      }
00455 //      return NULL;
00456 //}
00457 //
00458 //static int
00459 //ath_regd_init_wiphy(struct ath_regulatory *reg,
00460 //                  struct wiphy *wiphy,
00461 //                  int (*reg_notifier)(struct wiphy *wiphy,
00462 //                                      struct regulatory_request *request))
00463 //{
00464 //      const struct ieee80211_regdomain *regd;
00465 //
00466 //      wiphy->reg_notifier = reg_notifier;
00467 //      wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
00468 //
00469 //      if (ath_is_world_regd(reg)) {
00470 //              /*
00471 //               * Anything applied here (prior to wiphy registration) gets
00472 //               * saved on the wiphy orig_* parameters
00473 //               */
00474 //              regd = ath_world_regdomain(reg);
00475 //              wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
00476 //      } else {
00477 //              /*
00478 //               * This gets applied in the case of the absence of CRDA,
00479 //               * it's our own custom world regulatory domain, similar to
00480 //               * cfg80211's but we enable passive scanning.
00481 //               */
00482 //              regd = ath_default_world_regdomain();
00483 //      }
00484 //      wiphy_apply_custom_regulatory(wiphy, regd);
00485 //      ath_reg_apply_radar_flags(wiphy);
00486 //      ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
00487 //      return 0;
00488 //}
00489 //
00490 ///*
00491 // * Some users have reported their EEPROM programmed with
00492 // * 0x8000 set, this is not a supported regulatory domain
00493 // * but since we have more than one user with it we need
00494 // * a solution for them. We default to 0x64, which is the
00495 // * default Atheros world regulatory domain.
00496 // */
00497 //static void ath_regd_sanitize(struct ath_regulatory *reg)
00498 //{
00499 //      if (reg->current_rd != COUNTRY_ERD_FLAG)
00500 //              return;
00501 //      DBG2("ath: EEPROM regdomain sanitized\n");
00502 //      reg->current_rd = 0x64;
00503 //}
00504 //
00505 //int
00506 //ath_regd_init(struct ath_regulatory *reg,
00507 //            struct wiphy *wiphy,
00508 //            int (*reg_notifier)(struct wiphy *wiphy,
00509 //                                struct regulatory_request *request))
00510 //{
00511 //      struct country_code_to_enum_rd *country = NULL;
00512 //      u16 regdmn;
00513 //
00514 //      if (!reg)
00515 //              return -EINVAL;
00516 //
00517 //      ath_regd_sanitize(reg);
00518 //
00519 //      DBG2("ath: EEPROM regdomain: 0x%0x\n", reg->current_rd);
00520 //
00521 //      if (!ath_regd_is_eeprom_valid(reg)) {
00522 //              DBG("ath: Invalid EEPROM contents\n");
00523 //              return -EINVAL;
00524 //      }
00525 //
00526 //      regdmn = ath_regd_get_eepromRD(reg);
00527 //      reg->country_code = ath_regd_get_default_country(regdmn);
00528 //
00529 //      if (reg->country_code == CTRY_DEFAULT &&
00530 //          regdmn == CTRY_DEFAULT) {
00531 //              DBG2("ath: EEPROM indicates default "
00532 //                     "country code should be used\n");
00533 //              reg->country_code = CTRY_UNITED_STATES;
00534 //      }
00535 //
00536 //      if (reg->country_code == CTRY_DEFAULT) {
00537 //              country = NULL;
00538 //      } else {
00539 //              DBG2("ath: doing EEPROM country->regdmn "
00540 //                     "map search\n");
00541 //              country = ath_regd_find_country(reg->country_code);
00542 //              if (country == NULL) {
00543 //                      DBG(
00544 //                              "ath: no valid country maps found for "
00545 //                              "country code: 0x%0x\n",
00546 //                              reg->country_code);
00547 //                      return -EINVAL;
00548 //              } else {
00549 //                      regdmn = country->regDmnEnum;
00550 //                      DBG2("ath: country maps to "
00551 //                             "regdmn code: 0x%0x\n",
00552 //                             regdmn);
00553 //              }
00554 //      }
00555 //
00556 //      reg->regpair = ath_get_regpair(regdmn);
00557 //
00558 //      if (!reg->regpair) {
00559 //              DBG("ath: "
00560 //                      "No regulatory domain pair found, cannot continue\n");
00561 //              return -EINVAL;
00562 //      }
00563 //
00564 //      if (!country)
00565 //              country = ath_regd_find_country_by_rd(regdmn);
00566 //
00567 //      if (country) {
00568 //              reg->alpha2[0] = country->isoName[0];
00569 //              reg->alpha2[1] = country->isoName[1];
00570 //      } else {
00571 //              reg->alpha2[0] = '0';
00572 //              reg->alpha2[1] = '0';
00573 //      }
00574 //
00575 //      DBG2("ath: Country alpha2 being used: %c%c\n",
00576 //              reg->alpha2[0], reg->alpha2[1]);
00577 //      DBG2("ath: Regpair used: 0x%0x\n",
00578 //              reg->regpair->regDmnEnum);
00579 //
00580 //      ath_regd_init_wiphy(reg, wiphy, reg_notifier);
00581 //      return 0;
00582 //}
00583 
00584 u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
00585                           int band)
00586 {
00587         /* TODO Cottsay: reg */
00588 //      if (!reg->regpair ||
00589 //          (reg->country_code == CTRY_DEFAULT &&
00590 //           is_wwr_sku(ath_regd_get_eepromRD(reg)))) {
00591 //              return SD_NO_CTL;
00592 //      }
00593 
00594         switch (band) {
00595         case NET80211_BAND_2GHZ:
00596                 return reg->regpair->reg_2ghz_ctl;
00597         case NET80211_BAND_5GHZ:
00598                 return reg->regpair->reg_5ghz_ctl;
00599         default:
00600                 return NO_CTL;
00601         }
00602 }