aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-12-03 11:54:55 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-01-03 07:01:23 -0500
commit2f92212b71f198d42060f7133ff1dc4edf438f6c (patch)
tree0a1bd3a91dc246c474b74412beb1eada774ccce6
parent9027b1493b57a6a8f9f56741e4c4189048ea5633 (diff)
regulatory: use proper enum for return values
Instead of treating special error codes specially, like -EALREADY, introduce a real enum for all the needed possibilities and use it. Acked-by: Luis R. Rodriguez <mcgrof@do-not-panic.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/wireless/reg.c133
1 files changed, 69 insertions, 64 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index cf4386fade8a..129586994662 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -65,6 +65,13 @@
65#define REG_DBG_PRINT(args...) 65#define REG_DBG_PRINT(args...)
66#endif 66#endif
67 67
68enum reg_request_treatment {
69 REG_REQ_OK,
70 REG_REQ_IGNORE,
71 REG_REQ_INTERSECT,
72 REG_REQ_ALREADY_SET,
73};
74
68static struct regulatory_request core_request_world = { 75static struct regulatory_request core_request_world = {
69 .initiator = NL80211_REGDOM_SET_BY_CORE, 76 .initiator = NL80211_REGDOM_SET_BY_CORE,
70 .alpha2[0] = '0', 77 .alpha2[0] = '0',
@@ -925,16 +932,17 @@ bool reg_last_request_cell_base(void)
925 932
926#ifdef CONFIG_CFG80211_CERTIFICATION_ONUS 933#ifdef CONFIG_CFG80211_CERTIFICATION_ONUS
927/* Core specific check */ 934/* Core specific check */
928static int reg_ignore_cell_hint(struct regulatory_request *pending_request) 935static enum reg_request_treatment
936reg_ignore_cell_hint(struct regulatory_request *pending_request)
929{ 937{
930 if (!reg_num_devs_support_basehint) 938 if (!reg_num_devs_support_basehint)
931 return -EOPNOTSUPP; 939 return REG_REQ_IGNORE;
932 940
933 if (reg_request_cell_base(last_request) && 941 if (reg_request_cell_base(last_request) &&
934 !regdom_changes(pending_request->alpha2)) 942 !regdom_changes(pending_request->alpha2))
935 return -EALREADY; 943 return REG_REQ_ALREADY_SET;
936 944
937 return 0; 945 return REG_REQ_OK;
938} 946}
939 947
940/* Device specific check */ 948/* Device specific check */
@@ -945,7 +953,7 @@ static bool reg_dev_ignore_cell_hint(struct wiphy *wiphy)
945#else 953#else
946static int reg_ignore_cell_hint(struct regulatory_request *pending_request) 954static int reg_ignore_cell_hint(struct regulatory_request *pending_request)
947{ 955{
948 return -EOPNOTSUPP; 956 return REG_REQ_IGNORE;
949} 957}
950 958
951static bool reg_dev_ignore_cell_hint(struct wiphy *wiphy) 959static bool reg_dev_ignore_cell_hint(struct wiphy *wiphy)
@@ -1308,15 +1316,10 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
1308} 1316}
1309EXPORT_SYMBOL(wiphy_apply_custom_regulatory); 1317EXPORT_SYMBOL(wiphy_apply_custom_regulatory);
1310 1318
1311/*
1312 * Return value which can be used by ignore_request() to indicate
1313 * it has been determined we should intersect two regulatory domains
1314 */
1315#define REG_INTERSECT 1
1316
1317/* This has the logic which determines when a new request 1319/* This has the logic which determines when a new request
1318 * should be ignored. */ 1320 * should be ignored. */
1319static int ignore_request(struct wiphy *wiphy, 1321static enum reg_request_treatment
1322get_reg_request_treatment(struct wiphy *wiphy,
1320 struct regulatory_request *pending_request) 1323 struct regulatory_request *pending_request)
1321{ 1324{
1322 struct wiphy *last_wiphy = NULL; 1325 struct wiphy *last_wiphy = NULL;
@@ -1325,17 +1328,17 @@ static int ignore_request(struct wiphy *wiphy,
1325 1328
1326 /* All initial requests are respected */ 1329 /* All initial requests are respected */
1327 if (!last_request) 1330 if (!last_request)
1328 return 0; 1331 return REG_REQ_OK;
1329 1332
1330 switch (pending_request->initiator) { 1333 switch (pending_request->initiator) {
1331 case NL80211_REGDOM_SET_BY_CORE: 1334 case NL80211_REGDOM_SET_BY_CORE:
1332 return 0; 1335 return REG_REQ_OK;
1333 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 1336 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
1334 if (reg_request_cell_base(last_request)) { 1337 if (reg_request_cell_base(last_request)) {
1335 /* Trust a Cell base station over the AP's country IE */ 1338 /* Trust a Cell base station over the AP's country IE */
1336 if (regdom_changes(pending_request->alpha2)) 1339 if (regdom_changes(pending_request->alpha2))
1337 return -EOPNOTSUPP; 1340 return REG_REQ_IGNORE;
1338 return -EALREADY; 1341 return REG_REQ_ALREADY_SET;
1339 } 1342 }
1340 1343
1341 last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); 1344 last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
@@ -1352,23 +1355,23 @@ static int ignore_request(struct wiphy *wiphy,
1352 * to be correct. Reject second one for now. 1355 * to be correct. Reject second one for now.
1353 */ 1356 */
1354 if (regdom_changes(pending_request->alpha2)) 1357 if (regdom_changes(pending_request->alpha2))
1355 return -EOPNOTSUPP; 1358 return REG_REQ_IGNORE;
1356 return -EALREADY; 1359 return REG_REQ_ALREADY_SET;
1357 } 1360 }
1358 /* 1361 /*
1359 * Two consecutive Country IE hints on the same wiphy. 1362 * Two consecutive Country IE hints on the same wiphy.
1360 * This should be picked up early by the driver/stack 1363 * This should be picked up early by the driver/stack
1361 */ 1364 */
1362 if (WARN_ON(regdom_changes(pending_request->alpha2))) 1365 if (WARN_ON(regdom_changes(pending_request->alpha2)))
1363 return 0; 1366 return REG_REQ_OK;
1364 return -EALREADY; 1367 return REG_REQ_ALREADY_SET;
1365 } 1368 }
1366 return 0; 1369 return 0;
1367 case NL80211_REGDOM_SET_BY_DRIVER: 1370 case NL80211_REGDOM_SET_BY_DRIVER:
1368 if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) { 1371 if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) {
1369 if (regdom_changes(pending_request->alpha2)) 1372 if (regdom_changes(pending_request->alpha2))
1370 return 0; 1373 return REG_REQ_OK;
1371 return -EALREADY; 1374 return REG_REQ_ALREADY_SET;
1372 } 1375 }
1373 1376
1374 /* 1377 /*
@@ -1378,25 +1381,25 @@ static int ignore_request(struct wiphy *wiphy,
1378 */ 1381 */
1379 if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER && 1382 if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
1380 !regdom_changes(pending_request->alpha2)) 1383 !regdom_changes(pending_request->alpha2))
1381 return -EALREADY; 1384 return REG_REQ_ALREADY_SET;
1382 1385
1383 return REG_INTERSECT; 1386 return REG_REQ_INTERSECT;
1384 case NL80211_REGDOM_SET_BY_USER: 1387 case NL80211_REGDOM_SET_BY_USER:
1385 if (reg_request_cell_base(pending_request)) 1388 if (reg_request_cell_base(pending_request))
1386 return reg_ignore_cell_hint(pending_request); 1389 return reg_ignore_cell_hint(pending_request);
1387 1390
1388 if (reg_request_cell_base(last_request)) 1391 if (reg_request_cell_base(last_request))
1389 return -EOPNOTSUPP; 1392 return REG_REQ_IGNORE;
1390 1393
1391 if (last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) 1394 if (last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
1392 return REG_INTERSECT; 1395 return REG_REQ_INTERSECT;
1393 /* 1396 /*
1394 * If the user knows better the user should set the regdom 1397 * If the user knows better the user should set the regdom
1395 * to their country before the IE is picked up 1398 * to their country before the IE is picked up
1396 */ 1399 */
1397 if (last_request->initiator == NL80211_REGDOM_SET_BY_USER && 1400 if (last_request->initiator == NL80211_REGDOM_SET_BY_USER &&
1398 last_request->intersect) 1401 last_request->intersect)
1399 return -EOPNOTSUPP; 1402 return REG_REQ_IGNORE;
1400 /* 1403 /*
1401 * Process user requests only after previous user/driver/core 1404 * Process user requests only after previous user/driver/core
1402 * requests have been processed 1405 * requests have been processed
@@ -1405,15 +1408,15 @@ static int ignore_request(struct wiphy *wiphy,
1405 last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER || 1408 last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
1406 last_request->initiator == NL80211_REGDOM_SET_BY_USER) && 1409 last_request->initiator == NL80211_REGDOM_SET_BY_USER) &&
1407 regdom_changes(last_request->alpha2)) 1410 regdom_changes(last_request->alpha2))
1408 return -EAGAIN; 1411 return REG_REQ_IGNORE;
1409 1412
1410 if (!regdom_changes(pending_request->alpha2)) 1413 if (!regdom_changes(pending_request->alpha2))
1411 return -EALREADY; 1414 return REG_REQ_ALREADY_SET;
1412 1415
1413 return 0; 1416 return REG_REQ_OK;
1414 } 1417 }
1415 1418
1416 return -EINVAL; 1419 return REG_REQ_IGNORE;
1417} 1420}
1418 1421
1419static void reg_set_request_processed(void) 1422static void reg_set_request_processed(void)
@@ -1443,23 +1446,24 @@ static void reg_set_request_processed(void)
1443 * The Wireless subsystem can use this function to hint to the wireless core 1446 * The Wireless subsystem can use this function to hint to the wireless core
1444 * what it believes should be the current regulatory domain. 1447 * what it believes should be the current regulatory domain.
1445 * 1448 *
1446 * Returns zero if all went fine, %-EALREADY if a regulatory domain had 1449 * Returns one of the different reg request treatment values.
1447 * already been set or other standard error codes.
1448 * 1450 *
1449 * Caller must hold &cfg80211_mutex and &reg_mutex 1451 * Caller must hold &cfg80211_mutex and &reg_mutex
1450 */ 1452 */
1451static int __regulatory_hint(struct wiphy *wiphy, 1453static enum reg_request_treatment
1452 struct regulatory_request *pending_request) 1454__regulatory_hint(struct wiphy *wiphy,
1455 struct regulatory_request *pending_request)
1453{ 1456{
1454 const struct ieee80211_regdomain *regd; 1457 const struct ieee80211_regdomain *regd;
1455 bool intersect = false; 1458 bool intersect = false;
1456 int r = 0; 1459 enum reg_request_treatment treatment;
1457 1460
1458 assert_cfg80211_lock(); 1461 assert_cfg80211_lock();
1459 1462
1460 r = ignore_request(wiphy, pending_request); 1463 treatment = get_reg_request_treatment(wiphy, pending_request);
1461 1464
1462 if (r == REG_INTERSECT) { 1465 switch (treatment) {
1466 case REG_REQ_INTERSECT:
1463 if (pending_request->initiator == 1467 if (pending_request->initiator ==
1464 NL80211_REGDOM_SET_BY_DRIVER) { 1468 NL80211_REGDOM_SET_BY_DRIVER) {
1465 regd = reg_copy_regd(cfg80211_regdomain); 1469 regd = reg_copy_regd(cfg80211_regdomain);
@@ -1470,26 +1474,28 @@ static int __regulatory_hint(struct wiphy *wiphy,
1470 wiphy->regd = regd; 1474 wiphy->regd = regd;
1471 } 1475 }
1472 intersect = true; 1476 intersect = true;
1473 } else if (r) { 1477 break;
1478 case REG_REQ_OK:
1479 break;
1480 default:
1474 /* 1481 /*
1475 * If the regulatory domain being requested by the 1482 * If the regulatory domain being requested by the
1476 * driver has already been set just copy it to the 1483 * driver has already been set just copy it to the
1477 * wiphy 1484 * wiphy
1478 */ 1485 */
1479 if (r == -EALREADY && 1486 if (treatment == REG_REQ_ALREADY_SET &&
1480 pending_request->initiator == 1487 pending_request->initiator == NL80211_REGDOM_SET_BY_DRIVER) {
1481 NL80211_REGDOM_SET_BY_DRIVER) {
1482 regd = reg_copy_regd(cfg80211_regdomain); 1488 regd = reg_copy_regd(cfg80211_regdomain);
1483 if (IS_ERR(regd)) { 1489 if (IS_ERR(regd)) {
1484 kfree(pending_request); 1490 kfree(pending_request);
1485 return PTR_ERR(regd); 1491 return REG_REQ_IGNORE;
1486 } 1492 }
1487 r = -EALREADY; 1493 treatment = REG_REQ_ALREADY_SET;
1488 wiphy->regd = regd; 1494 wiphy->regd = regd;
1489 goto new_request; 1495 goto new_request;
1490 } 1496 }
1491 kfree(pending_request); 1497 kfree(pending_request);
1492 return r; 1498 return treatment;
1493 } 1499 }
1494 1500
1495new_request: 1501new_request:
@@ -1506,28 +1512,29 @@ new_request:
1506 user_alpha2[1] = last_request->alpha2[1]; 1512 user_alpha2[1] = last_request->alpha2[1];
1507 } 1513 }
1508 1514
1509 /* When r == REG_INTERSECT we do need to call CRDA */ 1515 /* When r == REG_REQ_INTERSECT we do need to call CRDA */
1510 if (r < 0) { 1516 if (treatment != REG_REQ_OK && treatment != REG_REQ_INTERSECT) {
1511 /* 1517 /*
1512 * Since CRDA will not be called in this case as we already 1518 * Since CRDA will not be called in this case as we already
1513 * have applied the requested regulatory domain before we just 1519 * have applied the requested regulatory domain before we just
1514 * inform userspace we have processed the request 1520 * inform userspace we have processed the request
1515 */ 1521 */
1516 if (r == -EALREADY) { 1522 if (treatment == REG_REQ_ALREADY_SET) {
1517 nl80211_send_reg_change_event(last_request); 1523 nl80211_send_reg_change_event(last_request);
1518 reg_set_request_processed(); 1524 reg_set_request_processed();
1519 } 1525 }
1520 return r; 1526 return treatment;
1521 } 1527 }
1522 1528
1523 return call_crda(last_request->alpha2); 1529 if (call_crda(last_request->alpha2))
1530 return REG_REQ_IGNORE;
1531 return REG_REQ_OK;
1524} 1532}
1525 1533
1526/* This processes *all* regulatory hints */ 1534/* This processes *all* regulatory hints */
1527static void reg_process_hint(struct regulatory_request *reg_request, 1535static void reg_process_hint(struct regulatory_request *reg_request,
1528 enum nl80211_reg_initiator reg_initiator) 1536 enum nl80211_reg_initiator reg_initiator)
1529{ 1537{
1530 int r = 0;
1531 struct wiphy *wiphy = NULL; 1538 struct wiphy *wiphy = NULL;
1532 1539
1533 BUG_ON(!reg_request->alpha2); 1540 BUG_ON(!reg_request->alpha2);
@@ -1540,20 +1547,18 @@ static void reg_process_hint(struct regulatory_request *reg_request,
1540 return; 1547 return;
1541 } 1548 }
1542 1549
1543 r = __regulatory_hint(wiphy, reg_request); 1550 switch (__regulatory_hint(wiphy, reg_request)) {
1544 /* This is required so that the orig_* parameters are saved */ 1551 case REG_REQ_ALREADY_SET:
1545 if (r == -EALREADY && wiphy && 1552 /* This is required so that the orig_* parameters are saved */
1546 wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) { 1553 if (wiphy && wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
1547 wiphy_update_regulatory(wiphy, reg_initiator); 1554 wiphy_update_regulatory(wiphy, reg_initiator);
1548 return; 1555 break;
1556 default:
1557 if (reg_initiator == NL80211_REGDOM_SET_BY_USER)
1558 schedule_delayed_work(&reg_timeout,
1559 msecs_to_jiffies(3142));
1560 break;
1549 } 1561 }
1550
1551 /*
1552 * We only time out user hints, given that they should be the only
1553 * source of bogus requests.
1554 */
1555 if (r != -EALREADY && reg_initiator == NL80211_REGDOM_SET_BY_USER)
1556 schedule_delayed_work(&reg_timeout, msecs_to_jiffies(3142));
1557} 1562}
1558 1563
1559/* 1564/*