]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/wireless/reg.c
cfg80211: Avoid regulatory restore when COUNTRY_IE_IGNORE is set
[mirror_ubuntu-bionic-kernel.git] / net / wireless / reg.c
index 2adfba286b48b04443d4fd617304c94d2f6a1167..f483b04918282a088cafed490517cbea2440accc 100644 (file)
@@ -3065,8 +3065,54 @@ static void restore_regulatory_settings(bool reset_user)
        schedule_work(&reg_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(&reg_pending_beacons_lock);
+               list_for_each_entry_safe(reg_beacon, btmp,
+                                        &reg_pending_beacons, list) {
+                       list_del(&reg_beacon->list);
+                       kfree(reg_beacon);
+               }
+               spin_unlock_bh(&reg_pending_beacons_lock);
+
+               list_for_each_entry_safe(reg_beacon, btmp,
+                                        &reg_beacon_list, list) {
+                       list_del(&reg_beacon->list);
+                       kfree(reg_beacon);
+               }
+
+               return;
+       }
+
        pr_debug("All devices are disconnected, going to restore regulatory settings\n");
        restore_regulatory_settings(false);
 }