Search Linux Wireless

Re: [PATCH] wifi: cfg80211: allow reg update by driver even if wiphy->regd is set

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 4/20/2023 11:13 PM, Raj Kumar Bhagat wrote:
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 requlatory with current operating

nit: s/requlatory/regulatory/

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@xxxxxxxxxxx>

Reviewed-by: Jeff Johnson <quic_jjohnson@xxxxxxxxxxx>

---
  net/wireless/reg.c | 9 ++++-----
  1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 0d40d6af7e10..6cf0bc386f94 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -3833,7 +3833,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))
@@ -3856,10 +3856,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)) {
@@ -3868,6 +3866,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;




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux