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 #include <linux/kernel.h> 18 #include <linux/export.h> 19 #include <net/cfg80211.h> 20 #include <net/mac80211.h> 21 #include "regd.h" 22 #include "regd_common.h" 23 24 static int __ath_regd_init(struct ath_regulatory *reg); 25 26 /* 27 * This is a set of common rules used by our world regulatory domains. 28 * We have 12 world regulatory domains. To save space we consolidate 29 * the regulatory domains in 5 structures by frequency and change 30 * the flags on our reg_notifier() on a case by case basis. 31 */ 32 33 /* Only these channels all allow active scan on all world regulatory domains */ 34 #define ATH9K_2GHZ_CH01_11 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0) 35 36 /* We enable active scan on these a case by case basis by regulatory domain */ 37 #define ATH9K_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\ 38 NL80211_RRF_PASSIVE_SCAN) 39 #define ATH9K_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\ 40 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM) 41 42 /* We allow IBSS on these on a case by case basis by regulatory domain */ 43 #define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 40, 0, 30,\ 44 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) 45 #define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 40, 0, 30,\ 46 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) 47 #define ATH9K_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 40, 0, 30,\ 48 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) 49 50 #define ATH9K_2GHZ_ALL ATH9K_2GHZ_CH01_11, \ 51 ATH9K_2GHZ_CH12_13, \ 52 ATH9K_2GHZ_CH14 53 54 #define ATH9K_5GHZ_ALL ATH9K_5GHZ_5150_5350, \ 55 ATH9K_5GHZ_5470_5850 56 57 /* This one skips what we call "mid band" */ 58 #define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \ 59 ATH9K_5GHZ_5725_5850 60 61 /* Can be used for: 62 * 0x60, 0x61, 0x62 */ 63 static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = { 64 .n_reg_rules = 5, 65 .alpha2 = "99", 66 .reg_rules = { 67 ATH9K_2GHZ_ALL, 68 ATH9K_5GHZ_ALL, 69 } 70 }; 71 72 /* Can be used by 0x63 and 0x65 */ 73 static const struct ieee80211_regdomain ath_world_regdom_63_65 = { 74 .n_reg_rules = 4, 75 .alpha2 = "99", 76 .reg_rules = { 77 ATH9K_2GHZ_CH01_11, 78 ATH9K_2GHZ_CH12_13, 79 ATH9K_5GHZ_NO_MIDBAND, 80 } 81 }; 82 83 /* Can be used by 0x64 only */ 84 static const struct ieee80211_regdomain ath_world_regdom_64 = { 85 .n_reg_rules = 3, 86 .alpha2 = "99", 87 .reg_rules = { 88 ATH9K_2GHZ_CH01_11, 89 ATH9K_5GHZ_NO_MIDBAND, 90 } 91 }; 92 93 /* Can be used by 0x66 and 0x69 */ 94 static const struct ieee80211_regdomain ath_world_regdom_66_69 = { 95 .n_reg_rules = 3, 96 .alpha2 = "99", 97 .reg_rules = { 98 ATH9K_2GHZ_CH01_11, 99 ATH9K_5GHZ_ALL, 100 } 101 }; 102 103 /* Can be used by 0x67, 0x68, 0x6A and 0x6C */ 104 static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = { 105 .n_reg_rules = 4, 106 .alpha2 = "99", 107 .reg_rules = { 108 ATH9K_2GHZ_CH01_11, 109 ATH9K_2GHZ_CH12_13, 110 ATH9K_5GHZ_ALL, 111 } 112 }; 113 114 static inline bool is_wwr_sku(u16 regd) 115 { 116 return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) && 117 (((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) || 118 (regd == WORLD)); 119 } 120 121 static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) 122 { 123 return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG; 124 } 125 126 bool ath_is_world_regd(struct ath_regulatory *reg) 127 { 128 return is_wwr_sku(ath_regd_get_eepromRD(reg)); 129 } 130 EXPORT_SYMBOL(ath_is_world_regd); 131 132 static const struct ieee80211_regdomain *ath_default_world_regdomain(void) 133 { 134 /* this is the most restrictive */ 135 return &ath_world_regdom_64; 136 } 137 138 static const struct 139 ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) 140 { 141 switch (reg->regpair->regDmnEnum) { 142 case 0x60: 143 case 0x61: 144 case 0x62: 145 return &ath_world_regdom_60_61_62; 146 case 0x63: 147 case 0x65: 148 return &ath_world_regdom_63_65; 149 case 0x64: 150 return &ath_world_regdom_64; 151 case 0x66: 152 case 0x69: 153 return &ath_world_regdom_66_69; 154 case 0x67: 155 case 0x68: 156 case 0x6A: 157 case 0x6C: 158 return &ath_world_regdom_67_68_6A_6C; 159 default: 160 WARN_ON(1); 161 return ath_default_world_regdomain(); 162 } 163 } 164 165 bool ath_is_49ghz_allowed(u16 regdomain) 166 { 167 /* possibly more */ 168 return regdomain == MKK9_MKKC; 169 } 170 EXPORT_SYMBOL(ath_is_49ghz_allowed); 171 172 /* Frequency is one where radar detection is required */ 173 static bool ath_is_radar_freq(u16 center_freq) 174 { 175 return (center_freq >= 5260 && center_freq <= 5700); 176 } 177 178 /* 179 * N.B: These exception rules do not apply radar freqs. 180 * 181 * - We enable adhoc (or beaconing) if allowed by 11d 182 * - We enable active scan if the channel is allowed by 11d 183 * - If no country IE has been processed and a we determine we have 184 * received a beacon on a channel we can enable active scan and 185 * adhoc (or beaconing). 186 */ 187 static void 188 ath_reg_apply_beaconing_flags(struct wiphy *wiphy, 189 enum nl80211_reg_initiator initiator) 190 { 191 enum ieee80211_band band; 192 struct ieee80211_supported_band *sband; 193 const struct ieee80211_reg_rule *reg_rule; 194 struct ieee80211_channel *ch; 195 unsigned int i; 196 u32 bandwidth = 0; 197 int r; 198 199 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 200 201 if (!wiphy->bands[band]) 202 continue; 203 204 sband = wiphy->bands[band]; 205 206 for (i = 0; i < sband->n_channels; i++) { 207 208 ch = &sband->channels[i]; 209 210 if (ath_is_radar_freq(ch->center_freq) || 211 (ch->flags & IEEE80211_CHAN_RADAR)) 212 continue; 213 214 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { 215 r = freq_reg_info(wiphy, 216 ch->center_freq, 217 bandwidth, 218 ®_rule); 219 if (r) 220 continue; 221 /* 222 * If 11d had a rule for this channel ensure 223 * we enable adhoc/beaconing if it allows us to 224 * use it. Note that we would have disabled it 225 * by applying our static world regdomain by 226 * default during init, prior to calling our 227 * regulatory_hint(). 228 */ 229 if (!(reg_rule->flags & 230 NL80211_RRF_NO_IBSS)) 231 ch->flags &= 232 ~IEEE80211_CHAN_NO_IBSS; 233 if (!(reg_rule->flags & 234 NL80211_RRF_PASSIVE_SCAN)) 235 ch->flags &= 236 ~IEEE80211_CHAN_PASSIVE_SCAN; 237 } else { 238 if (ch->beacon_found) 239 ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | 240 IEEE80211_CHAN_PASSIVE_SCAN); 241 } 242 } 243 } 244 245 } 246 247 /* Allows active scan scan on Ch 12 and 13 */ 248 static void 249 ath_reg_apply_active_scan_flags(struct wiphy *wiphy, 250 enum nl80211_reg_initiator initiator) 251 { 252 struct ieee80211_supported_band *sband; 253 struct ieee80211_channel *ch; 254 const struct ieee80211_reg_rule *reg_rule; 255 u32 bandwidth = 0; 256 int r; 257 258 sband = wiphy->bands[IEEE80211_BAND_2GHZ]; 259 if (!sband) 260 return; 261 262 /* 263 * If no country IE has been received always enable active scan 264 * on these channels. This is only done for specific regulatory SKUs 265 */ 266 if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { 267 ch = &sband->channels[11]; /* CH 12 */ 268 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 269 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 270 ch = &sband->channels[12]; /* CH 13 */ 271 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 272 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 273 return; 274 } 275 276 /* 277 * If a country IE has been received check its rule for this 278 * channel first before enabling active scan. The passive scan 279 * would have been enforced by the initial processing of our 280 * custom regulatory domain. 281 */ 282 283 ch = &sband->channels[11]; /* CH 12 */ 284 r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); 285 if (!r) { 286 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 287 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 288 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 289 } 290 291 ch = &sband->channels[12]; /* CH 13 */ 292 r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); 293 if (!r) { 294 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 295 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 296 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 297 } 298 } 299 300 /* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */ 301 static void ath_reg_apply_radar_flags(struct wiphy *wiphy) 302 { 303 struct ieee80211_supported_band *sband; 304 struct ieee80211_channel *ch; 305 unsigned int i; 306 307 if (!wiphy->bands[IEEE80211_BAND_5GHZ]) 308 return; 309 310 sband = wiphy->bands[IEEE80211_BAND_5GHZ]; 311 312 for (i = 0; i < sband->n_channels; i++) { 313 ch = &sband->channels[i]; 314 if (!ath_is_radar_freq(ch->center_freq)) 315 continue; 316 /* We always enable radar detection/DFS on this 317 * frequency range. Additionally we also apply on 318 * this frequency range: 319 * - If STA mode does not yet have DFS supports disable 320 * active scanning 321 * - If adhoc mode does not support DFS yet then 322 * disable adhoc in the frequency. 323 * - If AP mode does not yet support radar detection/DFS 324 * do not allow AP mode 325 */ 326 if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 327 ch->flags |= IEEE80211_CHAN_RADAR | 328 IEEE80211_CHAN_NO_IBSS | 329 IEEE80211_CHAN_PASSIVE_SCAN; 330 } 331 } 332 333 static void ath_reg_apply_world_flags(struct wiphy *wiphy, 334 enum nl80211_reg_initiator initiator, 335 struct ath_regulatory *reg) 336 { 337 switch (reg->regpair->regDmnEnum) { 338 case 0x60: 339 case 0x63: 340 case 0x66: 341 case 0x67: 342 case 0x6C: 343 ath_reg_apply_beaconing_flags(wiphy, initiator); 344 break; 345 case 0x68: 346 ath_reg_apply_beaconing_flags(wiphy, initiator); 347 ath_reg_apply_active_scan_flags(wiphy, initiator); 348 break; 349 } 350 } 351 352 static u16 ath_regd_find_country_by_name(char *alpha2) 353 { 354 unsigned int i; 355 356 for (i = 0; i < ARRAY_SIZE(allCountries); i++) { 357 if (!memcmp(allCountries[i].isoName, alpha2, 2)) 358 return allCountries[i].countryCode; 359 } 360 361 return -1; 362 } 363 364 int ath_reg_notifier_apply(struct wiphy *wiphy, 365 struct regulatory_request *request, 366 struct ath_regulatory *reg) 367 { 368 struct ath_common *common = container_of(reg, struct ath_common, 369 regulatory); 370 u16 country_code; 371 372 /* We always apply this */ 373 ath_reg_apply_radar_flags(wiphy); 374 375 /* 376 * This would happen when we have sent a custom regulatory request 377 * a world regulatory domain and the scheduler hasn't yet processed 378 * any pending requests in the queue. 379 */ 380 if (!request) 381 return 0; 382 383 switch (request->initiator) { 384 case NL80211_REGDOM_SET_BY_CORE: 385 /* 386 * If common->reg_world_copy is world roaming it means we *were* 387 * world roaming... so we now have to restore that data. 388 */ 389 if (!ath_is_world_regd(&common->reg_world_copy)) 390 break; 391 392 memcpy(reg, &common->reg_world_copy, 393 sizeof(struct ath_regulatory)); 394 break; 395 case NL80211_REGDOM_SET_BY_DRIVER: 396 case NL80211_REGDOM_SET_BY_USER: 397 break; 398 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 399 if (!ath_is_world_regd(reg)) 400 break; 401 402 country_code = ath_regd_find_country_by_name(request->alpha2); 403 if (country_code == (u16) -1) 404 break; 405 406 reg->current_rd = COUNTRY_ERD_FLAG; 407 reg->current_rd |= country_code; 408 409 printk(KERN_DEBUG "ath: regdomain 0x%0x updated by CountryIE\n", 410 reg->current_rd); 411 __ath_regd_init(reg); 412 413 ath_reg_apply_world_flags(wiphy, request->initiator, reg); 414 415 break; 416 } 417 418 return 0; 419 } 420 EXPORT_SYMBOL(ath_reg_notifier_apply); 421 422 static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) 423 { 424 u16 rd = ath_regd_get_eepromRD(reg); 425 int i; 426 427 if (rd & COUNTRY_ERD_FLAG) { 428 /* EEPROM value is a country code */ 429 u16 cc = rd & ~COUNTRY_ERD_FLAG; 430 printk(KERN_DEBUG 431 "ath: EEPROM indicates we should expect " 432 "a country code\n"); 433 for (i = 0; i < ARRAY_SIZE(allCountries); i++) 434 if (allCountries[i].countryCode == cc) 435 return true; 436 } else { 437 /* EEPROM value is a regpair value */ 438 if (rd != CTRY_DEFAULT) 439 printk(KERN_DEBUG "ath: EEPROM indicates we " 440 "should expect a direct regpair map\n"); 441 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) 442 if (regDomainPairs[i].regDmnEnum == rd) 443 return true; 444 } 445 printk(KERN_DEBUG 446 "ath: invalid regulatory domain/country code 0x%x\n", rd); 447 return false; 448 } 449 450 /* EEPROM country code to regpair mapping */ 451 static struct country_code_to_enum_rd* 452 ath_regd_find_country(u16 countryCode) 453 { 454 int i; 455 456 for (i = 0; i < ARRAY_SIZE(allCountries); i++) { 457 if (allCountries[i].countryCode == countryCode) 458 return &allCountries[i]; 459 } 460 return NULL; 461 } 462 463 /* EEPROM rd code to regpair mapping */ 464 static struct country_code_to_enum_rd* 465 ath_regd_find_country_by_rd(int regdmn) 466 { 467 int i; 468 469 for (i = 0; i < ARRAY_SIZE(allCountries); i++) { 470 if (allCountries[i].regDmnEnum == regdmn) 471 return &allCountries[i]; 472 } 473 return NULL; 474 } 475 476 /* Returns the map of the EEPROM set RD to a country code */ 477 static u16 ath_regd_get_default_country(u16 rd) 478 { 479 if (rd & COUNTRY_ERD_FLAG) { 480 struct country_code_to_enum_rd *country = NULL; 481 u16 cc = rd & ~COUNTRY_ERD_FLAG; 482 483 country = ath_regd_find_country(cc); 484 if (country != NULL) 485 return cc; 486 } 487 488 return CTRY_DEFAULT; 489 } 490 491 static struct reg_dmn_pair_mapping* 492 ath_get_regpair(int regdmn) 493 { 494 int i; 495 496 if (regdmn == NO_ENUMRD) 497 return NULL; 498 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) { 499 if (regDomainPairs[i].regDmnEnum == regdmn) 500 return ®DomainPairs[i]; 501 } 502 return NULL; 503 } 504 505 static int 506 ath_regd_init_wiphy(struct ath_regulatory *reg, 507 struct wiphy *wiphy, 508 int (*reg_notifier)(struct wiphy *wiphy, 509 struct regulatory_request *request)) 510 { 511 const struct ieee80211_regdomain *regd; 512 513 wiphy->reg_notifier = reg_notifier; 514 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; 515 516 if (ath_is_world_regd(reg)) { 517 /* 518 * Anything applied here (prior to wiphy registration) gets 519 * saved on the wiphy orig_* parameters 520 */ 521 regd = ath_world_regdomain(reg); 522 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 523 } else { 524 /* 525 * This gets applied in the case of the absence of CRDA, 526 * it's our own custom world regulatory domain, similar to 527 * cfg80211's but we enable passive scanning. 528 */ 529 regd = ath_default_world_regdomain(); 530 } 531 wiphy_apply_custom_regulatory(wiphy, regd); 532 ath_reg_apply_radar_flags(wiphy); 533 ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); 534 return 0; 535 } 536 537 /* 538 * Some users have reported their EEPROM programmed with 539 * 0x8000 set, this is not a supported regulatory domain 540 * but since we have more than one user with it we need 541 * a solution for them. We default to 0x64, which is the 542 * default Atheros world regulatory domain. 543 */ 544 static void ath_regd_sanitize(struct ath_regulatory *reg) 545 { 546 if (reg->current_rd != COUNTRY_ERD_FLAG) 547 return; 548 printk(KERN_DEBUG "ath: EEPROM regdomain sanitized\n"); 549 reg->current_rd = 0x64; 550 } 551 552 static int __ath_regd_init(struct ath_regulatory *reg) 553 { 554 struct country_code_to_enum_rd *country = NULL; 555 u16 regdmn; 556 557 if (!reg) 558 return -EINVAL; 559 560 ath_regd_sanitize(reg); 561 562 printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd); 563 564 if (!ath_regd_is_eeprom_valid(reg)) { 565 printk(KERN_ERR "ath: Invalid EEPROM contents\n"); 566 return -EINVAL; 567 } 568 569 regdmn = ath_regd_get_eepromRD(reg); 570 reg->country_code = ath_regd_get_default_country(regdmn); 571 572 if (reg->country_code == CTRY_DEFAULT && 573 regdmn == CTRY_DEFAULT) { 574 printk(KERN_DEBUG "ath: EEPROM indicates default " 575 "country code should be used\n"); 576 reg->country_code = CTRY_UNITED_STATES; 577 } 578 579 if (reg->country_code == CTRY_DEFAULT) { 580 country = NULL; 581 } else { 582 printk(KERN_DEBUG "ath: doing EEPROM country->regdmn " 583 "map search\n"); 584 country = ath_regd_find_country(reg->country_code); 585 if (country == NULL) { 586 printk(KERN_DEBUG 587 "ath: no valid country maps found for " 588 "country code: 0x%0x\n", 589 reg->country_code); 590 return -EINVAL; 591 } else { 592 regdmn = country->regDmnEnum; 593 printk(KERN_DEBUG "ath: country maps to " 594 "regdmn code: 0x%0x\n", 595 regdmn); 596 } 597 } 598 599 reg->regpair = ath_get_regpair(regdmn); 600 601 if (!reg->regpair) { 602 printk(KERN_DEBUG "ath: " 603 "No regulatory domain pair found, cannot continue\n"); 604 return -EINVAL; 605 } 606 607 if (!country) 608 country = ath_regd_find_country_by_rd(regdmn); 609 610 if (country) { 611 reg->alpha2[0] = country->isoName[0]; 612 reg->alpha2[1] = country->isoName[1]; 613 } else { 614 reg->alpha2[0] = '0'; 615 reg->alpha2[1] = '0'; 616 } 617 618 printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n", 619 reg->alpha2[0], reg->alpha2[1]); 620 printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n", 621 reg->regpair->regDmnEnum); 622 623 return 0; 624 } 625 626 int 627 ath_regd_init(struct ath_regulatory *reg, 628 struct wiphy *wiphy, 629 int (*reg_notifier)(struct wiphy *wiphy, 630 struct regulatory_request *request)) 631 { 632 struct ath_common *common = container_of(reg, struct ath_common, 633 regulatory); 634 int r; 635 636 r = __ath_regd_init(reg); 637 if (r) 638 return r; 639 640 if (ath_is_world_regd(reg)) 641 memcpy(&common->reg_world_copy, reg, 642 sizeof(struct ath_regulatory)); 643 644 ath_regd_init_wiphy(reg, wiphy, reg_notifier); 645 646 return 0; 647 } 648 EXPORT_SYMBOL(ath_regd_init); 649 650 u32 ath_regd_get_band_ctl(struct ath_regulatory *reg, 651 enum ieee80211_band band) 652 { 653 if (!reg->regpair || 654 (reg->country_code == CTRY_DEFAULT && 655 is_wwr_sku(ath_regd_get_eepromRD(reg)))) { 656 return SD_NO_CTL; 657 } 658 659 switch (band) { 660 case IEEE80211_BAND_2GHZ: 661 return reg->regpair->reg_2ghz_ctl; 662 case IEEE80211_BAND_5GHZ: 663 return reg->regpair->reg_5ghz_ctl; 664 default: 665 return NO_CTL; 666 } 667 } 668 EXPORT_SYMBOL(ath_regd_get_band_ctl); 669