diff options
Diffstat (limited to 'net/wireless/reg.c')
-rw-r--r-- | net/wireless/reg.c | 52 |
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 | ||
1323 | static void reg_set_request_processed(void) | ||
1324 | { | ||
1325 | bool need_more_processing = false; | ||
1326 | |||
1327 | last_request->processed = true; | ||
1328 | |||
1329 | spin_lock(®_requests_lock); | ||
1330 | if (!list_empty(®_requests_list)) | ||
1331 | need_more_processing = true; | ||
1332 | spin_unlock(®_requests_lock); | ||
1333 | |||
1334 | if (need_more_processing) | ||
1335 | schedule_work(®_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 | */ | ||
1432 | static void reg_process_pending_hints(void) | 1453 | static 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(®_mutex); | 1458 | mutex_lock(®_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(®_requests_lock); | 1467 | spin_lock(®_requests_lock); |
1440 | while (!list_empty(®_requests_list)) { | ||
1441 | reg_request = list_first_entry(®_requests_list, | ||
1442 | struct regulatory_request, | ||
1443 | list); | ||
1444 | list_del_init(®_request->list); | ||
1445 | 1468 | ||
1469 | if (list_empty(®_requests_list)) { | ||
1446 | spin_unlock(®_requests_lock); | 1470 | spin_unlock(®_requests_lock); |
1447 | reg_process_hint(reg_request); | 1471 | goto out; |
1448 | spin_lock(®_requests_lock); | ||
1449 | } | 1472 | } |
1473 | |||
1474 | reg_request = list_first_entry(®_requests_list, | ||
1475 | struct regulatory_request, | ||
1476 | list); | ||
1477 | list_del_init(®_request->list); | ||
1478 | |||
1450 | spin_unlock(®_requests_lock); | 1479 | spin_unlock(®_requests_lock); |
1451 | 1480 | ||
1481 | reg_process_hint(reg_request); | ||
1482 | |||
1483 | out: | ||
1452 | mutex_unlock(®_mutex); | 1484 | mutex_unlock(®_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(®_mutex); | 2094 | mutex_unlock(®_mutex); |
2061 | 2095 | ||
2062 | return r; | 2096 | return r; |