diff options
Diffstat (limited to 'net/wireless/reg.c')
-rw-r--r-- | net/wireless/reg.c | 36 |
1 files changed, 12 insertions, 24 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index cc35fbaa4578..e76559618588 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -377,7 +377,7 @@ static void reg_regdb_search(struct work_struct *work) | |||
377 | const struct ieee80211_regdomain *curdom, *regdom = NULL; | 377 | const struct ieee80211_regdomain *curdom, *regdom = NULL; |
378 | int i; | 378 | int i; |
379 | 379 | ||
380 | mutex_lock(&cfg80211_mutex); | 380 | rtnl_lock(); |
381 | 381 | ||
382 | mutex_lock(®_regdb_search_mutex); | 382 | mutex_lock(®_regdb_search_mutex); |
383 | while (!list_empty(®_regdb_search_list)) { | 383 | while (!list_empty(®_regdb_search_list)) { |
@@ -402,7 +402,7 @@ static void reg_regdb_search(struct work_struct *work) | |||
402 | if (!IS_ERR_OR_NULL(regdom)) | 402 | if (!IS_ERR_OR_NULL(regdom)) |
403 | set_regdom(regdom); | 403 | set_regdom(regdom); |
404 | 404 | ||
405 | mutex_unlock(&cfg80211_mutex); | 405 | rtnl_unlock(); |
406 | } | 406 | } |
407 | 407 | ||
408 | static DECLARE_WORK(reg_regdb_work, reg_regdb_search); | 408 | static DECLARE_WORK(reg_regdb_work, reg_regdb_search); |
@@ -1225,7 +1225,7 @@ static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator) | |||
1225 | struct cfg80211_registered_device *rdev; | 1225 | struct cfg80211_registered_device *rdev; |
1226 | struct wiphy *wiphy; | 1226 | struct wiphy *wiphy; |
1227 | 1227 | ||
1228 | assert_cfg80211_lock(); | 1228 | ASSERT_RTNL(); |
1229 | 1229 | ||
1230 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { | 1230 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { |
1231 | wiphy = &rdev->wiphy; | 1231 | wiphy = &rdev->wiphy; |
@@ -1570,21 +1570,19 @@ static void reg_process_pending_hints(void) | |||
1570 | { | 1570 | { |
1571 | struct regulatory_request *reg_request, *lr; | 1571 | struct regulatory_request *reg_request, *lr; |
1572 | 1572 | ||
1573 | mutex_lock(&cfg80211_mutex); | ||
1574 | mutex_lock(®_mutex); | ||
1575 | lr = get_last_request(); | 1573 | lr = get_last_request(); |
1576 | 1574 | ||
1577 | /* When last_request->processed becomes true this will be rescheduled */ | 1575 | /* When last_request->processed becomes true this will be rescheduled */ |
1578 | if (lr && !lr->processed) { | 1576 | if (lr && !lr->processed) { |
1579 | REG_DBG_PRINT("Pending regulatory request, waiting for it to be processed...\n"); | 1577 | REG_DBG_PRINT("Pending regulatory request, waiting for it to be processed...\n"); |
1580 | goto out; | 1578 | return; |
1581 | } | 1579 | } |
1582 | 1580 | ||
1583 | spin_lock(®_requests_lock); | 1581 | spin_lock(®_requests_lock); |
1584 | 1582 | ||
1585 | if (list_empty(®_requests_list)) { | 1583 | if (list_empty(®_requests_list)) { |
1586 | spin_unlock(®_requests_lock); | 1584 | spin_unlock(®_requests_lock); |
1587 | goto out; | 1585 | return; |
1588 | } | 1586 | } |
1589 | 1587 | ||
1590 | reg_request = list_first_entry(®_requests_list, | 1588 | reg_request = list_first_entry(®_requests_list, |
@@ -1595,10 +1593,6 @@ static void reg_process_pending_hints(void) | |||
1595 | spin_unlock(®_requests_lock); | 1593 | spin_unlock(®_requests_lock); |
1596 | 1594 | ||
1597 | reg_process_hint(reg_request, reg_request->initiator); | 1595 | reg_process_hint(reg_request, reg_request->initiator); |
1598 | |||
1599 | out: | ||
1600 | mutex_unlock(®_mutex); | ||
1601 | mutex_unlock(&cfg80211_mutex); | ||
1602 | } | 1596 | } |
1603 | 1597 | ||
1604 | /* Processes beacon hints -- this has nothing to do with country IEs */ | 1598 | /* Processes beacon hints -- this has nothing to do with country IEs */ |
@@ -1607,9 +1601,6 @@ static void reg_process_pending_beacon_hints(void) | |||
1607 | struct cfg80211_registered_device *rdev; | 1601 | struct cfg80211_registered_device *rdev; |
1608 | struct reg_beacon *pending_beacon, *tmp; | 1602 | struct reg_beacon *pending_beacon, *tmp; |
1609 | 1603 | ||
1610 | mutex_lock(&cfg80211_mutex); | ||
1611 | mutex_lock(®_mutex); | ||
1612 | |||
1613 | /* This goes through the _pending_ beacon list */ | 1604 | /* This goes through the _pending_ beacon list */ |
1614 | spin_lock_bh(®_pending_beacons_lock); | 1605 | spin_lock_bh(®_pending_beacons_lock); |
1615 | 1606 | ||
@@ -1626,14 +1617,16 @@ static void reg_process_pending_beacon_hints(void) | |||
1626 | } | 1617 | } |
1627 | 1618 | ||
1628 | spin_unlock_bh(®_pending_beacons_lock); | 1619 | spin_unlock_bh(®_pending_beacons_lock); |
1629 | mutex_unlock(®_mutex); | ||
1630 | mutex_unlock(&cfg80211_mutex); | ||
1631 | } | 1620 | } |
1632 | 1621 | ||
1633 | static void reg_todo(struct work_struct *work) | 1622 | static void reg_todo(struct work_struct *work) |
1634 | { | 1623 | { |
1624 | rtnl_lock(); | ||
1625 | mutex_lock(®_mutex); | ||
1635 | reg_process_pending_hints(); | 1626 | reg_process_pending_hints(); |
1636 | reg_process_pending_beacon_hints(); | 1627 | reg_process_pending_beacon_hints(); |
1628 | mutex_unlock(®_mutex); | ||
1629 | rtnl_unlock(); | ||
1637 | } | 1630 | } |
1638 | 1631 | ||
1639 | static void queue_regulatory_request(struct regulatory_request *request) | 1632 | static void queue_regulatory_request(struct regulatory_request *request) |
@@ -1717,10 +1710,6 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2) | |||
1717 | } | 1710 | } |
1718 | EXPORT_SYMBOL(regulatory_hint); | 1711 | EXPORT_SYMBOL(regulatory_hint); |
1719 | 1712 | ||
1720 | /* | ||
1721 | * We hold wdev_lock() here so we cannot hold cfg80211_mutex() and | ||
1722 | * therefore cannot iterate over the rdev list here. | ||
1723 | */ | ||
1724 | void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band, | 1713 | void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band, |
1725 | const u8 *country_ie, u8 country_ie_len) | 1714 | const u8 *country_ie, u8 country_ie_len) |
1726 | { | 1715 | { |
@@ -1752,7 +1741,7 @@ void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band, | |||
1752 | /* | 1741 | /* |
1753 | * We will run this only upon a successful connection on cfg80211. | 1742 | * We will run this only upon a successful connection on cfg80211. |
1754 | * We leave conflict resolution to the workqueue, where can hold | 1743 | * We leave conflict resolution to the workqueue, where can hold |
1755 | * cfg80211_mutex. | 1744 | * the RTNL. |
1756 | */ | 1745 | */ |
1757 | if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && | 1746 | if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && |
1758 | lr->wiphy_idx != WIPHY_IDX_INVALID) | 1747 | lr->wiphy_idx != WIPHY_IDX_INVALID) |
@@ -1858,7 +1847,8 @@ static void restore_regulatory_settings(bool reset_user) | |||
1858 | LIST_HEAD(tmp_reg_req_list); | 1847 | LIST_HEAD(tmp_reg_req_list); |
1859 | struct cfg80211_registered_device *rdev; | 1848 | struct cfg80211_registered_device *rdev; |
1860 | 1849 | ||
1861 | mutex_lock(&cfg80211_mutex); | 1850 | ASSERT_RTNL(); |
1851 | |||
1862 | mutex_lock(®_mutex); | 1852 | mutex_lock(®_mutex); |
1863 | 1853 | ||
1864 | reset_regdomains(true, &world_regdom); | 1854 | reset_regdomains(true, &world_regdom); |
@@ -1915,7 +1905,6 @@ static void restore_regulatory_settings(bool reset_user) | |||
1915 | spin_unlock(®_requests_lock); | 1905 | spin_unlock(®_requests_lock); |
1916 | 1906 | ||
1917 | mutex_unlock(®_mutex); | 1907 | mutex_unlock(®_mutex); |
1918 | mutex_unlock(&cfg80211_mutex); | ||
1919 | 1908 | ||
1920 | REG_DBG_PRINT("Kicking the queue\n"); | 1909 | REG_DBG_PRINT("Kicking the queue\n"); |
1921 | 1910 | ||
@@ -2297,7 +2286,6 @@ void wiphy_regulatory_register(struct wiphy *wiphy) | |||
2297 | mutex_unlock(®_mutex); | 2286 | mutex_unlock(®_mutex); |
2298 | } | 2287 | } |
2299 | 2288 | ||
2300 | /* Caller must hold cfg80211_mutex */ | ||
2301 | void wiphy_regulatory_deregister(struct wiphy *wiphy) | 2289 | void wiphy_regulatory_deregister(struct wiphy *wiphy) |
2302 | { | 2290 | { |
2303 | struct wiphy *request_wiphy = NULL; | 2291 | struct wiphy *request_wiphy = NULL; |