Patch "ath11k: Fix ETSI regd with weather radar overlap" has been added to the 5.10-stable tree

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

 



This is a note to let you know that I've just added the patch titled

    ath11k: Fix ETSI regd with weather radar overlap

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     ath11k-fix-etsi-regd-with-weather-radar-overlap.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 8967b15bc90f4c0d440a33f754aefddc444de9a4
Author: Sven Eckelmann <sven@xxxxxxxxxxxxx>
Date:   Mon Nov 15 11:29:55 2021 +0200

    ath11k: Fix ETSI regd with weather radar overlap
    
    [ Upstream commit 086c921a354089f209318501038d43c98d3f409f ]
    
    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@xxxxxxxxxxxxx>
    Signed-off-by: Kalle Valo <kvalo@xxxxxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20211112153116.1214421-1-sven@xxxxxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c
index b8f9f34408879..e34311516b958 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;
 }



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux