aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/reg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/reg.c')
-rw-r--r--net/wireless/reg.c64
1 files changed, 40 insertions, 24 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index e49ac9b2ada..d44f3b5481a 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -831,9 +831,12 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
831 const struct ieee80211_power_rule *power_rule = NULL; 831 const struct ieee80211_power_rule *power_rule = NULL;
832 struct ieee80211_supported_band *sband; 832 struct ieee80211_supported_band *sband;
833 struct ieee80211_channel *chan; 833 struct ieee80211_channel *chan;
834 struct wiphy *request_wiphy;
834 835
835 assert_cfg80211_lock(); 836 assert_cfg80211_lock();
836 837
838 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
839
837 sband = wiphy->bands[band]; 840 sband = wiphy->bands[band];
838 BUG_ON(chan_idx >= sband->n_channels); 841 BUG_ON(chan_idx >= sband->n_channels);
839 chan = &sband->channels[chan_idx]; 842 chan = &sband->channels[chan_idx];
@@ -881,8 +884,8 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
881 power_rule = &reg_rule->power_rule; 884 power_rule = &reg_rule->power_rule;
882 885
883 if (last_request->initiator == REGDOM_SET_BY_DRIVER && 886 if (last_request->initiator == REGDOM_SET_BY_DRIVER &&
884 last_request->wiphy && last_request->wiphy == wiphy && 887 request_wiphy && request_wiphy == wiphy &&
885 last_request->wiphy->strict_regulatory) { 888 request_wiphy->strict_regulatory) {
886 /* This gaurantees the driver's requested regulatory domain 889 /* This gaurantees the driver's requested regulatory domain
887 * will always be used as a base for further regulatory 890 * will always be used as a base for further regulatory
888 * settings */ 891 * settings */
@@ -1046,6 +1049,7 @@ static int reg_copy_regd(const struct ieee80211_regdomain **dst_regd,
1046static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by, 1049static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
1047 const char *alpha2) 1050 const char *alpha2)
1048{ 1051{
1052 struct wiphy *last_wiphy = NULL;
1049 1053
1050 assert_cfg80211_lock(); 1054 assert_cfg80211_lock();
1051 1055
@@ -1059,10 +1063,13 @@ static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
1059 case REGDOM_SET_BY_CORE: 1063 case REGDOM_SET_BY_CORE:
1060 return -EINVAL; 1064 return -EINVAL;
1061 case REGDOM_SET_BY_COUNTRY_IE: 1065 case REGDOM_SET_BY_COUNTRY_IE:
1066
1067 last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
1068
1062 if (unlikely(!is_an_alpha2(alpha2))) 1069 if (unlikely(!is_an_alpha2(alpha2)))
1063 return -EINVAL; 1070 return -EINVAL;
1064 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) { 1071 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
1065 if (last_request->wiphy != wiphy) { 1072 if (last_wiphy != wiphy) {
1066 /* 1073 /*
1067 * Two cards with two APs claiming different 1074 * Two cards with two APs claiming different
1068 * different Country IE alpha2s. We could 1075 * different Country IE alpha2s. We could
@@ -1163,7 +1170,7 @@ new_request:
1163 request->alpha2[0] = alpha2[0]; 1170 request->alpha2[0] = alpha2[0];
1164 request->alpha2[1] = alpha2[1]; 1171 request->alpha2[1] = alpha2[1];
1165 request->initiator = set_by; 1172 request->initiator = set_by;
1166 request->wiphy = wiphy; 1173 request->wiphy_idx = get_wiphy_idx(wiphy);
1167 request->intersect = intersect; 1174 request->intersect = intersect;
1168 request->country_ie_checksum = country_ie_checksum; 1175 request->country_ie_checksum = country_ie_checksum;
1169 request->country_ie_env = env; 1176 request->country_ie_env = env;
@@ -1226,11 +1233,16 @@ EXPORT_SYMBOL(regulatory_hint);
1226static bool reg_same_country_ie_hint(struct wiphy *wiphy, 1233static bool reg_same_country_ie_hint(struct wiphy *wiphy,
1227 u32 country_ie_checksum) 1234 u32 country_ie_checksum)
1228{ 1235{
1236 struct wiphy *request_wiphy;
1237
1229 assert_cfg80211_lock(); 1238 assert_cfg80211_lock();
1230 1239
1231 if (!last_request->wiphy) 1240 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
1241
1242 if (!request_wiphy)
1232 return false; 1243 return false;
1233 if (likely(last_request->wiphy != wiphy)) 1244
1245 if (likely(request_wiphy != wiphy))
1234 return !country_ie_integrity_changes(country_ie_checksum); 1246 return !country_ie_integrity_changes(country_ie_checksum);
1235 /* We should not have let these through at this point, they 1247 /* We should not have let these through at this point, they
1236 * should have been picked up earlier by the first alpha2 check 1248 * should have been picked up earlier by the first alpha2 check
@@ -1278,14 +1290,15 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1278 /* We will run this for *every* beacon processed for the BSSID, so 1290 /* We will run this for *every* beacon processed for the BSSID, so
1279 * we optimize an early check to exit out early if we don't have to 1291 * we optimize an early check to exit out early if we don't have to
1280 * do anything */ 1292 * do anything */
1281 if (likely(last_request->wiphy)) { 1293 if (likely(wiphy_idx_valid(last_request->wiphy_idx))) {
1282 struct cfg80211_registered_device *drv_last_ie; 1294 struct cfg80211_registered_device *drv_last_ie;
1283 1295
1284 drv_last_ie = wiphy_to_dev(last_request->wiphy); 1296 drv_last_ie =
1297 cfg80211_drv_by_wiphy_idx(last_request->wiphy_idx);
1285 1298
1286 /* Lets keep this simple -- we trust the first AP 1299 /* Lets keep this simple -- we trust the first AP
1287 * after we intersect with CRDA */ 1300 * after we intersect with CRDA */
1288 if (likely(last_request->wiphy == wiphy)) { 1301 if (likely(&drv_last_ie->wiphy == wiphy)) {
1289 /* Ignore IEs coming in on this wiphy with 1302 /* Ignore IEs coming in on this wiphy with
1290 * the same alpha2 and environment cap */ 1303 * the same alpha2 and environment cap */
1291 if (likely(alpha2_equal(drv_last_ie->country_ie_alpha2, 1304 if (likely(alpha2_equal(drv_last_ie->country_ie_alpha2,
@@ -1377,13 +1390,12 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
1377{ 1390{
1378 1391
1379 if (is_intersected_alpha2(rd->alpha2)) { 1392 if (is_intersected_alpha2(rd->alpha2)) {
1380 struct wiphy *wiphy = NULL;
1381 struct cfg80211_registered_device *drv;
1382 1393
1383 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) { 1394 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
1384 if (last_request->wiphy) { 1395 struct cfg80211_registered_device *drv;
1385 wiphy = last_request->wiphy; 1396 drv = cfg80211_drv_by_wiphy_idx(
1386 drv = wiphy_to_dev(wiphy); 1397 last_request->wiphy_idx);
1398 if (drv) {
1387 printk(KERN_INFO "cfg80211: Current regulatory " 1399 printk(KERN_INFO "cfg80211: Current regulatory "
1388 "domain updated by AP to: %c%c\n", 1400 "domain updated by AP to: %c%c\n",
1389 drv->country_ie_alpha2[0], 1401 drv->country_ie_alpha2[0],
@@ -1449,7 +1461,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1449{ 1461{
1450 const struct ieee80211_regdomain *intersected_rd = NULL; 1462 const struct ieee80211_regdomain *intersected_rd = NULL;
1451 struct cfg80211_registered_device *drv = NULL; 1463 struct cfg80211_registered_device *drv = NULL;
1452 struct wiphy *wiphy = NULL; 1464 struct wiphy *request_wiphy;
1453 /* Some basic sanity checks first */ 1465 /* Some basic sanity checks first */
1454 1466
1455 if (is_world_regdom(rd->alpha2)) { 1467 if (is_world_regdom(rd->alpha2)) {
@@ -1477,8 +1489,6 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1477 return -EINVAL; 1489 return -EINVAL;
1478 } 1490 }
1479 1491
1480 wiphy = last_request->wiphy;
1481
1482 /* Now lets set the regulatory domain, update all driver channels 1492 /* Now lets set the regulatory domain, update all driver channels
1483 * and finally inform them of what we have done, in case they want 1493 * and finally inform them of what we have done, in case they want
1484 * to review or adjust their own settings based on their own 1494 * to review or adjust their own settings based on their own
@@ -1494,6 +1504,8 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1494 return -EINVAL; 1504 return -EINVAL;
1495 } 1505 }
1496 1506
1507 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
1508
1497 if (!last_request->intersect) { 1509 if (!last_request->intersect) {
1498 int r; 1510 int r;
1499 1511
@@ -1506,9 +1518,9 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1506 /* For a driver hint, lets copy the regulatory domain the 1518 /* For a driver hint, lets copy the regulatory domain the
1507 * driver wanted to the wiphy to deal with conflicts */ 1519 * driver wanted to the wiphy to deal with conflicts */
1508 1520
1509 BUG_ON(last_request->wiphy->regd); 1521 BUG_ON(request_wiphy->regd);
1510 1522
1511 r = reg_copy_regd(&last_request->wiphy->regd, rd); 1523 r = reg_copy_regd(&request_wiphy->regd, rd);
1512 if (r) 1524 if (r)
1513 return r; 1525 return r;
1514 1526
@@ -1529,7 +1541,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1529 * However if a driver requested this specific regulatory 1541 * However if a driver requested this specific regulatory
1530 * domain we keep it for its private use */ 1542 * domain we keep it for its private use */
1531 if (last_request->initiator == REGDOM_SET_BY_DRIVER) 1543 if (last_request->initiator == REGDOM_SET_BY_DRIVER)
1532 last_request->wiphy->regd = rd; 1544 request_wiphy->regd = rd;
1533 else 1545 else
1534 kfree(rd); 1546 kfree(rd);
1535 1547
@@ -1569,7 +1581,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
1569 if (!intersected_rd) 1581 if (!intersected_rd)
1570 return -EINVAL; 1582 return -EINVAL;
1571 1583
1572 drv = wiphy_to_dev(wiphy); 1584 drv = wiphy_to_dev(request_wiphy);
1573 1585
1574 drv->country_ie_alpha2[0] = rd->alpha2[0]; 1586 drv->country_ie_alpha2[0] = rd->alpha2[0];
1575 drv->country_ie_alpha2[1] = rd->alpha2[1]; 1587 drv->country_ie_alpha2[1] = rd->alpha2[1];
@@ -1618,14 +1630,18 @@ int set_regdom(const struct ieee80211_regdomain *rd)
1618/* Caller must hold cfg80211_mutex */ 1630/* Caller must hold cfg80211_mutex */
1619void reg_device_remove(struct wiphy *wiphy) 1631void reg_device_remove(struct wiphy *wiphy)
1620{ 1632{
1633 struct wiphy *request_wiphy;
1634
1621 assert_cfg80211_lock(); 1635 assert_cfg80211_lock();
1622 1636
1637 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
1638
1623 kfree(wiphy->regd); 1639 kfree(wiphy->regd);
1624 if (!last_request || !last_request->wiphy) 1640 if (!last_request || !request_wiphy)
1625 return; 1641 return;
1626 if (last_request->wiphy != wiphy) 1642 if (request_wiphy != wiphy)
1627 return; 1643 return;
1628 last_request->wiphy = NULL; 1644 last_request->wiphy_idx = WIPHY_IDX_STALE;
1629 last_request->country_ie_env = ENVIRON_ANY; 1645 last_request->country_ie_env = ENVIRON_ANY;
1630} 1646}
1631 1647