aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <mcgrof@do-not-panic.com>2013-11-05 12:18:04 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-11-25 14:51:07 -0500
commit0d97a61917d8c00adb9e445ec23ee09150d720a4 (patch)
treed3bfc62b435a4747752c73f973147f56cb8ba8d2
parentb3eb7f3f592c0a5ae96c0cf53037f1a1d7eb4a85 (diff)
cfg80211: process user regulatory requests on its own
This makes the code path easier to read and lets us split out some functionality that is only user specific, that makes it easier to read the other types of requests. Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/wireless/reg.c114
1 files changed, 81 insertions, 33 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 2b7ab01b2616..1bd590c2ed7f 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1337,6 +1337,7 @@ get_reg_request_treatment(struct wiphy *wiphy,
1337 1337
1338 switch (pending_request->initiator) { 1338 switch (pending_request->initiator) {
1339 case NL80211_REGDOM_SET_BY_CORE: 1339 case NL80211_REGDOM_SET_BY_CORE:
1340 case NL80211_REGDOM_SET_BY_USER:
1340 return REG_REQ_IGNORE; 1341 return REG_REQ_IGNORE;
1341 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 1342 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
1342 if (reg_request_cell_base(lr)) { 1343 if (reg_request_cell_base(lr)) {
@@ -1388,36 +1389,6 @@ get_reg_request_treatment(struct wiphy *wiphy,
1388 return REG_REQ_ALREADY_SET; 1389 return REG_REQ_ALREADY_SET;
1389 1390
1390 return REG_REQ_INTERSECT; 1391 return REG_REQ_INTERSECT;
1391 case NL80211_REGDOM_SET_BY_USER:
1392 if (reg_request_cell_base(pending_request))
1393 return reg_ignore_cell_hint(pending_request);
1394
1395 if (reg_request_cell_base(lr))
1396 return REG_REQ_IGNORE;
1397
1398 if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
1399 return REG_REQ_INTERSECT;
1400 /*
1401 * If the user knows better the user should set the regdom
1402 * to their country before the IE is picked up
1403 */
1404 if (lr->initiator == NL80211_REGDOM_SET_BY_USER &&
1405 lr->intersect)
1406 return REG_REQ_IGNORE;
1407 /*
1408 * Process user requests only after previous user/driver/core
1409 * requests have been processed
1410 */
1411 if ((lr->initiator == NL80211_REGDOM_SET_BY_CORE ||
1412 lr->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
1413 lr->initiator == NL80211_REGDOM_SET_BY_USER) &&
1414 regdom_changes(lr->alpha2))
1415 return REG_REQ_IGNORE;
1416
1417 if (!regdom_changes(pending_request->alpha2))
1418 return REG_REQ_ALREADY_SET;
1419
1420 return REG_REQ_OK;
1421 } 1392 }
1422 1393
1423 return REG_REQ_IGNORE; 1394 return REG_REQ_IGNORE;
@@ -1469,6 +1440,80 @@ reg_process_hint_core(struct regulatory_request *core_request)
1469 return REG_REQ_OK; 1440 return REG_REQ_OK;
1470} 1441}
1471 1442
1443static enum reg_request_treatment
1444__reg_process_hint_user(struct regulatory_request *user_request)
1445{
1446 struct regulatory_request *lr = get_last_request();
1447
1448 if (reg_request_cell_base(user_request))
1449 return reg_ignore_cell_hint(user_request);
1450
1451 if (reg_request_cell_base(lr))
1452 return REG_REQ_IGNORE;
1453
1454 if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
1455 return REG_REQ_INTERSECT;
1456 /*
1457 * If the user knows better the user should set the regdom
1458 * to their country before the IE is picked up
1459 */
1460 if (lr->initiator == NL80211_REGDOM_SET_BY_USER &&
1461 lr->intersect)
1462 return REG_REQ_IGNORE;
1463 /*
1464 * Process user requests only after previous user/driver/core
1465 * requests have been processed
1466 */
1467 if ((lr->initiator == NL80211_REGDOM_SET_BY_CORE ||
1468 lr->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
1469 lr->initiator == NL80211_REGDOM_SET_BY_USER) &&
1470 regdom_changes(lr->alpha2))
1471 return REG_REQ_IGNORE;
1472
1473 if (!regdom_changes(user_request->alpha2))
1474 return REG_REQ_ALREADY_SET;
1475
1476 return REG_REQ_OK;
1477}
1478
1479/**
1480 * reg_process_hint_user - process user regulatory requests
1481 * @user_request: a pending user regulatory request
1482 *
1483 * The wireless subsystem can use this function to process
1484 * a regulatory request initiated by userspace.
1485 *
1486 * Returns one of the different reg request treatment values.
1487 */
1488static enum reg_request_treatment
1489reg_process_hint_user(struct regulatory_request *user_request)
1490{
1491 enum reg_request_treatment treatment;
1492 struct regulatory_request *lr;
1493
1494 treatment = __reg_process_hint_user(user_request);
1495 if (treatment == REG_REQ_IGNORE ||
1496 treatment == REG_REQ_ALREADY_SET) {
1497 kfree(user_request);
1498 return treatment;
1499 }
1500
1501 lr = get_last_request();
1502 if (lr != &core_request_world && lr)
1503 kfree_rcu(lr, rcu_head);
1504
1505 user_request->intersect = treatment == REG_REQ_INTERSECT;
1506 user_request->processed = false;
1507 rcu_assign_pointer(last_request, user_request);
1508
1509 user_alpha2[0] = user_request->alpha2[0];
1510 user_alpha2[1] = user_request->alpha2[1];
1511
1512 if (call_crda(user_request->alpha2))
1513 return REG_REQ_IGNORE;
1514 return REG_REQ_OK;
1515}
1516
1472/** 1517/**
1473 * __regulatory_hint - hint to the wireless core a regulatory domain 1518 * __regulatory_hint - hint to the wireless core a regulatory domain
1474 * @wiphy: if the hint comes from country information from an AP, this 1519 * @wiphy: if the hint comes from country information from an AP, this
@@ -1585,6 +1630,12 @@ static void reg_process_hint(struct regulatory_request *reg_request)
1585 reg_process_hint_core(reg_request); 1630 reg_process_hint_core(reg_request);
1586 return; 1631 return;
1587 case NL80211_REGDOM_SET_BY_USER: 1632 case NL80211_REGDOM_SET_BY_USER:
1633 treatment = reg_process_hint_user(reg_request);
1634 if (treatment == REG_REQ_OK ||
1635 treatment == REG_REQ_ALREADY_SET)
1636 return;
1637 schedule_delayed_work(&reg_timeout, msecs_to_jiffies(3142));
1638 return;
1588 case NL80211_REGDOM_SET_BY_DRIVER: 1639 case NL80211_REGDOM_SET_BY_DRIVER:
1589 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 1640 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
1590 treatment = __regulatory_hint(wiphy, reg_request); 1641 treatment = __regulatory_hint(wiphy, reg_request);
@@ -1601,9 +1652,6 @@ static void reg_process_hint(struct regulatory_request *reg_request)
1601 wiphy_update_regulatory(wiphy, reg_request->initiator); 1652 wiphy_update_regulatory(wiphy, reg_request->initiator);
1602 break; 1653 break;
1603 default: 1654 default:
1604 if (reg_request->initiator == NL80211_REGDOM_SET_BY_USER)
1605 schedule_delayed_work(&reg_timeout,
1606 msecs_to_jiffies(3142));
1607 break; 1655 break;
1608 } 1656 }
1609} 1657}