aboutsummaryrefslogtreecommitdiff
path: root/net/wireless
diff options
context:
space:
mode:
authorRaj Kumar Bhagat2023-04-21 11:43:12 +0530
committerJohannes Berg2023-09-13 12:34:01 +0200
commit13ba6794d29ee273c26f26b6c7892797ac9957ae (patch)
tree90032f67448c2481684a98ddc866c948f6830916 /net/wireless
parent6bc5ddb2fd0653a3e66a8e41fa4c20eced13e4d8 (diff)
wifi: cfg80211: allow reg update by driver even if wiphy->regd is set
Currently regulatory update by driver is not allowed when the wiphy->regd is already set and drivers_request->intersect is false. During wiphy registration, some drivers (ath10k does this currently) first register the world regulatory to cfg80211 using wiphy_apply_custom_regulatory(). The driver then obtain the current operating country and tries to update the correct regulatory to cfg80211 using regulatory_hint(). But at this point, wiphy->regd is already set to world regulatory. Also, since this is the first request from driver after the world regulatory is set this will result in drivers_request->intersect set to false. In this condition the driver request regulatory is not allowed to update to cfg80211 in reg_set_rd_driver(). This restricts the device operation to the world regulatory. This driver request to update the regulatory with current operating country is valid and should be updated to cfg80211. Hence allow regulatory update by driver even if the wiphy->regd is already set and driver_request->intersect is false. Signed-off-by: Raj Kumar Bhagat <quic_rajkbhag@quicinc.com> Reviewed-by: Jeff Johnson <quic_jjohnson@quicinc.com> Link: https://lore.kernel.org/r/20230421061312.13722-1-quic_rajkbhag@quicinc.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/reg.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index f86ee1a6daad..8a99eafa4b62 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -3827,7 +3827,7 @@ static int reg_set_rd_driver(const struct ieee80211_regdomain *rd,
{
const struct ieee80211_regdomain *regd;
const struct ieee80211_regdomain *intersected_rd = NULL;
- const struct ieee80211_regdomain *tmp;
+ const struct ieee80211_regdomain *tmp = NULL;
struct wiphy *request_wiphy;
if (is_world_regdom(rd->alpha2))
@@ -3850,10 +3850,8 @@ static int reg_set_rd_driver(const struct ieee80211_regdomain *rd,
if (!driver_request->intersect) {
ASSERT_RTNL();
wiphy_lock(request_wiphy);
- if (request_wiphy->regd) {
- wiphy_unlock(request_wiphy);
- return -EALREADY;
- }
+ if (request_wiphy->regd)
+ tmp = get_wiphy_regdom(request_wiphy);
regd = reg_copy_regd(rd);
if (IS_ERR(regd)) {
@@ -3862,6 +3860,7 @@ static int reg_set_rd_driver(const struct ieee80211_regdomain *rd,
}
rcu_assign_pointer(request_wiphy->regd, regd);
+ rcu_free_regdom(tmp);
wiphy_unlock(request_wiphy);
reset_regdomains(false, rd);
return 0;