nl80211: reset regdom when reloading regdb
authorFinn Behrens <me@kloenk.dev>
Sat, 27 Nov 2021 10:28:53 +0000 (11:28 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 29 Nov 2021 08:31:56 +0000 (09:31 +0100)
Reload the regdom when the regulatory db is reloaded.
Otherwise, the user had to change the regulatoy domain
to a different one and then reset it to the correct
one to have a new regulatory db take effect after a
reload.

Signed-off-by: Finn Behrens <fin@nyantec.com>
Link: https://lore.kernel.org/r/YaIIZfxHgqc/UTA7@gimli.kloenk.dev
[edit commit message]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/regulatory.h
net/wireless/reg.c

index 47f06f6f5a67cca76a30d37458ec43ca3ee0efe4..0cf9335431e0702cd70a223842d306300b887109 100644 (file)
@@ -83,6 +83,7 @@ struct regulatory_request {
        enum nl80211_dfs_regions dfs_region;
        bool intersect;
        bool processed;
+       bool reload;
        enum environment_cap country_ie_env;
        struct list_head list;
 };
index df87c7f3a04921d43ae0f536444101bc4ddfdab6..61f1bf1bc4a73aade27637887e9cad2c19138d58 100644 (file)
@@ -133,6 +133,7 @@ static u32 reg_is_indoor_portid;
 
 static void restore_regulatory_settings(bool reset_user, bool cached);
 static void print_regdomain(const struct ieee80211_regdomain *rd);
+static void reg_process_hint(struct regulatory_request *reg_request);
 
 static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
 {
@@ -1098,6 +1099,8 @@ int reg_reload_regdb(void)
        const struct firmware *fw;
        void *db;
        int err;
+       const struct ieee80211_regdomain *current_regdomain;
+       struct regulatory_request *request;
 
        err = request_firmware(&fw, "regulatory.db", &reg_pdev->dev);
        if (err)
@@ -1118,8 +1121,27 @@ int reg_reload_regdb(void)
        if (!IS_ERR_OR_NULL(regdb))
                kfree(regdb);
        regdb = db;
-       rtnl_unlock();
 
+       /* reset regulatory domain */
+       current_regdomain = get_cfg80211_regdom();
+
+       request = kzalloc(sizeof(*request), GFP_KERNEL);
+       if (!request) {
+               err = -ENOMEM;
+               goto out_unlock;
+       }
+
+       request->wiphy_idx = WIPHY_IDX_INVALID;
+       request->alpha2[0] = current_regdomain->alpha2[0];
+       request->alpha2[1] = current_regdomain->alpha2[1];
+       request->initiator = NL80211_USER_REG_HINT_USER;
+       request->user_reg_hint_type = NL80211_USER_REG_HINT_USER;
+       request->reload = true;
+
+       reg_process_hint(request);
+
+out_unlock:
+       rtnl_unlock();
  out:
        release_firmware(fw);
        return err;
@@ -2690,7 +2712,8 @@ reg_process_hint_user(struct regulatory_request *user_request)
 
        treatment = __reg_process_hint_user(user_request);
        if (treatment == REG_REQ_IGNORE ||
-           treatment == REG_REQ_ALREADY_SET)
+           (treatment == REG_REQ_ALREADY_SET &&
+            !user_request->reload))
                return REG_REQ_IGNORE;
 
        user_request->intersect = treatment == REG_REQ_INTERSECT;