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.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index b522c46c4748..bc14caab19cd 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1320,6 +1320,21 @@ static int ignore_request(struct wiphy *wiphy,
1320 return -EINVAL; 1320 return -EINVAL;
1321} 1321}
1322 1322
1323static void reg_set_request_processed(void)
1324{
1325 bool need_more_processing = false;
1326
1327 last_request->processed = true;
1328
1329 spin_lock(&reg_requests_lock);
1330 if (!list_empty(&reg_requests_list))
1331 need_more_processing = true;
1332 spin_unlock(&reg_requests_lock);
1333
1334 if (need_more_processing)
1335 schedule_work(&reg_work);
1336}
1337
1323/** 1338/**
1324 * __regulatory_hint - hint to the wireless core a regulatory domain 1339 * __regulatory_hint - hint to the wireless core a regulatory domain
1325 * @wiphy: if the hint comes from country information from an AP, this 1340 * @wiphy: if the hint comes from country information from an AP, this
@@ -1395,8 +1410,10 @@ new_request:
1395 * have applied the requested regulatory domain before we just 1410 * have applied the requested regulatory domain before we just
1396 * inform userspace we have processed the request 1411 * inform userspace we have processed the request
1397 */ 1412 */
1398 if (r == -EALREADY) 1413 if (r == -EALREADY) {
1399 nl80211_send_reg_change_event(last_request); 1414 nl80211_send_reg_change_event(last_request);
1415 reg_set_request_processed();
1416 }
1400 return r; 1417 return r;
1401 } 1418 }
1402 1419
@@ -1428,7 +1445,11 @@ static void reg_process_hint(struct regulatory_request *reg_request)
1428 wiphy_update_regulatory(wiphy, initiator); 1445 wiphy_update_regulatory(wiphy, initiator);
1429} 1446}
1430 1447
1431/* Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_* */ 1448/*
1449 * Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_*
1450 * Regulatory hints come on a first come first serve basis and we
1451 * must process each one atomically.
1452 */
1432static void reg_process_pending_hints(void) 1453static void reg_process_pending_hints(void)
1433{ 1454{
1434 struct regulatory_request *reg_request; 1455 struct regulatory_request *reg_request;
@@ -1436,19 +1457,30 @@ static void reg_process_pending_hints(void)
1436 mutex_lock(&cfg80211_mutex); 1457 mutex_lock(&cfg80211_mutex);
1437 mutex_lock(&reg_mutex); 1458 mutex_lock(&reg_mutex);
1438 1459
1460 /* When last_request->processed becomes true this will be rescheduled */
1461 if (last_request && !last_request->processed) {
1462 REG_DBG_PRINT("Pending regulatory request, waiting "
1463 "for it to be processed...");
1464 goto out;
1465 }
1466
1439 spin_lock(&reg_requests_lock); 1467 spin_lock(&reg_requests_lock);
1440 while (!list_empty(&reg_requests_list)) {
1441 reg_request = list_first_entry(&reg_requests_list,
1442 struct regulatory_request,
1443 list);
1444 list_del_init(&reg_request->list);
1445 1468
1469 if (list_empty(&reg_requests_list)) {
1446 spin_unlock(&reg_requests_lock); 1470 spin_unlock(&reg_requests_lock);
1447 reg_process_hint(reg_request); 1471 goto out;
1448 spin_lock(&reg_requests_lock);
1449 } 1472 }
1473
1474 reg_request = list_first_entry(&reg_requests_list,
1475 struct regulatory_request,
1476 list);
1477 list_del_init(&reg_request->list);
1478
1450 spin_unlock(&reg_requests_lock); 1479 spin_unlock(&reg_requests_lock);
1451 1480
1481 reg_process_hint(reg_request);
1482
1483out:
1452 mutex_unlock(&reg_mutex); 1484 mutex_unlock(&reg_mutex);
1453 mutex_unlock(&cfg80211_mutex); 1485 mutex_unlock(&cfg80211_mutex);
1454} 1486}
@@ -2057,6 +2089,8 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2057 2089
2058 nl80211_send_reg_change_event(last_request); 2090 nl80211_send_reg_change_event(last_request);
2059 2091
2092 reg_set_request_processed();
2093
2060 mutex_unlock(&reg_mutex); 2094 mutex_unlock(&reg_mutex);
2061 2095
2062 return r; 2096 return r;