reg.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. /*
  2. * Copyright 2002-2005, Instant802 Networks, Inc.
  3. * Copyright 2005-2006, Devicescape Software, Inc.
  4. * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
  5. * Copyright 2008 Luis R. Rodriguez <lrodriguz@atheros.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. /**
  12. * DOC: Wireless regulatory infrastructure
  13. *
  14. * The usual implementation is for a driver to read a device EEPROM to
  15. * determine which regulatory domain it should be operating under, then
  16. * looking up the allowable channels in a driver-local table and finally
  17. * registering those channels in the wiphy structure.
  18. *
  19. * Another set of compliance enforcement is for drivers to use their
  20. * own compliance limits which can be stored on the EEPROM. The host
  21. * driver or firmware may ensure these are used.
  22. *
  23. * In addition to all this we provide an extra layer of regulatory
  24. * conformance. For drivers which do not have any regulatory
  25. * information CRDA provides the complete regulatory solution.
  26. * For others it provides a community effort on further restrictions
  27. * to enhance compliance.
  28. *
  29. * Note: When number of rules --> infinity we will not be able to
  30. * index on alpha2 any more, instead we'll probably have to
  31. * rely on some SHA1 checksum of the regdomain for example.
  32. *
  33. */
  34. #include <linux/kernel.h>
  35. #include <linux/list.h>
  36. #include <linux/random.h>
  37. #include <linux/nl80211.h>
  38. #include <linux/platform_device.h>
  39. #include <net/wireless.h>
  40. #include <net/cfg80211.h>
  41. #include "core.h"
  42. #include "reg.h"
  43. /* wiphy is set if this request's initiator is REGDOM_SET_BY_DRIVER */
  44. struct regulatory_request {
  45. struct list_head list;
  46. struct wiphy *wiphy;
  47. int granted;
  48. enum reg_set_by initiator;
  49. char alpha2[2];
  50. };
  51. static LIST_HEAD(regulatory_requests);
  52. /* To trigger userspace events */
  53. static struct platform_device *reg_pdev;
  54. /* Keep the ordering from large to small */
  55. static u32 supported_bandwidths[] = {
  56. MHZ_TO_KHZ(40),
  57. MHZ_TO_KHZ(20),
  58. };
  59. /* Central wireless core regulatory domains, we only need two,
  60. * the current one and a world regulatory domain in case we have no
  61. * information to give us an alpha2 */
  62. static const struct ieee80211_regdomain *cfg80211_regdomain;
  63. /* We keep a static world regulatory domain in case of the absence of CRDA */
  64. static const struct ieee80211_regdomain world_regdom = {
  65. .n_reg_rules = 1,
  66. .alpha2 = "00",
  67. .reg_rules = {
  68. REG_RULE(2412-10, 2462+10, 40, 6, 20,
  69. NL80211_RRF_PASSIVE_SCAN |
  70. NL80211_RRF_NO_IBSS),
  71. }
  72. };
  73. static const struct ieee80211_regdomain *cfg80211_world_regdom =
  74. &world_regdom;
  75. #ifdef CONFIG_WIRELESS_OLD_REGULATORY
  76. static char *ieee80211_regdom = "US";
  77. module_param(ieee80211_regdom, charp, 0444);
  78. MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
  79. /* We assume 40 MHz bandwidth for the old regulatory work.
  80. * We make emphasis we are using the exact same frequencies
  81. * as before */
  82. static const struct ieee80211_regdomain us_regdom = {
  83. .n_reg_rules = 6,
  84. .alpha2 = "US",
  85. .reg_rules = {
  86. /* IEEE 802.11b/g, channels 1..11 */
  87. REG_RULE(2412-10, 2462+10, 40, 6, 27, 0),
  88. /* IEEE 802.11a, channel 36 */
  89. REG_RULE(5180-10, 5180+10, 40, 6, 23, 0),
  90. /* IEEE 802.11a, channel 40 */
  91. REG_RULE(5200-10, 5200+10, 40, 6, 23, 0),
  92. /* IEEE 802.11a, channel 44 */
  93. REG_RULE(5220-10, 5220+10, 40, 6, 23, 0),
  94. /* IEEE 802.11a, channels 48..64 */
  95. REG_RULE(5240-10, 5320+10, 40, 6, 23, 0),
  96. /* IEEE 802.11a, channels 149..165, outdoor */
  97. REG_RULE(5745-10, 5825+10, 40, 6, 30, 0),
  98. }
  99. };
  100. static const struct ieee80211_regdomain jp_regdom = {
  101. .n_reg_rules = 3,
  102. .alpha2 = "JP",
  103. .reg_rules = {
  104. /* IEEE 802.11b/g, channels 1..14 */
  105. REG_RULE(2412-10, 2484+10, 40, 6, 20, 0),
  106. /* IEEE 802.11a, channels 34..48 */
  107. REG_RULE(5170-10, 5240+10, 40, 6, 20,
  108. NL80211_RRF_PASSIVE_SCAN),
  109. /* IEEE 802.11a, channels 52..64 */
  110. REG_RULE(5260-10, 5320+10, 40, 6, 20,
  111. NL80211_RRF_NO_IBSS |
  112. NL80211_RRF_DFS),
  113. }
  114. };
  115. static const struct ieee80211_regdomain eu_regdom = {
  116. .n_reg_rules = 6,
  117. /* This alpha2 is bogus, we leave it here just for stupid
  118. * backward compatibility */
  119. .alpha2 = "EU",
  120. .reg_rules = {
  121. /* IEEE 802.11b/g, channels 1..13 */
  122. REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
  123. /* IEEE 802.11a, channel 36 */
  124. REG_RULE(5180-10, 5180+10, 40, 6, 23,
  125. NL80211_RRF_PASSIVE_SCAN),
  126. /* IEEE 802.11a, channel 40 */
  127. REG_RULE(5200-10, 5200+10, 40, 6, 23,
  128. NL80211_RRF_PASSIVE_SCAN),
  129. /* IEEE 802.11a, channel 44 */
  130. REG_RULE(5220-10, 5220+10, 40, 6, 23,
  131. NL80211_RRF_PASSIVE_SCAN),
  132. /* IEEE 802.11a, channels 48..64 */
  133. REG_RULE(5240-10, 5320+10, 40, 6, 20,
  134. NL80211_RRF_NO_IBSS |
  135. NL80211_RRF_DFS),
  136. /* IEEE 802.11a, channels 100..140 */
  137. REG_RULE(5500-10, 5700+10, 40, 6, 30,
  138. NL80211_RRF_NO_IBSS |
  139. NL80211_RRF_DFS),
  140. }
  141. };
  142. static const struct ieee80211_regdomain *static_regdom(char *alpha2)
  143. {
  144. if (alpha2[0] == 'U' && alpha2[1] == 'S')
  145. return &us_regdom;
  146. if (alpha2[0] == 'J' && alpha2[1] == 'P')
  147. return &jp_regdom;
  148. if (alpha2[0] == 'E' && alpha2[1] == 'U')
  149. return &eu_regdom;
  150. /* Default, as per the old rules */
  151. return &us_regdom;
  152. }
  153. static bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
  154. {
  155. if (rd == &us_regdom || rd == &jp_regdom || rd == &eu_regdom)
  156. return true;
  157. return false;
  158. }
  159. #else
  160. static inline bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
  161. {
  162. return false;
  163. }
  164. #endif
  165. static void reset_regdomains(void)
  166. {
  167. /* avoid freeing static information or freeing something twice */
  168. if (cfg80211_regdomain == cfg80211_world_regdom)
  169. cfg80211_regdomain = NULL;
  170. if (cfg80211_world_regdom == &world_regdom)
  171. cfg80211_world_regdom = NULL;
  172. if (cfg80211_regdomain == &world_regdom)
  173. cfg80211_regdomain = NULL;
  174. if (is_old_static_regdom(cfg80211_regdomain))
  175. cfg80211_regdomain = NULL;
  176. kfree(cfg80211_regdomain);
  177. kfree(cfg80211_world_regdom);
  178. cfg80211_world_regdom = &world_regdom;
  179. cfg80211_regdomain = NULL;
  180. }
  181. /* Dynamic world regulatory domain requested by the wireless
  182. * core upon initialization */
  183. static void update_world_regdomain(const struct ieee80211_regdomain *rd)
  184. {
  185. BUG_ON(list_empty(&regulatory_requests));
  186. reset_regdomains();
  187. cfg80211_world_regdom = rd;
  188. cfg80211_regdomain = rd;
  189. }
  190. bool is_world_regdom(const char *alpha2)
  191. {
  192. if (!alpha2)
  193. return false;
  194. if (alpha2[0] == '0' && alpha2[1] == '0')
  195. return true;
  196. return false;
  197. }
  198. static bool is_alpha2_set(const char *alpha2)
  199. {
  200. if (!alpha2)
  201. return false;
  202. if (alpha2[0] != 0 && alpha2[1] != 0)
  203. return true;
  204. return false;
  205. }
  206. static bool is_alpha_upper(char letter)
  207. {
  208. /* ASCII A - Z */
  209. if (letter >= 65 && letter <= 90)
  210. return true;
  211. return false;
  212. }
  213. static bool is_unknown_alpha2(const char *alpha2)
  214. {
  215. if (!alpha2)
  216. return false;
  217. /* Special case where regulatory domain was built by driver
  218. * but a specific alpha2 cannot be determined */
  219. if (alpha2[0] == '9' && alpha2[1] == '9')
  220. return true;
  221. return false;
  222. }
  223. static bool is_an_alpha2(const char *alpha2)
  224. {
  225. if (!alpha2)
  226. return false;
  227. if (is_alpha_upper(alpha2[0]) && is_alpha_upper(alpha2[1]))
  228. return true;
  229. return false;
  230. }
  231. static bool alpha2_equal(const char *alpha2_x, const char *alpha2_y)
  232. {
  233. if (!alpha2_x || !alpha2_y)
  234. return false;
  235. if (alpha2_x[0] == alpha2_y[0] &&
  236. alpha2_x[1] == alpha2_y[1])
  237. return true;
  238. return false;
  239. }
  240. static bool regdom_changed(const char *alpha2)
  241. {
  242. if (!cfg80211_regdomain)
  243. return true;
  244. if (alpha2_equal(cfg80211_regdomain->alpha2, alpha2))
  245. return false;
  246. return true;
  247. }
  248. /* This lets us keep regulatory code which is updated on a regulatory
  249. * basis in userspace. */
  250. static int call_crda(const char *alpha2)
  251. {
  252. char country_env[9 + 2] = "COUNTRY=";
  253. char *envp[] = {
  254. country_env,
  255. NULL
  256. };
  257. if (!is_world_regdom((char *) alpha2))
  258. printk(KERN_INFO "cfg80211: Calling CRDA for country: %c%c\n",
  259. alpha2[0], alpha2[1]);
  260. else
  261. printk(KERN_INFO "cfg80211: Calling CRDA to update world "
  262. "regulatory domain\n");
  263. country_env[8] = alpha2[0];
  264. country_env[9] = alpha2[1];
  265. return kobject_uevent_env(&reg_pdev->dev.kobj, KOBJ_CHANGE, envp);
  266. }
  267. /* This has the logic which determines when a new request
  268. * should be ignored. */
  269. static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
  270. char *alpha2, struct ieee80211_regdomain *rd)
  271. {
  272. struct regulatory_request *last_request = NULL;
  273. /* All initial requests are respected */
  274. if (list_empty(&regulatory_requests))
  275. return 0;
  276. last_request = list_first_entry(&regulatory_requests,
  277. struct regulatory_request, list);
  278. switch (set_by) {
  279. case REGDOM_SET_BY_INIT:
  280. return -EINVAL;
  281. case REGDOM_SET_BY_CORE:
  282. /* Always respect new wireless core hints, should only
  283. * come in for updating the world regulatory domain at init
  284. * anyway */
  285. return 0;
  286. case REGDOM_SET_BY_COUNTRY_IE:
  287. if (last_request->initiator == set_by) {
  288. if (last_request->wiphy != wiphy) {
  289. /* Two cards with two APs claiming different
  290. * different Country IE alpha2s!
  291. * You're special!! */
  292. if (!alpha2_equal(last_request->alpha2,
  293. cfg80211_regdomain->alpha2)) {
  294. /* XXX: Deal with conflict, consider
  295. * building a new one out of the
  296. * intersection */
  297. WARN_ON(1);
  298. return -EOPNOTSUPP;
  299. }
  300. return -EALREADY;
  301. }
  302. /* Two consecutive Country IE hints on the same wiphy */
  303. if (!alpha2_equal(cfg80211_regdomain->alpha2, alpha2))
  304. return 0;
  305. return -EALREADY;
  306. }
  307. if (WARN_ON(!is_alpha2_set(alpha2) || !is_an_alpha2(alpha2)),
  308. "Invalid Country IE regulatory hint passed "
  309. "to the wireless core\n")
  310. return -EINVAL;
  311. /* We ignore Country IE hints for now, as we haven't yet
  312. * added the dot11MultiDomainCapabilityEnabled flag
  313. * for wiphys */
  314. return 1;
  315. case REGDOM_SET_BY_DRIVER:
  316. BUG_ON(!wiphy);
  317. if (last_request->initiator == set_by) {
  318. /* Two separate drivers hinting different things,
  319. * this is possible if you have two devices present
  320. * on a system with different EEPROM regulatory
  321. * readings. XXX: Do intersection, we support only
  322. * the first regulatory hint for now */
  323. if (last_request->wiphy != wiphy)
  324. return -EALREADY;
  325. if (rd)
  326. return -EALREADY;
  327. /* Driver should not be trying to hint different
  328. * regulatory domains! */
  329. BUG_ON(!alpha2_equal(alpha2,
  330. cfg80211_regdomain->alpha2));
  331. return -EALREADY;
  332. }
  333. if (last_request->initiator == REGDOM_SET_BY_CORE)
  334. return 0;
  335. /* XXX: Handle intersection, and add the
  336. * dot11MultiDomainCapabilityEnabled flag to wiphy. For now
  337. * we assume the driver has this set to false, following the
  338. * 802.11d dot11MultiDomainCapabilityEnabled documentation */
  339. if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
  340. return 0;
  341. return 0;
  342. case REGDOM_SET_BY_USER:
  343. if (last_request->initiator == set_by ||
  344. last_request->initiator == REGDOM_SET_BY_CORE)
  345. return 0;
  346. /* Drivers can use their wiphy's reg_notifier()
  347. * to override any information */
  348. if (last_request->initiator == REGDOM_SET_BY_DRIVER)
  349. return 0;
  350. /* XXX: Handle intersection */
  351. if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
  352. return -EOPNOTSUPP;
  353. return 0;
  354. default:
  355. return -EINVAL;
  356. }
  357. }
  358. static bool __reg_is_valid_request(const char *alpha2,
  359. struct regulatory_request **request)
  360. {
  361. struct regulatory_request *req;
  362. if (list_empty(&regulatory_requests))
  363. return false;
  364. list_for_each_entry(req, &regulatory_requests, list) {
  365. if (alpha2_equal(req->alpha2, alpha2)) {
  366. *request = req;
  367. return true;
  368. }
  369. }
  370. return false;
  371. }
  372. /* Used by nl80211 before kmalloc'ing our regulatory domain */
  373. bool reg_is_valid_request(const char *alpha2)
  374. {
  375. struct regulatory_request *request = NULL;
  376. return __reg_is_valid_request(alpha2, &request);
  377. }
  378. /* Sanity check on a regulatory rule */
  379. static bool is_valid_reg_rule(const struct ieee80211_reg_rule *rule)
  380. {
  381. const struct ieee80211_freq_range *freq_range = &rule->freq_range;
  382. u32 freq_diff;
  383. if (freq_range->start_freq_khz == 0 || freq_range->end_freq_khz == 0)
  384. return false;
  385. if (freq_range->start_freq_khz > freq_range->end_freq_khz)
  386. return false;
  387. freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
  388. if (freq_range->max_bandwidth_khz > freq_diff)
  389. return false;
  390. return true;
  391. }
  392. static bool is_valid_rd(const struct ieee80211_regdomain *rd)
  393. {
  394. const struct ieee80211_reg_rule *reg_rule = NULL;
  395. unsigned int i;
  396. if (!rd->n_reg_rules)
  397. return false;
  398. for (i = 0; i < rd->n_reg_rules; i++) {
  399. reg_rule = &rd->reg_rules[i];
  400. if (!is_valid_reg_rule(reg_rule))
  401. return false;
  402. }
  403. return true;
  404. }
  405. /* Returns value in KHz */
  406. static u32 freq_max_bandwidth(const struct ieee80211_freq_range *freq_range,
  407. u32 freq)
  408. {
  409. unsigned int i;
  410. for (i = 0; i < ARRAY_SIZE(supported_bandwidths); i++) {
  411. u32 start_freq_khz = freq - supported_bandwidths[i]/2;
  412. u32 end_freq_khz = freq + supported_bandwidths[i]/2;
  413. if (start_freq_khz >= freq_range->start_freq_khz &&
  414. end_freq_khz <= freq_range->end_freq_khz)
  415. return supported_bandwidths[i];
  416. }
  417. return 0;
  418. }
  419. /* XXX: add support for the rest of enum nl80211_reg_rule_flags, we may
  420. * want to just have the channel structure use these */
  421. static u32 map_regdom_flags(u32 rd_flags)
  422. {
  423. u32 channel_flags = 0;
  424. if (rd_flags & NL80211_RRF_PASSIVE_SCAN)
  425. channel_flags |= IEEE80211_CHAN_PASSIVE_SCAN;
  426. if (rd_flags & NL80211_RRF_NO_IBSS)
  427. channel_flags |= IEEE80211_CHAN_NO_IBSS;
  428. if (rd_flags & NL80211_RRF_DFS)
  429. channel_flags |= IEEE80211_CHAN_RADAR;
  430. return channel_flags;
  431. }
  432. /**
  433. * freq_reg_info - get regulatory information for the given frequency
  434. * @center_freq: Frequency in KHz for which we want regulatory information for
  435. * @bandwidth: the bandwidth requirement you have in KHz, if you do not have one
  436. * you can set this to 0. If this frequency is allowed we then set
  437. * this value to the maximum allowed bandwidth.
  438. * @reg_rule: the regulatory rule which we have for this frequency
  439. *
  440. * Use this function to get the regulatory rule for a specific frequency.
  441. */
  442. static int freq_reg_info(u32 center_freq, u32 *bandwidth,
  443. const struct ieee80211_reg_rule **reg_rule)
  444. {
  445. int i;
  446. u32 max_bandwidth = 0;
  447. if (!cfg80211_regdomain)
  448. return -EINVAL;
  449. for (i = 0; i < cfg80211_regdomain->n_reg_rules; i++) {
  450. const struct ieee80211_reg_rule *rr;
  451. const struct ieee80211_freq_range *fr = NULL;
  452. const struct ieee80211_power_rule *pr = NULL;
  453. rr = &cfg80211_regdomain->reg_rules[i];
  454. fr = &rr->freq_range;
  455. pr = &rr->power_rule;
  456. max_bandwidth = freq_max_bandwidth(fr, center_freq);
  457. if (max_bandwidth && *bandwidth <= max_bandwidth) {
  458. *reg_rule = rr;
  459. *bandwidth = max_bandwidth;
  460. break;
  461. }
  462. }
  463. return !max_bandwidth;
  464. }
  465. static void handle_channel(struct ieee80211_channel *chan)
  466. {
  467. int r;
  468. u32 flags = chan->orig_flags;
  469. u32 max_bandwidth = 0;
  470. const struct ieee80211_reg_rule *reg_rule = NULL;
  471. const struct ieee80211_power_rule *power_rule = NULL;
  472. r = freq_reg_info(MHZ_TO_KHZ(chan->center_freq),
  473. &max_bandwidth, &reg_rule);
  474. if (r) {
  475. flags |= IEEE80211_CHAN_DISABLED;
  476. chan->flags = flags;
  477. return;
  478. }
  479. power_rule = &reg_rule->power_rule;
  480. chan->flags = flags | map_regdom_flags(reg_rule->flags);
  481. chan->max_antenna_gain = min(chan->orig_mag,
  482. (int) MBI_TO_DBI(power_rule->max_antenna_gain));
  483. chan->max_bandwidth = KHZ_TO_MHZ(max_bandwidth);
  484. if (chan->orig_mpwr)
  485. chan->max_power = min(chan->orig_mpwr,
  486. (int) MBM_TO_DBM(power_rule->max_eirp));
  487. else
  488. chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
  489. }
  490. static void handle_band(struct ieee80211_supported_band *sband)
  491. {
  492. int i;
  493. for (i = 0; i < sband->n_channels; i++)
  494. handle_channel(&sband->channels[i]);
  495. }
  496. static void update_all_wiphy_regulatory(enum reg_set_by setby)
  497. {
  498. struct cfg80211_registered_device *drv;
  499. list_for_each_entry(drv, &cfg80211_drv_list, list)
  500. wiphy_update_regulatory(&drv->wiphy, setby);
  501. }
  502. void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby)
  503. {
  504. enum ieee80211_band band;
  505. for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
  506. if (wiphy->bands[band])
  507. handle_band(wiphy->bands[band]);
  508. if (wiphy->reg_notifier)
  509. wiphy->reg_notifier(wiphy, setby);
  510. }
  511. }
  512. /* Caller must hold &cfg80211_drv_mutex */
  513. int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
  514. const char *alpha2, struct ieee80211_regdomain *rd)
  515. {
  516. struct regulatory_request *request;
  517. char *rd_alpha2;
  518. int r = 0;
  519. r = ignore_request(wiphy, set_by, (char *) alpha2, rd);
  520. if (r)
  521. return r;
  522. if (rd)
  523. rd_alpha2 = rd->alpha2;
  524. else
  525. rd_alpha2 = (char *) alpha2;
  526. switch (set_by) {
  527. case REGDOM_SET_BY_CORE:
  528. case REGDOM_SET_BY_COUNTRY_IE:
  529. case REGDOM_SET_BY_DRIVER:
  530. case REGDOM_SET_BY_USER:
  531. request = kzalloc(sizeof(struct regulatory_request),
  532. GFP_KERNEL);
  533. if (!request)
  534. return -ENOMEM;
  535. request->alpha2[0] = rd_alpha2[0];
  536. request->alpha2[1] = rd_alpha2[1];
  537. request->initiator = set_by;
  538. request->wiphy = wiphy;
  539. list_add_tail(&request->list, &regulatory_requests);
  540. if (rd)
  541. break;
  542. r = call_crda(alpha2);
  543. #ifndef CONFIG_WIRELESS_OLD_REGULATORY
  544. if (r)
  545. printk(KERN_ERR "cfg80211: Failed calling CRDA\n");
  546. #endif
  547. break;
  548. default:
  549. r = -ENOTSUPP;
  550. break;
  551. }
  552. return r;
  553. }
  554. /* If rd is not NULL and if this call fails the caller must free it */
  555. int regulatory_hint(struct wiphy *wiphy, const char *alpha2,
  556. struct ieee80211_regdomain *rd)
  557. {
  558. int r;
  559. BUG_ON(!rd && !alpha2);
  560. mutex_lock(&cfg80211_drv_mutex);
  561. r = __regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER, alpha2, rd);
  562. if (r || !rd)
  563. goto unlock_and_exit;
  564. /* If the driver passed a regulatory domain we skipped asking
  565. * userspace for one so we can now go ahead and set it */
  566. r = set_regdom(rd);
  567. unlock_and_exit:
  568. mutex_unlock(&cfg80211_drv_mutex);
  569. return r;
  570. }
  571. EXPORT_SYMBOL(regulatory_hint);
  572. static void print_rd_rules(const struct ieee80211_regdomain *rd)
  573. {
  574. unsigned int i;
  575. const struct ieee80211_reg_rule *reg_rule = NULL;
  576. const struct ieee80211_freq_range *freq_range = NULL;
  577. const struct ieee80211_power_rule *power_rule = NULL;
  578. printk(KERN_INFO "\t(start_freq - end_freq @ bandwidth), "
  579. "(max_antenna_gain, max_eirp)\n");
  580. for (i = 0; i < rd->n_reg_rules; i++) {
  581. reg_rule = &rd->reg_rules[i];
  582. freq_range = &reg_rule->freq_range;
  583. power_rule = &reg_rule->power_rule;
  584. /* There may not be documentation for max antenna gain
  585. * in certain regions */
  586. if (power_rule->max_antenna_gain)
  587. printk(KERN_INFO "\t(%d KHz - %d KHz @ %d KHz), "
  588. "(%d mBi, %d mBm)\n",
  589. freq_range->start_freq_khz,
  590. freq_range->end_freq_khz,
  591. freq_range->max_bandwidth_khz,
  592. power_rule->max_antenna_gain,
  593. power_rule->max_eirp);
  594. else
  595. printk(KERN_INFO "\t(%d KHz - %d KHz @ %d KHz), "
  596. "(N/A, %d mBm)\n",
  597. freq_range->start_freq_khz,
  598. freq_range->end_freq_khz,
  599. freq_range->max_bandwidth_khz,
  600. power_rule->max_eirp);
  601. }
  602. }
  603. static void print_regdomain(const struct ieee80211_regdomain *rd)
  604. {
  605. if (is_world_regdom(rd->alpha2))
  606. printk(KERN_INFO "cfg80211: World regulatory "
  607. "domain updated:\n");
  608. else {
  609. if (is_unknown_alpha2(rd->alpha2))
  610. printk(KERN_INFO "cfg80211: Regulatory domain "
  611. "changed to driver built-in settings "
  612. "(unknown country)\n");
  613. else
  614. printk(KERN_INFO "cfg80211: Regulatory domain "
  615. "changed to country: %c%c\n",
  616. rd->alpha2[0], rd->alpha2[1]);
  617. }
  618. print_rd_rules(rd);
  619. }
  620. void print_regdomain_info(const struct ieee80211_regdomain *rd)
  621. {
  622. printk(KERN_INFO "cfg80211: Regulatory domain: %c%c\n",
  623. rd->alpha2[0], rd->alpha2[1]);
  624. print_rd_rules(rd);
  625. }
  626. static int __set_regdom(const struct ieee80211_regdomain *rd)
  627. {
  628. struct regulatory_request *request = NULL;
  629. /* Some basic sanity checks first */
  630. if (is_world_regdom(rd->alpha2)) {
  631. if (WARN_ON(!__reg_is_valid_request(rd->alpha2, &request)))
  632. return -EINVAL;
  633. update_world_regdomain(rd);
  634. return 0;
  635. }
  636. if (!is_alpha2_set(rd->alpha2) && !is_an_alpha2(rd->alpha2) &&
  637. !is_unknown_alpha2(rd->alpha2))
  638. return -EINVAL;
  639. if (list_empty(&regulatory_requests))
  640. return -EINVAL;
  641. /* allow overriding the static definitions if CRDA is present */
  642. if (!is_old_static_regdom(cfg80211_regdomain) &&
  643. !regdom_changed(rd->alpha2))
  644. return -EINVAL;
  645. /* Now lets set the regulatory domain, update all driver channels
  646. * and finally inform them of what we have done, in case they want
  647. * to review or adjust their own settings based on their own
  648. * internal EEPROM data */
  649. if (WARN_ON(!__reg_is_valid_request(rd->alpha2, &request)))
  650. return -EINVAL;
  651. reset_regdomains();
  652. /* Country IE parsing coming soon */
  653. switch (request->initiator) {
  654. case REGDOM_SET_BY_CORE:
  655. case REGDOM_SET_BY_DRIVER:
  656. case REGDOM_SET_BY_USER:
  657. if (!is_valid_rd(rd)) {
  658. printk(KERN_ERR "cfg80211: Invalid "
  659. "regulatory domain detected:\n");
  660. print_regdomain_info(rd);
  661. return -EINVAL;
  662. }
  663. break;
  664. case REGDOM_SET_BY_COUNTRY_IE: /* Not yet */
  665. WARN_ON(1);
  666. default:
  667. return -EOPNOTSUPP;
  668. }
  669. /* Tada! */
  670. cfg80211_regdomain = rd;
  671. request->granted = 1;
  672. return 0;
  673. }
  674. /* Use this call to set the current regulatory domain. Conflicts with
  675. * multiple drivers can be ironed out later. Caller must've already
  676. * kmalloc'd the rd structure. If this calls fails you should kfree()
  677. * the passed rd. Caller must hold cfg80211_drv_mutex */
  678. int set_regdom(const struct ieee80211_regdomain *rd)
  679. {
  680. struct regulatory_request *this_request = NULL, *prev_request = NULL;
  681. int r;
  682. if (!list_empty(&regulatory_requests))
  683. prev_request = list_first_entry(&regulatory_requests,
  684. struct regulatory_request, list);
  685. /* Note that this doesn't update the wiphys, this is done below */
  686. r = __set_regdom(rd);
  687. if (r)
  688. return r;
  689. BUG_ON((!__reg_is_valid_request(rd->alpha2, &this_request)));
  690. /* The initial standard core update of the world regulatory domain, no
  691. * need to keep that request info around if it didn't fail. */
  692. if (is_world_regdom(rd->alpha2) &&
  693. this_request->initiator == REGDOM_SET_BY_CORE &&
  694. this_request->granted) {
  695. list_del(&this_request->list);
  696. kfree(this_request);
  697. this_request = NULL;
  698. }
  699. /* Remove old requests, we only leave behind the last one */
  700. if (prev_request) {
  701. list_del(&prev_request->list);
  702. kfree(prev_request);
  703. prev_request = NULL;
  704. }
  705. /* This would make this whole thing pointless */
  706. BUG_ON(rd != cfg80211_regdomain);
  707. /* update all wiphys now with the new established regulatory domain */
  708. update_all_wiphy_regulatory(this_request->initiator);
  709. print_regdomain(rd);
  710. return r;
  711. }
  712. int regulatory_init(void)
  713. {
  714. int err;
  715. reg_pdev = platform_device_register_simple("regulatory", 0, NULL, 0);
  716. if (IS_ERR(reg_pdev))
  717. return PTR_ERR(reg_pdev);
  718. #ifdef CONFIG_WIRELESS_OLD_REGULATORY
  719. cfg80211_regdomain = static_regdom(ieee80211_regdom);
  720. printk(KERN_INFO "cfg80211: Using static regulatory domain info\n");
  721. print_regdomain_info(cfg80211_regdomain);
  722. /* The old code still requests for a new regdomain and if
  723. * you have CRDA you get it updated, otherwise you get
  724. * stuck with the static values. We ignore "EU" code as
  725. * that is not a valid ISO / IEC 3166 alpha2 */
  726. if (ieee80211_regdom[0] != 'E' && ieee80211_regdom[1] != 'U')
  727. err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE,
  728. ieee80211_regdom, NULL);
  729. #else
  730. cfg80211_regdomain = cfg80211_world_regdom;
  731. err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE, "00", NULL);
  732. if (err)
  733. printk(KERN_ERR "cfg80211: calling CRDA failed - "
  734. "unable to update world regulatory domain, "
  735. "using static definition\n");
  736. #endif
  737. return 0;
  738. }
  739. void regulatory_exit(void)
  740. {
  741. struct regulatory_request *req, *req_tmp;
  742. mutex_lock(&cfg80211_drv_mutex);
  743. reset_regdomains();
  744. list_for_each_entry_safe(req, req_tmp, &regulatory_requests, list) {
  745. list_del(&req->list);
  746. kfree(req);
  747. }
  748. platform_device_unregister(reg_pdev);
  749. mutex_unlock(&cfg80211_drv_mutex);
  750. }