linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ath11k: Fix ETSI regd with weather radar overlap
@ 2021-11-12 15:31 Sven Eckelmann
  2021-11-17  7:27 ` Kalle Valo
  0 siblings, 1 reply; 2+ messages in thread
From: Sven Eckelmann @ 2021-11-12 15:31 UTC (permalink / raw)
  To: ath11k; +Cc: linux-wireless, Sven Eckelmann

Some ETSI countries have a small overlap in the wireless-regdb with an ETSI
channel (5590-5650). A good example is Australia:

  country AU: DFS-ETSI
  	(2400 - 2483.5 @ 40), (36)
  	(5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW
  	(5250 - 5350 @ 80), (20), NO-OUTDOOR, AUTO-BW, DFS
  	(5470 - 5600 @ 80), (27), DFS
  	(5650 - 5730 @ 80), (27), DFS
  	(5730 - 5850 @ 80), (36)
  	(57000 - 66000 @ 2160), (43), NO-OUTDOOR

If the firmware (or the BDF) is shipped with these rules then there is only
a 10 MHz overlap with the weather radar:

* below: 5470 - 5590
* weather radar: 5590 - 5600
* above: (none for the rule "5470 - 5600 @ 80")

There are several wrong assumption in the ath11k code:

* there is always a valid range below the weather radar
  (actually: there could be no range below the weather radar range OR range
   could be smaller than 20 MHz)
* intersected range in the weather radar range is valid
  (actually: the range could be smaller than 20 MHz)
* range above weather radar is either empty or valid
  (actually: the range could be smaller than 20 MHz)

These wrong assumption will lead in this example to a rule

  (5590 - 5600 @ 20), (N/A, 27), (600000 ms), DFS, AUTO-BW

which is invalid according to is_valid_reg_rule() because the freq_diff is
only 10 MHz but the max_bandwidth is set to 20 MHz. Which results in a
rejection like:

  WARNING: at backports-20210222_001-4.4.60-b157d2276/net/wireless/reg.c:3984
  [...]
  Call trace:
  [<ffffffbffc3d2e50>] reg_get_max_bandwidth+0x300/0x3a8 [cfg80211]
  [<ffffffbffc3d3d0c>] regulatory_set_wiphy_regd_sync+0x3c/0x98 [cfg80211]
  [<ffffffbffc651598>] ath11k_regd_update+0x1a8/0x210 [ath11k]
  [<ffffffbffc652108>] ath11k_regd_update_work+0x18/0x20 [ath11k]
  [<ffffffc0000a93e0>] process_one_work+0x1f8/0x340
  [<ffffffc0000a9784>] worker_thread+0x25c/0x448
  [<ffffffc0000aedc8>] kthread+0xd0/0xd8
  [<ffffffc000085550>] ret_from_fork+0x10/0x40
  ath11k c000000.wifi: failed to perform regd update : -22
  Invalid regulatory domain detected

To avoid this, the algorithm has to be changed slightly. Instead of
splitting a rule which overlaps with the weather radar range into 3 pieces
and accepting the first two parts blindly, it must actually be checked for
each piece whether it is a valid range. And only if it is valid, add it to
the output array.

When these checks are in place, the processed rules for AU would end up as

  country AU: DFS-ETSI
          (2400 - 2483 @ 40), (N/A, 36), (N/A)
          (5150 - 5250 @ 80), (6, 23), (N/A), NO-OUTDOOR, AUTO-BW
          (5250 - 5350 @ 80), (6, 20), (0 ms), NO-OUTDOOR, DFS, AUTO-BW
          (5470 - 5590 @ 80), (6, 27), (0 ms), DFS, AUTO-BW
          (5650 - 5730 @ 80), (6, 27), (0 ms), DFS, AUTO-BW
          (5730 - 5850 @ 80), (6, 36), (N/A), AUTO-BW

and will be accepted by the wireless regulatory code.

Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 drivers/net/wireless/ath/ath11k/reg.c | 103 ++++++++++++++------------
 1 file changed, 56 insertions(+), 47 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c
index a66b5bdd2167..8606170ba80d 100644
--- a/drivers/net/wireless/ath/ath11k/reg.c
+++ b/drivers/net/wireless/ath/ath11k/reg.c
@@ -456,6 +456,9 @@ ath11k_reg_adjust_bw(u16 start_freq, u16 end_freq, u16 max_bw)
 {
 	u16 bw;
 
+	if (end_freq <= start_freq)
+		return 0;
+
 	bw = end_freq - start_freq;
 	bw = min_t(u16, bw, max_bw);
 
@@ -463,8 +466,10 @@ ath11k_reg_adjust_bw(u16 start_freq, u16 end_freq, u16 max_bw)
 		bw = 80;
 	else if (bw >= 40 && bw < 80)
 		bw = 40;
-	else if (bw < 40)
+	else if (bw >= 20 && bw < 40)
 		bw = 20;
+	else
+		bw = 0;
 
 	return bw;
 }
@@ -488,73 +493,77 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab,
 				     struct cur_reg_rule *reg_rule,
 				     u8 *rule_idx, u32 flags, u16 max_bw)
 {
+	u32 start_freq;
 	u32 end_freq;
 	u16 bw;
 	u8 i;
 
 	i = *rule_idx;
 
+	/* there might be situations when even the input rule must be dropped */
+	i--;
+
+	/* frequencies below weather radar */
 	bw = ath11k_reg_adjust_bw(reg_rule->start_freq,
 				  ETSI_WEATHER_RADAR_BAND_LOW, max_bw);
+	if (bw > 0) {
+		i++;
 
-	ath11k_reg_update_rule(regd->reg_rules + i, reg_rule->start_freq,
-			       ETSI_WEATHER_RADAR_BAND_LOW, bw,
-			       reg_rule->ant_gain, reg_rule->reg_power,
-			       flags);
+		ath11k_reg_update_rule(regd->reg_rules + i,
+				       reg_rule->start_freq,
+				       ETSI_WEATHER_RADAR_BAND_LOW, bw,
+				       reg_rule->ant_gain, reg_rule->reg_power,
+				       flags);
 
-	ath11k_dbg(ab, ATH11K_DBG_REG,
-		   "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
-		   i + 1, reg_rule->start_freq, ETSI_WEATHER_RADAR_BAND_LOW,
-		   bw, reg_rule->ant_gain, reg_rule->reg_power,
-		   regd->reg_rules[i].dfs_cac_ms,
-		   flags);
-
-	if (reg_rule->end_freq > ETSI_WEATHER_RADAR_BAND_HIGH)
-		end_freq = ETSI_WEATHER_RADAR_BAND_HIGH;
-	else
-		end_freq = reg_rule->end_freq;
+		ath11k_dbg(ab, ATH11K_DBG_REG,
+			   "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
+			   i + 1, reg_rule->start_freq,
+			   ETSI_WEATHER_RADAR_BAND_LOW, bw, reg_rule->ant_gain,
+			   reg_rule->reg_power, regd->reg_rules[i].dfs_cac_ms,
+			   flags);
+	}
 
-	bw = ath11k_reg_adjust_bw(ETSI_WEATHER_RADAR_BAND_LOW, end_freq,
-				  max_bw);
+	/* weather radar frequencies */
+	start_freq = max_t(u32, reg_rule->start_freq,
+			   ETSI_WEATHER_RADAR_BAND_LOW);
+	end_freq = min_t(u32, reg_rule->end_freq, ETSI_WEATHER_RADAR_BAND_HIGH);
 
-	i++;
+	bw = ath11k_reg_adjust_bw(start_freq, end_freq, max_bw);
+	if (bw > 0) {
+		i++;
 
-	ath11k_reg_update_rule(regd->reg_rules + i,
-			       ETSI_WEATHER_RADAR_BAND_LOW, end_freq, bw,
-			       reg_rule->ant_gain, reg_rule->reg_power,
-			       flags);
+		ath11k_reg_update_rule(regd->reg_rules + i, start_freq,
+				       end_freq, bw, reg_rule->ant_gain,
+				       reg_rule->reg_power, flags);
 
-	regd->reg_rules[i].dfs_cac_ms = ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT;
+		regd->reg_rules[i].dfs_cac_ms = ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT;
 
-	ath11k_dbg(ab, ATH11K_DBG_REG,
-		   "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
-		   i + 1, ETSI_WEATHER_RADAR_BAND_LOW, end_freq,
-		   bw, reg_rule->ant_gain, reg_rule->reg_power,
-		   regd->reg_rules[i].dfs_cac_ms,
-		   flags);
-
-	if (end_freq == reg_rule->end_freq) {
-		regd->n_reg_rules--;
-		*rule_idx = i;
-		return;
+		ath11k_dbg(ab, ATH11K_DBG_REG,
+			   "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
+			   i + 1, start_freq, end_freq, bw,
+			   reg_rule->ant_gain, reg_rule->reg_power,
+			   regd->reg_rules[i].dfs_cac_ms, flags);
 	}
 
+	/* frequencies above weather radar */
 	bw = ath11k_reg_adjust_bw(ETSI_WEATHER_RADAR_BAND_HIGH,
 				  reg_rule->end_freq, max_bw);
+	if (bw > 0) {
+		i++;
 
-	i++;
-
-	ath11k_reg_update_rule(regd->reg_rules + i, ETSI_WEATHER_RADAR_BAND_HIGH,
-			       reg_rule->end_freq, bw,
-			       reg_rule->ant_gain, reg_rule->reg_power,
-			       flags);
+		ath11k_reg_update_rule(regd->reg_rules + i,
+				       ETSI_WEATHER_RADAR_BAND_HIGH,
+				       reg_rule->end_freq, bw,
+				       reg_rule->ant_gain, reg_rule->reg_power,
+				       flags);
 
-	ath11k_dbg(ab, ATH11K_DBG_REG,
-		   "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
-		   i + 1, ETSI_WEATHER_RADAR_BAND_HIGH, reg_rule->end_freq,
-		   bw, reg_rule->ant_gain, reg_rule->reg_power,
-		   regd->reg_rules[i].dfs_cac_ms,
-		   flags);
+		ath11k_dbg(ab, ATH11K_DBG_REG,
+			   "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
+			   i + 1, ETSI_WEATHER_RADAR_BAND_HIGH,
+			   reg_rule->end_freq, bw, reg_rule->ant_gain,
+			   reg_rule->reg_power, regd->reg_rules[i].dfs_cac_ms,
+			   flags);
+	}
 
 	*rule_idx = i;
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] ath11k: Fix ETSI regd with weather radar overlap
  2021-11-12 15:31 [PATCH] ath11k: Fix ETSI regd with weather radar overlap Sven Eckelmann
@ 2021-11-17  7:27 ` Kalle Valo
  0 siblings, 0 replies; 2+ messages in thread
