| From a887c647d8bb185669af370e194ca6074943aba7 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 10 Jul 2018 18:46:13 +0530 |
| Subject: cfg80211: Avoid regulatory restore when COUNTRY_IE_IGNORE is set |
| |
| From: Rajeev Kumar Sirasanagandla <rsirasan@codeaurora.org> |
| |
| [ Upstream commit 7417844b63d4b0dc8ab23f88259bf95de7d09b57 ] |
| |
| When REGULATORY_COUNTRY_IE_IGNORE is set, __reg_process_hint_country_ie() |
| ignores the country code change request from __cfg80211_connect_result() |
| via regulatory_hint_country_ie(). |
| |
| After Disconnect, similar to above, country code should not be reset to |
| world when country IE ignore is set. But this is violated and restore of |
| regulatory settings is invoked by cfg80211_disconnect_work via |
| regulatory_hint_disconnect(). |
| |
| To address this, avoid regulatory restore from regulatory_hint_disconnect() |
| when COUNTRY_IE_IGNORE is set. |
| |
| Note: Currently, restore_regulatory_settings() takes care of clearing |
| beacon hints. But in the proposed change, regulatory restore is avoided. |
| Therefore, explicitly clear beacon hints when DISABLE_BEACON_HINTS |
| is not set. |
| |
| Signed-off-by: Rajeev Kumar Sirasanagandla <rsirasan@codeaurora.org> |
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/wireless/reg.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ |
| 1 file changed, 46 insertions(+) |
| |
| diff --git a/net/wireless/reg.c b/net/wireless/reg.c |
| index cccbf845079c8..68ae97ef8bf0b 100644 |
| --- a/net/wireless/reg.c |
| +++ b/net/wireless/reg.c |
| @@ -3225,8 +3225,54 @@ static void restore_regulatory_settings(bool reset_user) |
| schedule_work(®_work); |
| } |
| |
| +static bool is_wiphy_all_set_reg_flag(enum ieee80211_regulatory_flags flag) |
| +{ |
| + struct cfg80211_registered_device *rdev; |
| + struct wireless_dev *wdev; |
| + |
| + list_for_each_entry(rdev, &cfg80211_rdev_list, list) { |
| + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { |
| + wdev_lock(wdev); |
| + if (!(wdev->wiphy->regulatory_flags & flag)) { |
| + wdev_unlock(wdev); |
| + return false; |
| + } |
| + wdev_unlock(wdev); |
| + } |
| + } |
| + |
| + return true; |
| +} |
| + |
| void regulatory_hint_disconnect(void) |
| { |
| + /* Restore of regulatory settings is not required when wiphy(s) |
| + * ignore IE from connected access point but clearance of beacon hints |
| + * is required when wiphy(s) supports beacon hints. |
| + */ |
| + if (is_wiphy_all_set_reg_flag(REGULATORY_COUNTRY_IE_IGNORE)) { |
| + struct reg_beacon *reg_beacon, *btmp; |
| + |
| + if (is_wiphy_all_set_reg_flag(REGULATORY_DISABLE_BEACON_HINTS)) |
| + return; |
| + |
| + spin_lock_bh(®_pending_beacons_lock); |
| + list_for_each_entry_safe(reg_beacon, btmp, |
| + ®_pending_beacons, list) { |
| + list_del(®_beacon->list); |
| + kfree(reg_beacon); |
| + } |
| + spin_unlock_bh(®_pending_beacons_lock); |
| + |
| + list_for_each_entry_safe(reg_beacon, btmp, |
| + ®_beacon_list, list) { |
| + list_del(®_beacon->list); |
| + kfree(reg_beacon); |
| + } |
| + |
| + return; |
| + } |
| + |
| pr_debug("All devices are disconnected, going to restore regulatory settings\n"); |
| restore_regulatory_settings(false); |
| } |
| -- |
| 2.20.1 |
| |