Initial commit
Some checks failed
Build Kernel / Build all affected Kernels (push) Has been cancelled
Build all core packages / Build all core packages for selected target (push) Has been cancelled
Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Has been cancelled
Build Toolchains / Build Toolchains for each target (push) Has been cancelled
Build host tools / Build host tools for linux and macos based systems (push) Has been cancelled
Coverity scan build / Coverity x86/64 build (push) Has been cancelled
Some checks failed
Build Kernel / Build all affected Kernels (push) Has been cancelled
Build all core packages / Build all core packages for selected target (push) Has been cancelled
Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Has been cancelled
Build Toolchains / Build Toolchains for each target (push) Has been cancelled
Build host tools / Build host tools for linux and macos based systems (push) Has been cancelled
Coverity scan build / Coverity x86/64 build (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
From a3be23672b4a81256d275af31afc6edcce5c5a26 Mon Sep 17 00:00:00 2001
|
||||
From: Mantas Pucka <mantas@8devices.com>
|
||||
Date: Mon, 22 Jan 2024 11:38:28 +0200
|
||||
Subject: [PATCH] wifi: ath11k: disable coldboot for ipq6018
|
||||
|
||||
Coldboot calibration does not work at the moment and causes failure during
|
||||
wifi startup.
|
||||
|
||||
Signed-off-by: Mantas Pucka <mantas@8devices.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -170,8 +170,8 @@ static const struct ath11k_hw_params ath
|
||||
.supports_shadow_regs = false,
|
||||
.idle_ps = false,
|
||||
.supports_sta_ps = false,
|
||||
- .coldboot_cal_mm = true,
|
||||
- .coldboot_cal_ftm = true,
|
||||
+ .coldboot_cal_mm = false,
|
||||
+ .coldboot_cal_ftm = false,
|
||||
.cbcal_restart_fw = true,
|
||||
.fw_mem_mode = 0,
|
||||
.num_vdevs = 16 + 1,
|
||||
@@ -0,0 +1,162 @@
|
||||
From 534a5f99d589cfa6b244b4433c192b6a278a67ff Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robimarko@gmail.com>
|
||||
Date: Sat, 5 Nov 2022 20:15:40 +0100
|
||||
Subject: [PATCH] wifi: ath11k: use unique QRTR instance ID
|
||||
|
||||
Currently, trying to use AHB + PCI/MHI cards or multiple PCI/MHI cards
|
||||
will cause a clash in the QRTR instance node ID and prevent the driver
|
||||
from talking via QMI to the card and thus initializing it with:
|
||||
[ 9.836329] ath11k c000000.wifi: host capability request failed: 1 90
|
||||
[ 9.842047] ath11k c000000.wifi: failed to send qmi host cap: -22
|
||||
|
||||
So, in order to allow for this combination of cards, especially AHB + PCI
|
||||
cards like IPQ8074 + QCN9074 (Used by me and tested on) set the desired
|
||||
QRTR instance ID offset by calculating a unique one based on PCI domain
|
||||
and bus ID-s and writing it to bits 7-0 of BHI_ERRDBG2 MHI register by
|
||||
using the SBL state callback that is added as part of the series.
|
||||
We also have to make sure that new QRTR offset is added on top of the
|
||||
default QRTR instance ID-s that are currently used in the driver.
|
||||
|
||||
This finally allows using AHB + PCI or multiple PCI cards on the same
|
||||
system.
|
||||
|
||||
Since this is not supported on QCA6390 and like, its limited to QCN9074
|
||||
which is known to support changing QRTR instance ID.
|
||||
|
||||
Before:
|
||||
root@OpenWrt:/# qrtr-lookup
|
||||
Service Version Instance Node Port
|
||||
1054 1 0 7 1 <unknown>
|
||||
69 1 2 7 3 ATH10k WLAN firmware service
|
||||
|
||||
After:
|
||||
root@OpenWrt:/# qrtr-lookup
|
||||
Service Version Instance Node Port
|
||||
1054 1 0 7 1 <unknown>
|
||||
69 1 2 7 3 ATH10k WLAN firmware service
|
||||
15 1 0 8 1 Test service
|
||||
69 1 8 8 2 ATH10k WLAN firmware service
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mhi.c | 49 ++++++++++++++++++---------
|
||||
drivers/net/wireless/ath/ath11k/mhi.h | 3 ++
|
||||
drivers/net/wireless/ath/ath11k/pci.c | 9 ++++-
|
||||
3 files changed, 44 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mhi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mhi.c
|
||||
@@ -239,6 +239,34 @@ static void ath11k_mhi_op_runtime_put(st
|
||||
{
|
||||
}
|
||||
|
||||
+static int ath11k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl,
|
||||
+ void __iomem *addr,
|
||||
+ u32 *out)
|
||||
+{
|
||||
+ *out = readl(addr);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void ath11k_mhi_op_write_reg(struct mhi_controller *mhi_cntrl,
|
||||
+ void __iomem *addr,
|
||||
+ u32 val)
|
||||
+{
|
||||
+ writel(val, addr);
|
||||
+}
|
||||
+
|
||||
+static void ath11k_mhi_qrtr_instance_set(struct mhi_controller *mhi_cntrl)
|
||||
+{
|
||||
+ struct ath11k_base *ab = dev_get_drvdata(mhi_cntrl->cntrl_dev);
|
||||
+
|
||||
+ if (ab->hw_rev == ATH11K_HW_QCN9074_HW10) {
|
||||
+ ath11k_mhi_op_write_reg(mhi_cntrl,
|
||||
+ mhi_cntrl->bhi + BHI_ERRDBG2,
|
||||
+ FIELD_PREP(QRTR_INSTANCE_MASK,
|
||||
+ ab->qmi.service_ins_id - ab->hw_params.qmi_service_ins_id));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static char *ath11k_mhi_op_callback_to_str(enum mhi_callback reason)
|
||||
{
|
||||
switch (reason) {
|
||||
@@ -260,6 +288,8 @@ static char *ath11k_mhi_op_callback_to_s
|
||||
return "MHI_CB_FATAL_ERROR";
|
||||
case MHI_CB_BW_REQ:
|
||||
return "MHI_CB_BW_REQ";
|
||||
+ case MHI_CB_EE_SBL_MODE:
|
||||
+ return "MHI_CB_EE_SBL_MODE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
@@ -282,27 +312,14 @@ static void ath11k_mhi_op_status_cb(stru
|
||||
if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)))
|
||||
queue_work(ab->workqueue_aux, &ab->reset_work);
|
||||
break;
|
||||
+ case MHI_CB_EE_SBL_MODE:
|
||||
+ ath11k_mhi_qrtr_instance_set(mhi_cntrl);
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
-static int ath11k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl,
|
||||
- void __iomem *addr,
|
||||
- u32 *out)
|
||||
-{
|
||||
- *out = readl(addr);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static void ath11k_mhi_op_write_reg(struct mhi_controller *mhi_cntrl,
|
||||
- void __iomem *addr,
|
||||
- u32 val)
|
||||
-{
|
||||
- writel(val, addr);
|
||||
-}
|
||||
-
|
||||
static int ath11k_mhi_read_addr_from_dt(struct mhi_controller *mhi_ctrl)
|
||||
{
|
||||
struct device_node *np;
|
||||
--- a/drivers/net/wireless/ath/ath11k/mhi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mhi.h
|
||||
@@ -17,6 +17,9 @@
|
||||
#define MHICTRL 0x38
|
||||
#define MHICTRL_RESET_MASK 0x2
|
||||
|
||||
+#define BHI_ERRDBG2 0x38
|
||||
+#define QRTR_INSTANCE_MASK GENMASK(7, 0)
|
||||
+
|
||||
int ath11k_mhi_start(struct ath11k_pci *ar_pci);
|
||||
void ath11k_mhi_stop(struct ath11k_pci *ar_pci);
|
||||
int ath11k_mhi_register(struct ath11k_pci *ar_pci);
|
||||
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
||||
@@ -374,13 +374,20 @@ static void ath11k_pci_sw_reset(struct a
|
||||
static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab)
|
||||
{
|
||||
struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
|
||||
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
|
||||
+ struct pci_bus *bus = ab_pci->pdev->bus;
|
||||
|
||||
cfg->tgt_ce = ab->hw_params.target_ce_config;
|
||||
cfg->tgt_ce_len = ab->hw_params.target_ce_count;
|
||||
|
||||
cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map;
|
||||
cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len;
|
||||
- ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
|
||||
+
|
||||
+ if (ab->hw_rev == ATH11K_HW_QCN9074_HW10) {
|
||||
+ ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id +
|
||||
+ (((pci_domain_nr(bus) & 0xF) << 4) | (bus->number & 0xF));
|
||||
+ } else
|
||||
+ ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
|
||||
|
||||
ath11k_ce_get_shadow_config(ab, &cfg->shadow_reg_v2,
|
||||
&cfg->shadow_reg_v2_len);
|
||||
@@ -0,0 +1,24 @@
|
||||
From 1338da257f299d35b4d954b9fda2cc7e0a54a69d Mon Sep 17 00:00:00 2001
|
||||
From: Christian Lamparter <chunkeey@gmail.com>
|
||||
Date: Sun, 11 Jun 2023 14:37:32 +0200
|
||||
Subject: [PATCH] wifi: ath11k: add support DT ieee80211-freq-limit
|
||||
|
||||
The common DT property can be used to limit the available
|
||||
channels/frequencies. But ath11k has to manually call
|
||||
wiphy_read_of_freq_limits().
|
||||
|
||||
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -10034,6 +10034,7 @@ static int __ath11k_mac_register(struct
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
+ wiphy_read_of_freq_limits(ar->hw->wiphy);
|
||||
ath11k_mac_setup_ht_vht_cap(ar, cap, &ht_cap);
|
||||
ath11k_mac_setup_he_cap(ar, cap);
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
From 703d6551f71e7290619d6effe2a25a64e10538b7 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robimarko@gmail.com>
|
||||
Date: Thu, 15 Dec 2022 12:20:52 +0100
|
||||
Subject: [PATCH] ath11k: control thermal support via symbol
|
||||
|
||||
Currently, thermal support will get built if CONFIG_THERMAL is reachable,
|
||||
however this is not suitable for OpenWrt as with ALL_KMODS being set to y
|
||||
ATH11K_THERMAL wont get selected and so hwmon and thermal kmods wont get
|
||||
pulled in resulting in a build-failure.
|
||||
|
||||
So, to avoid that, lets do what is already done for ath10k and add a
|
||||
config symbol into backports for enabling thermal support.
|
||||
|
||||
Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/Kconfig | 7 +++++++
|
||||
drivers/net/wireless/ath/ath11k/Makefile | 2 +-
|
||||
drivers/net/wireless/ath/ath11k/thermal.h | 2 +-
|
||||
local-symbols | 1 +
|
||||
4 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/Kconfig
|
||||
+++ b/drivers/net/wireless/ath/ath11k/Kconfig
|
||||
@@ -61,3 +61,10 @@ config ATH11K_SPECTRAL
|
||||
Enable ath11k spectral scan support
|
||||
|
||||
Say Y to enable access to the FFT/spectral data via debugfs.
|
||||
+
|
||||
+config ATH11K_THERMAL
|
||||
+ bool "ath11k thermal sensors and throttling support"
|
||||
+ depends on ATH11K
|
||||
+ depends on THERMAL
|
||||
+ help
|
||||
+ Enable ath11k thermal sensors and throttling support.
|
||||
--- a/drivers/net/wireless/ath/ath11k/Makefile
|
||||
+++ b/drivers/net/wireless/ath/ath11k/Makefile
|
||||
@@ -23,7 +23,7 @@ ath11k-y += core.o \
|
||||
ath11k-$(CPTCFG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o
|
||||
ath11k-$(CPTCFG_NL80211_TESTMODE) += testmode.o
|
||||
ath11k-$(CPTCFG_ATH11K_TRACING) += trace.o
|
||||
-ath11k-$(CONFIG_THERMAL) += thermal.o
|
||||
+ath11k-$(CPTCFG_ATH11K_THERMAL) += thermal.o
|
||||
ath11k-$(CPTCFG_ATH11K_SPECTRAL) += spectral.o
|
||||
ath11k-$(CONFIG_PM) += wow.o
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/thermal.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/thermal.h
|
||||
@@ -26,7 +26,7 @@ struct ath11k_thermal {
|
||||
int temperature;
|
||||
};
|
||||
|
||||
-#if IS_REACHABLE(CONFIG_THERMAL)
|
||||
+#if IS_REACHABLE(CPTCFG_ATH11K_THERMAL)
|
||||
int ath11k_thermal_register(struct ath11k_base *ab);
|
||||
void ath11k_thermal_unregister(struct ath11k_base *ab);
|
||||
int ath11k_thermal_set_throttling(struct ath11k *ar, u32 throttle_state);
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -166,6 +166,7 @@ ATH11K_DEBUG=
|
||||
ATH11K_DEBUGFS=
|
||||
ATH11K_TRACING=
|
||||
ATH11K_SPECTRAL=
|
||||
+ATH11K_THERMAL=
|
||||
ATH12K=
|
||||
ATH12K_DEBUG=
|
||||
ATH12K_TRACING=
|
||||
@@ -0,0 +1,75 @@
|
||||
From fb1c40c225cbc413d82c872dd8c8af3469b2b921 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robimarko@gmail.com>
|
||||
Date: Fri, 16 Dec 2022 17:17:52 +0100
|
||||
Subject: [PATCH] ath11k: support setting FW memory mode via DT
|
||||
|
||||
ath11k is really memory intensive for devices with less that 1GB of RAM,
|
||||
so lets allow saving a significant amount of memory by setting the FW to
|
||||
Mode-1 via DTS for devices that need it.
|
||||
|
||||
However the drawback is reduced number of VDEV-s and peers which is a
|
||||
reasonable tradeoff.
|
||||
|
||||
Mode-2 allows for further reduction, but it has further restrictions.
|
||||
|
||||
While we are here, lets add a print to be able to easily determine what
|
||||
FW memory mode is being used.
|
||||
|
||||
Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.c | 28 ++++++++++++++++++++++++--
|
||||
1 file changed, 26 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -37,7 +37,7 @@ bool ath11k_ftm_mode;
|
||||
module_param_named(ftm_mode, ath11k_ftm_mode, bool, 0444);
|
||||
MODULE_PARM_DESC(ftm_mode, "Boots up in factory test mode");
|
||||
|
||||
-static const struct ath11k_hw_params ath11k_hw_params[] = {
|
||||
+static struct ath11k_hw_params ath11k_hw_params[] = {
|
||||
{
|
||||
.hw_rev = ATH11K_HW_IPQ8074,
|
||||
.name = "ipq8074 hw2.0",
|
||||
@@ -2138,7 +2138,8 @@ static void ath11k_core_reset(struct wor
|
||||
static int ath11k_init_hw_params(struct ath11k_base *ab)
|
||||
{
|
||||
const struct ath11k_hw_params *hw_params = NULL;
|
||||
- int i;
|
||||
+ u32 fw_mem_mode;
|
||||
+ int i, ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) {
|
||||
hw_params = &ath11k_hw_params[i];
|
||||
@@ -2154,7 +2155,31 @@ static int ath11k_init_hw_params(struct
|
||||
|
||||
ab->hw_params = *hw_params;
|
||||
|
||||
+ ret = of_property_read_u32(ab->dev->of_node,
|
||||
+ "qcom,ath11k-fw-memory-mode",
|
||||
+ &fw_mem_mode);
|
||||
+ if (!ret) {
|
||||
+ if (fw_mem_mode == 0) {
|
||||
+ ab->hw_params.fw_mem_mode = 0;
|
||||
+ ab->hw_params.num_vdevs = 16 + 1;
|
||||
+ ab->hw_params.num_peers = 512;
|
||||
+ }
|
||||
+ else if (fw_mem_mode == 1) {
|
||||
+ ab->hw_params.fw_mem_mode = 1;
|
||||
+ ab->hw_params.num_vdevs = 8;
|
||||
+ ab->hw_params.num_peers = 128;
|
||||
+ } else if (fw_mem_mode == 2) {
|
||||
+ ab->hw_params.fw_mem_mode = 2;
|
||||
+ ab->hw_params.num_vdevs = 8;
|
||||
+ ab->hw_params.num_peers = 128;
|
||||
+ ab->hw_params.coldboot_cal_mm = false;
|
||||
+ ab->hw_params.coldboot_cal_ftm = false;
|
||||
+ } else
|
||||
+ ath11k_info(ab, "Unsupported FW memory mode: %u\n", fw_mem_mode);
|
||||
+ }
|
||||
+
|
||||
ath11k_info(ab, "%s\n", ab->hw_params.name);
|
||||
+ ath11k_info(ab, "FW memory mode: %d\n", ab->hw_params.fw_mem_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
From abdd0985a36189ef2cc0e393b027276e86137ace Mon Sep 17 00:00:00 2001
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Tue, 11 Apr 2023 20:08:49 +0200
|
||||
Subject: [PATCH] ath11k: remove intersection support for regulatory rules
|
||||
|
||||
Currently, regulatory rules from new country settings is intersected with
|
||||
rules from default country settings(during initialisation) in order to prevent
|
||||
users to bypass their default country settings such as power limits, channel
|
||||
flags, etc.
|
||||
|
||||
However, the country setting in the BDF will take higher higher precendence
|
||||
and FW will protect it. Therefore, there is no need to handle intersection
|
||||
on the driver side now.
|
||||
|
||||
Remove regulatory rules intersection logic support.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/reg.c | 168 +++-----------------------
|
||||
drivers/net/wireless/ath/ath11k/reg.h | 2 +-
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 24 +---
|
||||
3 files changed, 16 insertions(+), 178 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/reg.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/reg.c
|
||||
@@ -363,134 +363,6 @@ static u32 ath11k_map_fw_phy_flags(u32 p
|
||||
return flags;
|
||||
}
|
||||
|
||||
-static bool
|
||||
-ath11k_reg_can_intersect(struct ieee80211_reg_rule *rule1,
|
||||
- struct ieee80211_reg_rule *rule2)
|
||||
-{
|
||||
- u32 start_freq1, end_freq1;
|
||||
- u32 start_freq2, end_freq2;
|
||||
-
|
||||
- start_freq1 = rule1->freq_range.start_freq_khz;
|
||||
- start_freq2 = rule2->freq_range.start_freq_khz;
|
||||
-
|
||||
- end_freq1 = rule1->freq_range.end_freq_khz;
|
||||
- end_freq2 = rule2->freq_range.end_freq_khz;
|
||||
-
|
||||
- if ((start_freq1 >= start_freq2 &&
|
||||
- start_freq1 < end_freq2) ||
|
||||
- (start_freq2 > start_freq1 &&
|
||||
- start_freq2 < end_freq1))
|
||||
- return true;
|
||||
-
|
||||
- /* TODO: Should we restrict intersection feasibility
|
||||
- * based on min bandwidth of the intersected region also,
|
||||
- * say the intersected rule should have a min bandwidth
|
||||
- * of 20MHz?
|
||||
- */
|
||||
-
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
-static void ath11k_reg_intersect_rules(struct ieee80211_reg_rule *rule1,
|
||||
- struct ieee80211_reg_rule *rule2,
|
||||
- struct ieee80211_reg_rule *new_rule)
|
||||
-{
|
||||
- u32 start_freq1, end_freq1;
|
||||
- u32 start_freq2, end_freq2;
|
||||
- u32 freq_diff, max_bw;
|
||||
-
|
||||
- start_freq1 = rule1->freq_range.start_freq_khz;
|
||||
- start_freq2 = rule2->freq_range.start_freq_khz;
|
||||
-
|
||||
- end_freq1 = rule1->freq_range.end_freq_khz;
|
||||
- end_freq2 = rule2->freq_range.end_freq_khz;
|
||||
-
|
||||
- new_rule->freq_range.start_freq_khz = max_t(u32, start_freq1,
|
||||
- start_freq2);
|
||||
- new_rule->freq_range.end_freq_khz = min_t(u32, end_freq1, end_freq2);
|
||||
-
|
||||
- freq_diff = new_rule->freq_range.end_freq_khz -
|
||||
- new_rule->freq_range.start_freq_khz;
|
||||
- max_bw = min_t(u32, rule1->freq_range.max_bandwidth_khz,
|
||||
- rule2->freq_range.max_bandwidth_khz);
|
||||
- new_rule->freq_range.max_bandwidth_khz = min_t(u32, max_bw, freq_diff);
|
||||
-
|
||||
- new_rule->power_rule.max_antenna_gain =
|
||||
- min_t(u32, rule1->power_rule.max_antenna_gain,
|
||||
- rule2->power_rule.max_antenna_gain);
|
||||
-
|
||||
- new_rule->power_rule.max_eirp = min_t(u32, rule1->power_rule.max_eirp,
|
||||
- rule2->power_rule.max_eirp);
|
||||
-
|
||||
- /* Use the flags of both the rules */
|
||||
- new_rule->flags = rule1->flags | rule2->flags;
|
||||
-
|
||||
- if ((rule1->flags & NL80211_RRF_PSD) && (rule2->flags & NL80211_RRF_PSD))
|
||||
- new_rule->psd = min_t(s8, rule1->psd, rule2->psd);
|
||||
- else
|
||||
- new_rule->flags &= ~NL80211_RRF_PSD;
|
||||
-
|
||||
- /* To be safe, lts use the max cac timeout of both rules */
|
||||
- new_rule->dfs_cac_ms = max_t(u32, rule1->dfs_cac_ms,
|
||||
- rule2->dfs_cac_ms);
|
||||
-}
|
||||
-
|
||||
-static struct ieee80211_regdomain *
|
||||
-ath11k_regd_intersect(struct ieee80211_regdomain *default_regd,
|
||||
- struct ieee80211_regdomain *curr_regd)
|
||||
-{
|
||||
- u8 num_old_regd_rules, num_curr_regd_rules, num_new_regd_rules;
|
||||
- struct ieee80211_reg_rule *old_rule, *curr_rule, *new_rule;
|
||||
- struct ieee80211_regdomain *new_regd = NULL;
|
||||
- u8 i, j, k;
|
||||
-
|
||||
- num_old_regd_rules = default_regd->n_reg_rules;
|
||||
- num_curr_regd_rules = curr_regd->n_reg_rules;
|
||||
- num_new_regd_rules = 0;
|
||||
-
|
||||
- /* Find the number of intersecting rules to allocate new regd memory */
|
||||
- for (i = 0; i < num_old_regd_rules; i++) {
|
||||
- old_rule = default_regd->reg_rules + i;
|
||||
- for (j = 0; j < num_curr_regd_rules; j++) {
|
||||
- curr_rule = curr_regd->reg_rules + j;
|
||||
-
|
||||
- if (ath11k_reg_can_intersect(old_rule, curr_rule))
|
||||
- num_new_regd_rules++;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (!num_new_regd_rules)
|
||||
- return NULL;
|
||||
-
|
||||
- new_regd = kzalloc(sizeof(*new_regd) + (num_new_regd_rules *
|
||||
- sizeof(struct ieee80211_reg_rule)),
|
||||
- GFP_ATOMIC);
|
||||
-
|
||||
- if (!new_regd)
|
||||
- return NULL;
|
||||
-
|
||||
- /* We set the new country and dfs region directly and only trim
|
||||
- * the freq, power, antenna gain by intersecting with the
|
||||
- * default regdomain. Also MAX of the dfs cac timeout is selected.
|
||||
- */
|
||||
- new_regd->n_reg_rules = num_new_regd_rules;
|
||||
- memcpy(new_regd->alpha2, curr_regd->alpha2, sizeof(new_regd->alpha2));
|
||||
- new_regd->dfs_region = curr_regd->dfs_region;
|
||||
- new_rule = new_regd->reg_rules;
|
||||
-
|
||||
- for (i = 0, k = 0; i < num_old_regd_rules; i++) {
|
||||
- old_rule = default_regd->reg_rules + i;
|
||||
- for (j = 0; j < num_curr_regd_rules; j++) {
|
||||
- curr_rule = curr_regd->reg_rules + j;
|
||||
-
|
||||
- if (ath11k_reg_can_intersect(old_rule, curr_rule))
|
||||
- ath11k_reg_intersect_rules(old_rule, curr_rule,
|
||||
- (new_rule + k++));
|
||||
- }
|
||||
- }
|
||||
- return new_regd;
|
||||
-}
|
||||
-
|
||||
static const char *
|
||||
ath11k_reg_get_regdom_str(enum nl80211_dfs_regions dfs_region)
|
||||
{
|
||||
@@ -641,11 +513,11 @@ ath11k_reg_ap_pwr_convert(enum ieee80211
|
||||
|
||||
struct ieee80211_regdomain *
|
||||
ath11k_reg_build_regd(struct ath11k_base *ab,
|
||||
- struct cur_regulatory_info *reg_info, bool intersect,
|
||||
+ struct cur_regulatory_info *reg_info,
|
||||
enum wmi_vdev_type vdev_type,
|
||||
enum ieee80211_ap_reg_power power_type)
|
||||
{
|
||||
- struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL;
|
||||
+ struct ieee80211_regdomain *new_regd = NULL;
|
||||
struct cur_reg_rule *reg_rule, *reg_rule_6ghz;
|
||||
u8 i = 0, j = 0, k = 0;
|
||||
u8 num_rules;
|
||||
@@ -688,26 +560,26 @@ ath11k_reg_build_regd(struct ath11k_base
|
||||
}
|
||||
|
||||
if (!num_rules)
|
||||
- goto ret;
|
||||
+ return new_regd;
|
||||
|
||||
/* Add max additional rules to accommodate weather radar band */
|
||||
if (reg_info->dfs_region == ATH11K_DFS_REG_ETSI)
|
||||
num_rules += 2;
|
||||
|
||||
- tmp_regd = kzalloc(sizeof(*tmp_regd) +
|
||||
+ new_regd = kzalloc(sizeof(*new_regd) +
|
||||
(num_rules * sizeof(struct ieee80211_reg_rule)),
|
||||
GFP_ATOMIC);
|
||||
- if (!tmp_regd)
|
||||
- goto ret;
|
||||
+ if (!new_regd)
|
||||
+ return new_regd;
|
||||
|
||||
- memcpy(tmp_regd->alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
|
||||
+ memcpy(new_regd->alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
|
||||
memcpy(alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
|
||||
alpha2[2] = '\0';
|
||||
- tmp_regd->dfs_region = ath11k_map_fw_dfs_region(reg_info->dfs_region);
|
||||
+ new_regd->dfs_region = ath11k_map_fw_dfs_region(reg_info->dfs_region);
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_REG,
|
||||
"Country %s, CFG Regdomain %s FW Regdomain %d, num_reg_rules %d\n",
|
||||
- alpha2, ath11k_reg_get_regdom_str(tmp_regd->dfs_region),
|
||||
+ alpha2, ath11k_reg_get_regdom_str(new_regd->dfs_region),
|
||||
reg_info->dfs_region, num_rules);
|
||||
/* Update reg_rules[] below. Firmware is expected to
|
||||
* send these rules in order(2 GHz rules first and then 5 GHz)
|
||||
@@ -746,7 +618,7 @@ ath11k_reg_build_regd(struct ath11k_base
|
||||
flags |= ath11k_map_fw_reg_flags(reg_rule->flags);
|
||||
flags |= ath11k_map_fw_phy_flags(reg_info->phybitmap);
|
||||
|
||||
- ath11k_reg_update_rule(tmp_regd->reg_rules + i,
|
||||
+ ath11k_reg_update_rule(new_regd->reg_rules + i,
|
||||
reg_rule->start_freq,
|
||||
reg_rule->end_freq, max_bw,
|
||||
reg_rule->ant_gain, reg_rule->reg_power,
|
||||
@@ -761,7 +633,7 @@ ath11k_reg_build_regd(struct ath11k_base
|
||||
reg_info->dfs_region == ATH11K_DFS_REG_ETSI &&
|
||||
(reg_rule->end_freq > ETSI_WEATHER_RADAR_BAND_LOW &&
|
||||
reg_rule->start_freq < ETSI_WEATHER_RADAR_BAND_HIGH)){
|
||||
- ath11k_reg_update_weather_radar_band(ab, tmp_regd,
|
||||
+ ath11k_reg_update_weather_radar_band(ab, new_regd,
|
||||
reg_rule, &i,
|
||||
flags, max_bw);
|
||||
continue;
|
||||
@@ -772,51 +644,23 @@ ath11k_reg_build_regd(struct ath11k_base
|
||||
"\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d) (%d, %d)\n",
|
||||
i + 1, reg_rule->start_freq, reg_rule->end_freq,
|
||||
max_bw, reg_rule->ant_gain, reg_rule->reg_power,
|
||||
- tmp_regd->reg_rules[i].dfs_cac_ms, flags,
|
||||
+ new_regd->reg_rules[i].dfs_cac_ms, flags,
|
||||
reg_rule->psd_flag, reg_rule->psd_eirp);
|
||||
} else {
|
||||
ath11k_dbg(ab, ATH11K_DBG_REG,
|
||||
"\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
|
||||
i + 1, reg_rule->start_freq, reg_rule->end_freq,
|
||||
max_bw, reg_rule->ant_gain, reg_rule->reg_power,
|
||||
- tmp_regd->reg_rules[i].dfs_cac_ms,
|
||||
+ new_regd->reg_rules[i].dfs_cac_ms,
|
||||
flags);
|
||||
}
|
||||
}
|
||||
|
||||
- tmp_regd->n_reg_rules = i;
|
||||
+ new_regd->n_reg_rules = i;
|
||||
|
||||
- if (intersect) {
|
||||
- default_regd = ab->default_regd[reg_info->phy_id];
|
||||
-
|
||||
- /* Get a new regd by intersecting the received regd with
|
||||
- * our default regd.
|
||||
- */
|
||||
- new_regd = ath11k_regd_intersect(default_regd, tmp_regd);
|
||||
- kfree(tmp_regd);
|
||||
- if (!new_regd) {
|
||||
- ath11k_warn(ab, "Unable to create intersected regdomain\n");
|
||||
- goto ret;
|
||||
- }
|
||||
- } else {
|
||||
- new_regd = tmp_regd;
|
||||
- }
|
||||
-
|
||||
-ret:
|
||||
return new_regd;
|
||||
}
|
||||
|
||||
-static bool ath11k_reg_is_world_alpha(char *alpha)
|
||||
-{
|
||||
- if (alpha[0] == '0' && alpha[1] == '0')
|
||||
- return true;
|
||||
-
|
||||
- if (alpha[0] == 'n' && alpha[1] == 'a')
|
||||
- return true;
|
||||
-
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
static enum wmi_vdev_type ath11k_reg_get_ar_vdev_type(struct ath11k *ar)
|
||||
{
|
||||
struct ath11k_vif *arvif;
|
||||
@@ -839,7 +683,6 @@ int ath11k_reg_handle_chan_list(struct a
|
||||
enum ieee80211_ap_reg_power power_type)
|
||||
{
|
||||
struct ieee80211_regdomain *regd;
|
||||
- bool intersect = false;
|
||||
int pdev_idx;
|
||||
struct ath11k *ar;
|
||||
enum wmi_vdev_type vdev_type;
|
||||
@@ -891,24 +734,14 @@ int ath11k_reg_handle_chan_list(struct a
|
||||
(char *)reg_info->alpha2, 2))
|
||||
goto retfail;
|
||||
|
||||
- /* Intersect new rules with default regd if a new country setting was
|
||||
- * requested, i.e a default regd was already set during initialization
|
||||
- * and the regd coming from this event has a valid country info.
|
||||
- */
|
||||
- if (ab->default_regd[pdev_idx] &&
|
||||
- !ath11k_reg_is_world_alpha((char *)
|
||||
- ab->default_regd[pdev_idx]->alpha2) &&
|
||||
- !ath11k_reg_is_world_alpha((char *)reg_info->alpha2))
|
||||
- intersect = true;
|
||||
-
|
||||
ar = ab->pdevs[pdev_idx].ar;
|
||||
vdev_type = ath11k_reg_get_ar_vdev_type(ar);
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||||
- "wmi handle chan list power type %d vdev type %d intersect %d\n",
|
||||
- power_type, vdev_type, intersect);
|
||||
+ "wmi handle chan list power type %d vdev type %d\n",
|
||||
+ power_type, vdev_type);
|
||||
|
||||
- regd = ath11k_reg_build_regd(ab, reg_info, intersect, vdev_type, power_type);
|
||||
+ regd = ath11k_reg_build_regd(ab, reg_info, vdev_type, power_type);
|
||||
if (!regd) {
|
||||
ath11k_warn(ab, "failed to build regd from reg_info\n");
|
||||
goto fallback;
|
||||
--- a/drivers/net/wireless/ath/ath11k/reg.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/reg.h
|
||||
@@ -35,7 +35,7 @@ void ath11k_reg_free(struct ath11k_base
|
||||
void ath11k_regd_update_work(struct work_struct *work);
|
||||
struct ieee80211_regdomain *
|
||||
ath11k_reg_build_regd(struct ath11k_base *ab,
|
||||
- struct cur_regulatory_info *reg_info, bool intersect,
|
||||
+ struct cur_regulatory_info *reg_info,
|
||||
enum wmi_vdev_type vdev_type,
|
||||
enum ieee80211_ap_reg_power power_type);
|
||||
int ath11k_regd_update(struct ath11k *ar);
|
||||
Reference in New Issue
Block a user