diff options
Diffstat (limited to 'net/wireless/reg.c')
-rw-r--r-- | net/wireless/reg.c | 138 |
1 files changed, 45 insertions, 93 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index cc35fbaa4578..5a24c986f34b 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -81,7 +81,10 @@ static struct regulatory_request core_request_world = { | |||
81 | .country_ie_env = ENVIRON_ANY, | 81 | .country_ie_env = ENVIRON_ANY, |
82 | }; | 82 | }; |
83 | 83 | ||
84 | /* Receipt of information from last regulatory request */ | 84 | /* |
85 | * Receipt of information from last regulatory request, | ||
86 | * protected by RTNL (and can be accessed with RCU protection) | ||
87 | */ | ||
85 | static struct regulatory_request __rcu *last_request = | 88 | static struct regulatory_request __rcu *last_request = |
86 | (void __rcu *)&core_request_world; | 89 | (void __rcu *)&core_request_world; |
87 | 90 | ||
@@ -96,39 +99,25 @@ static struct device_type reg_device_type = { | |||
96 | * Central wireless core regulatory domains, we only need two, | 99 | * Central wireless core regulatory domains, we only need two, |
97 | * the current one and a world regulatory domain in case we have no | 100 | * the current one and a world regulatory domain in case we have no |
98 | * information to give us an alpha2. | 101 | * information to give us an alpha2. |
102 | * (protected by RTNL, can be read under RCU) | ||
99 | */ | 103 | */ |
100 | const struct ieee80211_regdomain __rcu *cfg80211_regdomain; | 104 | const struct ieee80211_regdomain __rcu *cfg80211_regdomain; |
101 | 105 | ||
102 | /* | 106 | /* |
103 | * Protects static reg.c components: | ||
104 | * - cfg80211_regdomain (if not used with RCU) | ||
105 | * - cfg80211_world_regdom | ||
106 | * - last_request (if not used with RCU) | ||
107 | * - reg_num_devs_support_basehint | ||
108 | */ | ||
109 | static DEFINE_MUTEX(reg_mutex); | ||
110 | |||
111 | /* | ||
112 | * Number of devices that registered to the core | 107 | * Number of devices that registered to the core |
113 | * that support cellular base station regulatory hints | 108 | * that support cellular base station regulatory hints |
109 | * (protected by RTNL) | ||
114 | */ | 110 | */ |
115 | static int reg_num_devs_support_basehint; | 111 | static int reg_num_devs_support_basehint; |
116 | 112 | ||
117 | static inline void assert_reg_lock(void) | ||
118 | { | ||
119 | lockdep_assert_held(®_mutex); | ||
120 | } | ||
121 | |||
122 | static const struct ieee80211_regdomain *get_cfg80211_regdom(void) | 113 | static const struct ieee80211_regdomain *get_cfg80211_regdom(void) |
123 | { | 114 | { |
124 | return rcu_dereference_protected(cfg80211_regdomain, | 115 | return rtnl_dereference(cfg80211_regdomain); |
125 | lockdep_is_held(®_mutex)); | ||
126 | } | 116 | } |
127 | 117 | ||
128 | static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy) | 118 | static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy) |
129 | { | 119 | { |
130 | return rcu_dereference_protected(wiphy->regd, | 120 | return rtnl_dereference(wiphy->regd); |
131 | lockdep_is_held(®_mutex)); | ||
132 | } | 121 | } |
133 | 122 | ||
134 | static void rcu_free_regdom(const struct ieee80211_regdomain *r) | 123 | static void rcu_free_regdom(const struct ieee80211_regdomain *r) |
@@ -140,8 +129,7 @@ static void rcu_free_regdom(const struct ieee80211_regdomain *r) | |||
140 | 129 | ||
141 | static struct regulatory_request *get_last_request(void) | 130 | static struct regulatory_request *get_last_request(void) |
142 | { | 131 | { |
143 | return rcu_dereference_check(last_request, | 132 | return rcu_dereference_rtnl(last_request); |
144 | lockdep_is_held(®_mutex)); | ||
145 | } | 133 | } |
146 | 134 | ||
147 | /* Used to queue up regulatory hints */ | 135 | /* Used to queue up regulatory hints */ |
@@ -200,6 +188,7 @@ static const struct ieee80211_regdomain world_regdom = { | |||
200 | } | 188 | } |
201 | }; | 189 | }; |
202 | 190 | ||
191 | /* protected by RTNL */ | ||
203 | static const struct ieee80211_regdomain *cfg80211_world_regdom = | 192 | static const struct ieee80211_regdomain *cfg80211_world_regdom = |
204 | &world_regdom; | 193 | &world_regdom; |
205 | 194 | ||
@@ -215,7 +204,7 @@ static void reset_regdomains(bool full_reset, | |||
215 | const struct ieee80211_regdomain *r; | 204 | const struct ieee80211_regdomain *r; |
216 | struct regulatory_request *lr; | 205 | struct regulatory_request *lr; |
217 | 206 | ||
218 | assert_reg_lock(); | 207 | ASSERT_RTNL(); |
219 | 208 | ||
220 | r = get_cfg80211_regdom(); | 209 | r = get_cfg80211_regdom(); |
221 | 210 | ||
@@ -377,7 +366,7 @@ static void reg_regdb_search(struct work_struct *work) | |||
377 | const struct ieee80211_regdomain *curdom, *regdom = NULL; | 366 | const struct ieee80211_regdomain *curdom, *regdom = NULL; |
378 | int i; | 367 | int i; |
379 | 368 | ||
380 | mutex_lock(&cfg80211_mutex); | 369 | rtnl_lock(); |
381 | 370 | ||
382 | mutex_lock(®_regdb_search_mutex); | 371 | mutex_lock(®_regdb_search_mutex); |
383 | while (!list_empty(®_regdb_search_list)) { | 372 | while (!list_empty(®_regdb_search_list)) { |
@@ -402,7 +391,7 @@ static void reg_regdb_search(struct work_struct *work) | |||
402 | if (!IS_ERR_OR_NULL(regdom)) | 391 | if (!IS_ERR_OR_NULL(regdom)) |
403 | set_regdom(regdom); | 392 | set_regdom(regdom); |
404 | 393 | ||
405 | mutex_unlock(&cfg80211_mutex); | 394 | rtnl_unlock(); |
406 | } | 395 | } |
407 | 396 | ||
408 | static DECLARE_WORK(reg_regdb_work, reg_regdb_search); | 397 | static DECLARE_WORK(reg_regdb_work, reg_regdb_search); |
@@ -936,13 +925,7 @@ static bool reg_request_cell_base(struct regulatory_request *request) | |||
936 | 925 | ||
937 | bool reg_last_request_cell_base(void) | 926 | bool reg_last_request_cell_base(void) |
938 | { | 927 | { |
939 | bool val; | 928 | return reg_request_cell_base(get_last_request()); |
940 | |||
941 | mutex_lock(®_mutex); | ||
942 | val = reg_request_cell_base(get_last_request()); | ||
943 | mutex_unlock(®_mutex); | ||
944 | |||
945 | return val; | ||
946 | } | 929 | } |
947 | 930 | ||
948 | #ifdef CONFIG_CFG80211_CERTIFICATION_ONUS | 931 | #ifdef CONFIG_CFG80211_CERTIFICATION_ONUS |
@@ -1225,7 +1208,7 @@ static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator) | |||
1225 | struct cfg80211_registered_device *rdev; | 1208 | struct cfg80211_registered_device *rdev; |
1226 | struct wiphy *wiphy; | 1209 | struct wiphy *wiphy; |
1227 | 1210 | ||
1228 | assert_cfg80211_lock(); | 1211 | ASSERT_RTNL(); |
1229 | 1212 | ||
1230 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { | 1213 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { |
1231 | wiphy = &rdev->wiphy; | 1214 | wiphy = &rdev->wiphy; |
@@ -1362,7 +1345,7 @@ get_reg_request_treatment(struct wiphy *wiphy, | |||
1362 | return REG_REQ_OK; | 1345 | return REG_REQ_OK; |
1363 | return REG_REQ_ALREADY_SET; | 1346 | return REG_REQ_ALREADY_SET; |
1364 | } | 1347 | } |
1365 | return 0; | 1348 | return REG_REQ_OK; |
1366 | case NL80211_REGDOM_SET_BY_DRIVER: | 1349 | case NL80211_REGDOM_SET_BY_DRIVER: |
1367 | if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) { | 1350 | if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) { |
1368 | if (regdom_changes(pending_request->alpha2)) | 1351 | if (regdom_changes(pending_request->alpha2)) |
@@ -1444,8 +1427,6 @@ static void reg_set_request_processed(void) | |||
1444 | * what it believes should be the current regulatory domain. | 1427 | * what it believes should be the current regulatory domain. |
1445 | * | 1428 | * |
1446 | * Returns one of the different reg request treatment values. | 1429 | * Returns one of the different reg request treatment values. |
1447 | * | ||
1448 | * Caller must hold ®_mutex | ||
1449 | */ | 1430 | */ |
1450 | static enum reg_request_treatment | 1431 | static enum reg_request_treatment |
1451 | __regulatory_hint(struct wiphy *wiphy, | 1432 | __regulatory_hint(struct wiphy *wiphy, |
@@ -1570,21 +1551,19 @@ static void reg_process_pending_hints(void) | |||
1570 | { | 1551 | { |
1571 | struct regulatory_request *reg_request, *lr; | 1552 | struct regulatory_request *reg_request, *lr; |
1572 | 1553 | ||
1573 | mutex_lock(&cfg80211_mutex); | ||
1574 | mutex_lock(®_mutex); | ||
1575 | lr = get_last_request(); | 1554 | lr = get_last_request(); |
1576 | 1555 | ||
1577 | /* When last_request->processed becomes true this will be rescheduled */ | 1556 | /* When last_request->processed becomes true this will be rescheduled */ |
1578 | if (lr && !lr->processed) { | 1557 | if (lr && !lr->processed) { |
1579 | REG_DBG_PRINT("Pending regulatory request, waiting for it to be processed...\n"); | 1558 | REG_DBG_PRINT("Pending regulatory request, waiting for it to be processed...\n"); |
1580 | goto out; | 1559 | return; |
1581 | } | 1560 | } |
1582 | 1561 | ||
1583 | spin_lock(®_requests_lock); | 1562 | spin_lock(®_requests_lock); |
1584 | 1563 | ||
1585 | if (list_empty(®_requests_list)) { | 1564 | if (list_empty(®_requests_list)) { |
1586 | spin_unlock(®_requests_lock); | 1565 | spin_unlock(®_requests_lock); |
1587 | goto out; | 1566 | return; |
1588 | } | 1567 | } |
1589 | 1568 | ||
1590 | reg_request = list_first_entry(®_requests_list, | 1569 | reg_request = list_first_entry(®_requests_list, |
@@ -1595,10 +1574,6 @@ static void reg_process_pending_hints(void) | |||
1595 | spin_unlock(®_requests_lock); | 1574 | spin_unlock(®_requests_lock); |
1596 | 1575 | ||
1597 | reg_process_hint(reg_request, reg_request->initiator); | 1576 | reg_process_hint(reg_request, reg_request->initiator); |
1598 | |||
1599 | out: | ||
1600 | mutex_unlock(®_mutex); | ||
1601 | mutex_unlock(&cfg80211_mutex); | ||
1602 | } | 1577 | } |
1603 | 1578 | ||
1604 | /* Processes beacon hints -- this has nothing to do with country IEs */ | 1579 | /* Processes beacon hints -- this has nothing to do with country IEs */ |
@@ -1607,9 +1582,6 @@ static void reg_process_pending_beacon_hints(void) | |||
1607 | struct cfg80211_registered_device *rdev; | 1582 | struct cfg80211_registered_device *rdev; |
1608 | struct reg_beacon *pending_beacon, *tmp; | 1583 | struct reg_beacon *pending_beacon, *tmp; |
1609 | 1584 | ||
1610 | mutex_lock(&cfg80211_mutex); | ||
1611 | mutex_lock(®_mutex); | ||
1612 | |||
1613 | /* This goes through the _pending_ beacon list */ | 1585 | /* This goes through the _pending_ beacon list */ |
1614 | spin_lock_bh(®_pending_beacons_lock); | 1586 | spin_lock_bh(®_pending_beacons_lock); |
1615 | 1587 | ||
@@ -1626,14 +1598,14 @@ static void reg_process_pending_beacon_hints(void) | |||
1626 | } | 1598 | } |
1627 | 1599 | ||
1628 | spin_unlock_bh(®_pending_beacons_lock); | 1600 | spin_unlock_bh(®_pending_beacons_lock); |
1629 | mutex_unlock(®_mutex); | ||
1630 | mutex_unlock(&cfg80211_mutex); | ||
1631 | } | 1601 | } |
1632 | 1602 | ||
1633 | static void reg_todo(struct work_struct *work) | 1603 | static void reg_todo(struct work_struct *work) |
1634 | { | 1604 | { |
1605 | rtnl_lock(); | ||
1635 | reg_process_pending_hints(); | 1606 | reg_process_pending_hints(); |
1636 | reg_process_pending_beacon_hints(); | 1607 | reg_process_pending_beacon_hints(); |
1608 | rtnl_unlock(); | ||
1637 | } | 1609 | } |
1638 | 1610 | ||
1639 | static void queue_regulatory_request(struct regulatory_request *request) | 1611 | static void queue_regulatory_request(struct regulatory_request *request) |
@@ -1717,29 +1689,23 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2) | |||
1717 | } | 1689 | } |
1718 | EXPORT_SYMBOL(regulatory_hint); | 1690 | EXPORT_SYMBOL(regulatory_hint); |
1719 | 1691 | ||
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, | 1692 | void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band, |
1725 | const u8 *country_ie, u8 country_ie_len) | 1693 | const u8 *country_ie, u8 country_ie_len) |
1726 | { | 1694 | { |
1727 | char alpha2[2]; | 1695 | char alpha2[2]; |
1728 | enum environment_cap env = ENVIRON_ANY; | 1696 | enum environment_cap env = ENVIRON_ANY; |
1729 | struct regulatory_request *request, *lr; | 1697 | struct regulatory_request *request = NULL, *lr; |
1730 | |||
1731 | mutex_lock(®_mutex); | ||
1732 | lr = get_last_request(); | ||
1733 | |||
1734 | if (unlikely(!lr)) | ||
1735 | goto out; | ||
1736 | 1698 | ||
1737 | /* IE len must be evenly divisible by 2 */ | 1699 | /* IE len must be evenly divisible by 2 */ |
1738 | if (country_ie_len & 0x01) | 1700 | if (country_ie_len & 0x01) |
1739 | goto out; | 1701 | return; |
1740 | 1702 | ||
1741 | if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) | 1703 | if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) |
1742 | goto out; | 1704 | return; |
1705 | |||
1706 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
1707 | if (!request) | ||
1708 | return; | ||
1743 | 1709 | ||
1744 | alpha2[0] = country_ie[0]; | 1710 | alpha2[0] = country_ie[0]; |
1745 | alpha2[1] = country_ie[1]; | 1711 | alpha2[1] = country_ie[1]; |
@@ -1749,19 +1715,21 @@ void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band, | |||
1749 | else if (country_ie[2] == 'O') | 1715 | else if (country_ie[2] == 'O') |
1750 | env = ENVIRON_OUTDOOR; | 1716 | env = ENVIRON_OUTDOOR; |
1751 | 1717 | ||
1718 | rcu_read_lock(); | ||
1719 | lr = get_last_request(); | ||
1720 | |||
1721 | if (unlikely(!lr)) | ||
1722 | goto out; | ||
1723 | |||
1752 | /* | 1724 | /* |
1753 | * We will run this only upon a successful connection on cfg80211. | 1725 | * We will run this only upon a successful connection on cfg80211. |
1754 | * We leave conflict resolution to the workqueue, where can hold | 1726 | * We leave conflict resolution to the workqueue, where can hold |
1755 | * cfg80211_mutex. | 1727 | * the RTNL. |
1756 | */ | 1728 | */ |
1757 | if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && | 1729 | if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && |
1758 | lr->wiphy_idx != WIPHY_IDX_INVALID) | 1730 | lr->wiphy_idx != WIPHY_IDX_INVALID) |
1759 | goto out; | 1731 | goto out; |
1760 | 1732 | ||
1761 | request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL); | ||
1762 | if (!request) | ||
1763 | goto out; | ||
1764 | |||
1765 | request->wiphy_idx = get_wiphy_idx(wiphy); | 1733 | request->wiphy_idx = get_wiphy_idx(wiphy); |
1766 | request->alpha2[0] = alpha2[0]; | 1734 | request->alpha2[0] = alpha2[0]; |
1767 | request->alpha2[1] = alpha2[1]; | 1735 | request->alpha2[1] = alpha2[1]; |
@@ -1769,8 +1737,10 @@ void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band, | |||
1769 | request->country_ie_env = env; | 1737 | request->country_ie_env = env; |
1770 | 1738 | ||
1771 | queue_regulatory_request(request); | 1739 | queue_regulatory_request(request); |
1740 | request = NULL; | ||
1772 | out: | 1741 | out: |
1773 | mutex_unlock(®_mutex); | 1742 | kfree(request); |
1743 | rcu_read_unlock(); | ||
1774 | } | 1744 | } |
1775 | 1745 | ||
1776 | static void restore_alpha2(char *alpha2, bool reset_user) | 1746 | static void restore_alpha2(char *alpha2, bool reset_user) |
@@ -1858,8 +1828,7 @@ static void restore_regulatory_settings(bool reset_user) | |||
1858 | LIST_HEAD(tmp_reg_req_list); | 1828 | LIST_HEAD(tmp_reg_req_list); |
1859 | struct cfg80211_registered_device *rdev; | 1829 | struct cfg80211_registered_device *rdev; |
1860 | 1830 | ||
1861 | mutex_lock(&cfg80211_mutex); | 1831 | ASSERT_RTNL(); |
1862 | mutex_lock(®_mutex); | ||
1863 | 1832 | ||
1864 | reset_regdomains(true, &world_regdom); | 1833 | reset_regdomains(true, &world_regdom); |
1865 | restore_alpha2(alpha2, reset_user); | 1834 | restore_alpha2(alpha2, reset_user); |
@@ -1914,9 +1883,6 @@ static void restore_regulatory_settings(bool reset_user) | |||
1914 | list_splice_tail_init(&tmp_reg_req_list, ®_requests_list); | 1883 | list_splice_tail_init(&tmp_reg_req_list, ®_requests_list); |
1915 | spin_unlock(®_requests_lock); | 1884 | spin_unlock(®_requests_lock); |
1916 | 1885 | ||
1917 | mutex_unlock(®_mutex); | ||
1918 | mutex_unlock(&cfg80211_mutex); | ||
1919 | |||
1920 | REG_DBG_PRINT("Kicking the queue\n"); | 1886 | REG_DBG_PRINT("Kicking the queue\n"); |
1921 | 1887 | ||
1922 | schedule_work(®_work); | 1888 | schedule_work(®_work); |
@@ -2231,7 +2197,6 @@ int set_regdom(const struct ieee80211_regdomain *rd) | |||
2231 | struct regulatory_request *lr; | 2197 | struct regulatory_request *lr; |
2232 | int r; | 2198 | int r; |
2233 | 2199 | ||
2234 | mutex_lock(®_mutex); | ||
2235 | lr = get_last_request(); | 2200 | lr = get_last_request(); |
2236 | 2201 | ||
2237 | /* Note that this doesn't update the wiphys, this is done below */ | 2202 | /* Note that this doesn't update the wiphys, this is done below */ |
@@ -2241,14 +2206,12 @@ int set_regdom(const struct ieee80211_regdomain *rd) | |||
2241 | reg_set_request_processed(); | 2206 | reg_set_request_processed(); |
2242 | 2207 | ||
2243 | kfree(rd); | 2208 | kfree(rd); |
2244 | goto out; | 2209 | return r; |
2245 | } | 2210 | } |
2246 | 2211 | ||
2247 | /* This would make this whole thing pointless */ | 2212 | /* This would make this whole thing pointless */ |
2248 | if (WARN_ON(!lr->intersect && rd != get_cfg80211_regdom())) { | 2213 | if (WARN_ON(!lr->intersect && rd != get_cfg80211_regdom())) |
2249 | r = -EINVAL; | 2214 | return -EINVAL; |
2250 | goto out; | ||
2251 | } | ||
2252 | 2215 | ||
2253 | /* update all wiphys now with the new established regulatory domain */ | 2216 | /* update all wiphys now with the new established regulatory domain */ |
2254 | update_all_wiphy_regulatory(lr->initiator); | 2217 | update_all_wiphy_regulatory(lr->initiator); |
@@ -2259,10 +2222,7 @@ int set_regdom(const struct ieee80211_regdomain *rd) | |||
2259 | 2222 | ||
2260 | reg_set_request_processed(); | 2223 | reg_set_request_processed(); |
2261 | 2224 | ||
2262 | out: | 2225 | return 0; |
2263 | mutex_unlock(®_mutex); | ||
2264 | |||
2265 | return r; | ||
2266 | } | 2226 | } |
2267 | 2227 | ||
2268 | int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env) | 2228 | int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env) |
@@ -2287,23 +2247,17 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
2287 | 2247 | ||
2288 | void wiphy_regulatory_register(struct wiphy *wiphy) | 2248 | void wiphy_regulatory_register(struct wiphy *wiphy) |
2289 | { | 2249 | { |
2290 | mutex_lock(®_mutex); | ||
2291 | |||
2292 | if (!reg_dev_ignore_cell_hint(wiphy)) | 2250 | if (!reg_dev_ignore_cell_hint(wiphy)) |
2293 | reg_num_devs_support_basehint++; | 2251 | reg_num_devs_support_basehint++; |
2294 | 2252 | ||
2295 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); | 2253 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); |
2296 | |||
2297 | mutex_unlock(®_mutex); | ||
2298 | } | 2254 | } |
2299 | 2255 | ||
2300 | /* Caller must hold cfg80211_mutex */ | ||
2301 | void wiphy_regulatory_deregister(struct wiphy *wiphy) | 2256 | void wiphy_regulatory_deregister(struct wiphy *wiphy) |
2302 | { | 2257 | { |
2303 | struct wiphy *request_wiphy = NULL; | 2258 | struct wiphy *request_wiphy = NULL; |
2304 | struct regulatory_request *lr; | 2259 | struct regulatory_request *lr; |
2305 | 2260 | ||
2306 | mutex_lock(®_mutex); | ||
2307 | lr = get_last_request(); | 2261 | lr = get_last_request(); |
2308 | 2262 | ||
2309 | if (!reg_dev_ignore_cell_hint(wiphy)) | 2263 | if (!reg_dev_ignore_cell_hint(wiphy)) |
@@ -2316,12 +2270,10 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy) | |||
2316 | request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx); | 2270 | request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx); |
2317 | 2271 | ||
2318 | if (!request_wiphy || request_wiphy != wiphy) | 2272 | if (!request_wiphy || request_wiphy != wiphy) |
2319 | goto out; | 2273 | return; |
2320 | 2274 | ||
2321 | lr->wiphy_idx = WIPHY_IDX_INVALID; | 2275 | lr->wiphy_idx = WIPHY_IDX_INVALID; |
2322 | lr->country_ie_env = ENVIRON_ANY; | 2276 | lr->country_ie_env = ENVIRON_ANY; |
2323 | out: | ||
2324 | mutex_unlock(®_mutex); | ||
2325 | } | 2277 | } |
2326 | 2278 | ||
2327 | static void reg_timeout_work(struct work_struct *work) | 2279 | static void reg_timeout_work(struct work_struct *work) |
@@ -2385,9 +2337,9 @@ void regulatory_exit(void) | |||
2385 | cancel_delayed_work_sync(®_timeout); | 2337 | cancel_delayed_work_sync(®_timeout); |
2386 | 2338 | ||
2387 | /* Lock to suppress warnings */ | 2339 | /* Lock to suppress warnings */ |
2388 | mutex_lock(®_mutex); | 2340 | rtnl_lock(); |
2389 | reset_regdomains(true, NULL); | 2341 | reset_regdomains(true, NULL); |
2390 | mutex_unlock(®_mutex); | 2342 | rtnl_unlock(); |
2391 | 2343 | ||
2392 | dev_set_uevent_suppress(®_pdev->dev, true); | 2344 | dev_set_uevent_suppress(®_pdev->dev, true); |
2393 | 2345 | ||