regd.c revision a44ea6ffbbf716cca9c2abaa4a3a3a9a9ce7c75a
1/* 2 * Copyright (c) 2008-2009 Atheros Communications Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18 19#include <linux/kernel.h> 20#include <linux/export.h> 21#include <net/cfg80211.h> 22#include <net/mac80211.h> 23#include "regd.h" 24#include "regd_common.h" 25 26static int __ath_regd_init(struct ath_regulatory *reg); 27 28/* 29 * This is a set of common rules used by our world regulatory domains. 30 * We have 12 world regulatory domains. To save space we consolidate 31 * the regulatory domains in 5 structures by frequency and change 32 * the flags on our reg_notifier() on a case by case basis. 33 */ 34 35/* Only these channels all allow active scan on all world regulatory domains */ 36#define ATH9K_2GHZ_CH01_11 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0) 37 38/* We enable active scan on these a case by case basis by regulatory domain */ 39#define ATH9K_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\ 40 NL80211_RRF_NO_IR) 41#define ATH9K_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\ 42 NL80211_RRF_NO_IR | \ 43 NL80211_RRF_NO_OFDM) 44 45/* We allow IBSS on these on a case by case basis by regulatory domain */ 46#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\ 47 NL80211_RRF_NO_IR) 48#define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\ 49 NL80211_RRF_NO_IR) 50#define ATH9K_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 80, 0, 30,\ 51 NL80211_RRF_NO_IR) 52 53#define ATH9K_2GHZ_ALL ATH9K_2GHZ_CH01_11, \ 54 ATH9K_2GHZ_CH12_13, \ 55 ATH9K_2GHZ_CH14 56 57#define ATH9K_5GHZ_ALL ATH9K_5GHZ_5150_5350, \ 58 ATH9K_5GHZ_5470_5850 59 60/* This one skips what we call "mid band" */ 61#define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \ 62 ATH9K_5GHZ_5725_5850 63 64/* Can be used for: 65 * 0x60, 0x61, 0x62 */ 66static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = { 67 .n_reg_rules = 5, 68 .alpha2 = "99", 69 .reg_rules = { 70 ATH9K_2GHZ_ALL, 71 ATH9K_5GHZ_ALL, 72 } 73}; 74 75/* Can be used by 0x63 and 0x65 */ 76static const struct ieee80211_regdomain ath_world_regdom_63_65 = { 77 .n_reg_rules = 4, 78 .alpha2 = "99", 79 .reg_rules = { 80 ATH9K_2GHZ_CH01_11, 81 ATH9K_2GHZ_CH12_13, 82 ATH9K_5GHZ_NO_MIDBAND, 83 } 84}; 85 86/* Can be used by 0x64 only */ 87static const struct ieee80211_regdomain ath_world_regdom_64 = { 88 .n_reg_rules = 3, 89 .alpha2 = "99", 90 .reg_rules = { 91 ATH9K_2GHZ_CH01_11, 92 ATH9K_5GHZ_NO_MIDBAND, 93 } 94}; 95 96/* Can be used by 0x66 and 0x69 */ 97static const struct ieee80211_regdomain ath_world_regdom_66_69 = { 98 .n_reg_rules = 3, 99 .alpha2 = "99", 100 .reg_rules = { 101 ATH9K_2GHZ_CH01_11, 102 ATH9K_5GHZ_ALL, 103 } 104}; 105 106/* Can be used by 0x67, 0x68, 0x6A and 0x6C */ 107static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = { 108 .n_reg_rules = 4, 109 .alpha2 = "99", 110 .reg_rules = { 111 ATH9K_2GHZ_CH01_11, 112 ATH9K_2GHZ_CH12_13, 113 ATH9K_5GHZ_ALL, 114 } 115}; 116 117static bool dynamic_country_user_possible(struct ath_regulatory *reg) 118{ 119 if (config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING)) 120 return true; 121 122 switch (reg->country_code) { 123 case CTRY_UNITED_STATES: 124 case CTRY_JAPAN1: 125 case CTRY_JAPAN2: 126 case CTRY_JAPAN3: 127 case CTRY_JAPAN4: 128 case CTRY_JAPAN5: 129 case CTRY_JAPAN6: 130 case CTRY_JAPAN7: 131 case CTRY_JAPAN8: 132 case CTRY_JAPAN9: 133 case CTRY_JAPAN10: 134 case CTRY_JAPAN11: 135 case CTRY_JAPAN12: 136 case CTRY_JAPAN13: 137 case CTRY_JAPAN14: 138 case CTRY_JAPAN15: 139 case CTRY_JAPAN16: 140 case CTRY_JAPAN17: 141 case CTRY_JAPAN18: 142 case CTRY_JAPAN19: 143 case CTRY_JAPAN20: 144 case CTRY_JAPAN21: 145 case CTRY_JAPAN22: 146 case CTRY_JAPAN23: 147 case CTRY_JAPAN24: 148 case CTRY_JAPAN25: 149 case CTRY_JAPAN26: 150 case CTRY_JAPAN27: 151 case CTRY_JAPAN28: 152 case CTRY_JAPAN29: 153 case CTRY_JAPAN30: 154 case CTRY_JAPAN31: 155 case CTRY_JAPAN32: 156 case CTRY_JAPAN33: 157 case CTRY_JAPAN34: 158 case CTRY_JAPAN35: 159 case CTRY_JAPAN36: 160 case CTRY_JAPAN37: 161 case CTRY_JAPAN38: 162 case CTRY_JAPAN39: 163 case CTRY_JAPAN40: 164 case CTRY_JAPAN41: 165 case CTRY_JAPAN42: 166 case CTRY_JAPAN43: 167 case CTRY_JAPAN44: 168 case CTRY_JAPAN45: 169 case CTRY_JAPAN46: 170 case CTRY_JAPAN47: 171 case CTRY_JAPAN48: 172 case CTRY_JAPAN49: 173 case CTRY_JAPAN50: 174 case CTRY_JAPAN51: 175 case CTRY_JAPAN52: 176 case CTRY_JAPAN53: 177 case CTRY_JAPAN54: 178 case CTRY_JAPAN55: 179 case CTRY_JAPAN56: 180 case CTRY_JAPAN57: 181 case CTRY_JAPAN58: 182 case CTRY_JAPAN59: 183 return false; 184 } 185 186 return true; 187} 188 189static inline bool is_wwr_sku(u16 regd) 190{ 191 return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) && 192 (((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) || 193 (regd == WORLD)); 194} 195 196static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) 197{ 198 return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG; 199} 200 201bool ath_is_world_regd(struct ath_regulatory *reg) 202{ 203 return is_wwr_sku(ath_regd_get_eepromRD(reg)); 204} 205EXPORT_SYMBOL(ath_is_world_regd); 206 207static const struct ieee80211_regdomain *ath_default_world_regdomain(void) 208{ 209 /* this is the most restrictive */ 210 return &ath_world_regdom_64; 211} 212 213static const struct 214ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) 215{ 216 switch (reg->regpair->regDmnEnum) { 217 case 0x60: 218 case 0x61: 219 case 0x62: 220 return &ath_world_regdom_60_61_62; 221 case 0x63: 222 case 0x65: 223 return &ath_world_regdom_63_65; 224 case 0x64: 225 return &ath_world_regdom_64; 226 case 0x66: 227 case 0x69: 228 return &ath_world_regdom_66_69; 229 case 0x67: 230 case 0x68: 231 case 0x6A: 232 case 0x6C: 233 return &ath_world_regdom_67_68_6A_6C; 234 default: 235 WARN_ON(1); 236 return ath_default_world_regdomain(); 237 } 238} 239 240bool ath_is_49ghz_allowed(u16 regdomain) 241{ 242 /* possibly more */ 243 return regdomain == MKK9_MKKC; 244} 245EXPORT_SYMBOL(ath_is_49ghz_allowed); 246 247/* Frequency is one where radar detection is required */ 248static bool ath_is_radar_freq(u16 center_freq) 249{ 250 return (center_freq >= 5260 && center_freq <= 5700); 251} 252 253static void ath_force_clear_no_ir_chan(struct wiphy *wiphy, 254 struct ieee80211_channel *ch) 255{ 256 const struct ieee80211_reg_rule *reg_rule; 257 258 reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq)); 259 if (IS_ERR(reg_rule)) 260 return; 261 262 if (!(reg_rule->flags & NL80211_RRF_NO_IR)) 263 if (ch->flags & IEEE80211_CHAN_NO_IR) 264 ch->flags &= ~IEEE80211_CHAN_NO_IR; 265} 266 267static void ath_force_clear_no_ir_freq(struct wiphy *wiphy, u16 center_freq) 268{ 269 struct ieee80211_channel *ch; 270 271 ch = ieee80211_get_channel(wiphy, center_freq); 272 if (!ch) 273 return; 274 275 ath_force_clear_no_ir_chan(wiphy, ch); 276} 277 278static void ath_force_no_ir_chan(struct ieee80211_channel *ch) 279{ 280 ch->flags |= IEEE80211_CHAN_NO_IR; 281} 282 283static void ath_force_no_ir_freq(struct wiphy *wiphy, u16 center_freq) 284{ 285 struct ieee80211_channel *ch; 286 287 ch = ieee80211_get_channel(wiphy, center_freq); 288 if (!ch) 289 return; 290 291 ath_force_no_ir_chan(ch); 292} 293 294static void 295__ath_reg_apply_beaconing_flags(struct wiphy *wiphy, 296 enum nl80211_reg_initiator initiator, 297 struct ieee80211_channel *ch) 298{ 299 if (ath_is_radar_freq(ch->center_freq) || 300 (ch->flags & IEEE80211_CHAN_RADAR)) 301 return; 302 303 switch (initiator) { 304 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 305 ath_force_clear_no_ir_chan(wiphy, ch); 306 break; 307 default: 308 if (ch->beacon_found) 309 ch->flags &= ~IEEE80211_CHAN_NO_IR; 310 } 311} 312 313/* 314 * These exception rules do not apply radar frequencies. 315 * 316 * - We enable initiating radiation if the country IE says its fine: 317 * - If no country IE has been processed and a we determine we have 318 * received a beacon on a channel we can enable initiating radiation. 319 */ 320static void 321ath_reg_apply_beaconing_flags(struct wiphy *wiphy, 322 enum nl80211_reg_initiator initiator) 323{ 324 enum ieee80211_band band; 325 struct ieee80211_supported_band *sband; 326 struct ieee80211_channel *ch; 327 unsigned int i; 328 329 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 330 if (!wiphy->bands[band]) 331 continue; 332 sband = wiphy->bands[band]; 333 for (i = 0; i < sband->n_channels; i++) { 334 ch = &sband->channels[i]; 335 __ath_reg_apply_beaconing_flags(wiphy, initiator, ch); 336 337 } 338 } 339} 340 341/** 342 * ath_reg_apply_ir_flags() 343 * @wiphy: the wiphy to use 344 * @initiator: the regulatory hint initiator 345 * 346 * If no country IE has been received always enable passive scan 347 * and no-ibss on these channels. This is only done for specific 348 * regulatory SKUs. 349 * 350 * If a country IE has been received check its rule for this 351 * channel first before enabling active scan. The passive scan 352 * would have been enforced by the initial processing of our 353 * custom regulatory domain. 354 */ 355static void 356ath_reg_apply_ir_flags(struct wiphy *wiphy, 357 enum nl80211_reg_initiator initiator) 358{ 359 struct ieee80211_supported_band *sband; 360 361 sband = wiphy->bands[IEEE80211_BAND_2GHZ]; 362 if (!sband) 363 return; 364 365 switch(initiator) { 366 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 367 ath_force_clear_no_ir_freq(wiphy, 2467); 368 ath_force_clear_no_ir_freq(wiphy, 2472); 369 break; 370 default: 371 ath_force_no_ir_freq(wiphy, 2467); 372 ath_force_no_ir_freq(wiphy, 2472); 373 } 374} 375 376/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */ 377static void ath_reg_apply_radar_flags(struct wiphy *wiphy) 378{ 379 struct ieee80211_supported_band *sband; 380 struct ieee80211_channel *ch; 381 unsigned int i; 382 383 if (!wiphy->bands[IEEE80211_BAND_5GHZ]) 384 return; 385 386 sband = wiphy->bands[IEEE80211_BAND_5GHZ]; 387 388 for (i = 0; i < sband->n_channels; i++) { 389 ch = &sband->channels[i]; 390 if (!ath_is_radar_freq(ch->center_freq)) 391 continue; 392 /* We always enable radar detection/DFS on this 393 * frequency range. Additionally we also apply on 394 * this frequency range: 395 * - If STA mode does not yet have DFS supports disable 396 * active scanning 397 * - If adhoc mode does not support DFS yet then 398 * disable adhoc in the frequency. 399 * - If AP mode does not yet support radar detection/DFS 400 * do not allow AP mode 401 */ 402 if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 403 ch->flags |= IEEE80211_CHAN_RADAR | 404 IEEE80211_CHAN_NO_IR; 405 } 406} 407 408static void ath_reg_apply_world_flags(struct wiphy *wiphy, 409 enum nl80211_reg_initiator initiator, 410 struct ath_regulatory *reg) 411{ 412 switch (reg->regpair->regDmnEnum) { 413 case 0x60: 414 case 0x63: 415 case 0x66: 416 case 0x67: 417 case 0x6C: 418 ath_reg_apply_beaconing_flags(wiphy, initiator); 419 break; 420 case 0x68: 421 ath_reg_apply_beaconing_flags(wiphy, initiator); 422 ath_reg_apply_ir_flags(wiphy, initiator); 423 break; 424 } 425} 426 427static u16 ath_regd_find_country_by_name(char *alpha2) 428{ 429 unsigned int i; 430 431 for (i = 0; i < ARRAY_SIZE(allCountries); i++) { 432 if (!memcmp(allCountries[i].isoName, alpha2, 2)) 433 return allCountries[i].countryCode; 434 } 435 436 return -1; 437} 438 439static int __ath_reg_dyn_country(struct wiphy *wiphy, 440 struct ath_regulatory *reg, 441 struct regulatory_request *request) 442{ 443 u16 country_code; 444 445 if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && 446 !ath_is_world_regd(reg)) 447 return -EINVAL; 448 449 country_code = ath_regd_find_country_by_name(request->alpha2); 450 if (country_code == (u16) -1) 451 return -EINVAL; 452 453 reg->current_rd = COUNTRY_ERD_FLAG; 454 reg->current_rd |= country_code; 455 456 __ath_regd_init(reg); 457 458 ath_reg_apply_world_flags(wiphy, request->initiator, reg); 459 460 return 0; 461} 462 463static void ath_reg_dyn_country(struct wiphy *wiphy, 464 struct ath_regulatory *reg, 465 struct regulatory_request *request) 466{ 467 if (__ath_reg_dyn_country(wiphy, reg, request)) 468 return; 469 470 printk(KERN_DEBUG "ath: regdomain 0x%0x " 471 "dynamically updated by %s\n", 472 reg->current_rd, 473 reg_initiator_name(request->initiator)); 474} 475 476static void ath_reg_dyn_country_user(struct wiphy *wiphy, 477 struct ath_regulatory *reg, 478 struct regulatory_request *request) 479{ 480 if (!config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS)) 481 return; 482 if (!dynamic_country_user_possible(reg)) 483 return; 484 ath_reg_dyn_country(wiphy, reg, request); 485} 486 487void ath_reg_notifier_apply(struct wiphy *wiphy, 488 struct regulatory_request *request, 489 struct ath_regulatory *reg) 490{ 491 struct ath_common *common = container_of(reg, struct ath_common, 492 regulatory); 493 /* We always apply this */ 494 ath_reg_apply_radar_flags(wiphy); 495 496 /* 497 * This would happen when we have sent a custom regulatory request 498 * a world regulatory domain and the scheduler hasn't yet processed 499 * any pending requests in the queue. 500 */ 501 if (!request) 502 return; 503 504 switch (request->initiator) { 505 case NL80211_REGDOM_SET_BY_CORE: 506 /* 507 * If common->reg_world_copy is world roaming it means we *were* 508 * world roaming... so we now have to restore that data. 509 */ 510 if (!ath_is_world_regd(&common->reg_world_copy)) 511 break; 512 513 memcpy(reg, &common->reg_world_copy, 514 sizeof(struct ath_regulatory)); 515 break; 516 case NL80211_REGDOM_SET_BY_DRIVER: 517 break; 518 case NL80211_REGDOM_SET_BY_USER: 519 ath_reg_dyn_country_user(wiphy, reg, request); 520 break; 521 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 522 ath_reg_dyn_country(wiphy, reg, request); 523 break; 524 } 525} 526EXPORT_SYMBOL(ath_reg_notifier_apply); 527 528static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) 529{ 530 u16 rd = ath_regd_get_eepromRD(reg); 531 int i; 532 533 if (rd & COUNTRY_ERD_FLAG) { 534 /* EEPROM value is a country code */ 535 u16 cc = rd & ~COUNTRY_ERD_FLAG; 536 printk(KERN_DEBUG 537 "ath: EEPROM indicates we should expect " 538 "a country code\n"); 539 for (i = 0; i < ARRAY_SIZE(allCountries); i++) 540 if (allCountries[i].countryCode == cc) 541 return true; 542 } else { 543 /* EEPROM value is a regpair value */ 544 if (rd != CTRY_DEFAULT) 545 printk(KERN_DEBUG "ath: EEPROM indicates we " 546 "should expect a direct regpair map\n"); 547 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) 548 if (regDomainPairs[i].regDmnEnum == rd) 549 return true; 550 } 551 printk(KERN_DEBUG 552 "ath: invalid regulatory domain/country code 0x%x\n", rd); 553 return false; 554} 555 556/* EEPROM country code to regpair mapping */ 557static struct country_code_to_enum_rd* 558ath_regd_find_country(u16 countryCode) 559{ 560 int i; 561 562 for (i = 0; i < ARRAY_SIZE(allCountries); i++) { 563 if (allCountries[i].countryCode == countryCode) 564 return &allCountries[i]; 565 } 566 return NULL; 567} 568 569/* EEPROM rd code to regpair mapping */ 570static struct country_code_to_enum_rd* 571ath_regd_find_country_by_rd(int regdmn) 572{ 573 int i; 574 575 for (i = 0; i < ARRAY_SIZE(allCountries); i++) { 576 if (allCountries[i].regDmnEnum == regdmn) 577 return &allCountries[i]; 578 } 579 return NULL; 580} 581 582/* Returns the map of the EEPROM set RD to a country code */ 583static u16 ath_regd_get_default_country(u16 rd) 584{ 585 if (rd & COUNTRY_ERD_FLAG) { 586 struct country_code_to_enum_rd *country = NULL; 587 u16 cc = rd & ~COUNTRY_ERD_FLAG; 588 589 country = ath_regd_find_country(cc); 590 if (country != NULL) 591 return cc; 592 } 593 594 return CTRY_DEFAULT; 595} 596 597static struct reg_dmn_pair_mapping* 598ath_get_regpair(int regdmn) 599{ 600 int i; 601 602 if (regdmn == NO_ENUMRD) 603 return NULL; 604 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) { 605 if (regDomainPairs[i].regDmnEnum == regdmn) 606 return ®DomainPairs[i]; 607 } 608 return NULL; 609} 610 611static int 612ath_regd_init_wiphy(struct ath_regulatory *reg, 613 struct wiphy *wiphy, 614 void (*reg_notifier)(struct wiphy *wiphy, 615 struct regulatory_request *request)) 616{ 617 const struct ieee80211_regdomain *regd; 618 619 wiphy->reg_notifier = reg_notifier; 620 wiphy->regulatory_flags |= REGULATORY_STRICT_REG; 621 622 if (ath_is_world_regd(reg)) { 623 /* 624 * Anything applied here (prior to wiphy registration) gets 625 * saved on the wiphy orig_* parameters 626 */ 627 regd = ath_world_regdomain(reg); 628 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG | 629 REGULATORY_COUNTRY_IE_FOLLOW_POWER; 630 } else { 631 /* 632 * This gets applied in the case of the absence of CRDA, 633 * it's our own custom world regulatory domain, similar to 634 * cfg80211's but we enable passive scanning. 635 */ 636 regd = ath_default_world_regdomain(); 637 } 638 wiphy_apply_custom_regulatory(wiphy, regd); 639 ath_reg_apply_radar_flags(wiphy); 640 ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); 641 return 0; 642} 643 644/* 645 * Some users have reported their EEPROM programmed with 646 * 0x8000 set, this is not a supported regulatory domain 647 * but since we have more than one user with it we need 648 * a solution for them. We default to 0x64, which is the 649 * default Atheros world regulatory domain. 650 */ 651static void ath_regd_sanitize(struct ath_regulatory *reg) 652{ 653 if (reg->current_rd != COUNTRY_ERD_FLAG) 654 return; 655 printk(KERN_DEBUG "ath: EEPROM regdomain sanitized\n"); 656 reg->current_rd = 0x64; 657} 658 659static int __ath_regd_init(struct ath_regulatory *reg) 660{ 661 struct country_code_to_enum_rd *country = NULL; 662 u16 regdmn; 663 664 if (!reg) 665 return -EINVAL; 666 667 ath_regd_sanitize(reg); 668 669 printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd); 670 671 if (!ath_regd_is_eeprom_valid(reg)) { 672 pr_err("Invalid EEPROM contents\n"); 673 return -EINVAL; 674 } 675 676 regdmn = ath_regd_get_eepromRD(reg); 677 reg->country_code = ath_regd_get_default_country(regdmn); 678 679 if (reg->country_code == CTRY_DEFAULT && 680 regdmn == CTRY_DEFAULT) { 681 printk(KERN_DEBUG "ath: EEPROM indicates default " 682 "country code should be used\n"); 683 reg->country_code = CTRY_UNITED_STATES; 684 } 685 686 if (reg->country_code == CTRY_DEFAULT) { 687 country = NULL; 688 } else { 689 printk(KERN_DEBUG "ath: doing EEPROM country->regdmn " 690 "map search\n"); 691 country = ath_regd_find_country(reg->country_code); 692 if (country == NULL) { 693 printk(KERN_DEBUG 694 "ath: no valid country maps found for " 695 "country code: 0x%0x\n", 696 reg->country_code); 697 return -EINVAL; 698 } else { 699 regdmn = country->regDmnEnum; 700 printk(KERN_DEBUG "ath: country maps to " 701 "regdmn code: 0x%0x\n", 702 regdmn); 703 } 704 } 705 706 reg->regpair = ath_get_regpair(regdmn); 707 708 if (!reg->regpair) { 709 printk(KERN_DEBUG "ath: " 710 "No regulatory domain pair found, cannot continue\n"); 711 return -EINVAL; 712 } 713 714 if (!country) 715 country = ath_regd_find_country_by_rd(regdmn); 716 717 if (country) { 718 reg->alpha2[0] = country->isoName[0]; 719 reg->alpha2[1] = country->isoName[1]; 720 } else { 721 reg->alpha2[0] = '0'; 722 reg->alpha2[1] = '0'; 723 } 724 725 printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n", 726 reg->alpha2[0], reg->alpha2[1]); 727 printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n", 728 reg->regpair->regDmnEnum); 729 730 return 0; 731} 732 733int 734ath_regd_init(struct ath_regulatory *reg, 735 struct wiphy *wiphy, 736 void (*reg_notifier)(struct wiphy *wiphy, 737 struct regulatory_request *request)) 738{ 739 struct ath_common *common = container_of(reg, struct ath_common, 740 regulatory); 741 int r; 742 743 r = __ath_regd_init(reg); 744 if (r) 745 return r; 746 747 if (ath_is_world_regd(reg)) 748 memcpy(&common->reg_world_copy, reg, 749 sizeof(struct ath_regulatory)); 750 751 ath_regd_init_wiphy(reg, wiphy, reg_notifier); 752 753 return 0; 754} 755EXPORT_SYMBOL(ath_regd_init); 756 757u32 ath_regd_get_band_ctl(struct ath_regulatory *reg, 758 enum ieee80211_band band) 759{ 760 if (!reg->regpair || 761 (reg->country_code == CTRY_DEFAULT && 762 is_wwr_sku(ath_regd_get_eepromRD(reg)))) { 763 return SD_NO_CTL; 764 } 765 766 switch (band) { 767 case IEEE80211_BAND_2GHZ: 768 return reg->regpair->reg_2ghz_ctl; 769 case IEEE80211_BAND_5GHZ: 770 return reg->regpair->reg_5ghz_ctl; 771 default: 772 return NO_CTL; 773 } 774} 775EXPORT_SYMBOL(ath_regd_get_band_ctl); 776