mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-18 01:41:24 +00:00
279 lines
10 KiB
Diff
279 lines
10 KiB
Diff
From patchwork Fri Nov 12 15:31:16 2021
|
|
Content-Type: text/plain; charset="utf-8"
|
|
MIME-Version: 1.0
|
|
Content-Transfer-Encoding: 7bit
|
|
X-Patchwork-Submitter: Sven Eckelmann <sven@narfation.org>
|
|
X-Patchwork-Id: 12616993
|
|
X-Patchwork-Delegate: kvalo@adurom.com
|
|
Return-Path: <linux-wireless-owner@kernel.org>
|
|
X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
|
|
aws-us-west-2-korg-lkml-1.web.codeaurora.org
|
|
Received: from mail.kernel.org (mail.kernel.org [198.145.29.99])
|
|
by smtp.lore.kernel.org (Postfix) with ESMTP id 721EAC433F5
|
|
for <linux-wireless@archiver.kernel.org>;
|
|
Fri, 12 Nov 2021 15:32:26 +0000 (UTC)
|
|
Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
|
|
by mail.kernel.org (Postfix) with ESMTP id 4E73F60C40
|
|
for <linux-wireless@archiver.kernel.org>;
|
|
Fri, 12 Nov 2021 15:32:26 +0000 (UTC)
|
|
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
|
|
id S230182AbhKLPfQ (ORCPT
|
|
<rfc822;linux-wireless@archiver.kernel.org>);
|
|
Fri, 12 Nov 2021 10:35:16 -0500
|
|
Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56078 "EHLO
|
|
lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
|
|
with ESMTP id S229509AbhKLPfP (ORCPT
|
|
<rfc822;linux-wireless@vger.kernel.org>);
|
|
Fri, 12 Nov 2021 10:35:15 -0500
|
|
Received: from dvalin.narfation.org (dvalin.narfation.org
|
|
[IPv6:2a00:17d8:100::8b1])
|
|
by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C3035C061766
|
|
for <linux-wireless@vger.kernel.org>;
|
|
Fri, 12 Nov 2021 07:32:24 -0800 (PST)
|
|
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=narfation.org;
|
|
s=20121; t=1636731141;
|
|
h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
|
|
to:to:cc:cc:mime-version:mime-version:
|
|
content-transfer-encoding:content-transfer-encoding;
|
|
bh=oHqfDu/AzlIIJ7kJWRvWS79eoKm0cbRICNb1jk+xitA=;
|
|
b=QcxgTgtUlyXNy5WQL+HLDH08b/xtVIevhpQATuhOx1ydUSKdszhvhpZwXwoQO6YajcE44M
|
|
ZxrForTEDSbDg0ewdn/v6X0/tUqzAFbLruW76huN+w/XEO2/egNP0LiAxknVbhFwgf0rX8
|
|
s4RipvwxFT/ecJd/iL80lK1oLkTVeSg=
|
|
From: Sven Eckelmann <sven@narfation.org>
|
|
To: ath11k@lists.infradead.org
|
|
Cc: linux-wireless@vger.kernel.org, Sven Eckelmann <sven@narfation.org>
|
|
Subject: [PATCH] ath11k: Fix ETSI regd with weather radar overlap
|
|
Date: Fri, 12 Nov 2021 16:31:16 +0100
|
|
Message-Id: <20211112153116.1214421-1-sven@narfation.org>
|
|
X-Mailer: git-send-email 2.30.2
|
|
MIME-Version: 1.0
|
|
Precedence: bulk
|
|
List-ID: <linux-wireless.vger.kernel.org>
|
|
X-Mailing-List: linux-wireless@vger.kernel.org
|
|
|
|
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;
|
|
}
|