Advertisement
Guest User

Untitled

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