From: Kalle Valo @ 2021-11-17  7:27 UTC (permalink / raw)
  To: Sven Eckelmann; +Cc: ath11k, linux-wireless, Sven Eckelmann

Sven Eckelmann <sven@narfation.org> wrote:

> Some ETSI countries have a small overlap in the wireless-regdb with an ETSI
> channel (5590-5650). A good example is Australia:
> 
>   country AU: DFS-ETSI
>         (2400 - 2483.5 @ 40), (36)
>         (5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW
>         (5250 - 5350 @ 80), (20), NO-OUTDOOR, AUTO-BW, DFS
>         (5470 - 5600 @ 80), (27), DFS
>         (5650 - 5730 @ 80), (27), DFS
>         (5730 - 5850 @ 80), (36)
>         (57000 - 66000 @ 2160), (43), NO-OUTDOOR
> 
> If the firmware (or the BDF) is shipped with these rules then there is only
> a 10 MHz overlap with the weather radar:
> 
> * below: 5470 - 5590
> * weather radar: 5590 - 5600
> * above: (none for the rule "5470 - 5600 @ 80")
> 
> There are several wrong assumption in the ath11k code:
> 
> * there is always a valid range below the weather radar
>   (actually: there could be no range below the weather radar range OR range
>    could be smaller than 20 MHz)
> * intersected range in the weather radar range is valid
>   (actually: the range could be smaller than 20 MHz)
> * range above weather radar is either empty or valid
>   (actually: the range could be smaller than 20 MHz)
> 
> These wrong assumption will lead in this example to a rule
> 
>   (5590 - 5600 @ 20), (N/A, 27), (600000 ms), DFS, AUTO-BW
> 
> which is invalid according to is_valid_reg_rule() because the freq_diff is
> only 10 MHz but the max_bandwidth is set to 20 MHz. Which results in a
> rejection like:
> 
>   WARNING: at backports-20210222_001-4.4.60-b157d2276/net/wireless/reg.c:3984
>   [...]
>   Call trace:
>   [<ffffffbffc3d2e50>] reg_get_max_bandwidth+0x300/0x3a8 [cfg80211]
>   [<ffffffbffc3d3d0c>] regulatory_set_wiphy_regd_sync+0x3c/0x98 [cfg80211]
>   [<ffffffbffc651598>] ath11k_regd_update+0x1a8/0x210 [ath11k]
>   [<ffffffbffc652108>] ath11k_regd_update_work+0x18/0x20 [ath11k]
>   [<ffffffc0000a93e0>] process_one_work+0x1f8/0x340
>   [<ffffffc0000a9784>] worker_thread+0x25c/0x448
>   [<ffffffc0000aedc8>] kthread+0xd0/0xd8
>   [<ffffffc000085550>] ret_from_fork+0x10/0x40
>   ath11k c000000.wifi: failed to perform regd update : -22
>   Invalid regulatory domain detected
> 
> To avoid this, the algorithm has to be changed slightly. Instead of
> splitting a rule which overlaps with the weather radar range into 3 pieces
> and accepting the first two parts blindly, it must actually be checked for
> each piece whether it is a valid range. And only if it is valid, add it to
> the output array.
> 
> When these checks are in place, the processed rules for AU would end up as
> 
>   country AU: DFS-ETSI
>           (2400 - 2483 @ 40), (N/A, 36), (N/A)
>           (5150 - 5250 @ 80), (6, 23), (N/A), NO-OUTDOOR, AUTO-BW
>           (5250 - 5350 @ 80), (6, 20), (0 ms), NO-OUTDOOR, DFS, AUTO-BW
>           (5470 - 5590 @ 80), (6, 27), (0 ms), DFS, AUTO-BW
>           (5650 - 5730 @ 80), (6, 27), (0 ms), DFS, AUTO-BW
>           (5730 - 5850 @ 80), (6, 36), (N/A), AUTO-BW
> 
> and will be accepted by the wireless regulatory code.
> 
> Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
> Signed-off-by: Sven Eckelmann <sven@narfation.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Patch applied to ath-next branch of ath.git, thanks.

086c921a3540 ath11k: Fix ETSI regd with weather radar overlap

-- 
https://patchwork.kernel.org/project/linux-wireless/patch/20211112153116.1214421-1-sven@narfation.org/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-11-17  7:27 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-12 15:31 [PATCH] ath11k: Fix ETSI regd with weather radar overlap Sven Eckelmann
2021-11-17  7:27 ` Kalle Valo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).