summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/realtek/rtw89
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/realtek/rtw89')
-rw-r--r--drivers/net/wireless/realtek/rtw89/Kconfig39
-rw-r--r--drivers/net/wireless/realtek/rtw89/Makefile26
-rw-r--r--drivers/net/wireless/realtek/rtw89/acpi.c1083
-rw-r--r--drivers/net/wireless/realtek/rtw89/acpi.h220
-rw-r--r--drivers/net/wireless/realtek/rtw89/cam.c531
-rw-r--r--drivers/net/wireless/realtek/rtw89/cam.h124
-rw-r--r--drivers/net/wireless/realtek/rtw89/chan.c986
-rw-r--r--drivers/net/wireless/realtek/rtw89/chan.h59
-rw-r--r--drivers/net/wireless/realtek/rtw89/coex.c5231
-rw-r--r--drivers/net/wireless/realtek/rtw89/coex.h144
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.c2262
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.h1589
-rw-r--r--drivers/net/wireless/realtek/rtw89/debug.c2410
-rw-r--r--drivers/net/wireless/realtek/rtw89/debug.h2
-rw-r--r--drivers/net/wireless/realtek/rtw89/efuse.c150
-rw-r--r--drivers/net/wireless/realtek/rtw89/efuse.h2
-rw-r--r--drivers/net/wireless/realtek/rtw89/efuse_be.c52
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.c2873
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.h1172
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.c1261
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.h217
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac80211.c1166
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac_be.c125
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci.c422
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci.h145
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci_be.c80
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.c2009
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.h108
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy_be.c30
-rw-r--r--drivers/net/wireless/realtek/rtw89/ps.c276
-rw-r--r--drivers/net/wireless/realtek/rtw89/ps.h15
-rw-r--r--drivers/net/wireless/realtek/rtw89/reg.h217
-rw-r--r--drivers/net/wireless/realtek/rtw89/regd.c1041
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8851b.c97
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c140
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h18
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8851be.c6
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852a.c101
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852a.h4
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c292
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h17
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852ae.c6
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852b.c1961
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852b.h122
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852b_common.c2104
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852b_common.h400
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c241
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h20
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852be.c6
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852bt.c875
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852bt.h15
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c4254
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.h31
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.c490
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.h38
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852bte.c103
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852c.c189
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c310
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h17
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852c_table.c2706
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852ce.c28
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8922a.c543
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8922a.h1
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c71
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8922ae.c27
-rw-r--r--drivers/net/wireless/realtek/rtw89/sar.c741
-rw-r--r--drivers/net/wireless/realtek/rtw89/sar.h31
-rw-r--r--drivers/net/wireless/realtek/rtw89/ser.c64
-rw-r--r--drivers/net/wireless/realtek/rtw89/txrx.h105
-rw-r--r--drivers/net/wireless/realtek/rtw89/util.c162
-rw-r--r--drivers/net/wireless/realtek/rtw89/util.h26
-rw-r--r--drivers/net/wireless/realtek/rtw89/wow.c1161
-rw-r--r--drivers/net/wireless/realtek/rtw89/wow.h108
73 files changed, 31700 insertions, 11998 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/Kconfig b/drivers/net/wireless/realtek/rtw89/Kconfig
index 90ffbab7cc4c..205d7ecca7d7 100644
--- a/drivers/net/wireless/realtek/rtw89/Kconfig
+++ b/drivers/net/wireless/realtek/rtw89/Kconfig
@@ -12,6 +12,7 @@ if RTW89
config RTW89_CORE
tristate
+ select WANT_DEV_COREDUMP
config RTW89_PCI
tristate
@@ -22,12 +23,21 @@ config RTW89_8851B
config RTW89_8852A
tristate
+config RTW89_8852B_COMMON
+ tristate
+
config RTW89_8852B
tristate
+config RTW89_8852BT
+ tristate
+
config RTW89_8852C
tristate
+config RTW89_8922A
+ tristate
+
config RTW89_8851BE
tristate "Realtek 8851BE PCI wireless network (Wi-Fi 6) adapter"
depends on PCI
@@ -56,11 +66,24 @@ config RTW89_8852BE
select RTW89_CORE
select RTW89_PCI
select RTW89_8852B
+ select RTW89_8852B_COMMON
help
Select this option will enable support for 8852BE chipset
802.11ax PCIe wireless network (Wi-Fi 6) adapter
+config RTW89_8852BTE
+ tristate "Realtek 8852BE-VT PCI wireless network (Wi-Fi 6) adapter"
+ depends on PCI
+ select RTW89_CORE
+ select RTW89_PCI
+ select RTW89_8852BT
+ select RTW89_8852B_COMMON
+ help
+ Select this option will enable support for 8852BE-VT chipset
+
+ 802.11ax PCIe wireless network (Wi-Fi 6) adapter
+
config RTW89_8852CE
tristate "Realtek 8852CE PCI wireless network (Wi-Fi 6E) adapter"
depends on PCI
@@ -72,6 +95,20 @@ config RTW89_8852CE
802.11ax PCIe wireless network (Wi-Fi 6E) adapter
+config RTW89_8922AE
+ tristate "Realtek 8922AE/8922AE-VS PCI wireless network (Wi-Fi 7) adapter"
+ depends on PCI
+ select RTW89_CORE
+ select RTW89_PCI
+ select RTW89_8922A
+ help
+ Select this option will enable support for 8922AE/8922AE-VS chipset
+
+ 802.11be PCIe wireless network (Wi-Fi 7) adapter
+ supporting 2x2 2GHz/5GHz/6GHz 4096-QAM 160MHz channels.
+
+ The variant 8922AE-VS has the same features except 1024-QAM.
+
config RTW89_DEBUG
bool
@@ -86,7 +123,7 @@ config RTW89_DEBUGMSG
config RTW89_DEBUGFS
bool "Realtek rtw89 debugfs support"
- depends on RTW89_CORE
+ depends on RTW89_CORE && CFG80211_DEBUGFS
select RTW89_DEBUG
help
Enable debugfs support
diff --git a/drivers/net/wireless/realtek/rtw89/Makefile b/drivers/net/wireless/realtek/rtw89/Makefile
index 41940099af1b..c751013e811e 100644
--- a/drivers/net/wireless/realtek/rtw89/Makefile
+++ b/drivers/net/wireless/realtek/rtw89/Makefile
@@ -4,17 +4,21 @@ obj-$(CONFIG_RTW89_CORE) += rtw89_core.o
rtw89_core-y += core.o \
mac80211.o \
mac.o \
+ mac_be.o \
phy.o \
+ phy_be.o \
fw.o \
cam.o \
efuse.o \
+ efuse_be.o \
regd.o \
sar.o \
coex.o \
ps.o \
chan.o \
ser.o \
- acpi.o
+ acpi.o \
+ util.o
rtw89_core-$(CONFIG_PM) += wow.o
@@ -36,6 +40,9 @@ rtw89_8852a-objs := rtw8852a.o \
obj-$(CONFIG_RTW89_8852AE) += rtw89_8852ae.o
rtw89_8852ae-objs := rtw8852ae.o
+obj-$(CONFIG_RTW89_8852B_COMMON) += rtw89_8852b_common.o
+rtw89_8852b_common-objs := rtw8852b_common.o
+
obj-$(CONFIG_RTW89_8852B) += rtw89_8852b.o
rtw89_8852b-objs := rtw8852b.o \
rtw8852b_table.o \
@@ -45,6 +52,14 @@ rtw89_8852b-objs := rtw8852b.o \
obj-$(CONFIG_RTW89_8852BE) += rtw89_8852be.o
rtw89_8852be-objs := rtw8852be.o
+obj-$(CONFIG_RTW89_8852BT) += rtw89_8852bt.o
+rtw89_8852bt-objs := rtw8852bt.o \
+ rtw8852bt_rfk.o \
+ rtw8852bt_rfk_table.o
+
+obj-$(CONFIG_RTW89_8852BTE) += rtw89_8852bte.o
+rtw89_8852bte-objs := rtw8852bte.o
+
obj-$(CONFIG_RTW89_8852C) += rtw89_8852c.o
rtw89_8852c-objs := rtw8852c.o \
rtw8852c_table.o \
@@ -54,8 +69,15 @@ rtw89_8852c-objs := rtw8852c.o \
obj-$(CONFIG_RTW89_8852CE) += rtw89_8852ce.o
rtw89_8852ce-objs := rtw8852ce.o
+obj-$(CONFIG_RTW89_8922A) += rtw89_8922a.o
+rtw89_8922a-objs := rtw8922a.o \
+ rtw8922a_rfk.o
+
+obj-$(CONFIG_RTW89_8922AE) += rtw89_8922ae.o
+rtw89_8922ae-objs := rtw8922ae.o
+
rtw89_core-$(CONFIG_RTW89_DEBUG) += debug.o
obj-$(CONFIG_RTW89_PCI) += rtw89_pci.o
-rtw89_pci-y := pci.o
+rtw89_pci-y := pci.o pci_be.o
diff --git a/drivers/net/wireless/realtek/rtw89/acpi.c b/drivers/net/wireless/realtek/rtw89/acpi.c
index 2e7326a8e3e4..581d6d4154d3 100644
--- a/drivers/net/wireless/realtek/rtw89/acpi.c
+++ b/drivers/net/wireless/realtek/rtw89/acpi.c
@@ -12,6 +12,121 @@ static const guid_t rtw89_guid = GUID_INIT(0xD2A8C3E8, 0x4B69, 0x4F00,
0x82, 0xBD, 0xFE, 0x86,
0x07, 0x80, 0x3A, 0xA7);
+static u32 rtw89_acpi_traversal_object(struct rtw89_dev *rtwdev,
+ const union acpi_object *obj, u8 *pos)
+{
+ const union acpi_object *elm;
+ unsigned int i;
+ u32 sub_len;
+ u32 len = 0;
+ u8 *tmp;
+
+ switch (obj->type) {
+ case ACPI_TYPE_INTEGER:
+ if (pos)
+ pos[len] = obj->integer.value;
+
+ len++;
+ break;
+ case ACPI_TYPE_BUFFER:
+ if (unlikely(obj->buffer.length == 0)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI,
+ "%s: invalid buffer type\n", __func__);
+ goto err;
+ }
+
+ if (pos)
+ memcpy(pos, obj->buffer.pointer, obj->buffer.length);
+
+ len += obj->buffer.length;
+ break;
+ case ACPI_TYPE_PACKAGE:
+ if (unlikely(obj->package.count == 0)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI,
+ "%s: invalid package type\n", __func__);
+ goto err;
+ }
+
+ for (i = 0; i < obj->package.count; i++) {
+ elm = &obj->package.elements[i];
+ tmp = pos ? pos + len : NULL;
+
+ sub_len = rtw89_acpi_traversal_object(rtwdev, elm, tmp);
+ if (unlikely(sub_len == 0))
+ goto err;
+
+ len += sub_len;
+ }
+ break;
+ default:
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: unhandled type: %d\n",
+ __func__, obj->type);
+ goto err;
+ }
+
+ return len;
+
+err:
+ return 0;
+}
+
+static u32 rtw89_acpi_calculate_object_length(struct rtw89_dev *rtwdev,
+ const union acpi_object *obj)
+{
+ return rtw89_acpi_traversal_object(rtwdev, obj, NULL);
+}
+
+static struct rtw89_acpi_data *
+rtw89_acpi_evaluate_method(struct rtw89_dev *rtwdev, const char *method)
+{
+ struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
+ struct rtw89_acpi_data *data = NULL;
+ acpi_handle root, handle;
+ union acpi_object *obj;
+ acpi_status status;
+ u32 len;
+
+ root = ACPI_HANDLE(rtwdev->dev);
+ if (!root) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI,
+ "acpi (%s): failed to get root\n", method);
+ return NULL;
+ }
+
+ status = acpi_get_handle(root, (acpi_string)method, &handle);
+ if (ACPI_FAILURE(status)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI,
+ "acpi (%s): failed to get handle\n", method);
+ return NULL;
+ }
+
+ status = acpi_evaluate_object(handle, NULL, NULL, &buf);
+ if (ACPI_FAILURE(status)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI,
+ "acpi (%s): failed to evaluate object\n", method);
+ return NULL;
+ }
+
+ obj = buf.pointer;
+ len = rtw89_acpi_calculate_object_length(rtwdev, obj);
+ if (unlikely(len == 0)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI,
+ "acpi (%s): failed to traversal obj len\n", method);
+ goto out;
+ }
+
+ data = kzalloc(struct_size(data, buf, len), GFP_KERNEL);
+ if (!data)
+ goto out;
+
+ data->len = len;
+ rtw89_acpi_traversal_object(rtwdev, obj, data->buf);
+
+out:
+ ACPI_FREE(obj);
+ return data;
+}
+
static
int rtw89_acpi_dsm_get_value(struct rtw89_dev *rtwdev, union acpi_object *obj,
u8 *value)
@@ -77,6 +192,93 @@ int rtw89_acpi_dsm_get_policy_6ghz(struct rtw89_dev *rtwdev,
return 0;
}
+static bool chk_acpi_policy_6ghz_sp_sig(const struct rtw89_acpi_policy_6ghz_sp *p)
+{
+ return p->signature[0] == 0x52 &&
+ p->signature[1] == 0x54 &&
+ p->signature[2] == 0x4B &&
+ p->signature[3] == 0x07;
+}
+
+static
+int rtw89_acpi_dsm_get_policy_6ghz_sp(struct rtw89_dev *rtwdev,
+ union acpi_object *obj,
+ struct rtw89_acpi_policy_6ghz_sp **policy)
+{
+ const struct rtw89_acpi_policy_6ghz_sp *ptr;
+ u32 buf_len;
+
+ if (obj->type != ACPI_TYPE_BUFFER) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI,
+ "acpi: expect buffer but type: %d\n", obj->type);
+ return -EINVAL;
+ }
+
+ buf_len = obj->buffer.length;
+ if (buf_len < sizeof(*ptr)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n",
+ __func__, buf_len);
+ return -EINVAL;
+ }
+
+ ptr = (typeof(ptr))obj->buffer.pointer;
+ if (!chk_acpi_policy_6ghz_sp_sig(ptr)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__);
+ return -EINVAL;
+ }
+
+ *policy = kmemdup(ptr, sizeof(*ptr), GFP_KERNEL);
+ if (!*policy)
+ return -ENOMEM;
+
+ rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_6ghz_sp: ", *policy,
+ sizeof(*ptr));
+ return 0;
+}
+
+static bool chk_acpi_policy_tas_sig(const struct rtw89_acpi_policy_tas *p)
+{
+ return p->signature[0] == 0x52 &&
+ p->signature[1] == 0x54 &&
+ p->signature[2] == 0x4B &&
+ p->signature[3] == 0x05;
+}
+
+static int rtw89_acpi_dsm_get_policy_tas(struct rtw89_dev *rtwdev,
+ union acpi_object *obj,
+ struct rtw89_acpi_policy_tas **policy)
+{
+ const struct rtw89_acpi_policy_tas *ptr;
+ u32 buf_len;
+
+ if (obj->type != ACPI_TYPE_BUFFER) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI,
+ "acpi: expect buffer but type: %d\n", obj->type);
+ return -EINVAL;
+ }
+
+ buf_len = obj->buffer.length;
+ if (buf_len < sizeof(*ptr)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n",
+ __func__, buf_len);
+ return -EINVAL;
+ }
+
+ ptr = (typeof(ptr))obj->buffer.pointer;
+ if (!chk_acpi_policy_tas_sig(ptr)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__);
+ return -EINVAL;
+ }
+
+ *policy = kmemdup(ptr, sizeof(*ptr), GFP_KERNEL);
+ if (!*policy)
+ return -ENOMEM;
+
+ rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_tas: ", *policy,
+ sizeof(*ptr));
+ return 0;
+}
+
int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
enum rtw89_acpi_dsm_func func,
struct rtw89_acpi_dsm_result *res)
@@ -95,9 +297,890 @@ int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
if (func == RTW89_ACPI_DSM_FUNC_6G_BP)
ret = rtw89_acpi_dsm_get_policy_6ghz(rtwdev, obj,
&res->u.policy_6ghz);
+ else if (func == RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP)
+ ret = rtw89_acpi_dsm_get_policy_6ghz_sp(rtwdev, obj,
+ &res->u.policy_6ghz_sp);
+ else if (func == RTW89_ACPI_DSM_FUNC_TAS_EN)
+ ret = rtw89_acpi_dsm_get_policy_tas(rtwdev, obj, &res->u.policy_tas);
else
ret = rtw89_acpi_dsm_get_value(rtwdev, obj, &res->u.value);
ACPI_FREE(obj);
return ret;
}
+
+int rtw89_acpi_evaluate_rtag(struct rtw89_dev *rtwdev,
+ struct rtw89_acpi_rtag_result *res)
+{
+ const struct rtw89_acpi_data *data;
+ u32 buf_len;
+ int ret = 0;
+
+ data = rtw89_acpi_evaluate_method(rtwdev, "RTAG");
+ if (!data)
+ return -EIO;
+
+ buf_len = data->len;
+ if (buf_len != sizeof(*res)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n",
+ __func__, buf_len);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ *res = *(struct rtw89_acpi_rtag_result *)data->buf;
+
+ rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "antenna_gain: ", res, sizeof(*res));
+
+out:
+ kfree(data);
+ return ret;
+}
+
+enum rtw89_acpi_sar_subband rtw89_acpi_sar_get_subband(struct rtw89_dev *rtwdev,
+ u32 center_freq)
+{
+ switch (center_freq) {
+ default:
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI,
+ "center freq %u to ACPI SAR subband is unhandled\n",
+ center_freq);
+ fallthrough;
+ case 2412 ... 2484:
+ return RTW89_ACPI_SAR_2GHZ_SUBBAND;
+ case 5180 ... 5240:
+ return RTW89_ACPI_SAR_5GHZ_SUBBAND_1;
+ case 5250 ... 5320:
+ return RTW89_ACPI_SAR_5GHZ_SUBBAND_2;
+ case 5500 ... 5720:
+ return RTW89_ACPI_SAR_5GHZ_SUBBAND_2E;
+ case 5745 ... 5885:
+ return RTW89_ACPI_SAR_5GHZ_SUBBAND_3_4;
+ case 5955 ... 6155:
+ return RTW89_ACPI_SAR_6GHZ_SUBBAND_5_L;
+ case 6175 ... 6415:
+ return RTW89_ACPI_SAR_6GHZ_SUBBAND_5_H;
+ case 6435 ... 6515:
+ return RTW89_ACPI_SAR_6GHZ_SUBBAND_6;
+ case 6535 ... 6695:
+ return RTW89_ACPI_SAR_6GHZ_SUBBAND_7_L;
+ case 6715 ... 6855:
+ return RTW89_ACPI_SAR_6GHZ_SUBBAND_7_H;
+
+ /* freq 6875 (ch 185, 20MHz) spans RTW89_ACPI_SAR_6GHZ_SUBBAND_7_H
+ * and RTW89_ACPI_SAR_6GHZ_SUBBAND_8, so directly describe it with
+ * struct rtw89_6ghz_span.
+ */
+
+ case 6895 ... 7115:
+ return RTW89_ACPI_SAR_6GHZ_SUBBAND_8;
+ }
+}
+
+enum rtw89_band rtw89_acpi_sar_subband_to_band(struct rtw89_dev *rtwdev,
+ enum rtw89_acpi_sar_subband subband)
+{
+ switch (subband) {
+ default:
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI,
+ "ACPI SAR subband %u to band is unhandled\n", subband);
+ fallthrough;
+ case RTW89_ACPI_SAR_2GHZ_SUBBAND:
+ return RTW89_BAND_2G;
+ case RTW89_ACPI_SAR_5GHZ_SUBBAND_1:
+ return RTW89_BAND_5G;
+ case RTW89_ACPI_SAR_5GHZ_SUBBAND_2:
+ return RTW89_BAND_5G;
+ case RTW89_ACPI_SAR_5GHZ_SUBBAND_2E:
+ return RTW89_BAND_5G;
+ case RTW89_ACPI_SAR_5GHZ_SUBBAND_3_4:
+ return RTW89_BAND_5G;
+ case RTW89_ACPI_SAR_6GHZ_SUBBAND_5_L:
+ return RTW89_BAND_6G;
+ case RTW89_ACPI_SAR_6GHZ_SUBBAND_5_H:
+ return RTW89_BAND_6G;
+ case RTW89_ACPI_SAR_6GHZ_SUBBAND_6:
+ return RTW89_BAND_6G;
+ case RTW89_ACPI_SAR_6GHZ_SUBBAND_7_L:
+ return RTW89_BAND_6G;
+ case RTW89_ACPI_SAR_6GHZ_SUBBAND_7_H:
+ return RTW89_BAND_6G;
+ case RTW89_ACPI_SAR_6GHZ_SUBBAND_8:
+ return RTW89_BAND_6G;
+ }
+}
+
+static u8 rtw89_acpi_sar_rfpath_to_hp_antidx(enum rtw89_rf_path rfpath)
+{
+ switch (rfpath) {
+ default:
+ case RF_PATH_B:
+ return 0;
+ case RF_PATH_A:
+ return 1;
+ }
+}
+
+static u8 rtw89_acpi_sar_rfpath_to_rt_antidx(enum rtw89_rf_path rfpath)
+{
+ switch (rfpath) {
+ default:
+ case RF_PATH_A:
+ return 0;
+ case RF_PATH_B:
+ return 1;
+ }
+}
+
+static s16 rtw89_acpi_sar_normalize_hp_val(u8 v)
+{
+ static const u8 bias = 10;
+ static const u8 fct = 1;
+ u16 res;
+
+ BUILD_BUG_ON(fct > TXPWR_FACTOR_OF_RTW89_ACPI_SAR);
+
+ res = (bias << TXPWR_FACTOR_OF_RTW89_ACPI_SAR) +
+ (v << (TXPWR_FACTOR_OF_RTW89_ACPI_SAR - fct));
+
+ return min_t(s32, res, MAX_VAL_OF_RTW89_ACPI_SAR);
+}
+
+static s16 rtw89_acpi_sar_normalize_rt_val(u8 v)
+{
+ static const u8 fct = 3;
+ u16 res;
+
+ BUILD_BUG_ON(fct > TXPWR_FACTOR_OF_RTW89_ACPI_SAR);
+
+ res = v << (TXPWR_FACTOR_OF_RTW89_ACPI_SAR - fct);
+
+ return min_t(s32, res, MAX_VAL_OF_RTW89_ACPI_SAR);
+}
+
+static
+void rtw89_acpi_sar_load_std_legacy(struct rtw89_dev *rtwdev,
+ const struct rtw89_acpi_sar_recognition *rec,
+ const void *content,
+ struct rtw89_sar_entry_from_acpi *ent)
+{
+ const struct rtw89_acpi_sar_std_legacy *ptr = content;
+ enum rtw89_acpi_sar_subband subband;
+ enum rtw89_rf_path path;
+
+ for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
+ for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) {
+ u8 antidx = rec->rfpath_to_antidx(path);
+
+ if (subband < RTW89_ACPI_SAR_SUBBAND_NR_LEGACY)
+ ent->v[subband][path] =
+ rec->normalize(ptr->v[antidx][subband]);
+ else
+ ent->v[subband][path] = MAX_VAL_OF_RTW89_ACPI_SAR;
+ }
+ }
+}
+
+static
+void rtw89_acpi_sar_load_std_has_6ghz(struct rtw89_dev *rtwdev,
+ const struct rtw89_acpi_sar_recognition *rec,
+ const void *content,
+ struct rtw89_sar_entry_from_acpi *ent)
+{
+ const struct rtw89_acpi_sar_std_has_6ghz *ptr = content;
+ enum rtw89_acpi_sar_subband subband;
+ enum rtw89_rf_path path;
+
+ BUILD_BUG_ON(RTW89_ACPI_SAR_SUBBAND_NR_HAS_6GHZ != NUM_OF_RTW89_ACPI_SAR_SUBBAND);
+
+ for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
+ for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) {
+ u8 antidx = rec->rfpath_to_antidx(path);
+
+ ent->v[subband][path] = rec->normalize(ptr->v[antidx][subband]);
+ }
+ }
+}
+
+static
+void rtw89_acpi_sar_load_sml_legacy(struct rtw89_dev *rtwdev,
+ const struct rtw89_acpi_sar_recognition *rec,
+ const void *content,
+ struct rtw89_sar_entry_from_acpi *ent)
+{
+ const struct rtw89_acpi_sar_sml_legacy *ptr = content;
+ enum rtw89_acpi_sar_subband subband;
+ enum rtw89_rf_path path;
+
+ for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
+ for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) {
+ u8 antidx = rec->rfpath_to_antidx(path);
+
+ if (subband < RTW89_ACPI_SAR_SUBBAND_NR_LEGACY)
+ ent->v[subband][path] =
+ rec->normalize(ptr->v[antidx][subband]);
+ else
+ ent->v[subband][path] = MAX_VAL_OF_RTW89_ACPI_SAR;
+ }
+ }
+}
+
+static
+void rtw89_acpi_sar_load_sml_has_6ghz(struct rtw89_dev *rtwdev,
+ const struct rtw89_acpi_sar_recognition *rec,
+ const void *content,
+ struct rtw89_sar_entry_from_acpi *ent)
+{
+ const struct rtw89_acpi_sar_sml_has_6ghz *ptr = content;
+ enum rtw89_acpi_sar_subband subband;
+ enum rtw89_rf_path path;
+
+ BUILD_BUG_ON(RTW89_ACPI_SAR_SUBBAND_NR_HAS_6GHZ != NUM_OF_RTW89_ACPI_SAR_SUBBAND);
+
+ for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
+ for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) {
+ u8 antidx = rec->rfpath_to_antidx(path);
+
+ ent->v[subband][path] = rec->normalize(ptr->v[antidx][subband]);
+ }
+ }
+}
+
+static s16 rtw89_acpi_geo_sar_normalize_delta(s8 delta)
+{
+ static const u8 fct = 1;
+
+ BUILD_BUG_ON(fct > TXPWR_FACTOR_OF_RTW89_ACPI_SAR);
+
+ return delta << (TXPWR_FACTOR_OF_RTW89_ACPI_SAR - fct);
+}
+
+static enum rtw89_acpi_geo_sar_regd_hp
+rtw89_acpi_geo_sar_regd_convert_hp_idx(enum rtw89_regulation_type regd)
+{
+ switch (regd) {
+ case RTW89_FCC:
+ case RTW89_IC:
+ case RTW89_NCC:
+ case RTW89_CHILE:
+ case RTW89_MEXICO:
+ return RTW89_ACPI_GEO_SAR_REGD_HP_FCC;
+ case RTW89_ETSI:
+ case RTW89_MKK:
+ case RTW89_ACMA:
+ return RTW89_ACPI_GEO_SAR_REGD_HP_ETSI;
+ default:
+ case RTW89_WW:
+ case RTW89_NA:
+ case RTW89_KCC:
+ return RTW89_ACPI_GEO_SAR_REGD_HP_WW;
+ }
+}
+
+static enum rtw89_acpi_geo_sar_regd_rt
+rtw89_acpi_geo_sar_regd_convert_rt_idx(enum rtw89_regulation_type regd)
+{
+ switch (regd) {
+ case RTW89_FCC:
+ case RTW89_NCC:
+ case RTW89_CHILE:
+ case RTW89_MEXICO:
+ return RTW89_ACPI_GEO_SAR_REGD_RT_FCC;
+ case RTW89_ETSI:
+ case RTW89_ACMA:
+ return RTW89_ACPI_GEO_SAR_REGD_RT_ETSI;
+ case RTW89_MKK:
+ return RTW89_ACPI_GEO_SAR_REGD_RT_MKK;
+ case RTW89_IC:
+ return RTW89_ACPI_GEO_SAR_REGD_RT_IC;
+ case RTW89_KCC:
+ return RTW89_ACPI_GEO_SAR_REGD_RT_KCC;
+ default:
+ case RTW89_WW:
+ case RTW89_NA:
+ return RTW89_ACPI_GEO_SAR_REGD_RT_WW;
+ }
+}
+
+static
+void rtw89_acpi_geo_sar_load_by_hp(struct rtw89_dev *rtwdev,
+ const struct rtw89_acpi_geo_sar_hp_val *ptr,
+ enum rtw89_rf_path path, s16 *val)
+{
+ u8 antidx = rtw89_acpi_sar_rfpath_to_hp_antidx(path);
+ s16 delta = rtw89_acpi_geo_sar_normalize_delta(ptr->delta[antidx]);
+ s16 max = rtw89_acpi_sar_normalize_hp_val(ptr->max);
+
+ *val = clamp_t(s32, (*val) + delta, MIN_VAL_OF_RTW89_ACPI_SAR, max);
+}
+
+static
+void rtw89_acpi_geo_sar_load_by_rt(struct rtw89_dev *rtwdev,
+ const struct rtw89_acpi_geo_sar_rt_val *ptr,
+ s16 *val)
+{
+ s16 delta = rtw89_acpi_geo_sar_normalize_delta(ptr->delta);
+ s16 max = rtw89_acpi_sar_normalize_rt_val(ptr->max);
+
+ *val = clamp_t(s32, (*val) + delta, MIN_VAL_OF_RTW89_ACPI_SAR, max);
+}
+
+static
+void rtw89_acpi_geo_sar_load_hp_legacy(struct rtw89_dev *rtwdev,
+ const void *content,
+ enum rtw89_regulation_type regd,
+ struct rtw89_sar_entry_from_acpi *ent)
+{
+ const struct rtw89_acpi_geo_sar_hp_legacy *ptr = content;
+ const struct rtw89_acpi_geo_sar_hp_legacy_entry *ptr_ent;
+ const struct rtw89_acpi_geo_sar_hp_val *ptr_ent_val;
+ enum rtw89_acpi_geo_sar_regd_hp geo_idx =
+ rtw89_acpi_geo_sar_regd_convert_hp_idx(regd);
+ enum rtw89_acpi_sar_subband subband;
+ enum rtw89_rf_path path;
+ enum rtw89_band band;
+
+ ptr_ent = &ptr->entries[geo_idx];
+
+ for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
+ band = rtw89_acpi_sar_subband_to_band(rtwdev, subband);
+ switch (band) {
+ case RTW89_BAND_2G:
+ ptr_ent_val = &ptr_ent->val_2ghz;
+ break;
+ case RTW89_BAND_5G:
+ ptr_ent_val = &ptr_ent->val_5ghz;
+ break;
+ default:
+ case RTW89_BAND_6G:
+ ptr_ent_val = NULL;
+ break;
+ }
+
+ if (!ptr_ent_val)
+ continue;
+
+ for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++)
+ rtw89_acpi_geo_sar_load_by_hp(rtwdev, ptr_ent_val, path,
+ &ent->v[subband][path]);
+ }
+}
+
+static
+void rtw89_acpi_geo_sar_load_hp_has_6ghz(struct rtw89_dev *rtwdev,
+ const void *content,
+ enum rtw89_regulation_type regd,
+ struct rtw89_sar_entry_from_acpi *ent)
+{
+ const struct rtw89_acpi_geo_sar_hp_has_6ghz *ptr = content;
+ const struct rtw89_acpi_geo_sar_hp_has_6ghz_entry *ptr_ent;
+ const struct rtw89_acpi_geo_sar_hp_val *ptr_ent_val;
+ enum rtw89_acpi_geo_sar_regd_hp geo_idx =
+ rtw89_acpi_geo_sar_regd_convert_hp_idx(regd);
+ enum rtw89_acpi_sar_subband subband;
+ enum rtw89_rf_path path;
+ enum rtw89_band band;
+
+ ptr_ent = &ptr->entries[geo_idx];
+
+ for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
+ band = rtw89_acpi_sar_subband_to_band(rtwdev, subband);
+ switch (band) {
+ case RTW89_BAND_2G:
+ ptr_ent_val = &ptr_ent->val_2ghz;
+ break;
+ case RTW89_BAND_5G:
+ ptr_ent_val = &ptr_ent->val_5ghz;
+ break;
+ case RTW89_BAND_6G:
+ ptr_ent_val = &ptr_ent->val_6ghz;
+ break;
+ default:
+ ptr_ent_val = NULL;
+ break;
+ }
+
+ if (!ptr_ent_val)
+ continue;
+
+ for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++)
+ rtw89_acpi_geo_sar_load_by_hp(rtwdev, ptr_ent_val, path,
+ &ent->v[subband][path]);
+ }
+}
+
+static
+void rtw89_acpi_geo_sar_load_rt_legacy(struct rtw89_dev *rtwdev,
+ const void *content,
+ enum rtw89_regulation_type regd,
+ struct rtw89_sar_entry_from_acpi *ent)
+{
+ const struct rtw89_acpi_geo_sar_rt_legacy *ptr = content;
+ const struct rtw89_acpi_geo_sar_rt_legacy_entry *ptr_ent;
+ const struct rtw89_acpi_geo_sar_rt_val *ptr_ent_val;
+ enum rtw89_acpi_geo_sar_regd_rt geo_idx =
+ rtw89_acpi_geo_sar_regd_convert_rt_idx(regd);
+ enum rtw89_acpi_sar_subband subband;
+ enum rtw89_rf_path path;
+ enum rtw89_band band;
+
+ ptr_ent = &ptr->entries[geo_idx];
+
+ for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
+ band = rtw89_acpi_sar_subband_to_band(rtwdev, subband);
+ switch (band) {
+ case RTW89_BAND_2G:
+ ptr_ent_val = &ptr_ent->val_2ghz;
+ break;
+ case RTW89_BAND_5G:
+ ptr_ent_val = &ptr_ent->val_5ghz;
+ break;
+ default:
+ case RTW89_BAND_6G:
+ ptr_ent_val = NULL;
+ break;
+ }
+
+ if (!ptr_ent_val)
+ continue;
+
+ for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++)
+ rtw89_acpi_geo_sar_load_by_rt(rtwdev, ptr_ent_val,
+ &ent->v[subband][path]);
+ }
+}
+
+static
+void rtw89_acpi_geo_sar_load_rt_has_6ghz(struct rtw89_dev *rtwdev,
+ const void *content,
+ enum rtw89_regulation_type regd,
+ struct rtw89_sar_entry_from_acpi *ent)
+{
+ const struct rtw89_acpi_geo_sar_rt_has_6ghz *ptr = content;
+ const struct rtw89_acpi_geo_sar_rt_has_6ghz_entry *ptr_ent;
+ const struct rtw89_acpi_geo_sar_rt_val *ptr_ent_val;
+ enum rtw89_acpi_geo_sar_regd_rt geo_idx =
+ rtw89_acpi_geo_sar_regd_convert_rt_idx(regd);
+ enum rtw89_acpi_sar_subband subband;
+ enum rtw89_rf_path path;
+ enum rtw89_band band;
+
+ ptr_ent = &ptr->entries[geo_idx];
+
+ for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
+ band = rtw89_acpi_sar_subband_to_band(rtwdev, subband);
+ switch (band) {
+ case RTW89_BAND_2G:
+ ptr_ent_val = &ptr_ent->val_2ghz;
+ break;
+ case RTW89_BAND_5G:
+ ptr_ent_val = &ptr_ent->val_5ghz;
+ break;
+ case RTW89_BAND_6G:
+ ptr_ent_val = &ptr_ent->val_6ghz;
+ break;
+ default:
+ ptr_ent_val = NULL;
+ break;
+ }
+
+ if (!ptr_ent_val)
+ continue;
+
+ for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++)
+ rtw89_acpi_geo_sar_load_by_rt(rtwdev, ptr_ent_val,
+ &ent->v[subband][path]);
+ }
+}
+
+#define RTW89_ACPI_GEO_SAR_DECL_HANDLER(type) \
+static const struct rtw89_acpi_geo_sar_handler \
+rtw89_acpi_geo_sar_handler_ ## type = { \
+ .data_size = RTW89_ACPI_GEO_SAR_SIZE_OF(type), \
+ .load = rtw89_acpi_geo_sar_load_ ## type, \
+}
+
+RTW89_ACPI_GEO_SAR_DECL_HANDLER(hp_legacy);
+RTW89_ACPI_GEO_SAR_DECL_HANDLER(hp_has_6ghz);
+RTW89_ACPI_GEO_SAR_DECL_HANDLER(rt_legacy);
+RTW89_ACPI_GEO_SAR_DECL_HANDLER(rt_has_6ghz);
+
+static const struct rtw89_acpi_sar_recognition rtw89_acpi_sar_recs[] = {
+ {
+ .id = {
+ .cid = RTW89_ACPI_SAR_CID_HP,
+ .rev = RTW89_ACPI_SAR_REV_LEGACY,
+ .size = RTW89_ACPI_SAR_SIZE_OF(std_legacy),
+ },
+ .geo = &rtw89_acpi_geo_sar_handler_hp_legacy,
+
+ .rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_hp_antidx,
+ .normalize = rtw89_acpi_sar_normalize_hp_val,
+ .load = rtw89_acpi_sar_load_std_legacy,
+ },
+ {
+ .id = {
+ .cid = RTW89_ACPI_SAR_CID_HP,
+ .rev = RTW89_ACPI_SAR_REV_HAS_6GHZ,
+ .size = RTW89_ACPI_SAR_SIZE_OF(std_has_6ghz),
+ },
+ .geo = &rtw89_acpi_geo_sar_handler_hp_has_6ghz,
+
+ .rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_hp_antidx,
+ .normalize = rtw89_acpi_sar_normalize_hp_val,
+ .load = rtw89_acpi_sar_load_std_has_6ghz,
+ },
+ {
+ .id = {
+ .cid = RTW89_ACPI_SAR_CID_RT,
+ .rev = RTW89_ACPI_SAR_REV_LEGACY,
+ .size = RTW89_ACPI_SAR_SIZE_OF(std_legacy),
+ },
+ .geo = &rtw89_acpi_geo_sar_handler_rt_legacy,
+
+ .rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_rt_antidx,
+ .normalize = rtw89_acpi_sar_normalize_rt_val,
+ .load = rtw89_acpi_sar_load_std_legacy,
+ },
+ {
+ .id = {
+ .cid = RTW89_ACPI_SAR_CID_RT,
+ .rev = RTW89_ACPI_SAR_REV_HAS_6GHZ,
+ .size = RTW89_ACPI_SAR_SIZE_OF(std_has_6ghz),
+ },
+ .geo = &rtw89_acpi_geo_sar_handler_rt_has_6ghz,
+
+ .rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_rt_antidx,
+ .normalize = rtw89_acpi_sar_normalize_rt_val,
+ .load = rtw89_acpi_sar_load_std_has_6ghz,
+ },
+ {
+ .id = {
+ .cid = RTW89_ACPI_SAR_CID_RT,
+ .rev = RTW89_ACPI_SAR_REV_LEGACY,
+ .size = RTW89_ACPI_SAR_SIZE_OF(sml_legacy),
+ },
+ .geo = &rtw89_acpi_geo_sar_handler_rt_legacy,
+
+ .rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_rt_antidx,
+ .normalize = rtw89_acpi_sar_normalize_rt_val,
+ .load = rtw89_acpi_sar_load_sml_legacy,
+ },
+ {
+ .id = {
+ .cid = RTW89_ACPI_SAR_CID_RT,
+ .rev = RTW89_ACPI_SAR_REV_HAS_6GHZ,
+ .size = RTW89_ACPI_SAR_SIZE_OF(sml_has_6ghz),
+ },
+ .geo = &rtw89_acpi_geo_sar_handler_rt_has_6ghz,
+
+ .rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_rt_antidx,
+ .normalize = rtw89_acpi_sar_normalize_rt_val,
+ .load = rtw89_acpi_sar_load_sml_has_6ghz,
+ },
+};
+
+struct rtw89_acpi_sar_rec_parm {
+ u32 pld_len;
+ u8 tbl_cnt;
+ u16 cid;
+ u8 rev;
+};
+
+static const struct rtw89_acpi_sar_recognition *
+rtw89_acpi_sar_recognize(struct rtw89_dev *rtwdev,
+ const struct rtw89_acpi_sar_rec_parm *parm)
+{
+ const u32 tbl_len = parm->pld_len / parm->tbl_cnt;
+ const struct rtw89_acpi_sar_recognition *rec;
+ struct rtw89_acpi_sar_identifier id = {};
+
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI,
+ "%s: cid %u, rev %u, tbl len %u, tbl cnt %u\n",
+ __func__, parm->cid, parm->rev, tbl_len, parm->tbl_cnt);
+
+ if (unlikely(parm->pld_len % parm->tbl_cnt)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid pld len %u\n",
+ parm->pld_len);
+ return NULL;
+ }
+
+ if (unlikely(tbl_len > RTW89_ACPI_SAR_SIZE_MAX)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid tbl len %u\n",
+ tbl_len);
+ return NULL;
+ }
+
+ if (unlikely(parm->tbl_cnt > MAX_NUM_OF_RTW89_ACPI_SAR_TBL)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid tbl cnt %u\n",
+ parm->tbl_cnt);
+ return NULL;
+ }
+
+ switch (parm->cid) {
+ case RTW89_ACPI_SAR_CID_HP:
+ case RTW89_ACPI_SAR_CID_RT:
+ id.cid = parm->cid;
+ break;
+ default:
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid cid 0x%x\n",
+ parm->cid);
+ return NULL;
+ }
+
+ switch (parm->rev) {
+ case RTW89_ACPI_SAR_REV_LEGACY:
+ case RTW89_ACPI_SAR_REV_HAS_6GHZ:
+ id.rev = parm->rev;
+ break;
+ default:
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid rev %u\n",
+ parm->rev);
+ return NULL;
+ }
+
+ id.size = tbl_len;
+ for (unsigned int i = 0; i < ARRAY_SIZE(rtw89_acpi_sar_recs); i++) {
+ rec = &rtw89_acpi_sar_recs[i];
+ if (memcmp(&rec->id, &id, sizeof(rec->id)) == 0)
+ return rec;
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "failed to recognize\n");
+ return NULL;
+}
+
+static const struct rtw89_acpi_sar_recognition *
+rtw89_acpi_evaluate_static_sar(struct rtw89_dev *rtwdev,
+ struct rtw89_sar_cfg_acpi *cfg)
+{
+ const struct rtw89_acpi_sar_recognition *rec = NULL;
+ const struct rtw89_acpi_static_sar_hdr *hdr;
+ struct rtw89_sar_entry_from_acpi tmp = {};
+ struct rtw89_acpi_sar_rec_parm parm = {};
+ struct rtw89_sar_table_from_acpi *tbl;
+ const struct rtw89_acpi_data *data;
+ u32 len;
+
+ data = rtw89_acpi_evaluate_method(rtwdev, RTW89_ACPI_METHOD_STATIC_SAR);
+ if (!data)
+ return NULL;
+
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "acpi load static sar\n");
+
+ len = data->len;
+ if (len <= sizeof(*hdr)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid buf len %u\n", len);
+ goto out;
+ }
+
+ hdr = (typeof(hdr))data->buf;
+
+ parm.cid = le16_to_cpu(hdr->cid);
+ parm.rev = hdr->rev;
+ parm.tbl_cnt = 1;
+ parm.pld_len = len - sizeof(*hdr);
+
+ rec = rtw89_acpi_sar_recognize(rtwdev, &parm);
+ if (!rec)
+ goto out;
+
+ rec->load(rtwdev, rec, hdr->content, &tmp);
+
+ tbl = &cfg->tables[0];
+ for (u8 regd = 0; regd < RTW89_REGD_NUM; regd++)
+ tbl->entries[regd] = tmp;
+
+ cfg->valid_num = 1;
+
+out:
+ kfree(data);
+ return rec;
+}
+
+static const struct rtw89_acpi_sar_recognition *
+rtw89_acpi_evaluate_dynamic_sar(struct rtw89_dev *rtwdev,
+ struct rtw89_sar_cfg_acpi *cfg)
+{
+ const struct rtw89_acpi_sar_recognition *rec = NULL;
+ const struct rtw89_acpi_dynamic_sar_hdr *hdr;
+ struct rtw89_acpi_sar_rec_parm parm = {};
+ struct rtw89_sar_table_from_acpi *tbl;
+ const struct rtw89_acpi_data *data;
+ u32 len;
+
+ data = rtw89_acpi_evaluate_method(rtwdev, RTW89_ACPI_METHOD_DYNAMIC_SAR);
+ if (!data)
+ return NULL;
+
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "acpi load dynamic sar\n");
+
+ len = data->len;
+ if (len <= sizeof(*hdr)) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid buf len %u\n", len);
+ goto out;
+ }
+
+ hdr = (typeof(hdr))data->buf;
+
+ parm.cid = le16_to_cpu(hdr->cid);
+ parm.rev = hdr->rev;
+ parm.tbl_cnt = hdr->cnt;
+ parm.pld_len = len - sizeof(*hdr);
+
+ rec = rtw89_acpi_sar_recognize(rtwdev, &parm);
+ if (!rec)
+ goto out;
+
+ for (unsigned int i = 0; i < hdr->cnt; i++) {
+ const u8 *content = hdr->content + rec->id.size * i;
+ struct rtw89_sar_entry_from_acpi tmp = {};
+
+ rec->load(rtwdev, rec, content, &tmp);
+
+ tbl = &cfg->tables[i];
+ for (u8 regd = 0; regd < RTW89_REGD_NUM; regd++)
+ tbl->entries[regd] = tmp;
+ }
+
+ cfg->valid_num = hdr->cnt;
+
+out:
+ kfree(data);
+ return rec;
+}
+
+int rtw89_acpi_evaluate_dynamic_sar_indicator(struct rtw89_dev *rtwdev,
+ struct rtw89_sar_cfg_acpi *cfg,
+ bool *poll_changed)
+{
+ struct rtw89_sar_indicator_from_acpi *ind = &cfg->indicator;
+ struct rtw89_sar_indicator_from_acpi tmp = *ind;
+ const struct rtw89_acpi_data *data;
+ const u8 *tbl_base1_by_ant;
+ enum rtw89_rf_path path;
+ int ret = 0;
+ u32 len;
+
+ data = rtw89_acpi_evaluate_method(rtwdev, RTW89_ACPI_METHOD_DYNAMIC_SAR_INDICATOR);
+ if (!data)
+ return -EFAULT;
+
+ if (!poll_changed)
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "acpi load dynamic sar indicator\n");
+
+ len = data->len;
+ if (len != ind->fields) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid buf len %u\n", len);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ tbl_base1_by_ant = data->buf;
+
+ for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) {
+ u8 antidx = ind->rfpath_to_antidx(path);
+ u8 sel;
+
+ if (antidx >= ind->fields)
+ antidx = 0;
+
+ /* convert the table index from 1-based to 0-based */
+ sel = tbl_base1_by_ant[antidx] - 1;
+ if (sel >= cfg->valid_num)
+ sel = 0;
+
+ tmp.tblsel[path] = sel;
+ }
+
+ if (memcmp(ind, &tmp, sizeof(*ind)) == 0) {
+ if (poll_changed)
+ *poll_changed = false;
+ } else {
+ if (poll_changed)
+ *poll_changed = true;
+
+ *ind = tmp;
+ }
+
+out:
+ kfree(data);
+ return ret;
+}
+
+static
+void rtw89_acpi_evaluate_geo_sar(struct rtw89_dev *rtwdev,
+ const struct rtw89_acpi_geo_sar_handler *hdl,
+ struct rtw89_sar_cfg_acpi *cfg)
+{
+ const struct rtw89_acpi_data *data;
+ u32 len;
+
+ data = rtw89_acpi_evaluate_method(rtwdev, RTW89_ACPI_METHOD_GEO_SAR);
+ if (!data)
+ return;
+
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "acpi load geo sar\n");
+
+ len = data->len;
+ if (len != hdl->data_size) {
+ rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid buf len %u (expected %u)\n",
+ len, hdl->data_size);
+ goto out;
+ }
+
+ for (unsigned int i = 0; i < cfg->valid_num; i++)
+ for (u8 regd = 0; regd < RTW89_REGD_NUM; regd++)
+ hdl->load(rtwdev, data->buf, regd, &cfg->tables[i].entries[regd]);
+
+out:
+ kfree(data);
+}
+
+int rtw89_acpi_evaluate_sar(struct rtw89_dev *rtwdev,
+ struct rtw89_sar_cfg_acpi *cfg)
+{
+ struct rtw89_sar_indicator_from_acpi *ind = &cfg->indicator;
+ const struct rtw89_acpi_sar_recognition *rec;
+ bool fetch_indicator = false;
+ int ret;
+
+ rec = rtw89_acpi_evaluate_static_sar(rtwdev, cfg);
+ if (rec)
+ goto recognized;
+
+ rec = rtw89_acpi_evaluate_dynamic_sar(rtwdev, cfg);
+ if (!rec)
+ return -ENOENT;
+
+ fetch_indicator = true;
+
+recognized:
+ rtw89_acpi_evaluate_geo_sar(rtwdev, rec->geo, cfg);
+
+ switch (rec->id.cid) {
+ case RTW89_ACPI_SAR_CID_HP:
+ cfg->downgrade_2tx = 3 << TXPWR_FACTOR_OF_RTW89_ACPI_SAR;
+ ind->fields = RTW89_ACPI_SAR_ANT_NR_STD;
+ break;
+ case RTW89_ACPI_SAR_CID_RT:
+ cfg->downgrade_2tx = 0;
+ ind->fields = 1;
+ break;
+ default:
+ return -EFAULT;
+ }
+
+ if (fetch_indicator) {
+ ind->rfpath_to_antidx = rec->rfpath_to_antidx;
+ ret = rtw89_acpi_evaluate_dynamic_sar_indicator(rtwdev, cfg, NULL);
+ if (ret)
+ fetch_indicator = false;
+ }
+
+ if (!fetch_indicator)
+ memset(ind->tblsel, 0, sizeof(ind->tblsel));
+
+ ind->enable_sync = fetch_indicator;
+ return 0;
+}
diff --git a/drivers/net/wireless/realtek/rtw89/acpi.h b/drivers/net/wireless/realtek/rtw89/acpi.h
index fe85b40cf076..8c918ee02d2e 100644
--- a/drivers/net/wireless/realtek/rtw89/acpi.h
+++ b/drivers/net/wireless/realtek/rtw89/acpi.h
@@ -7,12 +7,23 @@
#include "core.h"
+struct rtw89_acpi_data {
+ u32 len;
+ u8 buf[] __counted_by(len);
+};
+
enum rtw89_acpi_dsm_func {
RTW89_ACPI_DSM_FUNC_IDN_BAND_SUP = 2,
RTW89_ACPI_DSM_FUNC_6G_DIS = 3,
RTW89_ACPI_DSM_FUNC_6G_BP = 4,
RTW89_ACPI_DSM_FUNC_TAS_EN = 5,
- RTW89_ACPI_DSM_FUNC_59G_EN = 6,
+ RTW89_ACPI_DSM_FUNC_UNII4_SUP = 6,
+ RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP = 7,
+};
+
+enum rtw89_acpi_conf_unii4 {
+ RTW89_ACPI_CONF_UNII4_FCC = BIT(0),
+ RTW89_ACPI_CONF_UNII4_IC = BIT(1),
};
enum rtw89_acpi_policy_mode {
@@ -20,6 +31,13 @@ enum rtw89_acpi_policy_mode {
RTW89_ACPI_POLICY_ALLOW = 1,
};
+enum rtw89_acpi_conf_tas {
+ RTW89_ACPI_CONF_TAS_US = BIT(0),
+ RTW89_ACPI_CONF_TAS_CA = BIT(1),
+ RTW89_ACPI_CONF_TAS_KR = BIT(2),
+ RTW89_ACPI_CONF_TAS_OTHERS = BIT(7),
+};
+
struct rtw89_acpi_country_code {
/* below are allowed:
* * ISO alpha2 country code
@@ -36,16 +54,216 @@ struct rtw89_acpi_policy_6ghz {
struct rtw89_acpi_country_code country_list[] __counted_by(country_count);
} __packed;
+enum rtw89_acpi_conf_6ghz_sp {
+ RTW89_ACPI_CONF_6GHZ_SP_US = BIT(0),
+};
+
+struct rtw89_acpi_policy_6ghz_sp {
+ u8 signature[4];
+ u8 revision;
+ u8 override;
+ u8 conf;
+ u8 rsvd;
+} __packed;
+
+struct rtw89_acpi_policy_tas {
+ u8 signature[4];
+ u8 revision;
+ u8 enable;
+ u8 enabled_countries;
+ u8 rsvd[3];
+} __packed;
+
struct rtw89_acpi_dsm_result {
union {
u8 value;
/* caller needs to free it after using */
struct rtw89_acpi_policy_6ghz *policy_6ghz;
+ struct rtw89_acpi_policy_6ghz_sp *policy_6ghz_sp;
+ struct rtw89_acpi_policy_tas *policy_tas;
} u;
};
+struct rtw89_acpi_rtag_result {
+ u8 tag[4];
+ u8 revision;
+ __le32 domain;
+ u8 ant_gain_table[RTW89_ANT_GAIN_CHAIN_NUM][RTW89_ANT_GAIN_SUBBAND_NR];
+} __packed;
+
+enum rtw89_acpi_sar_cid {
+ RTW89_ACPI_SAR_CID_HP = 0x5048,
+ RTW89_ACPI_SAR_CID_RT = 0x5452,
+};
+
+enum rtw89_acpi_sar_rev {
+ RTW89_ACPI_SAR_REV_LEGACY = 1,
+ RTW89_ACPI_SAR_REV_HAS_6GHZ = 2,
+};
+
+#define RTW89_ACPI_SAR_ANT_NR_STD 4
+#define RTW89_ACPI_SAR_ANT_NR_SML 2
+
+#define RTW89_ACPI_METHOD_STATIC_SAR "WRDS"
+#define RTW89_ACPI_METHOD_DYNAMIC_SAR "RWRD"
+#define RTW89_ACPI_METHOD_DYNAMIC_SAR_INDICATOR "RWSI"
+#define RTW89_ACPI_METHOD_GEO_SAR "RWGS"
+
+struct rtw89_acpi_sar_std_legacy {
+ u8 v[RTW89_ACPI_SAR_ANT_NR_STD][RTW89_ACPI_SAR_SUBBAND_NR_LEGACY];
+} __packed;
+
+struct rtw89_acpi_sar_std_has_6ghz {
+ u8 v[RTW89_ACPI_SAR_ANT_NR_STD][RTW89_ACPI_SAR_SUBBAND_NR_HAS_6GHZ];
+} __packed;
+
+struct rtw89_acpi_sar_sml_legacy {
+ u8 v[RTW89_ACPI_SAR_ANT_NR_SML][RTW89_ACPI_SAR_SUBBAND_NR_LEGACY];
+} __packed;
+
+struct rtw89_acpi_sar_sml_has_6ghz {
+ u8 v[RTW89_ACPI_SAR_ANT_NR_SML][RTW89_ACPI_SAR_SUBBAND_NR_HAS_6GHZ];
+} __packed;
+
+struct rtw89_acpi_static_sar_hdr {
+ __le16 cid;
+ u8 rev;
+ u8 content[];
+} __packed;
+
+struct rtw89_acpi_dynamic_sar_hdr {
+ __le16 cid;
+ u8 rev;
+ u8 cnt;
+ u8 content[];
+} __packed;
+
+struct rtw89_acpi_sar_identifier {
+ enum rtw89_acpi_sar_cid cid;
+ enum rtw89_acpi_sar_rev rev;
+ u8 size;
+};
+
+/* for rtw89_acpi_sar_identifier::size */
+#define RTW89_ACPI_SAR_SIZE_MAX U8_MAX
+#define RTW89_ACPI_SAR_SIZE_OF(type) \
+ (BUILD_BUG_ON_ZERO(sizeof(struct rtw89_acpi_sar_ ## type) > \
+ RTW89_ACPI_SAR_SIZE_MAX) + \
+ sizeof(struct rtw89_acpi_sar_ ## type))
+
+struct rtw89_acpi_sar_recognition {
+ struct rtw89_acpi_sar_identifier id;
+ const struct rtw89_acpi_geo_sar_handler *geo;
+
+ u8 (*rfpath_to_antidx)(enum rtw89_rf_path rfpath);
+ s16 (*normalize)(u8 v);
+ void (*load)(struct rtw89_dev *rtwdev,
+ const struct rtw89_acpi_sar_recognition *rec,
+ const void *content,
+ struct rtw89_sar_entry_from_acpi *ent);
+};
+
+struct rtw89_acpi_geo_sar_hp_val {
+ u8 max;
+ s8 delta[RTW89_ACPI_SAR_ANT_NR_STD];
+} __packed;
+
+struct rtw89_acpi_geo_sar_hp_legacy_entry {
+ struct rtw89_acpi_geo_sar_hp_val val_2ghz;
+ struct rtw89_acpi_geo_sar_hp_val val_5ghz;
+} __packed;
+
+struct rtw89_acpi_geo_sar_hp_has_6ghz_entry {
+ struct rtw89_acpi_geo_sar_hp_val val_2ghz;
+ struct rtw89_acpi_geo_sar_hp_val val_5ghz;
+ struct rtw89_acpi_geo_sar_hp_val val_6ghz;
+} __packed;
+
+enum rtw89_acpi_geo_sar_regd_hp {
+ RTW89_ACPI_GEO_SAR_REGD_HP_FCC = 0,
+ RTW89_ACPI_GEO_SAR_REGD_HP_ETSI = 1,
+ RTW89_ACPI_GEO_SAR_REGD_HP_WW = 2,
+
+ RTW89_ACPI_GEO_SAR_REGD_NR_HP,
+};
+
+struct rtw89_acpi_geo_sar_hp_legacy {
+ struct rtw89_acpi_geo_sar_hp_legacy_entry
+ entries[RTW89_ACPI_GEO_SAR_REGD_NR_HP];
+} __packed;
+
+struct rtw89_acpi_geo_sar_hp_has_6ghz {
+ struct rtw89_acpi_geo_sar_hp_has_6ghz_entry
+ entries[RTW89_ACPI_GEO_SAR_REGD_NR_HP];
+} __packed;
+
+struct rtw89_acpi_geo_sar_rt_val {
+ u8 max;
+ s8 delta;
+} __packed;
+
+struct rtw89_acpi_geo_sar_rt_legacy_entry {
+ struct rtw89_acpi_geo_sar_rt_val val_2ghz;
+ struct rtw89_acpi_geo_sar_rt_val val_5ghz;
+} __packed;
+
+struct rtw89_acpi_geo_sar_rt_has_6ghz_entry {
+ struct rtw89_acpi_geo_sar_rt_val val_2ghz;
+ struct rtw89_acpi_geo_sar_rt_val val_5ghz;
+ struct rtw89_acpi_geo_sar_rt_val val_6ghz;
+} __packed;
+
+enum rtw89_acpi_geo_sar_regd_rt {
+ RTW89_ACPI_GEO_SAR_REGD_RT_FCC = 0,
+ RTW89_ACPI_GEO_SAR_REGD_RT_ETSI = 1,
+ RTW89_ACPI_GEO_SAR_REGD_RT_MKK = 2,
+ RTW89_ACPI_GEO_SAR_REGD_RT_IC = 3,
+ RTW89_ACPI_GEO_SAR_REGD_RT_KCC = 4,
+ RTW89_ACPI_GEO_SAR_REGD_RT_WW = 5,
+
+ RTW89_ACPI_GEO_SAR_REGD_NR_RT,
+};
+
+struct rtw89_acpi_geo_sar_rt_legacy {
+ struct rtw89_acpi_geo_sar_rt_legacy_entry
+ entries[RTW89_ACPI_GEO_SAR_REGD_NR_RT];
+} __packed;
+
+struct rtw89_acpi_geo_sar_rt_has_6ghz {
+ struct rtw89_acpi_geo_sar_rt_has_6ghz_entry
+ entries[RTW89_ACPI_GEO_SAR_REGD_NR_RT];
+} __packed;
+
+struct rtw89_acpi_geo_sar_handler {
+ u8 data_size;
+
+ void (*load)(struct rtw89_dev *rtwdev,
+ const void *content,
+ enum rtw89_regulation_type regd,
+ struct rtw89_sar_entry_from_acpi *ent);
+};
+
+/* for rtw89_acpi_geo_sar_handler::data_size */
+#define RTW89_ACPI_GEO_SAR_SIZE_MAX U8_MAX
+#define RTW89_ACPI_GEO_SAR_SIZE_OF(type) \
+ (BUILD_BUG_ON_ZERO(sizeof(struct rtw89_acpi_geo_sar_ ## type) > \
+ RTW89_ACPI_GEO_SAR_SIZE_MAX) + \
+ sizeof(struct rtw89_acpi_geo_sar_ ## type))
+
+enum rtw89_acpi_sar_subband rtw89_acpi_sar_get_subband(struct rtw89_dev *rtwdev,
+ u32 center_freq);
+enum rtw89_band rtw89_acpi_sar_subband_to_band(struct rtw89_dev *rtwdev,
+ enum rtw89_acpi_sar_subband subband);
+
int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
enum rtw89_acpi_dsm_func func,
struct rtw89_acpi_dsm_result *res);
+int rtw89_acpi_evaluate_rtag(struct rtw89_dev *rtwdev,
+ struct rtw89_acpi_rtag_result *res);
+int rtw89_acpi_evaluate_sar(struct rtw89_dev *rtwdev,
+ struct rtw89_sar_cfg_acpi *cfg);
+int rtw89_acpi_evaluate_dynamic_sar_indicator(struct rtw89_dev *rtwdev,
+ struct rtw89_sar_cfg_acpi *cfg,
+ bool *changed);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c
index 11fbdd142162..385a238fe5cc 100644
--- a/drivers/net/wireless/realtek/rtw89/cam.c
+++ b/drivers/net/wireless/realtek/rtw89/cam.c
@@ -6,6 +6,7 @@
#include "debug.h"
#include "fw.h"
#include "mac.h"
+#include "ps.h"
static struct sk_buff *
rtw89_cam_get_sec_key_cmd(struct rtw89_dev *rtwdev,
@@ -135,8 +136,8 @@ again:
}
static int rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry *addr_cam,
- struct rtw89_sec_cam_entry *sec_cam,
- struct ieee80211_key_conf *key,
+ const struct rtw89_sec_cam_entry *sec_cam,
+ const struct ieee80211_key_conf *key,
u8 *key_idx)
{
u8 idx;
@@ -150,8 +151,6 @@ static int rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry *addr_cam,
case RTW89_ADDR_CAM_SEC_NONE:
return -EINVAL;
case RTW89_ADDR_CAM_SEC_ALL_UNI:
- if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
- return -EINVAL;
idx = find_first_zero_bit(addr_cam->sec_cam_map,
RTW89_SEC_CAM_IN_ADDR_CAM);
if (idx >= RTW89_SEC_CAM_IN_ADDR_CAM)
@@ -213,25 +212,54 @@ static int rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry *addr_cam,
return 0;
}
-static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key,
- struct rtw89_sec_cam_entry *sec_cam)
+static int __rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ const struct rtw89_sec_cam_entry *sec_cam,
+ bool inform_fw)
+{
+ struct rtw89_addr_cam_entry *addr_cam;
+ unsigned int i;
+ int ret = 0;
+
+ addr_cam = rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
+
+ for_each_set_bit(i, addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM) {
+ if (addr_cam->sec_ent[i] != sec_cam->sec_cam_idx)
+ continue;
+
+ clear_bit(i, addr_cam->sec_cam_map);
+ }
+
+ if (inform_fw) {
+ ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link);
+ if (ret)
+ rtw89_err(rtwdev,
+ "failed to update dctl cam del key: %d\n", ret);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
+ if (ret)
+ rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret);
+ }
+
+ return ret;
+}
+
+static int __rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ const struct ieee80211_key_conf *key,
+ const struct rtw89_sec_cam_entry *sec_cam)
{
- struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
- struct rtw89_vif *rtwvif;
struct rtw89_addr_cam_entry *addr_cam;
u8 key_idx = 0;
int ret;
- if (!vif) {
- rtw89_err(rtwdev, "No iface for adding sec cam\n");
- return -EINVAL;
- }
+ addr_cam = rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
+
+ if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+ key->cipher == WLAN_CIPHER_SUITE_WEP104)
+ addr_cam->sec_ent_mode = RTW89_ADDR_CAM_SEC_ALL_UNI;
- rtwvif = (struct rtw89_vif *)vif->drv_priv;
- addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
ret = rtw89_cam_get_addr_cam_key_idx(addr_cam, sec_cam, key, &key_idx);
if (ret) {
rtw89_err(rtwdev, "failed to get addr cam key idx %d, %d\n",
@@ -239,29 +267,133 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
return ret;
}
- key->hw_key_idx = key_idx;
addr_cam->sec_ent_keyid[key_idx] = key->keyidx;
addr_cam->sec_ent[key_idx] = sec_cam->sec_cam_idx;
- addr_cam->sec_entries[key_idx] = sec_cam;
set_bit(key_idx, addr_cam->sec_cam_map);
- ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
+ ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link);
if (ret) {
rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n",
ret);
return ret;
}
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret) {
rtw89_err(rtwdev, "failed to update addr cam sec entry: %d\n",
ret);
clear_bit(key_idx, addr_cam->sec_cam_map);
- addr_cam->sec_entries[key_idx] = NULL;
return ret;
}
return 0;
}
+int rtw89_cam_attach_link_sec_cam(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ u8 sec_cam_idx)
+{
+ struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
+ const struct rtw89_sec_cam_entry *sec_cam;
+
+ sec_cam = cam_info->sec_entries[sec_cam_idx];
+ if (!sec_cam)
+ return -ENOENT;
+
+ return __rtw89_cam_attach_sec_cam(rtwdev, rtwvif_link, rtwsta_link,
+ sec_cam->key_conf, sec_cam);
+}
+
+static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ const struct rtw89_sec_cam_entry *sec_cam,
+ bool inform_fw)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
+ struct rtw89_sta_link *rtwsta_link;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_vif *rtwvif;
+ unsigned int link_id;
+ int ret;
+
+ if (!vif) {
+ rtw89_err(rtwdev, "No iface for deleting sec cam\n");
+ return -EINVAL;
+ }
+
+ rtwvif = vif_to_rtwvif(vif);
+
+ if (rtwsta)
+ clear_bit(sec_cam->sec_cam_idx, rtwsta->pairwise_sec_cam_map);
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ rtwsta_link = rtwsta ? rtwsta->links[link_id] : NULL;
+ if (rtwsta && !rtwsta_link)
+ continue;
+
+ ret = __rtw89_cam_detach_sec_cam(rtwdev, rtwvif_link, rtwsta_link,
+ sec_cam, inform_fw);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key,
+ struct rtw89_sec_cam_entry *sec_cam)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
+ struct rtw89_sta_link *rtwsta_link;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_vif *rtwvif;
+ unsigned int link_id;
+ int key_link_id;
+ int ret;
+
+ if (!vif) {
+ rtw89_err(rtwdev, "No iface for adding sec cam\n");
+ return -EINVAL;
+ }
+
+ rtwvif = vif_to_rtwvif(vif);
+
+ key_link_id = ieee80211_vif_is_mld(vif) ? key->link_id : 0;
+ if (key_link_id >= 0) {
+ rtwvif_link = rtwvif->links[key_link_id];
+ rtwsta_link = rtwsta ? rtwsta->links[key_link_id] : NULL;
+
+ if (!rtwvif_link || (rtwsta && !rtwsta_link)) {
+ rtw89_err(rtwdev, "No drv link for adding sec cam\n");
+ return -ENOLINK;
+ }
+
+ return __rtw89_cam_attach_sec_cam(rtwdev, rtwvif_link,
+ rtwsta_link, key, sec_cam);
+ }
+
+ /* key_link_id < 0: MLD pairwise key */
+ if (!rtwsta) {
+ rtw89_err(rtwdev, "No sta for adding MLD pairwise sec cam\n");
+ return -EINVAL;
+ }
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ ret = __rtw89_cam_attach_sec_cam(rtwdev, rtwvif_link,
+ rtwsta_link, key, sec_cam);
+ if (ret)
+ return ret;
+ }
+
+ set_bit(sec_cam->sec_cam_idx, rtwsta->pairwise_sec_cam_map);
+
+ return 0;
+}
+
static int rtw89_cam_sec_key_install(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -292,11 +424,17 @@ static int rtw89_cam_sec_key_install(struct rtw89_dev *rtwdev,
goto err_release_cam;
}
+ key->hw_key_idx = sec_cam_idx;
+ cam_info->sec_entries[sec_cam_idx] = sec_cam;
+
sec_cam->sec_cam_idx = sec_cam_idx;
sec_cam->type = hw_key_type;
sec_cam->len = RTW89_SEC_CAM_LEN;
sec_cam->ext_key = ext_key;
memcpy(sec_cam->key, key->key, key->keylen);
+
+ sec_cam->key_conf = key;
+
ret = rtw89_cam_send_sec_key_cmd(rtwdev, sec_cam);
if (ret) {
rtw89_err(rtwdev, "failed to send sec key cmd: %d\n", ret);
@@ -313,6 +451,7 @@ static int rtw89_cam_sec_key_install(struct rtw89_dev *rtwdev,
return 0;
err_release_cam:
+ cam_info->sec_entries[sec_cam_idx] = NULL;
kfree(sec_cam);
clear_bit(sec_cam_idx, cam_info->sec_cam_map);
if (ext_key)
@@ -331,31 +470,50 @@ int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
bool ext_key = false;
int ret;
+ if (ieee80211_vif_is_mld(vif) && !chip->hw_mlo_bmc_crypto &&
+ !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+ return -EOPNOTSUPP;
+
switch (key->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
+ rtw89_leave_ips_by_hwflags(rtwdev);
hw_key_type = RTW89_SEC_KEY_TYPE_WEP40;
break;
case WLAN_CIPHER_SUITE_WEP104:
+ rtw89_leave_ips_by_hwflags(rtwdev);
hw_key_type = RTW89_SEC_KEY_TYPE_WEP104;
break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ if (!chip->hw_tkip_crypto)
+ return -EOPNOTSUPP;
+ hw_key_type = RTW89_SEC_KEY_TYPE_TKIP;
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+ break;
case WLAN_CIPHER_SUITE_CCMP:
hw_key_type = RTW89_SEC_KEY_TYPE_CCMP128;
- key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+ if (!chip->hw_mgmt_tx_encrypt)
+ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
break;
case WLAN_CIPHER_SUITE_CCMP_256:
hw_key_type = RTW89_SEC_KEY_TYPE_CCMP256;
- key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+ if (!chip->hw_mgmt_tx_encrypt)
+ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
ext_key = true;
break;
case WLAN_CIPHER_SUITE_GCMP:
hw_key_type = RTW89_SEC_KEY_TYPE_GCMP128;
- key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+ if (!chip->hw_mgmt_tx_encrypt)
+ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
break;
case WLAN_CIPHER_SUITE_GCMP_256:
hw_key_type = RTW89_SEC_KEY_TYPE_GCMP256;
- key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+ if (!chip->hw_mgmt_tx_encrypt)
+ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
ext_key = true;
break;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ hw_key_type = RTW89_SEC_KEY_TYPE_BIP_CCMP128;
+ break;
default:
return -EOPNOTSUPP;
}
@@ -380,42 +538,22 @@ int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev,
struct ieee80211_key_conf *key,
bool inform_fw)
{
- struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
- struct rtw89_vif *rtwvif;
- struct rtw89_addr_cam_entry *addr_cam;
- struct rtw89_sec_cam_entry *sec_cam;
- u8 key_idx = key->hw_key_idx;
+ const struct rtw89_sec_cam_entry *sec_cam;
u8 sec_cam_idx;
- int ret = 0;
-
- if (!vif) {
- rtw89_err(rtwdev, "No iface for deleting sec cam\n");
- return -EINVAL;
- }
+ int ret;
- rtwvif = (struct rtw89_vif *)vif->drv_priv;
- addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
- sec_cam = addr_cam->sec_entries[key_idx];
+ sec_cam_idx = key->hw_key_idx;
+ sec_cam = cam_info->sec_entries[sec_cam_idx];
if (!sec_cam)
return -EINVAL;
- /* detach sec cam from addr cam */
- clear_bit(key_idx, addr_cam->sec_cam_map);
- addr_cam->sec_entries[key_idx] = NULL;
- if (inform_fw) {
- ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
- if (ret)
- rtw89_err(rtwdev, "failed to update dctl cam del key: %d\n", ret);
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
- if (ret)
- rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret);
- }
+ ret = rtw89_cam_detach_sec_cam(rtwdev, vif, sta, sec_cam, inform_fw);
/* clear valid bit in addr cam will disable sec cam,
* so we don't need to send H2C command again
*/
- sec_cam_idx = sec_cam->sec_cam_idx;
+ cam_info->sec_entries[sec_cam_idx] = NULL;
clear_bit(sec_cam_idx, cam_info->sec_cam_map);
if (sec_cam->ext_key)
clear_bit(sec_cam_idx + 1, cam_info->sec_cam_map);
@@ -454,10 +592,10 @@ void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev,
clear_bit(bssid_cam->bssid_cam_idx, cam_info->bssid_cam_map);
}
-void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
- struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
- struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
+ struct rtw89_addr_cam_entry *addr_cam = &rtwvif_link->addr_cam;
+ struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
rtw89_cam_deinit_addr_cam(rtwdev, addr_cam);
rtw89_cam_deinit_bssid_cam(rtwdev, bssid_cam);
@@ -496,6 +634,7 @@ static u8 rtw89_get_addr_cam_entry_size(struct rtw89_dev *rtwdev)
case RTL8852A:
case RTL8852B:
case RTL8851B:
+ case RTL8852BT:
return ADDR_CAM_ENT_SIZE;
default:
return ADDR_CAM_ENT_SHORT_SIZE;
@@ -561,7 +700,7 @@ static int rtw89_cam_get_avail_bssid_cam(struct rtw89_dev *rtwdev,
}
int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct rtw89_bssid_cam_entry *bssid_cam,
const u8 *bssid)
{
@@ -581,7 +720,7 @@ int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
}
bssid_cam->bssid_cam_idx = bssid_cam_idx;
- bssid_cam->phy_idx = rtwvif->phy_idx;
+ bssid_cam->phy_idx = rtwvif_link->phy_idx;
bssid_cam->len = BSSID_CAM_ENT_SIZE;
bssid_cam->offset = 0;
bssid_cam->valid = true;
@@ -590,20 +729,21 @@ int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
return 0;
}
-void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
- struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
+ struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
- ether_addr_copy(bssid_cam->bssid, rtwvif->bssid);
+ ether_addr_copy(bssid_cam->bssid, rtwvif_link->bssid);
}
-int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
- struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
- struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
+ struct rtw89_addr_cam_entry *addr_cam = &rtwvif_link->addr_cam;
+ struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
int ret;
- ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif, bssid_cam, rtwvif->bssid);
+ ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif_link, bssid_cam,
+ rtwvif_link->bssid);
if (ret) {
rtw89_err(rtwdev, "failed to init bssid cam\n");
return ret;
@@ -619,19 +759,27 @@ int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
}
int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta, u8 *cmd)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link, u8 *cmd)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
- struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif, rtwsta);
- u8 bss_color = vif->bss_conf.he_bss_color.color;
+ struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link,
+ rtwsta_link);
+ struct ieee80211_bss_conf *bss_conf;
+ u8 bss_color;
u8 bss_mask;
- if (vif->bss_conf.nontransmitted)
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+ bss_color = bss_conf->he_bss_color.color;
+
+ if (bss_conf->nontransmitted)
bss_mask = RTW89_BSSID_MATCH_5_BYTES;
else
bss_mask = RTW89_BSSID_MATCH_ALL;
+ rcu_read_unlock();
+
FWCMD_SET_ADDR_BSSID_IDX(cmd, bssid_cam->bssid_cam_idx);
FWCMD_SET_ADDR_BSSID_OFFSET(cmd, bssid_cam->offset);
FWCMD_SET_ADDR_BSSID_LEN(cmd, bssid_cam->len);
@@ -662,19 +810,30 @@ static u8 rtw89_cam_addr_hash(u8 start, const u8 *addr)
}
void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
const u8 *scan_mac_addr,
u8 *cmd)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
- struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
- struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta);
- const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif->mac_addr;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_addr_cam_entry *addr_cam =
+ rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
+ struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link);
+ struct ieee80211_link_sta *link_sta;
+ const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif_link->mac_addr;
u8 sma_hash, tma_hash, addr_msk_start;
u8 sma_start = 0;
u8 tma_start = 0;
- u8 *tma = sta ? sta->addr : rtwvif->bssid;
+ const u8 *tma;
+
+ rcu_read_lock();
+
+ if (sta) {
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ tma = link_sta->addr;
+ } else {
+ tma = rtwvif_link->bssid;
+ }
if (addr_cam->addr_mask != 0) {
addr_msk_start = __ffs(addr_cam->addr_mask);
@@ -691,10 +850,10 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
FWCMD_SET_ADDR_LEN(cmd, addr_cam->len);
FWCMD_SET_ADDR_VALID(cmd, addr_cam->valid);
- FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif->net_type);
- FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif->bcn_hit_cond);
- FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif->hit_rule);
- FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif->phy_idx);
+ FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif_link->net_type);
+ FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif_link->bcn_hit_cond);
+ FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif_link->hit_rule);
+ FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif_link->phy_idx);
FWCMD_SET_ADDR_ADDR_MASK(cmd, addr_cam->addr_mask);
FWCMD_SET_ADDR_MASK_SEL(cmd, addr_cam->mask_sel);
FWCMD_SET_ADDR_SMA_HASH(cmd, sma_hash);
@@ -716,20 +875,21 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
FWCMD_SET_ADDR_TMA4(cmd, tma[4]);
FWCMD_SET_ADDR_TMA5(cmd, tma[5]);
- FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif->port);
- FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif->port);
- FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif->trigger);
- FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif->lsig_txop);
- FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif->tgt_ind);
- FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif->frm_tgt_ind);
- FWCMD_SET_ADDR_MACID(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id);
- if (rtwvif->net_type == RTW89_NET_TYPE_INFRA)
+ FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif_link->port);
+ FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif_link->port);
+ FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif_link->trigger);
+ FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif_link->lsig_txop);
+ FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif_link->tgt_ind);
+ FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif_link->frm_tgt_ind);
+ FWCMD_SET_ADDR_MACID(cmd, rtwsta_link ? rtwsta_link->mac_id :
+ rtwvif_link->mac_id);
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_INFRA)
FWCMD_SET_ADDR_AID12(cmd, vif->cfg.aid & 0xfff);
- else if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
+ else if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
FWCMD_SET_ADDR_AID12(cmd, sta ? sta->aid & 0xfff : 0);
- FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif->wowlan_pattern);
- FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif->wowlan_uc);
- FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif->wowlan_magic);
+ FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif_link->wowlan_pattern);
+ FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif_link->wowlan_uc);
+ FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif_link->wowlan_magic);
FWCMD_SET_ADDR_WAPI(cmd, addr_cam->wapi);
FWCMD_SET_ADDR_SEC_ENT_MODE(cmd, addr_cam->sec_ent_mode);
FWCMD_SET_ADDR_SEC_ENT0_KEYID(cmd, addr_cam->sec_ent_keyid[0]);
@@ -748,47 +908,114 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
FWCMD_SET_ADDR_SEC_ENT4(cmd, addr_cam->sec_ent[4]);
FWCMD_SET_ADDR_SEC_ENT5(cmd, addr_cam->sec_ent[5]);
FWCMD_SET_ADDR_SEC_ENT6(cmd, addr_cam->sec_ent[6]);
+
+ rcu_read_unlock();
}
void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta,
- u8 *cmd)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ struct rtw89_h2c_dctlinfo_ud_v1 *h2c)
{
- struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
-
- SET_DCTL_MACID_V1(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id);
- SET_DCTL_OPERATION_V1(cmd, 1);
-
- SET_DCTL_SEC_ENT0_KEYID_V1(cmd, addr_cam->sec_ent_keyid[0]);
- SET_DCTL_SEC_ENT1_KEYID_V1(cmd, addr_cam->sec_ent_keyid[1]);
- SET_DCTL_SEC_ENT2_KEYID_V1(cmd, addr_cam->sec_ent_keyid[2]);
- SET_DCTL_SEC_ENT3_KEYID_V1(cmd, addr_cam->sec_ent_keyid[3]);
- SET_DCTL_SEC_ENT4_KEYID_V1(cmd, addr_cam->sec_ent_keyid[4]);
- SET_DCTL_SEC_ENT5_KEYID_V1(cmd, addr_cam->sec_ent_keyid[5]);
- SET_DCTL_SEC_ENT6_KEYID_V1(cmd, addr_cam->sec_ent_keyid[6]);
-
- SET_DCTL_SEC_ENT_VALID_V1(cmd, addr_cam->sec_cam_map[0] & 0xff);
- SET_DCTL_SEC_ENT0_V1(cmd, addr_cam->sec_ent[0]);
- SET_DCTL_SEC_ENT1_V1(cmd, addr_cam->sec_ent[1]);
- SET_DCTL_SEC_ENT2_V1(cmd, addr_cam->sec_ent[2]);
- SET_DCTL_SEC_ENT3_V1(cmd, addr_cam->sec_ent[3]);
- SET_DCTL_SEC_ENT4_V1(cmd, addr_cam->sec_ent[4]);
- SET_DCTL_SEC_ENT5_V1(cmd, addr_cam->sec_ent[5]);
- SET_DCTL_SEC_ENT6_V1(cmd, addr_cam->sec_ent[6]);
+ struct rtw89_addr_cam_entry *addr_cam =
+ rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv;
+
+ h2c->c0 = le32_encode_bits(rtwsta_link ? rtwsta_link->mac_id :
+ rtwvif_link->mac_id,
+ DCTLINFO_V1_C0_MACID) |
+ le32_encode_bits(1, DCTLINFO_V1_C0_OP);
+
+ h2c->w4 = le32_encode_bits(addr_cam->sec_ent_keyid[0],
+ DCTLINFO_V1_W4_SEC_ENT0_KEYID) |
+ le32_encode_bits(addr_cam->sec_ent_keyid[1],
+ DCTLINFO_V1_W4_SEC_ENT1_KEYID) |
+ le32_encode_bits(addr_cam->sec_ent_keyid[2],
+ DCTLINFO_V1_W4_SEC_ENT2_KEYID) |
+ le32_encode_bits(addr_cam->sec_ent_keyid[3],
+ DCTLINFO_V1_W4_SEC_ENT3_KEYID) |
+ le32_encode_bits(addr_cam->sec_ent_keyid[4],
+ DCTLINFO_V1_W4_SEC_ENT4_KEYID) |
+ le32_encode_bits(addr_cam->sec_ent_keyid[5],
+ DCTLINFO_V1_W4_SEC_ENT5_KEYID) |
+ le32_encode_bits(addr_cam->sec_ent_keyid[6],
+ DCTLINFO_V1_W4_SEC_ENT6_KEYID);
+ h2c->m4 = cpu_to_le32(DCTLINFO_V1_W4_SEC_ENT0_KEYID |
+ DCTLINFO_V1_W4_SEC_ENT1_KEYID |
+ DCTLINFO_V1_W4_SEC_ENT2_KEYID |
+ DCTLINFO_V1_W4_SEC_ENT3_KEYID |
+ DCTLINFO_V1_W4_SEC_ENT4_KEYID |
+ DCTLINFO_V1_W4_SEC_ENT5_KEYID |
+ DCTLINFO_V1_W4_SEC_ENT6_KEYID);
+
+ h2c->w5 = le32_encode_bits(addr_cam->sec_cam_map[0] & 0xff,
+ DCTLINFO_V1_W5_SEC_ENT_VALID) |
+ le32_encode_bits(addr_cam->sec_ent[0],
+ DCTLINFO_V1_W5_SEC_ENT0) |
+ le32_encode_bits(addr_cam->sec_ent[1],
+ DCTLINFO_V1_W5_SEC_ENT1) |
+ le32_encode_bits(addr_cam->sec_ent[2],
+ DCTLINFO_V1_W5_SEC_ENT2);
+ h2c->m5 = cpu_to_le32(DCTLINFO_V1_W5_SEC_ENT_VALID |
+ DCTLINFO_V1_W5_SEC_ENT0 |
+ DCTLINFO_V1_W5_SEC_ENT1 |
+ DCTLINFO_V1_W5_SEC_ENT2);
+
+ h2c->w6 = le32_encode_bits(addr_cam->sec_ent[3],
+ DCTLINFO_V1_W6_SEC_ENT3) |
+ le32_encode_bits(addr_cam->sec_ent[4],
+ DCTLINFO_V1_W6_SEC_ENT4) |
+ le32_encode_bits(addr_cam->sec_ent[5],
+ DCTLINFO_V1_W6_SEC_ENT5) |
+ le32_encode_bits(addr_cam->sec_ent[6],
+ DCTLINFO_V1_W6_SEC_ENT6);
+ h2c->m6 = cpu_to_le32(DCTLINFO_V1_W6_SEC_ENT3 |
+ DCTLINFO_V1_W6_SEC_ENT4 |
+ DCTLINFO_V1_W6_SEC_ENT5 |
+ DCTLINFO_V1_W6_SEC_ENT6);
+
+ if (rtw_wow->ptk_alg) {
+ h2c->w0 = le32_encode_bits(ptk_tx_iv[0] | ptk_tx_iv[1] << 8,
+ DCTLINFO_V1_W0_AES_IV_L);
+ h2c->m0 = cpu_to_le32(DCTLINFO_V1_W0_AES_IV_L);
+
+ h2c->w1 = le32_encode_bits(ptk_tx_iv[4] |
+ ptk_tx_iv[5] << 8 |
+ ptk_tx_iv[6] << 16 |
+ ptk_tx_iv[7] << 24,
+ DCTLINFO_V1_W1_AES_IV_H);
+ h2c->m1 = cpu_to_le32(DCTLINFO_V1_W1_AES_IV_H);
+
+ h2c->w4 |= le32_encode_bits(rtw_wow->ptk_keyidx,
+ DCTLINFO_V1_W4_SEC_KEY_ID);
+ h2c->m4 |= cpu_to_le32(DCTLINFO_V1_W4_SEC_KEY_ID);
+ }
}
void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_dctlinfo_ud_v2 *h2c)
{
- struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
-
- h2c->c0 = le32_encode_bits(rtwsta ? rtwsta->mac_id : rtwvif->mac_id,
+ struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link);
+ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link->rtwvif);
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ struct rtw89_addr_cam_entry *addr_cam =
+ rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
+ bool is_mld = sta ? sta->mlo : ieee80211_vif_is_mld(vif);
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv;
+ u8 *mld_sma, *mld_tma, *mld_bssid;
+
+ h2c->c0 = le32_encode_bits(rtwsta_link ? rtwsta_link->mac_id :
+ rtwvif_link->mac_id,
DCTLINFO_V2_C0_MACID) |
le32_encode_bits(1, DCTLINFO_V2_C0_OP);
+ h2c->w2 = le32_encode_bits(is_mld, DCTLINFO_V2_W2_IS_MLD);
+ h2c->m2 = cpu_to_le32(DCTLINFO_V2_W2_IS_MLD);
+
h2c->w4 = le32_encode_bits(addr_cam->sec_ent_keyid[0],
DCTLINFO_V2_W4_SEC_ENT0_KEYID) |
le32_encode_bits(addr_cam->sec_ent_keyid[1],
@@ -837,4 +1064,64 @@ void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
DCTLINFO_V2_W7_SEC_ENT6_V1);
h2c->m7 = cpu_to_le32(DCTLINFO_V2_W7_SEC_ENT5_V1 |
DCTLINFO_V2_W7_SEC_ENT6_V1);
+
+ if (rtw_wow->ptk_alg) {
+ h2c->w0 = le32_encode_bits(ptk_tx_iv[0] | ptk_tx_iv[1] << 8,
+ DCTLINFO_V2_W0_AES_IV_L);
+ h2c->m0 = cpu_to_le32(DCTLINFO_V2_W0_AES_IV_L);
+
+ h2c->w1 = le32_encode_bits(ptk_tx_iv[4] |
+ ptk_tx_iv[5] << 8 |
+ ptk_tx_iv[6] << 16 |
+ ptk_tx_iv[7] << 24,
+ DCTLINFO_V2_W1_AES_IV_H);
+ h2c->m1 = cpu_to_le32(DCTLINFO_V2_W1_AES_IV_H);
+
+ h2c->w4 |= le32_encode_bits(rtw_wow->ptk_keyidx,
+ DCTLINFO_V2_W4_SEC_KEY_ID);
+ h2c->m4 |= cpu_to_le32(DCTLINFO_V2_W4_SEC_KEY_ID);
+ }
+
+ if (!is_mld)
+ return;
+
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_INFRA) {
+ mld_sma = rtwvif->mac_addr;
+ mld_tma = vif->cfg.ap_addr;
+ mld_bssid = vif->cfg.ap_addr;
+ } else if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE && sta) {
+ mld_sma = rtwvif->mac_addr;
+ mld_tma = sta->addr;
+ mld_bssid = rtwvif->mac_addr;
+ } else {
+ return;
+ }
+
+ h2c->w8 = le32_encode_bits(mld_sma[0], DCTLINFO_V2_W8_MLD_SMA_0) |
+ le32_encode_bits(mld_sma[1], DCTLINFO_V2_W8_MLD_SMA_1) |
+ le32_encode_bits(mld_sma[2], DCTLINFO_V2_W8_MLD_SMA_2) |
+ le32_encode_bits(mld_sma[3], DCTLINFO_V2_W8_MLD_SMA_3);
+ h2c->m8 = cpu_to_le32(DCTLINFO_V2_W8_ALL);
+
+ h2c->w9 = le32_encode_bits(mld_sma[4], DCTLINFO_V2_W9_MLD_SMA_4) |
+ le32_encode_bits(mld_sma[5], DCTLINFO_V2_W9_MLD_SMA_5) |
+ le32_encode_bits(mld_tma[0], DCTLINFO_V2_W9_MLD_TMA_0) |
+ le32_encode_bits(mld_tma[1], DCTLINFO_V2_W9_MLD_TMA_1);
+ h2c->m9 = cpu_to_le32(DCTLINFO_V2_W9_ALL);
+
+ h2c->w10 = le32_encode_bits(mld_tma[2], DCTLINFO_V2_W10_MLD_TMA_2) |
+ le32_encode_bits(mld_tma[3], DCTLINFO_V2_W10_MLD_TMA_3) |
+ le32_encode_bits(mld_tma[4], DCTLINFO_V2_W10_MLD_TMA_4) |
+ le32_encode_bits(mld_tma[5], DCTLINFO_V2_W10_MLD_TMA_5);
+ h2c->m10 = cpu_to_le32(DCTLINFO_V2_W10_ALL);
+
+ h2c->w11 = le32_encode_bits(mld_bssid[0], DCTLINFO_V2_W11_MLD_BSSID_0) |
+ le32_encode_bits(mld_bssid[1], DCTLINFO_V2_W11_MLD_BSSID_1) |
+ le32_encode_bits(mld_bssid[2], DCTLINFO_V2_W11_MLD_BSSID_2) |
+ le32_encode_bits(mld_bssid[3], DCTLINFO_V2_W11_MLD_BSSID_3);
+ h2c->m11 = cpu_to_le32(DCTLINFO_V2_W11_ALL);
+
+ h2c->w12 = le32_encode_bits(mld_bssid[4], DCTLINFO_V2_W12_MLD_BSSID_4) |
+ le32_encode_bits(mld_bssid[5], DCTLINFO_V2_W12_MLD_BSSID_5);
+ h2c->m12 = cpu_to_le32(DCTLINFO_V2_W12_ALL);
}
diff --git a/drivers/net/wireless/realtek/rtw89/cam.h b/drivers/net/wireless/realtek/rtw89/cam.h
index fa09d11c345c..8fd2d776408e 100644
--- a/drivers/net/wireless/realtek/rtw89/cam.h
+++ b/drivers/net/wireless/realtek/rtw89/cam.h
@@ -352,6 +352,75 @@ static inline void FWCMD_SET_ADDR_BSSID_BSSID5(void *cmd, u32 value)
le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(31, 24));
}
+struct rtw89_h2c_dctlinfo_ud_v1 {
+ __le32 c0;
+ __le32 w0;
+ __le32 w1;
+ __le32 w2;
+ __le32 w3;
+ __le32 w4;
+ __le32 w5;
+ __le32 w6;
+ __le32 w7;
+ __le32 m0;
+ __le32 m1;
+ __le32 m2;
+ __le32 m3;
+ __le32 m4;
+ __le32 m5;
+ __le32 m6;
+ __le32 m7;
+} __packed;
+
+#define DCTLINFO_V1_C0_MACID GENMASK(6, 0)
+#define DCTLINFO_V1_C0_OP BIT(7)
+
+#define DCTLINFO_V1_W0_QOS_FIELD_H GENMASK(7, 0)
+#define DCTLINFO_V1_W0_HW_EXSEQ_MACID GENMASK(14, 8)
+#define DCTLINFO_V1_W0_QOS_DATA BIT(15)
+#define DCTLINFO_V1_W0_AES_IV_L GENMASK(31, 16)
+#define DCTLINFO_V1_W0_ALL GENMASK(31, 0)
+#define DCTLINFO_V1_W1_AES_IV_H GENMASK(31, 0)
+#define DCTLINFO_V1_W1_ALL GENMASK(31, 0)
+#define DCTLINFO_V1_W2_SEQ0 GENMASK(11, 0)
+#define DCTLINFO_V1_W2_SEQ1 GENMASK(23, 12)
+#define DCTLINFO_V1_W2_AMSDU_MAX_LEN GENMASK(26, 24)
+#define DCTLINFO_V1_W2_STA_AMSDU_EN BIT(27)
+#define DCTLINFO_V1_W2_CHKSUM_OFLD_EN BIT(28)
+#define DCTLINFO_V1_W2_WITH_LLC BIT(29)
+#define DCTLINFO_V1_W2_ALL GENMASK(29, 0)
+#define DCTLINFO_V1_W3_SEQ2 GENMASK(11, 0)
+#define DCTLINFO_V1_W3_SEQ3 GENMASK(23, 12)
+#define DCTLINFO_V1_W3_TGT_IND GENMASK(27, 24)
+#define DCTLINFO_V1_W3_TGT_IND_EN BIT(28)
+#define DCTLINFO_V1_W3_HTC_LB GENMASK(31, 29)
+#define DCTLINFO_V1_W3_ALL GENMASK(31, 0)
+#define DCTLINFO_V1_W4_MHDR_LEN GENMASK(4, 0)
+#define DCTLINFO_V1_W4_VLAN_TAG_VALID BIT(5)
+#define DCTLINFO_V1_W4_VLAN_TAG_SEL GENMASK(7, 6)
+#define DCTLINFO_V1_W4_HTC_ORDER BIT(8)
+#define DCTLINFO_V1_W4_SEC_KEY_ID GENMASK(10, 9)
+#define DCTLINFO_V1_W4_WAPI BIT(15)
+#define DCTLINFO_V1_W4_SEC_ENT_MODE GENMASK(17, 16)
+#define DCTLINFO_V1_W4_SEC_ENT0_KEYID GENMASK(19, 18)
+#define DCTLINFO_V1_W4_SEC_ENT1_KEYID GENMASK(21, 20)
+#define DCTLINFO_V1_W4_SEC_ENT2_KEYID GENMASK(23, 22)
+#define DCTLINFO_V1_W4_SEC_ENT3_KEYID GENMASK(25, 24)
+#define DCTLINFO_V1_W4_SEC_ENT4_KEYID GENMASK(27, 26)
+#define DCTLINFO_V1_W4_SEC_ENT5_KEYID GENMASK(29, 28)
+#define DCTLINFO_V1_W4_SEC_ENT6_KEYID GENMASK(31, 30)
+#define DCTLINFO_V1_W4_ALL (GENMASK(31, 15) | GENMASK(10, 0))
+#define DCTLINFO_V1_W5_SEC_ENT_VALID GENMASK(7, 0)
+#define DCTLINFO_V1_W5_SEC_ENT0 GENMASK(15, 8)
+#define DCTLINFO_V1_W5_SEC_ENT1 GENMASK(23, 16)
+#define DCTLINFO_V1_W5_SEC_ENT2 GENMASK(31, 24)
+#define DCTLINFO_V1_W5_ALL GENMASK(31, 0)
+#define DCTLINFO_V1_W6_SEC_ENT3 GENMASK(7, 0)
+#define DCTLINFO_V1_W6_SEC_ENT4 GENMASK(15, 8)
+#define DCTLINFO_V1_W6_SEC_ENT5 GENMASK(23, 16)
+#define DCTLINFO_V1_W6_SEC_ENT6 GENMASK(31, 24)
+#define DCTLINFO_V1_W6_ALL GENMASK(31, 0)
+
struct rtw89_h2c_dctlinfo_ud_v2 {
__le32 c0;
__le32 w0;
@@ -445,46 +514,58 @@ struct rtw89_h2c_dctlinfo_ud_v2 {
#define DCTLINFO_V2_W7_SEC_ENT7 GENMASK(23, 16)
#define DCTLINFO_V2_W7_SEC_ENT8 GENMASK(31, 24)
#define DCTLINFO_V2_W7_ALL GENMASK(31, 0)
-#define DCTLINFO_V2_W8_MLD_SMA_L_V1 GENMASK(31, 0)
+#define DCTLINFO_V2_W8_MLD_SMA_0 GENMASK(7, 0)
+#define DCTLINFO_V2_W8_MLD_SMA_1 GENMASK(15, 8)
+#define DCTLINFO_V2_W8_MLD_SMA_2 GENMASK(23, 16)
+#define DCTLINFO_V2_W8_MLD_SMA_3 GENMASK(31, 24)
#define DCTLINFO_V2_W8_ALL GENMASK(31, 0)
-#define DCTLINFO_V2_W9_MLD_SMA_H_V1 GENMASK(15, 0)
-#define DCTLINFO_V2_W9_MLD_TMA_L_V1 GENMASK(31, 16)
+#define DCTLINFO_V2_W9_MLD_SMA_4 GENMASK(7, 0)
+#define DCTLINFO_V2_W9_MLD_SMA_5 GENMASK(15, 8)
+#define DCTLINFO_V2_W9_MLD_TMA_0 GENMASK(23, 16)
+#define DCTLINFO_V2_W9_MLD_TMA_1 GENMASK(31, 24)
#define DCTLINFO_V2_W9_ALL GENMASK(31, 0)
-#define DCTLINFO_V2_W10_MLD_TMA_H_V1 GENMASK(31, 0)
+#define DCTLINFO_V2_W10_MLD_TMA_2 GENMASK(7, 0)
+#define DCTLINFO_V2_W10_MLD_TMA_3 GENMASK(15, 8)
+#define DCTLINFO_V2_W10_MLD_TMA_4 GENMASK(23, 16)
+#define DCTLINFO_V2_W10_MLD_TMA_5 GENMASK(31, 24)
#define DCTLINFO_V2_W10_ALL GENMASK(31, 0)
-#define DCTLINFO_V2_W11_MLD_TA_BSSID_L_V1 GENMASK(31, 0)
+#define DCTLINFO_V2_W11_MLD_BSSID_0 GENMASK(7, 0)
+#define DCTLINFO_V2_W11_MLD_BSSID_1 GENMASK(15, 8)
+#define DCTLINFO_V2_W11_MLD_BSSID_2 GENMASK(23, 16)
+#define DCTLINFO_V2_W11_MLD_BSSID_3 GENMASK(31, 24)
#define DCTLINFO_V2_W11_ALL GENMASK(31, 0)
-#define DCTLINFO_V2_W12_MLD_TA_BSSID_H_V1 GENMASK(15, 0)
+#define DCTLINFO_V2_W12_MLD_BSSID_4 GENMASK(7, 0)
+#define DCTLINFO_V2_W12_MLD_BSSID_5 GENMASK(15, 8)
#define DCTLINFO_V2_W12_ALL GENMASK(15, 0)
-int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
-void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
+int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
+void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev,
struct rtw89_addr_cam_entry *addr_cam,
const struct rtw89_bssid_cam_entry *bssid_cam);
void rtw89_cam_deinit_addr_cam(struct rtw89_dev *rtwdev,
struct rtw89_addr_cam_entry *addr_cam);
int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct rtw89_bssid_cam_entry *bssid_cam,
const u8 *bssid);
void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev,
struct rtw89_bssid_cam_entry *bssid_cam);
void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
- struct rtw89_vif *vif,
- struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *vif,
+ struct rtw89_sta_link *rtwsta_link,
const u8 *scan_mac_addr, u8 *cmd);
void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta,
- u8 *cmd);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ struct rtw89_h2c_dctlinfo_ud_v1 *h2c);
void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_dctlinfo_ud_v2 *h2c);
int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta, u8 *cmd);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link, u8 *cmd);
int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -495,6 +576,11 @@ int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev,
struct ieee80211_key_conf *key,
bool inform_fw);
void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif);
+ struct rtw89_vif_link *rtwvif_link);
void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev);
+int rtw89_cam_attach_link_sec_cam(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ u8 sec_cam_idx);
+
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index 051a3cad6101..806f42429a29 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -8,8 +8,13 @@
#include "fw.h"
#include "mac.h"
#include "ps.h"
+#include "sar.h"
#include "util.h"
+static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev,
+ enum rtw89_chanctx_idx idx1,
+ enum rtw89_chanctx_idx idx2);
+
static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band,
u8 center_chan)
{
@@ -124,12 +129,12 @@ void rtw89_chan_create(struct rtw89_chan *chan, u8 center_chan, u8 primary_chan,
}
bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
- enum rtw89_sub_entity_idx idx,
+ enum rtw89_chanctx_idx idx,
const struct rtw89_chan *new)
{
struct rtw89_hal *hal = &rtwdev->hal;
- struct rtw89_chan *chan = &hal->sub[idx].chan;
- struct rtw89_chan_rcd *rcd = &hal->sub[idx].rcd;
+ struct rtw89_chan *chan = &hal->chanctx[idx].chan;
+ struct rtw89_chan_rcd *rcd = &hal->chanctx[idx].rcd;
bool band_changed;
rcd->prev_primary_channel = chan->primary_channel;
@@ -141,50 +146,74 @@ bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
return band_changed;
}
+int rtw89_iterate_entity_chan(struct rtw89_dev *rtwdev,
+ int (*iterator)(const struct rtw89_chan *chan,
+ void *data),
+ void *data)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ const struct rtw89_chan *chan;
+ int ret;
+ u8 idx;
+
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_CHANCTX) {
+ chan = rtw89_chan_get(rtwdev, idx);
+ ret = iterator(chan, data);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static void __rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
- enum rtw89_sub_entity_idx idx,
+ enum rtw89_chanctx_idx idx,
const struct cfg80211_chan_def *chandef,
bool from_stack)
{
struct rtw89_hal *hal = &rtwdev->hal;
- hal->sub[idx].chandef = *chandef;
+ hal->chanctx[idx].chandef = *chandef;
if (from_stack)
set_bit(idx, hal->entity_map);
}
void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
- enum rtw89_sub_entity_idx idx,
+ enum rtw89_chanctx_idx idx,
const struct cfg80211_chan_def *chandef)
{
__rtw89_config_entity_chandef(rtwdev, idx, chandef, true);
}
void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
- enum rtw89_sub_entity_idx idx,
+ struct rtw89_vif_link *rtwvif_link,
const struct cfg80211_chan_def *chandef)
{
+ enum rtw89_chanctx_idx idx = rtwvif_link->chanctx_idx;
struct rtw89_hal *hal = &rtwdev->hal;
- enum rtw89_sub_entity_idx cur;
+ enum rtw89_chanctx_idx cur;
if (chandef) {
- cur = atomic_cmpxchg(&hal->roc_entity_idx,
- RTW89_SUB_ENTITY_IDLE, idx);
- if (cur != RTW89_SUB_ENTITY_IDLE) {
+ cur = atomic_cmpxchg(&hal->roc_chanctx_idx,
+ RTW89_CHANCTX_IDLE, idx);
+ if (cur != RTW89_CHANCTX_IDLE) {
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
"ROC still processing on entity %d\n", idx);
return;
}
hal->roc_chandef = *chandef;
+ hal->roc_link_index = rtw89_vif_link_inst_get_index(rtwvif_link);
} else {
- cur = atomic_cmpxchg(&hal->roc_entity_idx, idx,
- RTW89_SUB_ENTITY_IDLE);
+ cur = atomic_cmpxchg(&hal->roc_chanctx_idx, idx,
+ RTW89_CHANCTX_IDLE);
if (cur == idx)
return;
- if (cur == RTW89_SUB_ENTITY_IDLE)
+ if (cur == RTW89_CHANCTX_IDLE)
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
"ROC already finished on entity %d\n", idx);
else
@@ -198,20 +227,36 @@ static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev)
struct cfg80211_chan_def chandef = {0};
rtw89_get_default_chandef(&chandef);
- __rtw89_config_entity_chandef(rtwdev, RTW89_SUB_ENTITY_0, &chandef, false);
+ __rtw89_config_entity_chandef(rtwdev, RTW89_CHANCTX_0, &chandef, false);
}
void rtw89_entity_init(struct rtw89_dev *rtwdev)
{
struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
hal->entity_pause = false;
- bitmap_zero(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
+ bitmap_zero(hal->entity_map, NUM_OF_RTW89_CHANCTX);
bitmap_zero(hal->changes, NUM_OF_RTW89_CHANCTX_CHANGES);
- atomic_set(&hal->roc_entity_idx, RTW89_SUB_ENTITY_IDLE);
+ atomic_set(&hal->roc_chanctx_idx, RTW89_CHANCTX_IDLE);
+
+ INIT_LIST_HEAD(&mgnt->active_list);
+
rtw89_config_default_chandef(rtwdev);
}
+static bool rtw89_vif_is_active_role(struct rtw89_vif *rtwvif)
+{
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ if (rtwvif_link->chanctx_assigned)
+ return true;
+
+ return false;
+}
+
static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev,
struct rtw89_entity_weight *w)
{
@@ -220,8 +265,8 @@ static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif;
int idx;
- for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_SUB_ENTITY) {
- cfg = hal->sub[idx].cfg;
+ for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_CHANCTX) {
+ cfg = hal->chanctx[idx].cfg;
if (!cfg) {
/* doesn't run with chanctx ops; one channel at most */
w->active_chanctxs = 1;
@@ -233,14 +278,182 @@ static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev,
}
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
- if (rtwvif->chanctx_assigned)
+ if (rtw89_vif_is_active_role(rtwvif))
w->active_roles++;
}
}
+static void rtw89_normalize_link_chanctx(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ struct rtw89_vif_link *cur;
+
+ if (unlikely(!rtwvif_link->chanctx_assigned))
+ return;
+
+ cur = rtw89_vif_get_link_inst(rtwvif, 0);
+ if (!cur || !cur->chanctx_assigned)
+ return;
+
+ if (cur == rtwvif_link)
+ return;
+
+ rtw89_swap_chanctx(rtwdev, rtwvif_link->chanctx_idx, cur->chanctx_idx);
+}
+
+const struct rtw89_chan *__rtw89_mgnt_chan_get(struct rtw89_dev *rtwdev,
+ const char *caller_message,
+ u8 link_index)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
+ enum rtw89_chanctx_idx chanctx_idx;
+ enum rtw89_chanctx_idx roc_idx;
+ enum rtw89_entity_mode mode;
+ u8 role_index;
+
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ if (unlikely(link_index >= __RTW89_MLD_MAX_LINK_NUM)) {
+ WARN(1, "link index %u is invalid (max link inst num: %d)\n",
+ link_index, __RTW89_MLD_MAX_LINK_NUM);
+ goto dflt;
+ }
+
+ mode = rtw89_get_entity_mode(rtwdev);
+ switch (mode) {
+ case RTW89_ENTITY_MODE_SCC_OR_SMLD:
+ case RTW89_ENTITY_MODE_MCC:
+ role_index = 0;
+ break;
+ case RTW89_ENTITY_MODE_MCC_PREPARE:
+ role_index = 1;
+ break;
+ default:
+ WARN(1, "Invalid ent mode: %d\n", mode);
+ goto dflt;
+ }
+
+ chanctx_idx = mgnt->chanctx_tbl[role_index][link_index];
+ if (chanctx_idx == RTW89_CHANCTX_IDLE)
+ goto dflt;
+
+ roc_idx = atomic_read(&hal->roc_chanctx_idx);
+ if (roc_idx != RTW89_CHANCTX_IDLE) {
+ /* ROC is ongoing (given ROC runs on @hal->roc_link_index).
+ * If @link_index is the same, get the ongoing ROC chanctx.
+ */
+ if (link_index == hal->roc_link_index)
+ chanctx_idx = roc_idx;
+ }
+
+ return rtw89_chan_get(rtwdev, chanctx_idx);
+
+dflt:
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "%s (%s): prefetch NULL on link index %u\n",
+ __func__, caller_message ?: "", link_index);
+
+ return rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
+}
+EXPORT_SYMBOL(__rtw89_mgnt_chan_get);
+
+static enum rtw89_mlo_dbcc_mode
+rtw89_entity_sel_mlo_dbcc_mode(struct rtw89_dev *rtwdev, u8 active_hws)
+{
+ if (rtwdev->chip->chip_gen != RTW89_CHIP_BE)
+ return MLO_DBCC_NOT_SUPPORT;
+
+ switch (active_hws) {
+ case BIT(0):
+ return MLO_2_PLUS_0_1RF;
+ case BIT(1):
+ return MLO_0_PLUS_2_1RF;
+ case BIT(0) | BIT(1):
+ default:
+ return MLO_1_PLUS_1_1RF;
+ }
+}
+
+static
+void rtw89_entity_recalc_mlo_dbcc_mode(struct rtw89_dev *rtwdev, u8 active_hws)
+{
+ enum rtw89_mlo_dbcc_mode mode;
+
+ mode = rtw89_entity_sel_mlo_dbcc_mode(rtwdev, active_hws);
+ rtwdev->mlo_dbcc_mode = mode;
+
+ rtw89_debug(rtwdev, RTW89_DBG_STATE, "recalc mlo dbcc mode to %d\n", mode);
+}
+
+static void rtw89_entity_recalc_mgnt_roles(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
+ struct rtw89_vif_link *link;
+ struct rtw89_vif *role;
+ u8 active_hws = 0;
+ u8 pos = 0;
+ int i, j;
+
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ for (i = 0; i < RTW89_MAX_INTERFACE_NUM; i++)
+ mgnt->active_roles[i] = NULL;
+
+ for (i = 0; i < RTW89_MAX_INTERFACE_NUM; i++) {
+ for (j = 0; j < __RTW89_MLD_MAX_LINK_NUM; j++)
+ mgnt->chanctx_tbl[i][j] = RTW89_CHANCTX_IDLE;
+ }
+
+ /* To be consistent with legacy behavior, expect the first active role
+ * which uses RTW89_CHANCTX_0 to put at position 0, and make its first
+ * link instance take RTW89_CHANCTX_0. (normalizing)
+ */
+ list_for_each_entry(role, &mgnt->active_list, mgnt_entry) {
+ for (i = 0; i < role->links_inst_valid_num; i++) {
+ link = rtw89_vif_get_link_inst(role, i);
+ if (!link || !link->chanctx_assigned)
+ continue;
+
+ if (link->chanctx_idx == RTW89_CHANCTX_0) {
+ rtw89_normalize_link_chanctx(rtwdev, link);
+
+ list_del(&role->mgnt_entry);
+ list_add(&role->mgnt_entry, &mgnt->active_list);
+ goto fill;
+ }
+ }
+ }
+
+fill:
+ list_for_each_entry(role, &mgnt->active_list, mgnt_entry) {
+ if (unlikely(pos >= RTW89_MAX_INTERFACE_NUM)) {
+ rtw89_warn(rtwdev,
+ "%s: active roles are over max iface num\n",
+ __func__);
+ break;
+ }
+
+ for (i = 0; i < role->links_inst_valid_num; i++) {
+ link = rtw89_vif_get_link_inst(role, i);
+ if (!link || !link->chanctx_assigned)
+ continue;
+
+ mgnt->chanctx_tbl[pos][i] = link->chanctx_idx;
+ active_hws |= BIT(i);
+ }
+
+ mgnt->active_roles[pos++] = role;
+ }
+
+ rtw89_entity_recalc_mlo_dbcc_mode(rtwdev, active_hws);
+}
+
enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
{
- DECLARE_BITMAP(recalc_map, NUM_OF_RTW89_SUB_ENTITY) = {};
+ DECLARE_BITMAP(recalc_map, NUM_OF_RTW89_CHANCTX) = {};
struct rtw89_hal *hal = &rtwdev->hal;
const struct cfg80211_chan_def *chandef;
struct rtw89_entity_weight w = {};
@@ -248,25 +461,30 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
struct rtw89_chan chan;
u8 idx;
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
- bitmap_copy(recalc_map, hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
+ bitmap_copy(recalc_map, hal->entity_map, NUM_OF_RTW89_CHANCTX);
rtw89_entity_calculate_weight(rtwdev, &w);
switch (w.active_chanctxs) {
default:
rtw89_warn(rtwdev, "unknown ent chanctxs weight: %d\n",
w.active_chanctxs);
- bitmap_zero(recalc_map, NUM_OF_RTW89_SUB_ENTITY);
+ bitmap_zero(recalc_map, NUM_OF_RTW89_CHANCTX);
fallthrough;
case 0:
rtw89_config_default_chandef(rtwdev);
- set_bit(RTW89_SUB_ENTITY_0, recalc_map);
+ set_bit(RTW89_CHANCTX_0, recalc_map);
fallthrough;
case 1:
- mode = RTW89_ENTITY_MODE_SCC;
+ mode = RTW89_ENTITY_MODE_SCC_OR_SMLD;
break;
- case 2 ... NUM_OF_RTW89_SUB_ENTITY:
+ case 2 ... NUM_OF_RTW89_CHANCTX:
+ if (w.active_roles == 1) {
+ mode = RTW89_ENTITY_MODE_SCC_OR_SMLD;
+ break;
+ }
+
if (w.active_roles != NUM_OF_RTW89_MCC_ROLES) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"unhandled ent: %d chanctxs %d roles\n",
@@ -282,7 +500,7 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
break;
}
- for_each_set_bit(idx, recalc_map, NUM_OF_RTW89_SUB_ENTITY) {
+ for_each_set_bit(idx, recalc_map, NUM_OF_RTW89_CHANCTX) {
chandef = rtw89_chandef_get(rtwdev, idx);
rtw89_get_channel_params(chandef, &chan);
if (chan.channel == 0) {
@@ -293,6 +511,8 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
rtw89_assign_entity_chan(rtwdev, idx, &chan);
}
+ rtw89_entity_recalc_mgnt_roles(rtwdev);
+
if (hal->entity_pause)
return rtw89_get_entity_mode(rtwdev);
@@ -365,12 +585,14 @@ int rtw89_iterate_mcc_roles(struct rtw89_dev *rtwdev,
static u32 rtw89_mcc_get_tbtt_ofst(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *role, u64 tsf)
{
- struct rtw89_vif *rtwvif = role->rtwvif;
+ struct rtw89_vif_link *rtwvif_link = role->rtwvif_link;
u32 bcn_intvl_us = ieee80211_tu_to_usec(role->beacon_interval);
- u64 sync_tsf = READ_ONCE(rtwvif->sync_bcn_tsf);
+ u64 sync_tsf = READ_ONCE(rtwvif_link->sync_bcn_tsf);
u32 remainder;
- if (tsf < sync_tsf) {
+ if (role->is_go) {
+ sync_tsf = 0;
+ } else if (tsf < sync_tsf) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"MCC get tbtt ofst: tsf might not update yet\n");
sync_tsf = 0;
@@ -391,8 +613,8 @@ static int __mcc_fw_req_tsf(struct rtw89_dev *rtwdev, u64 *tsf_ref, u64 *tsf_aux
int ret;
req.group = mcc->group;
- req.macid_x = ref->rtwvif->mac_id;
- req.macid_y = aux->rtwvif->mac_id;
+ req.macid_x = ref->rtwvif_link->mac_id;
+ req.macid_y = aux->rtwvif_link->mac_id;
ret = rtw89_fw_h2c_mcc_req_tsf(rtwdev, &req, &rpt);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
@@ -418,10 +640,10 @@ static int __mrc_fw_req_tsf(struct rtw89_dev *rtwdev, u64 *tsf_ref, u64 *tsf_aux
BUILD_BUG_ON(RTW89_MAC_MRC_MAX_REQ_TSF_NUM < NUM_OF_RTW89_MCC_ROLES);
arg.num = 2;
- arg.infos[0].band = ref->rtwvif->mac_idx;
- arg.infos[0].port = ref->rtwvif->port;
- arg.infos[1].band = aux->rtwvif->mac_idx;
- arg.infos[1].port = aux->rtwvif->port;
+ arg.infos[0].band = ref->rtwvif_link->mac_idx;
+ arg.infos[0].port = ref->rtwvif_link->port;
+ arg.infos[1].band = aux->rtwvif_link->mac_idx;
+ arg.infos[1].port = aux->rtwvif_link->port;
ret = rtw89_fw_h2c_mrc_req_tsf(rtwdev, &arg, &rpt);
if (ret) {
@@ -500,23 +722,25 @@ out:
static void rtw89_mcc_role_macid_sta_iter(void *data, struct ieee80211_sta *sta)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_mcc_role *mcc_role = data;
- struct rtw89_vif *target = mcc_role->rtwvif;
+ struct rtw89_vif *target = mcc_role->rtwvif_link->rtwvif;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif *rtwvif = rtwsta->rtwvif;
+ u8 macid;
if (rtwvif != target)
return;
- rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwsta->mac_id);
+ macid = rtw89_sta_get_main_macid(rtwsta);
+ rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, macid);
}
static void rtw89_mcc_fill_role_macid_bitmap(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *mcc_role)
{
- struct rtw89_vif *rtwvif = mcc_role->rtwvif;
+ struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link;
- rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwvif->mac_id);
+ rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwvif_link->mac_id);
ieee80211_iterate_stations_atomic(rtwdev->hw,
rtw89_mcc_role_macid_sta_iter,
mcc_role);
@@ -542,8 +766,9 @@ static void rtw89_mcc_fill_role_policy(struct rtw89_dev *rtwdev,
static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *mcc_role)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(mcc_role->rtwvif);
+ struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link;
struct ieee80211_p2p_noa_desc *noa_desc;
+ struct ieee80211_bss_conf *bss_conf;
u32 bcn_intvl_us = ieee80211_tu_to_usec(mcc_role->beacon_interval);
u32 max_toa_us, max_tob_us, max_dur_us;
u32 start_time, interval, duration;
@@ -551,16 +776,23 @@ static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev,
int ret;
int i;
- if (!mcc_role->is_go && !mcc_role->is_gc)
+ if (!mcc_role->is_gc)
return;
+ rtw89_p2p_noa_once_recalc(rtwvif_link);
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
/* find the first periodic NoA */
for (i = 0; i < RTW89_P2P_MAX_NOA_NUM; i++) {
- noa_desc = &vif->bss_conf.p2p_noa_attr.desc[i];
+ noa_desc = &bss_conf->p2p_noa_attr.desc[i];
if (noa_desc->count == 255)
goto fill;
}
+ rcu_read_unlock();
return;
fill:
@@ -568,6 +800,8 @@ fill:
interval = le32_to_cpu(noa_desc->interval);
duration = le32_to_cpu(noa_desc->duration);
+ rcu_read_unlock();
+
if (interval != bcn_intvl_us) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"MCC role limit: mismatch interval: %d vs. %d\n",
@@ -575,13 +809,16 @@ fill:
return;
}
- ret = rtw89_mac_port_get_tsf(rtwdev, mcc_role->rtwvif, &tsf);
+ ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
if (ret) {
rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret);
return;
}
tsf_lmt = (tsf & GENMASK_ULL(63, 32)) | start_time;
+ if (tsf_lmt < tsf)
+ tsf_lmt += roundup_u64(tsf - tsf_lmt, interval);
+
max_toa_us = rtw89_mcc_get_tbtt_ofst(rtwdev, mcc_role, tsf_lmt);
max_dur_us = interval - duration;
max_tob_us = max_dur_us - max_toa_us;
@@ -600,7 +837,7 @@ fill:
mcc_role->limit.max_toa = max_toa_us / 1024;
mcc_role->limit.max_tob = max_tob_us / 1024;
- mcc_role->limit.max_dur = max_dur_us / 1024;
+ mcc_role->limit.max_dur = mcc_role->limit.max_toa + mcc_role->limit.max_tob;
mcc_role->limit.enable = true;
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
@@ -610,15 +847,21 @@ fill:
}
static int rtw89_mcc_fill_role(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct rtw89_mcc_role *role)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_bss_conf *bss_conf;
const struct rtw89_chan *chan;
memset(role, 0, sizeof(*role));
- role->rtwvif = rtwvif;
- role->beacon_interval = vif->bss_conf.beacon_int;
+ role->rtwvif_link = rtwvif_link;
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ role->beacon_interval = bss_conf->beacon_int;
+
+ rcu_read_unlock();
if (!role->beacon_interval) {
rtw89_warn(rtwdev,
@@ -628,10 +871,10 @@ static int rtw89_mcc_fill_role(struct rtw89_dev *rtwdev,
role->duration = role->beacon_interval / 2;
- chan = rtw89_chan_get(rtwdev, rtwvif->sub_entity_idx);
+ chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
role->is_2ghz = chan->band_type == RTW89_BAND_2G;
- role->is_go = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_GO;
- role->is_gc = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
+ role->is_go = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_GO;
+ role->is_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
rtw89_mcc_fill_role_macid_bitmap(rtwdev, role);
rtw89_mcc_fill_role_policy(rtwdev, role);
@@ -656,10 +899,11 @@ static void rtw89_mcc_fill_bt_role(struct rtw89_dev *rtwdev)
}
struct rtw89_mcc_fill_role_selector {
- struct rtw89_vif *bind_vif[NUM_OF_RTW89_SUB_ENTITY];
+ struct rtw89_vif_link *bind_vif[NUM_OF_RTW89_CHANCTX];
};
-static_assert((u8)NUM_OF_RTW89_SUB_ENTITY >= NUM_OF_RTW89_MCC_ROLES);
+static_assert((u8)NUM_OF_RTW89_CHANCTX >= NUM_OF_RTW89_MCC_ROLES);
+static_assert(RTW89_MAX_INTERFACE_NUM >= NUM_OF_RTW89_MCC_ROLES);
static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *mcc_role,
@@ -667,7 +911,7 @@ static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
void *data)
{
struct rtw89_mcc_fill_role_selector *sel = data;
- struct rtw89_vif *role_vif = sel->bind_vif[ordered_idx];
+ struct rtw89_vif_link *role_vif = sel->bind_vif[ordered_idx];
int ret;
if (!role_vif) {
@@ -689,22 +933,26 @@ static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev)
{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
struct rtw89_mcc_fill_role_selector sel = {};
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
int ret;
+ int i;
- rtw89_for_each_rtwvif(rtwdev, rtwvif) {
- if (!rtwvif->chanctx_assigned)
- continue;
+ for (i = 0; i < NUM_OF_RTW89_MCC_ROLES; i++) {
+ rtwvif = mgnt->active_roles[i];
+ if (!rtwvif)
+ break;
- if (sel.bind_vif[rtwvif->sub_entity_idx]) {
- rtw89_warn(rtwdev,
- "MCC skip extra vif <macid %d> on chanctx[%d]\n",
- rtwvif->mac_id, rtwvif->sub_entity_idx);
+ rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "mcc fill roles: find no link on HW-0\n");
continue;
}
- sel.bind_vif[rtwvif->sub_entity_idx] = rtwvif;
+ sel.bind_vif[i] = rtwvif_link;
}
ret = rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_fill_role_iterator, &sel);
@@ -715,6 +963,15 @@ static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev)
return 0;
}
+static bool rtw89_mcc_can_courtesy(const struct rtw89_mcc_role *provider,
+ const struct rtw89_mcc_role *receiver)
+{
+ if (provider->is_go || receiver->is_gc)
+ return false;
+
+ return true;
+}
+
static void rtw89_mcc_assign_pattern(struct rtw89_dev *rtwdev,
const struct rtw89_mcc_pattern *new)
{
@@ -723,37 +980,44 @@ static void rtw89_mcc_assign_pattern(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *aux = &mcc->role_aux;
struct rtw89_mcc_config *config = &mcc->config;
struct rtw89_mcc_pattern *pattern = &config->pattern;
+ struct rtw89_mcc_courtesy_cfg *crtz;
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"MCC assign pattern: ref {%d | %d}, aux {%d | %d}\n",
new->tob_ref, new->toa_ref, new->tob_aux, new->toa_aux);
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC pattern plan: %d\n", new->plan);
+
*pattern = *new;
memset(&pattern->courtesy, 0, sizeof(pattern->courtesy));
- if (pattern->tob_aux <= 0 || pattern->toa_aux <= 0) {
- pattern->courtesy.macid_tgt = aux->rtwvif->mac_id;
- pattern->courtesy.macid_src = ref->rtwvif->mac_id;
- pattern->courtesy.slot_num = RTW89_MCC_DFLT_COURTESY_SLOT;
- pattern->courtesy.enable = true;
- } else if (pattern->tob_ref <= 0 || pattern->toa_ref <= 0) {
- pattern->courtesy.macid_tgt = ref->rtwvif->mac_id;
- pattern->courtesy.macid_src = aux->rtwvif->mac_id;
- pattern->courtesy.slot_num = RTW89_MCC_DFLT_COURTESY_SLOT;
- pattern->courtesy.enable = true;
+ if (RTW89_MCC_REQ_COURTESY(pattern, aux) && rtw89_mcc_can_courtesy(ref, aux)) {
+ crtz = &pattern->courtesy.ref;
+ ref->crtz = crtz;
+
+ crtz->macid_tgt = aux->rtwvif_link->mac_id;
+ crtz->slot_num = RTW89_MCC_DFLT_COURTESY_SLOT;
+
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MCC courtesy ref: tgt %d, slot %d\n",
+ crtz->macid_tgt, crtz->slot_num);
+ } else {
+ ref->crtz = NULL;
}
- rtw89_debug(rtwdev, RTW89_DBG_CHAN,
- "MCC pattern flags: plan %d, courtesy_en %d\n",
- pattern->plan, pattern->courtesy.enable);
+ if (RTW89_MCC_REQ_COURTESY(pattern, ref) && rtw89_mcc_can_courtesy(aux, ref)) {
+ crtz = &pattern->courtesy.aux;
+ aux->crtz = crtz;
- if (!pattern->courtesy.enable)
- return;
+ crtz->macid_tgt = ref->rtwvif_link->mac_id;
+ crtz->slot_num = RTW89_MCC_DFLT_COURTESY_SLOT;
- rtw89_debug(rtwdev, RTW89_DBG_CHAN,
- "MCC pattern courtesy: tgt %d, src %d, slot %d\n",
- pattern->courtesy.macid_tgt, pattern->courtesy.macid_src,
- pattern->courtesy.slot_num);
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MCC courtesy aux: tgt %d, slot %d\n",
+ crtz->macid_tgt, crtz->slot_num);
+ } else {
+ aux->crtz = NULL;
+ }
}
/* The follow-up roughly shows the relationship between the parameters
@@ -778,6 +1042,7 @@ static void __rtw89_mcc_calc_pattern_loose(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *ref = &mcc->role_ref;
struct rtw89_mcc_role *aux = &mcc->role_aux;
struct rtw89_mcc_config *config = &mcc->config;
+ u16 mcc_intvl = config->mcc_interval;
u16 bcn_ofst = config->beacon_offset;
u16 bt_dur_in_mid = 0;
u16 max_bcn_ofst;
@@ -811,7 +1076,7 @@ calc:
res = bcn_ofst - bt_dur_in_mid;
upper = min_t(s16, ref->duration, res);
- lower = 0;
+ lower = max_t(s16, 0, ref->duration - (mcc_intvl - bcn_ofst));
if (ref->limit.enable) {
upper = min_t(s16, upper, ref->limit.max_toa);
@@ -922,6 +1187,107 @@ static int __rtw89_mcc_calc_pattern_strict(struct rtw89_dev *rtwdev,
return 0;
}
+static void __rtw89_mcc_fill_ptrn_anchor_ref(struct rtw89_dev *rtwdev,
+ struct rtw89_mcc_pattern *ptrn,
+ bool small_bcn_ofst)
+{
+ struct rtw89_mcc_info *mcc = &rtwdev->mcc;
+ struct rtw89_mcc_role *ref = &mcc->role_ref;
+ struct rtw89_mcc_role *aux = &mcc->role_aux;
+ struct rtw89_mcc_config *config = &mcc->config;
+ u16 bcn_ofst = config->beacon_offset;
+ u16 ref_tob;
+ u16 ref_toa;
+
+ if (ref->limit.enable) {
+ ref_tob = ref->limit.max_tob;
+ ref_toa = ref->limit.max_toa;
+ } else {
+ ref_tob = ref->duration / 2;
+ ref_toa = ref->duration / 2;
+ }
+
+ if (small_bcn_ofst) {
+ ptrn->toa_ref = ref_toa;
+ ptrn->tob_ref = ref->duration - ptrn->toa_ref;
+ } else {
+ ptrn->tob_ref = ref_tob;
+ ptrn->toa_ref = ref->duration - ptrn->tob_ref;
+ }
+
+ ptrn->tob_aux = bcn_ofst - ptrn->toa_ref;
+ ptrn->toa_aux = aux->duration - ptrn->tob_aux;
+}
+
+static void __rtw89_mcc_fill_ptrn_anchor_aux(struct rtw89_dev *rtwdev,
+ struct rtw89_mcc_pattern *ptrn,
+ bool small_bcn_ofst)
+{
+ struct rtw89_mcc_info *mcc = &rtwdev->mcc;
+ struct rtw89_mcc_role *ref = &mcc->role_ref;
+ struct rtw89_mcc_role *aux = &mcc->role_aux;
+ struct rtw89_mcc_config *config = &mcc->config;
+ u16 bcn_ofst = config->beacon_offset;
+ u16 aux_tob;
+ u16 aux_toa;
+
+ if (aux->limit.enable) {
+ aux_tob = aux->limit.max_tob;
+ aux_toa = aux->limit.max_toa;
+ } else {
+ aux_tob = aux->duration / 2;
+ aux_toa = aux->duration / 2;
+ }
+
+ if (small_bcn_ofst) {
+ ptrn->tob_aux = aux_tob;
+ ptrn->toa_aux = aux->duration - ptrn->tob_aux;
+ } else {
+ ptrn->toa_aux = aux_toa;
+ ptrn->tob_aux = aux->duration - ptrn->toa_aux;
+ }
+
+ ptrn->toa_ref = bcn_ofst - ptrn->tob_aux;
+ ptrn->tob_ref = ref->duration - ptrn->toa_ref;
+}
+
+static int __rtw89_mcc_calc_pattern_anchor(struct rtw89_dev *rtwdev,
+ struct rtw89_mcc_pattern *ptrn,
+ bool hdl_bt)
+{
+ struct rtw89_mcc_info *mcc = &rtwdev->mcc;
+ struct rtw89_mcc_role *ref = &mcc->role_ref;
+ struct rtw89_mcc_role *aux = &mcc->role_aux;
+ struct rtw89_mcc_config *config = &mcc->config;
+ u16 mcc_intvl = config->mcc_interval;
+ u16 bcn_ofst = config->beacon_offset;
+ bool small_bcn_ofst;
+
+ if (bcn_ofst < RTW89_MCC_MIN_RX_BCN_TIME)
+ small_bcn_ofst = true;
+ else if (mcc_intvl - bcn_ofst < RTW89_MCC_MIN_RX_BCN_TIME)
+ small_bcn_ofst = false;
+ else
+ return -EPERM;
+
+ *ptrn = (typeof(*ptrn)){
+ .plan = hdl_bt ? RTW89_MCC_PLAN_TAIL_BT : RTW89_MCC_PLAN_NO_BT,
+ };
+
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MCC calc ptrn_ac: plan %d, bcn_ofst %d\n",
+ ptrn->plan, bcn_ofst);
+
+ if (ref->is_go || ref->is_gc)
+ __rtw89_mcc_fill_ptrn_anchor_ref(rtwdev, ptrn, small_bcn_ofst);
+ else if (aux->is_go || aux->is_gc)
+ __rtw89_mcc_fill_ptrn_anchor_aux(rtwdev, ptrn, small_bcn_ofst);
+ else
+ __rtw89_mcc_fill_ptrn_anchor_ref(rtwdev, ptrn, small_bcn_ofst);
+
+ return 0;
+}
+
static int rtw89_mcc_calc_pattern(struct rtw89_dev *rtwdev, bool hdl_bt)
{
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
@@ -975,6 +1341,10 @@ static int rtw89_mcc_calc_pattern(struct rtw89_dev *rtwdev, bool hdl_bt)
goto done;
}
+ ret = __rtw89_mcc_calc_pattern_anchor(rtwdev, &ptrn, hdl_bt);
+ if (!ret)
+ goto done;
+
__rtw89_mcc_calc_pattern_loose(rtwdev, &ptrn, hdl_bt);
done:
@@ -1225,88 +1595,41 @@ static bool rtw89_mcc_duration_decision_on_bt(struct rtw89_dev *rtwdev)
return false;
}
-static void rtw89_mcc_sync_tbtt(struct rtw89_dev *rtwdev,
- struct rtw89_mcc_role *tgt,
- struct rtw89_mcc_role *src,
- bool ref_is_src)
-{
- struct rtw89_mcc_info *mcc = &rtwdev->mcc;
- struct rtw89_mcc_config *config = &mcc->config;
- u16 beacon_offset_us = ieee80211_tu_to_usec(config->beacon_offset);
- u32 bcn_intvl_src_us = ieee80211_tu_to_usec(src->beacon_interval);
- u32 cur_tbtt_ofst_src;
- u32 tsf_ofst_tgt;
- u32 remainder;
- u64 tbtt_tgt;
- u64 tsf_src;
- int ret;
-
- ret = rtw89_mac_port_get_tsf(rtwdev, src->rtwvif, &tsf_src);
- if (ret) {
- rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret);
- return;
- }
-
- cur_tbtt_ofst_src = rtw89_mcc_get_tbtt_ofst(rtwdev, src, tsf_src);
-
- if (ref_is_src)
- tbtt_tgt = tsf_src - cur_tbtt_ofst_src + beacon_offset_us;
- else
- tbtt_tgt = tsf_src - cur_tbtt_ofst_src +
- (bcn_intvl_src_us - beacon_offset_us);
-
- div_u64_rem(tbtt_tgt, bcn_intvl_src_us, &remainder);
- tsf_ofst_tgt = bcn_intvl_src_us - remainder;
-
- config->sync.macid_tgt = tgt->rtwvif->mac_id;
- config->sync.band_tgt = tgt->rtwvif->mac_idx;
- config->sync.port_tgt = tgt->rtwvif->port;
- config->sync.macid_src = src->rtwvif->mac_id;
- config->sync.band_src = src->rtwvif->mac_idx;
- config->sync.port_src = src->rtwvif->port;
- config->sync.offset = tsf_ofst_tgt / 1024;
- config->sync.enable = true;
-
- rtw89_debug(rtwdev, RTW89_DBG_CHAN,
- "MCC sync tbtt: tgt %d, src %d, offset %d\n",
- config->sync.macid_tgt, config->sync.macid_src,
- config->sync.offset);
-
- rtw89_mac_port_tsf_sync(rtwdev, tgt->rtwvif, src->rtwvif,
- config->sync.offset);
-}
-
static int rtw89_mcc_fill_start_tsf(struct rtw89_dev *rtwdev)
{
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
struct rtw89_mcc_role *ref = &mcc->role_ref;
+ struct rtw89_mcc_role *aux = &mcc->role_aux;
struct rtw89_mcc_config *config = &mcc->config;
u32 bcn_intvl_ref_us = ieee80211_tu_to_usec(ref->beacon_interval);
- u32 tob_ref_us = ieee80211_tu_to_usec(config->pattern.tob_ref);
- struct rtw89_vif *rtwvif = ref->rtwvif;
+ s32 tob_ref_us = ieee80211_tu_to_usec(config->pattern.tob_ref);
u64 tsf, start_tsf;
u32 cur_tbtt_ofst;
u64 min_time;
+ u64 tsf_aux;
int ret;
- ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif, &tsf);
- if (ret) {
- rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret);
+ if (rtw89_concurrent_via_mrc(rtwdev))
+ ret = __mrc_fw_req_tsf(rtwdev, &tsf, &tsf_aux);
+ else
+ ret = __mcc_fw_req_tsf(rtwdev, &tsf, &tsf_aux);
+
+ if (ret)
return ret;
- }
min_time = tsf;
- if (ref->is_go)
+ if (ref->is_go || aux->is_go)
min_time += ieee80211_tu_to_usec(RTW89_MCC_SHORT_TRIGGER_TIME);
else
min_time += ieee80211_tu_to_usec(RTW89_MCC_LONG_TRIGGER_TIME);
cur_tbtt_ofst = rtw89_mcc_get_tbtt_ofst(rtwdev, ref, tsf);
start_tsf = tsf - cur_tbtt_ofst + bcn_intvl_ref_us - tob_ref_us;
- while (start_tsf < min_time)
- start_tsf += bcn_intvl_ref_us;
+ if (start_tsf < min_time)
+ start_tsf += roundup_u64(min_time - start_tsf, bcn_intvl_ref_us);
config->start_tsf = start_tsf;
+ config->start_tsf_in_aux_domain = tsf_aux + start_tsf - tsf;
return 0;
}
@@ -1323,13 +1646,11 @@ static int rtw89_mcc_fill_config(struct rtw89_dev *rtwdev)
switch (mcc->mode) {
case RTW89_MCC_MODE_GO_STA:
- config->beacon_offset = RTW89_MCC_DFLT_BCN_OFST_TIME;
+ config->beacon_offset = rtw89_mcc_get_bcn_ofst(rtwdev);
if (ref->is_go) {
- rtw89_mcc_sync_tbtt(rtwdev, ref, aux, false);
config->mcc_interval = ref->beacon_interval;
rtw89_mcc_set_duration_go_sta(rtwdev, ref, aux);
} else {
- rtw89_mcc_sync_tbtt(rtwdev, aux, ref, true);
config->mcc_interval = aux->beacon_interval;
rtw89_mcc_set_duration_go_sta(rtwdev, aux, ref);
}
@@ -1359,22 +1680,20 @@ bottom:
static int __mcc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role)
{
+ const struct rtw89_mcc_courtesy_cfg *crtz = role->crtz;
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
- struct rtw89_mcc_config *config = &mcc->config;
- struct rtw89_mcc_pattern *pattern = &config->pattern;
- struct rtw89_mcc_courtesy *courtesy = &pattern->courtesy;
struct rtw89_mcc_policy *policy = &role->policy;
struct rtw89_fw_mcc_add_req req = {};
const struct rtw89_chan *chan;
int ret;
- chan = rtw89_chan_get(rtwdev, role->rtwvif->sub_entity_idx);
+ chan = rtw89_chan_get(rtwdev, role->rtwvif_link->chanctx_idx);
req.central_ch_seg0 = chan->channel;
req.primary_ch = chan->primary_channel;
req.bandwidth = chan->band_width;
req.ch_band_type = chan->band_type;
- req.macid = role->rtwvif->mac_id;
+ req.macid = role->rtwvif_link->mac_id;
req.group = mcc->group;
req.c2h_rpt = policy->c2h_rpt;
req.tx_null_early = policy->tx_null_early;
@@ -1385,9 +1704,9 @@ static int __mcc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *ro
req.duration = role->duration;
req.btc_in_2g = false;
- if (courtesy->enable && courtesy->macid_src == req.macid) {
- req.courtesy_target = courtesy->macid_tgt;
- req.courtesy_num = courtesy->slot_num;
+ if (crtz) {
+ req.courtesy_target = crtz->macid_tgt;
+ req.courtesy_num = crtz->slot_num;
req.courtesy_en = true;
}
@@ -1399,7 +1718,7 @@ static int __mcc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *ro
}
ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group,
- role->rtwvif->mac_id,
+ role->rtwvif_link->mac_id,
role->macid_bitmap);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
@@ -1426,7 +1745,7 @@ void __mrc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role,
slot_arg->duration = role->duration;
slot_arg->role_num = 1;
- chan = rtw89_chan_get(rtwdev, role->rtwvif->sub_entity_idx);
+ chan = rtw89_chan_get(rtwdev, role->rtwvif_link->chanctx_idx);
slot_arg->roles[0].role_type = RTW89_H2C_MRC_ROLE_WIFI;
slot_arg->roles[0].is_master = role == ref;
@@ -1436,7 +1755,7 @@ void __mrc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role,
slot_arg->roles[0].primary_ch = chan->primary_channel;
slot_arg->roles[0].en_tx_null = !policy->dis_tx_null;
slot_arg->roles[0].null_early = policy->tx_null_early;
- slot_arg->roles[0].macid = role->rtwvif->mac_id;
+ slot_arg->roles[0].macid = role->rtwvif_link->mac_id;
slot_arg->roles[0].macid_main_bitmap =
rtw89_mcc_role_fw_macid_bitmap_to_u32(role);
}
@@ -1547,7 +1866,7 @@ static int __mcc_fw_start(struct rtw89_dev *rtwdev, bool replace)
}
}
- req.macid = ref->rtwvif->mac_id;
+ req.macid = ref->rtwvif_link->mac_id;
req.tsf_high = config->start_tsf >> 32;
req.tsf_low = config->start_tsf;
@@ -1567,26 +1886,23 @@ static void __mrc_fw_add_courtesy(struct rtw89_dev *rtwdev,
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
struct rtw89_mcc_role *ref = &mcc->role_ref;
struct rtw89_mcc_role *aux = &mcc->role_aux;
- struct rtw89_mcc_config *config = &mcc->config;
- struct rtw89_mcc_pattern *pattern = &config->pattern;
- struct rtw89_mcc_courtesy *courtesy = &pattern->courtesy;
struct rtw89_fw_mrc_add_slot_arg *slot_arg_src;
- u8 slot_idx_tgt;
- if (!courtesy->enable)
- return;
-
- if (courtesy->macid_src == ref->rtwvif->mac_id) {
+ if (ref->crtz) {
slot_arg_src = &arg->slots[ref->slot_idx];
- slot_idx_tgt = aux->slot_idx;
- } else {
- slot_arg_src = &arg->slots[aux->slot_idx];
- slot_idx_tgt = ref->slot_idx;
+
+ slot_arg_src->courtesy_target = aux->slot_idx;
+ slot_arg_src->courtesy_period = ref->crtz->slot_num;
+ slot_arg_src->courtesy_en = true;
}
- slot_arg_src->courtesy_target = slot_idx_tgt;
- slot_arg_src->courtesy_period = courtesy->slot_num;
- slot_arg_src->courtesy_en = true;
+ if (aux->crtz) {
+ slot_arg_src = &arg->slots[aux->slot_idx];
+
+ slot_arg_src->courtesy_target = ref->slot_idx;
+ slot_arg_src->courtesy_period = aux->crtz->slot_num;
+ slot_arg_src->courtesy_en = true;
+ }
}
static int __mrc_fw_start(struct rtw89_dev *rtwdev, bool replace)
@@ -1695,9 +2011,9 @@ static int __mcc_fw_set_duration_no_bt(struct rtw89_dev *rtwdev, bool sync_chang
struct rtw89_fw_mcc_duration req = {
.group = mcc->group,
.btc_in_group = false,
- .start_macid = ref->rtwvif->mac_id,
- .macid_x = ref->rtwvif->mac_id,
- .macid_y = aux->rtwvif->mac_id,
+ .start_macid = ref->rtwvif_link->mac_id,
+ .macid_x = ref->rtwvif_link->mac_id,
+ .macid_y = aux->rtwvif_link->mac_id,
.duration_x = ref->duration,
.duration_y = aux->duration,
.start_tsf_high = config->start_tsf >> 32,
@@ -1786,30 +2102,24 @@ static void rtw89_mcc_handle_beacon_noa(struct rtw89_dev *rtwdev, bool enable)
struct rtw89_mcc_role *ref = &mcc->role_ref;
struct rtw89_mcc_role *aux = &mcc->role_aux;
struct rtw89_mcc_config *config = &mcc->config;
- struct rtw89_mcc_pattern *pattern = &config->pattern;
- struct rtw89_mcc_sync *sync = &config->sync;
struct ieee80211_p2p_noa_desc noa_desc = {};
- u64 start_time = config->start_tsf;
u32 interval = config->mcc_interval;
- struct rtw89_vif *rtwvif_go;
+ struct rtw89_vif_link *rtwvif_go;
+ u64 start_time;
u32 duration;
if (mcc->mode != RTW89_MCC_MODE_GO_STA)
return;
if (ref->is_go) {
- rtwvif_go = ref->rtwvif;
+ start_time = config->start_tsf;
+ rtwvif_go = ref->rtwvif_link;
start_time += ieee80211_tu_to_usec(ref->duration);
duration = config->mcc_interval - ref->duration;
} else if (aux->is_go) {
- rtwvif_go = aux->rtwvif;
- start_time += ieee80211_tu_to_usec(pattern->tob_ref) +
- ieee80211_tu_to_usec(config->beacon_offset) +
- ieee80211_tu_to_usec(pattern->toa_aux);
+ start_time = config->start_tsf_in_aux_domain;
+ rtwvif_go = aux->rtwvif_link;
duration = config->mcc_interval - aux->duration;
-
- /* convert time domain from sta(ref) to GO(aux) */
- start_time += ieee80211_tu_to_usec(sync->offset);
} else {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"MCC find no GO: skip updating beacon NoA\n");
@@ -1843,9 +2153,9 @@ static void rtw89_mcc_start_beacon_noa(struct rtw89_dev *rtwdev)
return;
if (ref->is_go)
- rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif, true);
+ rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif_link, true);
else if (aux->is_go)
- rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif, true);
+ rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif_link, true);
rtw89_mcc_handle_beacon_noa(rtwdev, true);
}
@@ -1860,9 +2170,9 @@ static void rtw89_mcc_stop_beacon_noa(struct rtw89_dev *rtwdev)
return;
if (ref->is_go)
- rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif, false);
+ rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif_link, false);
else if (aux->is_go)
- rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif, false);
+ rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif_link, false);
rtw89_mcc_handle_beacon_noa(rtwdev, false);
}
@@ -1912,22 +2222,78 @@ static int rtw89_mcc_start(struct rtw89_dev *rtwdev)
return 0;
}
-static void rtw89_mcc_stop(struct rtw89_dev *rtwdev)
+struct rtw89_mcc_stop_sel {
+ struct {
+ const struct rtw89_vif_link *target;
+ } hint;
+
+ /* selection content */
+ bool filled;
+ u8 mac_id;
+ u8 slot_idx;
+};
+
+static void rtw89_mcc_stop_sel_fill(struct rtw89_mcc_stop_sel *sel,
+ const struct rtw89_mcc_role *mcc_role)
+{
+ sel->mac_id = mcc_role->rtwvif_link->mac_id;
+ sel->slot_idx = mcc_role->slot_idx;
+ sel->filled = true;
+}
+
+static int rtw89_mcc_stop_sel_iterator(struct rtw89_dev *rtwdev,
+ struct rtw89_mcc_role *mcc_role,
+ unsigned int ordered_idx,
+ void *data)
+{
+ struct rtw89_mcc_stop_sel *sel = data;
+
+ if (mcc_role->rtwvif_link == sel->hint.target) {
+ rtw89_mcc_stop_sel_fill(sel, mcc_role);
+ return 1; /* break iteration */
+ }
+
+ if (sel->filled)
+ return 0;
+
+ if (!mcc_role->rtwvif_link->chanctx_assigned)
+ return 0;
+
+ rtw89_mcc_stop_sel_fill(sel, mcc_role);
+ return 0;
+}
+
+static void rtw89_mcc_stop(struct rtw89_dev *rtwdev,
+ const struct rtw89_chanctx_pause_parm *pause)
{
+ struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
struct rtw89_mcc_role *ref = &mcc->role_ref;
+ struct rtw89_mcc_stop_sel sel = {
+ .hint.target = pause ? pause->trigger : NULL,
+ };
int ret;
- rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC stop\n");
+ if (!pause) {
+ wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->chanctx_work);
+ bitmap_zero(hal->changes, NUM_OF_RTW89_CHANCTX_CHANGES);
+ }
+
+ /* by default, stop at ref */
+ rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_stop_sel_iterator, &sel);
+ if (!sel.filled)
+ rtw89_mcc_stop_sel_fill(&sel, ref);
+
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC stop at <macid %d>\n", sel.mac_id);
if (rtw89_concurrent_via_mrc(rtwdev)) {
- ret = rtw89_fw_h2c_mrc_del(rtwdev, mcc->group);
+ ret = rtw89_fw_h2c_mrc_del(rtwdev, mcc->group, sel.slot_idx);
if (ret)
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"MRC h2c failed to trigger del: %d\n", ret);
} else {
ret = rtw89_fw_h2c_stop_mcc(rtwdev, mcc->group,
- ref->rtwvif->mac_id, true);
+ sel.mac_id, true);
if (ret)
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"MCC h2c failed to trigger stop: %d\n", ret);
@@ -1948,6 +2314,7 @@ static int rtw89_mcc_update(struct rtw89_dev *rtwdev)
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
struct rtw89_mcc_config *config = &mcc->config;
struct rtw89_mcc_config old_cfg = *config;
+ bool courtesy_changed;
bool sync_changed;
int ret;
@@ -1960,8 +2327,15 @@ static int rtw89_mcc_update(struct rtw89_dev *rtwdev)
if (ret)
return ret;
+ if (memcmp(&old_cfg.pattern.courtesy, &config->pattern.courtesy,
+ sizeof(old_cfg.pattern.courtesy)) == 0)
+ courtesy_changed = false;
+ else
+ courtesy_changed = true;
+
if (old_cfg.pattern.plan != RTW89_MCC_PLAN_NO_BT ||
- config->pattern.plan != RTW89_MCC_PLAN_NO_BT) {
+ config->pattern.plan != RTW89_MCC_PLAN_NO_BT ||
+ courtesy_changed) {
if (rtw89_concurrent_via_mrc(rtwdev))
ret = __mrc_fw_start(rtwdev, true);
else
@@ -1993,7 +2367,7 @@ static void rtw89_mcc_track(struct rtw89_dev *rtwdev)
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
struct rtw89_mcc_config *config = &mcc->config;
struct rtw89_mcc_pattern *pattern = &config->pattern;
- s16 tolerance;
+ u16 tolerance;
u16 bcn_ofst;
u16 diff;
@@ -2001,18 +2375,25 @@ static void rtw89_mcc_track(struct rtw89_dev *rtwdev)
return;
bcn_ofst = rtw89_mcc_get_bcn_ofst(rtwdev);
+ if (bcn_ofst == config->beacon_offset)
+ return;
+
if (bcn_ofst > config->beacon_offset) {
diff = bcn_ofst - config->beacon_offset;
if (pattern->tob_aux < 0)
tolerance = -pattern->tob_aux;
- else
+ else if (pattern->toa_aux > 0)
tolerance = pattern->toa_aux;
+ else
+ return; /* no chance to improve */
} else {
diff = config->beacon_offset - bcn_ofst;
if (pattern->toa_aux < 0)
tolerance = -pattern->toa_aux;
- else
+ else if (pattern->tob_aux > 0)
tolerance = pattern->tob_aux;
+ else
+ return; /* no chance to improve */
}
if (diff <= tolerance)
@@ -2028,7 +2409,7 @@ static int __mcc_fw_upd_macid_bitmap(struct rtw89_dev *rtwdev,
int ret;
ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group,
- upd->rtwvif->mac_id,
+ upd->rtwvif_link->mac_id,
upd->macid_bitmap);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
@@ -2053,7 +2434,7 @@ static int __mrc_fw_upd_macid_bitmap(struct rtw89_dev *rtwdev,
int i;
arg.sch_idx = mcc->group;
- arg.macid = upd->rtwvif->mac_id;
+ arg.macid = upd->rtwvif_link->mac_id;
for (i = 0; i < 32; i++) {
if (add & BIT(i)) {
@@ -2091,7 +2472,7 @@ static int rtw89_mcc_upd_map_iterator(struct rtw89_dev *rtwdev,
void *data)
{
struct rtw89_mcc_role upd = {
- .rtwvif = mcc_role->rtwvif,
+ .rtwvif_link = mcc_role->rtwvif_link,
};
int ret;
@@ -2146,7 +2527,7 @@ static void rtw89_mcc_update_limit(struct rtw89_dev *rtwdev)
rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_upd_lmt_iterator, NULL);
}
-void rtw89_chanctx_work(struct work_struct *work)
+void rtw89_chanctx_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
chanctx_work.work);
@@ -2157,12 +2538,10 @@ void rtw89_chanctx_work(struct work_struct *work)
int ret;
int i;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(wiphy);
- if (hal->entity_pause) {
- mutex_unlock(&rtwdev->mutex);
+ if (hal->entity_pause)
return;
- }
for (i = 0; i < NUM_OF_RTW89_CHANCTX_CHANGES; i++) {
if (test_and_clear_bit(i, hal->changes))
@@ -2201,8 +2580,6 @@ void rtw89_chanctx_work(struct work_struct *work)
default:
break;
}
-
- mutex_unlock(&rtwdev->mutex);
}
void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
@@ -2233,8 +2610,8 @@ void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"queue chanctx work for mode %d with delay %d us\n",
mode, delay);
- ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->chanctx_work,
- usecs_to_jiffies(delay));
+ wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->chanctx_work,
+ usecs_to_jiffies(delay));
}
void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev)
@@ -2247,7 +2624,7 @@ void rtw89_chanctx_track(struct rtw89_dev *rtwdev)
struct rtw89_hal *hal = &rtwdev->hal;
enum rtw89_entity_mode mode;
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (hal->entity_pause)
return;
@@ -2263,22 +2640,22 @@ void rtw89_chanctx_track(struct rtw89_dev *rtwdev)
}
void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
- enum rtw89_chanctx_pause_reasons rsn)
+ const struct rtw89_chanctx_pause_parm *pause_parm)
{
struct rtw89_hal *hal = &rtwdev->hal;
enum rtw89_entity_mode mode;
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (hal->entity_pause)
return;
- rtw89_debug(rtwdev, RTW89_DBG_CHAN, "chanctx pause (rsn: %d)\n", rsn);
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, "chanctx pause (rsn: %d)\n", pause_parm->rsn);
mode = rtw89_get_entity_mode(rtwdev);
switch (mode) {
case RTW89_ENTITY_MODE_MCC:
- rtw89_mcc_stop(rtwdev);
+ rtw89_mcc_stop(rtwdev, pause_parm);
break;
default:
break;
@@ -2287,22 +2664,44 @@ void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
hal->entity_pause = true;
}
-void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev)
+static void rtw89_chanctx_proceed_cb(struct rtw89_dev *rtwdev,
+ const struct rtw89_chanctx_cb_parm *parm)
+{
+ int ret;
+
+ if (!parm || !parm->cb)
+ return;
+
+ ret = parm->cb(rtwdev, parm->data);
+ if (ret)
+ rtw89_warn(rtwdev, "%s (%s): cb failed: %d\n", __func__,
+ parm->caller ?: "unknown", ret);
+}
+
+/* pass @cb_parm if there is a @cb_parm->cb which needs to invoke right after
+ * call rtw89_set_channel() and right before proceed entity according to mode.
+ */
+void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev,
+ const struct rtw89_chanctx_cb_parm *cb_parm)
{
struct rtw89_hal *hal = &rtwdev->hal;
enum rtw89_entity_mode mode;
int ret;
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
- if (!hal->entity_pause)
+ if (unlikely(!hal->entity_pause)) {
+ rtw89_chanctx_proceed_cb(rtwdev, cb_parm);
return;
+ }
rtw89_debug(rtwdev, RTW89_DBG_CHAN, "chanctx proceed\n");
hal->entity_pause = false;
rtw89_set_channel(rtwdev);
+ rtw89_chanctx_proceed_cb(rtwdev, cb_parm);
+
mode = rtw89_get_entity_mode(rtwdev);
switch (mode) {
case RTW89_ENTITY_MODE_MCC:
@@ -2317,39 +2716,48 @@ void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev)
rtw89_queue_chanctx_work(rtwdev);
}
-static void rtw89_swap_sub_entity(struct rtw89_dev *rtwdev,
- enum rtw89_sub_entity_idx idx1,
- enum rtw89_sub_entity_idx idx2)
+static void __rtw89_swap_chanctx(struct rtw89_vif *rtwvif,
+ enum rtw89_chanctx_idx idx1,
+ enum rtw89_chanctx_idx idx2)
+{
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ if (!rtwvif_link->chanctx_assigned)
+ continue;
+
+ if (rtwvif_link->chanctx_idx == idx1)
+ rtwvif_link->chanctx_idx = idx2;
+ else if (rtwvif_link->chanctx_idx == idx2)
+ rtwvif_link->chanctx_idx = idx1;
+ }
+}
+
+static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev,
+ enum rtw89_chanctx_idx idx1,
+ enum rtw89_chanctx_idx idx2)
{
struct rtw89_hal *hal = &rtwdev->hal;
- struct rtw89_sub_entity tmp;
struct rtw89_vif *rtwvif;
u8 cur;
if (idx1 == idx2)
return;
- hal->sub[idx1].cfg->idx = idx2;
- hal->sub[idx2].cfg->idx = idx1;
+ hal->chanctx[idx1].cfg->idx = idx2;
+ hal->chanctx[idx2].cfg->idx = idx1;
- tmp = hal->sub[idx1];
- hal->sub[idx1] = hal->sub[idx2];
- hal->sub[idx2] = tmp;
+ swap(hal->chanctx[idx1], hal->chanctx[idx2]);
- rtw89_for_each_rtwvif(rtwdev, rtwvif) {
- if (!rtwvif->chanctx_assigned)
- continue;
- if (rtwvif->sub_entity_idx == idx1)
- rtwvif->sub_entity_idx = idx2;
- else if (rtwvif->sub_entity_idx == idx2)
- rtwvif->sub_entity_idx = idx1;
- }
+ rtw89_for_each_rtwvif(rtwdev, rtwvif)
+ __rtw89_swap_chanctx(rtwvif, idx1, idx2);
- cur = atomic_read(&hal->roc_entity_idx);
+ cur = atomic_read(&hal->roc_chanctx_idx);
if (cur == idx1)
- atomic_set(&hal->roc_entity_idx, idx2);
+ atomic_set(&hal->roc_chanctx_idx, idx2);
else if (cur == idx2)
- atomic_set(&hal->roc_entity_idx, idx1);
+ atomic_set(&hal->roc_chanctx_idx, idx1);
}
int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
@@ -2360,14 +2768,14 @@ int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
const struct rtw89_chip_info *chip = rtwdev->chip;
u8 idx;
- idx = find_first_zero_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
+ idx = find_first_zero_bit(hal->entity_map, NUM_OF_RTW89_CHANCTX);
if (idx >= chip->support_chanctx_num)
return -ENOENT;
rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
cfg->idx = idx;
cfg->ref_count = 0;
- hal->sub[idx].cfg = cfg;
+ hal->chanctx[idx].cfg = cfg;
return 0;
}
@@ -2394,77 +2802,107 @@ void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
}
int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
struct rtw89_entity_weight w = {};
+ int ret;
- rtwvif->sub_entity_idx = cfg->idx;
- rtwvif->chanctx_assigned = true;
+ rtwvif_link->chanctx_idx = cfg->idx;
+ rtwvif_link->chanctx_assigned = true;
cfg->ref_count++;
- if (cfg->idx == RTW89_SUB_ENTITY_0)
+ if (list_empty(&rtwvif->mgnt_entry))
+ list_add_tail(&rtwvif->mgnt_entry, &mgnt->active_list);
+
+ if (cfg->idx == RTW89_CHANCTX_0)
goto out;
rtw89_entity_calculate_weight(rtwdev, &w);
if (w.active_chanctxs != 1)
goto out;
- /* put the first active chanctx at RTW89_SUB_ENTITY_0 */
- rtw89_swap_sub_entity(rtwdev, cfg->idx, RTW89_SUB_ENTITY_0);
+ /* put the first active chanctx at RTW89_CHANCTX_0 */
+ rtw89_swap_chanctx(rtwdev, cfg->idx, RTW89_CHANCTX_0);
out:
- return rtw89_set_channel(rtwdev);
+ ret = rtw89_set_channel(rtwdev);
+ if (ret)
+ return ret;
+
+ rtw89_tas_reset(rtwdev, true);
+
+ return 0;
}
void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_hal *hal = &rtwdev->hal;
- struct rtw89_entity_weight w = {};
- enum rtw89_sub_entity_idx roll;
+ enum rtw89_chanctx_idx roll;
enum rtw89_entity_mode cur;
+ enum rtw89_entity_mode new;
+ int ret;
- rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0;
- rtwvif->chanctx_assigned = false;
+ rtwvif_link->chanctx_idx = RTW89_CHANCTX_0;
+ rtwvif_link->chanctx_assigned = false;
cfg->ref_count--;
+ if (!rtw89_vif_is_active_role(rtwvif))
+ list_del_init(&rtwvif->mgnt_entry);
+
if (cfg->ref_count != 0)
goto out;
- if (cfg->idx != RTW89_SUB_ENTITY_0)
+ if (cfg->idx != RTW89_CHANCTX_0)
goto out;
- roll = find_next_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY,
+ roll = find_next_bit(hal->entity_map, NUM_OF_RTW89_CHANCTX,
cfg->idx + 1);
/* Follow rtw89_config_default_chandef() when rtw89_entity_recalc(). */
- if (roll == NUM_OF_RTW89_SUB_ENTITY)
+ if (roll == NUM_OF_RTW89_CHANCTX)
goto out;
- /* RTW89_SUB_ENTITY_0 is going to release, and another exists.
- * Make another roll down to RTW89_SUB_ENTITY_0 to replace.
+ /* RTW89_CHANCTX_0 is going to release, and another exists.
+ * Make another roll down to RTW89_CHANCTX_0 to replace.
*/
- rtw89_swap_sub_entity(rtwdev, cfg->idx, roll);
+ rtw89_swap_chanctx(rtwdev, cfg->idx, roll);
out:
- rtw89_entity_calculate_weight(rtwdev, &w);
+ if (!hal->entity_pause) {
+ cur = rtw89_get_entity_mode(rtwdev);
+ switch (cur) {
+ case RTW89_ENTITY_MODE_MCC:
+ rtw89_mcc_stop(rtwdev, NULL);
+ break;
+ default:
+ break;
+ }
+ }
+
+ ret = rtw89_set_channel(rtwdev);
+ if (ret)
+ return;
- cur = rtw89_get_entity_mode(rtwdev);
- switch (cur) {
+ if (hal->entity_pause)
+ return;
+
+ new = rtw89_get_entity_mode(rtwdev);
+ switch (new) {
case RTW89_ENTITY_MODE_MCC:
- /* If still multi-roles, re-plan MCC for chanctx changes.
- * Otherwise, just stop MCC.
- */
- rtw89_mcc_stop(rtwdev);
- if (w.active_roles == NUM_OF_RTW89_MCC_ROLES)
- rtw89_mcc_start(rtwdev);
+ /* re-plan MCC for chanctx changes. */
+ ret = rtw89_mcc_start(rtwdev);
+ if (ret)
+ rtw89_warn(rtwdev, "failed to start MCC: %d\n", ret);
break;
default:
break;
}
-
- rtw89_set_channel(rtwdev);
}
diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h
index ffa412f281f3..2a25563593af 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.h
+++ b/drivers/net/wireless/realtek/rtw89/chan.h
@@ -31,6 +31,14 @@
#define RTW89_MCC_DFLT_TX_NULL_EARLY 3
#define RTW89_MCC_DFLT_COURTESY_SLOT 3
+#define RTW89_MCC_REQ_COURTESY_TIME 5
+#define RTW89_MCC_REQ_COURTESY(pattern, role) \
+({ \
+ const struct rtw89_mcc_pattern *p = pattern; \
+ p->tob_ ## role <= RTW89_MCC_REQ_COURTESY_TIME || \
+ p->toa_ ## role <= RTW89_MCC_REQ_COURTESY_TIME; \
+})
+
#define NUM_OF_RTW89_MCC_ROLES 2
enum rtw89_chanctx_pause_reasons {
@@ -38,23 +46,37 @@ enum rtw89_chanctx_pause_reasons {
RTW89_CHANCTX_PAUSE_REASON_ROC,
};
+struct rtw89_chanctx_pause_parm {
+ const struct rtw89_vif_link *trigger;
+ enum rtw89_chanctx_pause_reasons rsn;
+};
+
+struct rtw89_chanctx_cb_parm {
+ int (*cb)(struct rtw89_dev *rtwdev, void *data);
+ void *data;
+ const char *caller;
+};
+
struct rtw89_entity_weight {
unsigned int active_chanctxs;
unsigned int active_roles;
};
-static inline bool rtw89_get_entity_state(struct rtw89_dev *rtwdev)
+static inline bool rtw89_get_entity_state(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
{
struct rtw89_hal *hal = &rtwdev->hal;
- return READ_ONCE(hal->entity_active);
+ return READ_ONCE(hal->entity_active[phy_idx]);
}
-static inline void rtw89_set_entity_state(struct rtw89_dev *rtwdev, bool active)
+static inline void rtw89_set_entity_state(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx,
+ bool active)
{
struct rtw89_hal *hal = &rtwdev->hal;
- WRITE_ONCE(hal->entity_active, active);
+ WRITE_ONCE(hal->entity_active[phy_idx], active);
}
static inline
@@ -76,24 +98,37 @@ static inline void rtw89_set_entity_mode(struct rtw89_dev *rtwdev,
void rtw89_chan_create(struct rtw89_chan *chan, u8 center_chan, u8 primary_chan,
enum rtw89_band band, enum rtw89_bandwidth bandwidth);
bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
- enum rtw89_sub_entity_idx idx,
+ enum rtw89_chanctx_idx idx,
const struct rtw89_chan *new);
+int rtw89_iterate_entity_chan(struct rtw89_dev *rtwdev,
+ int (*iterator)(const struct rtw89_chan *chan,
+ void *data),
+ void *data);
void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
- enum rtw89_sub_entity_idx idx,
+ enum rtw89_chanctx_idx idx,
const struct cfg80211_chan_def *chandef);
void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
- enum rtw89_sub_entity_idx idx,
+ struct rtw89_vif_link *rtwvif_link,
const struct cfg80211_chan_def *chandef);
void rtw89_entity_init(struct rtw89_dev *rtwdev);
enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev);
-void rtw89_chanctx_work(struct work_struct *work);
+void rtw89_chanctx_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev);
void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_changes change);
void rtw89_chanctx_track(struct rtw89_dev *rtwdev);
void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
- enum rtw89_chanctx_pause_reasons rsn);
-void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev);
+ const struct rtw89_chanctx_pause_parm *parm);
+void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev,
+ const struct rtw89_chanctx_cb_parm *cb_parm);
+
+const struct rtw89_chan *__rtw89_mgnt_chan_get(struct rtw89_dev *rtwdev,
+ const char *caller_message,
+ u8 link_index);
+
+#define rtw89_mgnt_chan_get(rtwdev, link_index) \
+ __rtw89_mgnt_chan_get(rtwdev, __func__, link_index)
+
int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx);
void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
@@ -102,10 +137,10 @@ void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx,
u32 changed);
int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx);
void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index d9b66d43f32e..5ccf0cbaed2f 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -10,8 +10,9 @@
#include "ps.h"
#include "reg.h"
-#define RTW89_COEX_VERSION 0x07000113
+#define RTW89_COEX_VERSION 0x07000413
#define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/
+#define BTC_E2G_LIMIT_DEF 80
enum btc_fbtc_tdma_template {
CXTD_OFF = 0x0,
@@ -54,7 +55,6 @@ enum btc_mlme_state {
MLME_LINKED,
};
-#define FCXONESLOT_VER 1
struct btc_fbtc_1slot {
u8 fver;
u8 sid; /* slot id */
@@ -89,10 +89,10 @@ static const struct rtw89_btc_fbtc_slot s_def[] = {
[CXST_B4] = __DEF_FBTC_SLOT(50, 0xe5555555, SLOT_MIX),
[CXST_LK] = __DEF_FBTC_SLOT(20, 0xea5a5a5a, SLOT_ISO),
[CXST_BLK] = __DEF_FBTC_SLOT(500, 0x55555555, SLOT_MIX),
- [CXST_E2G] = __DEF_FBTC_SLOT(0, 0xea5a5a5a, SLOT_MIX),
- [CXST_E5G] = __DEF_FBTC_SLOT(0, 0xffffffff, SLOT_ISO),
- [CXST_EBT] = __DEF_FBTC_SLOT(0, 0xe5555555, SLOT_MIX),
- [CXST_ENULL] = __DEF_FBTC_SLOT(0, 0xaaaaaaaa, SLOT_ISO),
+ [CXST_E2G] = __DEF_FBTC_SLOT(5, 0xea5a5a5a, SLOT_MIX),
+ [CXST_E5G] = __DEF_FBTC_SLOT(5, 0xffffffff, SLOT_ISO),
+ [CXST_EBT] = __DEF_FBTC_SLOT(5, 0xe5555555, SLOT_MIX),
+ [CXST_ENULL] = __DEF_FBTC_SLOT(5, 0xaaaaaaaa, SLOT_ISO),
[CXST_WLK] = __DEF_FBTC_SLOT(250, 0xea5a5a5a, SLOT_MIX),
[CXST_W1FDD] = __DEF_FBTC_SLOT(50, 0xffffffff, SLOT_ISO),
[CXST_B1FDD] = __DEF_FBTC_SLOT(50, 0xffffdfff, SLOT_ISO),
@@ -125,79 +125,108 @@ static const u32 cxtbl[] = {
0xfafaaafa, /* 23 */
0xfafffaff, /* 24 */
0xea6a5a5a, /* 25 */
+ 0xfaff5aff, /* 26 */
+ 0xffffdfff, /* 27 */
+ 0xe6555555, /* 28 */
};
static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
/* firmware version must be in decreasing order for each chip */
+ {RTL8852BT, RTW89_FW_VER_CODE(0, 29, 122, 0),
+ .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7,
+ .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
+ .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
+ .fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
+ .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800,
+ .max_role_num = 6,
+ },
+ {RTL8852BT, RTW89_FW_VER_CODE(0, 29, 90, 0),
+ .fcxbtcrpt = 7, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7,
+ .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
+ .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
+ .fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
+ .fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800,
+ .max_role_num = 6,
+ },
{RTL8922A, RTW89_FW_VER_CODE(0, 35, 8, 0),
.fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7,
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
.fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
- .fwlrole = 2, .frptmap = 7, .fcxctrl = 7, .fcxinit = 7,
- .drvinfo_type = 1, .info_buf = 1800, .max_role_num = 6,
+ .fwlrole = 8, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
+ .fwevntrptl = 1, .fwc2hfunc = 1, .drvinfo_type = 1, .info_buf = 1800,
+ .max_role_num = 6,
},
{RTL8851B, RTW89_FW_VER_CODE(0, 29, 29, 0),
.fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
+ .max_role_num = 6,
},
{RTL8852C, RTW89_FW_VER_CODE(0, 27, 57, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
+ .max_role_num = 5,
},
{RTL8852C, RTW89_FW_VER_CODE(0, 27, 42, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0,
- .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
+ .max_role_num = 5,
},
{RTL8852C, RTW89_FW_VER_CODE(0, 27, 0, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0,
- .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
+ .max_role_num = 5,
},
{RTL8852B, RTW89_FW_VER_CODE(0, 29, 29, 0),
.fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
+ .max_role_num = 6,
},
{RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0),
.fcxbtcrpt = 5, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 4,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
+ .max_role_num = 6,
},
{RTL8852B, RTW89_FW_VER_CODE(0, 27, 0, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 1, .fcxctrl = 1, .fcxinit = 0,
- .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
+ .max_role_num = 5,
},
{RTL8852A, RTW89_FW_VER_CODE(0, 13, 37, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
- .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
+ .fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_type = 0, .info_buf = 1280,
+ .max_role_num = 5,
},
{RTL8852A, RTW89_FW_VER_CODE(0, 13, 0, 0),
.fcxbtcrpt = 1, .fcxtdma = 1, .fcxslots = 1, .fcxcysta = 2,
.fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0,
- .drvinfo_type = 0, .info_buf = 1024, .max_role_num = 5,
+ .fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_type = 0, .info_buf = 1024,
+ .max_role_num = 5,
},
/* keep it to be the last as default entry */
@@ -206,18 +235,53 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0,
- .drvinfo_type = 0, .info_buf = 1024, .max_role_num = 5,
+ .fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1024,
+ .max_role_num = 5,
},
};
#define RTW89_DEFAULT_BTC_VER_IDX (ARRAY_SIZE(rtw89_btc_ver_defs) - 1)
+static const union rtw89_btc_wl_state_map btc_scanning_map = {
+ .map = {
+ .scan = 1,
+ .connecting = 1,
+ .roaming = 1,
+ .dbccing = 1,
+ ._4way = 1,
+ },
+};
+
+static u32 chip_id_to_bt_rom_code_id(u32 id)
+{
+ switch (id) {
+ case RTL8852A:
+ case RTL8852B:
+ case RTL8852C:
+ case RTL8852BT:
+ return 0x8852;
+ case RTL8851B:
+ return 0x8851;
+ case RTL8922A:
+ return 0x8922;
+ default:
+ return 0;
+ }
+}
+
struct rtw89_btc_btf_tlv {
u8 type;
u8 len;
u8 val[];
} __packed;
+struct rtw89_btc_btf_tlv_v7 {
+ u8 type;
+ u8 ver;
+ u8 len;
+ u8 val[];
+} __packed;
+
enum btc_btf_set_report_en {
RPT_EN_TDMA,
RPT_EN_CYCLE,
@@ -235,13 +299,24 @@ enum btc_btf_set_report_en {
RPT_EN_MONITER,
};
-#define BTF_SET_REPORT_VER 1
-struct rtw89_btc_btf_set_report {
+struct rtw89_btc_btf_set_report_v1 {
u8 fver;
__le32 enable;
__le32 para;
} __packed;
+struct rtw89_btc_btf_set_report_v8 {
+ u8 type;
+ u8 fver;
+ u8 len;
+ __le32 map;
+} __packed;
+
+union rtw89_fbtc_rtp_ctrl {
+ struct rtw89_btc_btf_set_report_v1 v1;
+ struct rtw89_btc_btf_set_report_v8 v8;
+};
+
#define BTF_SET_SLOT_TABLE_VER 1
struct rtw89_btc_btf_set_slot_table {
u8 fver;
@@ -249,12 +324,31 @@ struct rtw89_btc_btf_set_slot_table {
struct rtw89_btc_fbtc_slot tbls[] __counted_by(tbl_num);
} __packed;
-struct rtw89_btc_btf_set_mon_reg {
+struct rtw89_btc_btf_set_slot_table_v7 {
+ u8 type;
+ u8 ver;
+ u8 len;
+ struct rtw89_btc_fbtc_slot_v7 v7[CXST_MAX];
+} __packed;
+
+struct rtw89_btc_btf_set_mon_reg_v1 {
u8 fver;
u8 reg_num;
struct rtw89_btc_fbtc_mreg regs[] __counted_by(reg_num);
} __packed;
+struct rtw89_btc_btf_set_mon_reg_v7 {
+ u8 type;
+ u8 fver;
+ u8 len;
+ struct rtw89_btc_fbtc_mreg regs[] __counted_by(len);
+} __packed;
+
+union rtw89_fbtc_set_mon_reg {
+ struct rtw89_btc_btf_set_mon_reg_v1 v1;
+ struct rtw89_btc_btf_set_mon_reg_v7 v7;
+} __packed;
+
struct _wl_rinfo_now {
u8 link_mode;
u32 dbcc_2g_phy: 2;
@@ -310,6 +404,7 @@ enum btc_ant_phase {
BTC_ANT_W25G,
BTC_ANT_FREERUN,
BTC_ANT_WRFK,
+ BTC_ANT_WRFK2,
BTC_ANT_BRFK,
BTC_ANT_MAX
};
@@ -614,6 +709,13 @@ enum btc_ctr_path {
BTC_CTRL_BY_WL
};
+enum btc_wlact_state {
+ BTC_WLACT_HW = 0,
+ BTC_WLACT_SW_LO,
+ BTC_WLACT_SW_HI,
+ BTC_WLACT_MAX,
+};
+
enum btc_wl_max_tx_time {
BTC_MAX_TX_TIME_L1 = 500,
BTC_MAX_TX_TIME_L2 = 1000,
@@ -739,7 +841,7 @@ static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type)
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_bt_info *bt = &btc->cx.bt;
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
- struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info;
+ struct rtw89_btc_wl_link_info *wl_linfo;
u8 i;
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s\n", __func__);
@@ -761,16 +863,31 @@ static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type)
if (type & BTC_RESET_DM) {
memset(&btc->dm, 0, sizeof(btc->dm));
memset(bt_linfo->rssi_state, 0, sizeof(bt_linfo->rssi_state));
-
- for (i = 0; i < RTW89_PORT_NUM; i++)
- memset(wl_linfo[i].rssi_state, 0,
- sizeof(wl_linfo[i].rssi_state));
+ for (i = 0; i < RTW89_PORT_NUM; i++) {
+ if (btc->ver->fwlrole == 8)
+ wl_linfo = &wl->rlink_info[i][0];
+ else
+ wl_linfo = &wl->link_info[i];
+ memset(wl_linfo->rssi_state, 0, sizeof(wl_linfo->rssi_state));
+ }
/* set the slot_now table to original */
btc->dm.tdma_now = t_def[CXTD_OFF];
btc->dm.tdma = t_def[CXTD_OFF];
- memcpy(&btc->dm.slot_now, s_def, sizeof(btc->dm.slot_now));
- memcpy(&btc->dm.slot, s_def, sizeof(btc->dm.slot));
+ if (ver->fcxslots >= 7) {
+ for (i = 0; i < ARRAY_SIZE(s_def); i++) {
+ btc->dm.slot.v7[i].dur = s_def[i].dur;
+ btc->dm.slot.v7[i].cxtype = s_def[i].cxtype;
+ btc->dm.slot.v7[i].cxtbl = s_def[i].cxtbl;
+ }
+ memcpy(&btc->dm.slot_now.v7, &btc->dm.slot.v7,
+ sizeof(btc->dm.slot_now.v7));
+ } else {
+ memcpy(&btc->dm.slot_now.v1, s_def,
+ sizeof(btc->dm.slot_now.v1));
+ memcpy(&btc->dm.slot.v1, s_def,
+ sizeof(btc->dm.slot.v1));
+ }
btc->policy_len = 0;
btc->bt_req_len = 0;
@@ -901,14 +1018,25 @@ static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 type, u32 cnt)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_cx *cx = &btc->cx;
- struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_bt_info *bt = &cx->bt;
+ struct rtw89_btc_wl_info *wl = &cx->wl;
+ struct rtw89_btc_dm *dm = &btc->dm;
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): type:%d cnt:%d\n",
__func__, type, cnt);
switch (type) {
+ case BTC_DCNT_WL_FW_VER_MATCH:
+ if ((wl->ver_info.fw_coex & 0xffff0000) !=
+ rtwdev->chip->wlcx_desired) {
+ wl->fw_ver_mismatch = true;
+ dm->error.map.wl_ver_mismatch = true;
+ } else {
+ wl->fw_ver_mismatch = false;
+ dm->error.map.wl_ver_mismatch = false;
+ }
+ break;
case BTC_DCNT_RPT_HANG:
if (dm->cnt_dm[BTC_DCNT_RPT] == cnt && btc->fwinfo.rpt_en_map)
dm->cnt_dm[BTC_DCNT_RPT_HANG]++;
@@ -1001,6 +1129,19 @@ static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 type, u32 cnt)
else
dm->error.map.slot_no_sync = false;
break;
+ case BTC_DCNT_BTTX_HANG:
+ cnt = cx->cnt_bt[BTC_BCNT_LOPRI_TX];
+
+ if (cnt == 0 && bt->link_info.slave_role)
+ dm->cnt_dm[BTC_DCNT_BTTX_HANG]++;
+ else
+ dm->cnt_dm[BTC_DCNT_BTTX_HANG] = 0;
+
+ if (dm->cnt_dm[BTC_DCNT_BTTX_HANG] >= BTC_CHK_HANG_MAX)
+ dm->error.map.bt_tx_hang = true;
+ else
+ dm->error.map.bt_tx_hang = false;
+ break;
case BTC_DCNT_BTCNT_HANG:
cnt = cx->cnt_bt[BTC_BCNT_HIPRI_RX] +
cx->cnt_bt[BTC_BCNT_HIPRI_TX] +
@@ -1050,27 +1191,36 @@ static void _update_bt_report(struct rtw89_dev *rtwdev, u8 rpt_type, u8 *pfinfo)
struct rtw89_btc_bt_info *bt = &btc->cx.bt;
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
struct rtw89_btc_bt_a2dp_desc *a2dp = &bt_linfo->a2dp_desc;
- struct rtw89_btc_fbtc_btver *pver = NULL;
- struct rtw89_btc_fbtc_btscan_v1 *pscan_v1;
- struct rtw89_btc_fbtc_btscan_v2 *pscan_v2;
- struct rtw89_btc_fbtc_btafh *pafh_v1 = NULL;
+ union rtw89_btc_fbtc_btver *pver = &btc->fwinfo.rpt_fbtc_btver.finfo;
struct rtw89_btc_fbtc_btafh_v2 *pafh_v2 = NULL;
+ struct rtw89_btc_fbtc_btafh_v7 *pafh_v7 = NULL;
struct rtw89_btc_fbtc_btdevinfo *pdev = NULL;
+ struct rtw89_btc_fbtc_btafh *pafh_v1 = NULL;
+ struct rtw89_btc_fbtc_btscan_v1 *pscan_v1;
+ struct rtw89_btc_fbtc_btscan_v2 *pscan_v2;
+ struct rtw89_btc_fbtc_btscan_v7 *pscan_v7;
bool scan_update = true;
int i;
- pver = (struct rtw89_btc_fbtc_btver *)pfinfo;
- pdev = (struct rtw89_btc_fbtc_btdevinfo *)pfinfo;
-
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): rpt_type:%d\n",
__func__, rpt_type);
switch (rpt_type) {
case BTC_RPT_TYPE_BT_VER:
- bt->ver_info.fw = le32_to_cpu(pver->fw_ver);
- bt->ver_info.fw_coex = le32_get_bits(pver->coex_ver, GENMASK(7, 0));
- bt->feature = le32_to_cpu(pver->feature);
+ if (ver->fcxbtver == 7) {
+ pver->v7 = *(struct rtw89_btc_fbtc_btver_v7 *)pfinfo;
+ bt->ver_info.fw = le32_to_cpu(pver->v7.fw_ver);
+ bt->ver_info.fw_coex = le32_get_bits(pver->v7.coex_ver,
+ GENMASK(7, 0));
+ bt->feature = le32_to_cpu(pver->v7.feature);
+ } else {
+ pver->v1 = *(struct rtw89_btc_fbtc_btver_v1 *)pfinfo;
+ bt->ver_info.fw = le32_to_cpu(pver->v1.fw_ver);
+ bt->ver_info.fw_coex = le32_get_bits(pver->v1.coex_ver,
+ GENMASK(7, 0));
+ bt->feature = le32_to_cpu(pver->v1.feature);
+ }
break;
case BTC_RPT_TYPE_BT_SCAN:
if (ver->fcxbtscan == 1) {
@@ -1090,6 +1240,15 @@ static void _update_bt_report(struct rtw89_dev *rtwdev, u8 rpt_type, u8 *pfinfo)
pscan_v2->para[i].intvl == 0)
scan_update = false;
}
+ } else if (ver->fcxbtscan == 7) {
+ pscan_v7 = (struct rtw89_btc_fbtc_btscan_v7 *)pfinfo;
+ for (i = 0; i < CXSCAN_MAX; i++) {
+ bt->scan_info_v2[i] = pscan_v7->para[i];
+ if ((pscan_v7->type & BIT(i)) &&
+ pscan_v7->para[i].win == 0 &&
+ pscan_v7->para[i].intvl == 0)
+ scan_update = false;
+ }
}
if (scan_update)
bt->scan_info_update = 1;
@@ -1106,6 +1265,17 @@ static void _update_bt_report(struct rtw89_dev *rtwdev, u8 rpt_type, u8 *pfinfo)
memcpy(&bt_linfo->afh_map_le[0], pafh_v2->afh_le_a, 4);
memcpy(&bt_linfo->afh_map_le[4], pafh_v2->afh_le_b, 1);
}
+ } else if (ver->fcxbtafh == 7) {
+ pafh_v7 = (struct rtw89_btc_fbtc_btafh_v7 *)pfinfo;
+ if (pafh_v7->map_type & RPT_BT_AFH_SEQ_LEGACY) {
+ memcpy(&bt_linfo->afh_map[0], pafh_v7->afh_l, 4);
+ memcpy(&bt_linfo->afh_map[4], pafh_v7->afh_m, 4);
+ memcpy(&bt_linfo->afh_map[8], pafh_v7->afh_h, 2);
+ }
+ if (pafh_v7->map_type & RPT_BT_AFH_SEQ_LE) {
+ memcpy(&bt_linfo->afh_map_le[0], pafh_v7->afh_le_a, 4);
+ memcpy(&bt_linfo->afh_map_le[4], pafh_v7->afh_le_b, 1);
+ }
} else if (ver->fcxbtafh == 1) {
pafh_v1 = (struct rtw89_btc_fbtc_btafh *)pfinfo;
memcpy(&bt_linfo->afh_map[0], pafh_v1->afh_l, 4);
@@ -1114,6 +1284,7 @@ static void _update_bt_report(struct rtw89_dev *rtwdev, u8 rpt_type, u8 *pfinfo)
}
break;
case BTC_RPT_TYPE_BT_DEVICE:
+ pdev = (struct rtw89_btc_fbtc_btdevinfo *)pfinfo;
a2dp->device_name = le32_to_cpu(pdev->dev_name);
a2dp->vendor_id = le16_to_cpu(pdev->vendor_id);
a2dp->flush_time = le32_to_cpu(pdev->flush_time);
@@ -1123,6 +1294,22 @@ static void _update_bt_report(struct rtw89_dev *rtwdev, u8 rpt_type, u8 *pfinfo)
}
}
+static void rtw89_btc_fw_rpt_evnt_ver(struct rtw89_dev *rtwdev, u8 *index)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ const struct rtw89_btc_ver *ver = btc->ver;
+
+ if (ver->fwevntrptl == 1)
+ return;
+
+ if (*index <= __BTC_RPT_TYPE_V0_SAME)
+ return;
+ else if (*index <= __BTC_RPT_TYPE_V0_MAX)
+ (*index)++;
+ else
+ *index = BTC_RPT_TYPE_MAX;
+}
+
#define BTC_LEAK_AP_TH 10
#define BTC_CYSTA_CHK_PERIOD 100
@@ -1147,10 +1334,10 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
struct rtw89_btc_prpt *btc_prpt = NULL;
void *rpt_content = NULL, *pfinfo = NULL;
u8 rpt_type = 0;
- u16 wl_slot_set = 0, wl_slot_real = 0;
+ u16 wl_slot_set = 0, wl_slot_real = 0, val16;
u32 trace_step = 0, rpt_len = 0, diff_t = 0;
u32 cnt_leak_slot, bt_slot_real, bt_slot_set, cnt_rx_imr;
- u8 i, val = 0;
+ u8 i, val = 0, val1, val2;
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): index:%d\n",
@@ -1170,6 +1357,8 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
"[BTC], %s(): rpt_type:%d\n",
__func__, rpt_type);
+ rtw89_btc_fw_rpt_evnt_ver(rtwdev, &rpt_type);
+
switch (rpt_type) {
case BTC_RPT_TYPE_CTRL:
pcinfo = &pfwinfo->rpt_ctrl.cinfo;
@@ -1188,6 +1377,12 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v105);
pcinfo->req_fver = 5;
break;
+ } else if (ver->fcxbtcrpt == 8) {
+ pfinfo = &pfwinfo->rpt_ctrl.finfo.v8;
+ pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v8);
+ } else if (ver->fcxbtcrpt == 7) {
+ pfinfo = &pfwinfo->rpt_ctrl.finfo.v7;
+ pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v7);
} else {
goto err;
}
@@ -1198,7 +1393,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
if (ver->fcxtdma == 1) {
pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v1;
pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v1);
- } else if (ver->fcxtdma == 3) {
+ } else if (ver->fcxtdma == 3 || ver->fcxtdma == 7) {
pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v3;
pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v3);
} else {
@@ -1208,8 +1403,15 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
break;
case BTC_RPT_TYPE_SLOT:
pcinfo = &pfwinfo->rpt_fbtc_slots.cinfo;
- pfinfo = &pfwinfo->rpt_fbtc_slots.finfo;
- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo);
+ if (ver->fcxslots == 1) {
+ pfinfo = &pfwinfo->rpt_fbtc_slots.finfo.v1;
+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo.v1);
+ } else if (ver->fcxslots == 7) {
+ pfinfo = &pfwinfo->rpt_fbtc_slots.finfo.v7;
+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo.v7);
+ } else {
+ goto err;
+ }
pcinfo->req_fver = ver->fcxslots;
break;
case BTC_RPT_TYPE_CYSTA:
@@ -1231,6 +1433,10 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v5;
pcysta->v5 = pfwinfo->rpt_fbtc_cysta.finfo.v5;
pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v5);
+ } else if (ver->fcxcysta == 7) {
+ pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v7;
+ pcysta->v7 = pfwinfo->rpt_fbtc_cysta.finfo.v7;
+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v7);
} else {
goto err;
}
@@ -1264,6 +1470,9 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
} else if (ver->fcxnullsta == 2) {
pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v2;
pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v2);
+ } else if (ver->fcxnullsta == 7) {
+ pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v7;
+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v7);
} else {
goto err;
}
@@ -1277,6 +1486,9 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
} else if (ver->fcxmreg == 2) {
pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v2;
pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v2);
+ } else if (ver->fcxmreg == 7) {
+ pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo.v7;
+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo.v7);
} else {
goto err;
}
@@ -1284,14 +1496,24 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
break;
case BTC_RPT_TYPE_GPIO_DBG:
pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo;
- pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo;
- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo);
+ if (ver->fcxgpiodbg == 7) {
+ pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo.v7;
+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo.v7);
+ } else {
+ pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo.v1;
+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo.v1);
+ }
pcinfo->req_fver = ver->fcxgpiodbg;
break;
case BTC_RPT_TYPE_BT_VER:
pcinfo = &pfwinfo->rpt_fbtc_btver.cinfo;
- pfinfo = &pfwinfo->rpt_fbtc_btver.finfo;
- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo);
+ if (ver->fcxbtver == 1) {
+ pfinfo = &pfwinfo->rpt_fbtc_btver.finfo.v1;
+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo.v1);
+ } else if (ver->fcxbtver == 7) {
+ pfinfo = &pfwinfo->rpt_fbtc_btver.finfo.v7;
+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo.v7);
+ }
pcinfo->req_fver = ver->fcxbtver;
break;
case BTC_RPT_TYPE_BT_SCAN:
@@ -1302,6 +1524,11 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
} else if (ver->fcxbtscan == 2) {
pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v2;
pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v2);
+ } else if (ver->fcxbtscan == 7) {
+ pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo.v7;
+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo.v7);
+ } else {
+ goto err;
}
pcinfo->req_fver = ver->fcxbtscan;
break;
@@ -1313,6 +1540,9 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
} else if (ver->fcxbtafh == 2) {
pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v2;
pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v2);
+ } else if (ver->fcxbtafh == 7) {
+ pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v7;
+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v7);
} else {
goto err;
}
@@ -1381,7 +1611,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
wl->ver_info.fw = le32_to_cpu(prpt->v4.wl_fw_info.fw_ver);
dm->wl_fw_cx_offload = !!le32_to_cpu(prpt->v4.wl_fw_info.cx_offload);
- for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++)
+ for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++)
memcpy(&dm->gnt.band[i], &prpt->v4.gnt_val[i],
sizeof(dm->gnt.band[i]));
@@ -1413,7 +1643,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
wl->ver_info.fw = le32_to_cpu(prpt->v5.rpt_info.fw_ver);
dm->wl_fw_cx_offload = 0;
- for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++)
+ for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++)
memcpy(&dm->gnt.band[i], &prpt->v5.gnt_val[i][0],
sizeof(dm->gnt.band[i]));
@@ -1440,7 +1670,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
wl->ver_info.fw = le32_to_cpu(prpt->v105.rpt_info.fw_ver);
dm->wl_fw_cx_offload = 0;
- for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++)
+ for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++)
memcpy(&dm->gnt.band[i], &prpt->v105.gnt_val[i][0],
sizeof(dm->gnt.band[i]));
@@ -1460,6 +1690,76 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
pfwinfo->event[BTF_EVNT_RPT]);
dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout;
+ } else if (ver->fcxbtcrpt == 7) {
+ prpt->v7 = pfwinfo->rpt_ctrl.finfo.v7;
+ pfwinfo->rpt_en_map = le32_to_cpu(prpt->v7.rpt_info.en);
+ wl->ver_info.fw_coex = le32_to_cpu(prpt->v7.rpt_info.cx_ver);
+ wl->ver_info.fw = le32_to_cpu(prpt->v7.rpt_info.fw_ver);
+
+ for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++)
+ memcpy(&dm->gnt.band[i], &prpt->v7.gnt_val[i][0],
+ sizeof(dm->gnt.band[i]));
+
+ btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] =
+ le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_HI_TX_V105]);
+ btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] =
+ le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_HI_RX_V105]);
+ btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] =
+ le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_LO_TX_V105]);
+ btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] =
+ le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_LO_RX_V105]);
+
+ val1 = le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_POLLUTED_V105]);
+ if (val1 > btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW])
+ val1 -= btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW]; /* diff */
+
+ btc->cx.cnt_bt[BTC_BCNT_POLUT_DIFF] = val1;
+ btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW] =
+ le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_POLLUTED_V105]);
+
+ val1 = pfwinfo->event[BTF_EVNT_RPT];
+ _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
+ _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, val1);
+ _chk_btc_err(rtwdev, BTC_DCNT_WL_FW_VER_MATCH, 0);
+ _chk_btc_err(rtwdev, BTC_DCNT_BTTX_HANG, 0);
+ } else if (ver->fcxbtcrpt == 8) {
+ prpt->v8 = pfwinfo->rpt_ctrl.finfo.v8;
+ pfwinfo->rpt_en_map = le32_to_cpu(prpt->v8.rpt_info.en);
+ wl->ver_info.fw_coex = le32_to_cpu(prpt->v8.rpt_info.cx_ver);
+ wl->ver_info.fw = le32_to_cpu(prpt->v8.rpt_info.fw_ver);
+
+ for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++)
+ memcpy(&dm->gnt.band[i], &prpt->v8.gnt_val[i][0],
+ sizeof(dm->gnt.band[i]));
+
+ btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] =
+ le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_HI_TX_V105]);
+ btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] =
+ le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_HI_RX_V105]);
+ btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] =
+ le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_LO_TX_V105]);
+ btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] =
+ le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_LO_RX_V105]);
+
+ val1 = le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_POLLUTED_V105]);
+ if (val1 > btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW])
+ val1 -= btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW]; /* diff */
+
+ btc->cx.cnt_bt[BTC_BCNT_POLUT_DIFF] = val1;
+ btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW] =
+ le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_POLLUTED_V105]);
+
+ val1 = pfwinfo->event[BTF_EVNT_RPT];
+ if (((prpt->v8.rpt_len_max_h << 8) +
+ prpt->v8.rpt_len_max_l) != ver->info_buf)
+ dm->error.map.h2c_c2h_buffer_mismatch = true;
+ else
+ dm->error.map.h2c_c2h_buffer_mismatch = false;
+
+ _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
+ _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, val1);
+ _chk_btc_err(rtwdev, BTC_DCNT_WL_FW_VER_MATCH, 0);
+ _chk_btc_err(rtwdev, BTC_DCNT_BTTX_HANG, 0);
} else {
goto err;
}
@@ -1474,7 +1774,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
memcmp(&dm->tdma_now,
&pfwinfo->rpt_fbtc_tdma.finfo.v1,
sizeof(dm->tdma_now)));
- else if (ver->fcxtdma == 3)
+ else if (ver->fcxtdma == 3 || ver->fcxtdma == 7)
_chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC,
memcmp(&dm->tdma_now,
&pfwinfo->rpt_fbtc_tdma.finfo.v3.tdma,
@@ -1483,14 +1783,25 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
goto err;
break;
case BTC_RPT_TYPE_SLOT:
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): check %d %zu\n",
- __func__, BTC_DCNT_SLOT_NONSYNC,
- sizeof(dm->slot_now));
- _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC,
- memcmp(dm->slot_now,
- pfwinfo->rpt_fbtc_slots.finfo.slot,
- sizeof(dm->slot_now)));
+ if (ver->fcxslots == 7) {
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s(): check %d %zu\n",
+ __func__, BTC_DCNT_SLOT_NONSYNC,
+ sizeof(dm->slot_now.v7));
+ _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC,
+ memcmp(dm->slot_now.v7,
+ pfwinfo->rpt_fbtc_slots.finfo.v7.slot,
+ sizeof(dm->slot_now.v7)));
+ } else if (ver->fcxslots == 1) {
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s(): check %d %zu\n",
+ __func__, BTC_DCNT_SLOT_NONSYNC,
+ sizeof(dm->slot_now.v1));
+ _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC,
+ memcmp(dm->slot_now.v1,
+ pfwinfo->rpt_fbtc_slots.finfo.v1.slot,
+ sizeof(dm->slot_now.v1)));
+ }
break;
case BTC_RPT_TYPE_CYSTA:
if (ver->fcxcysta == 2) {
@@ -1506,10 +1817,17 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
/* Check diff time between WL slot and W1/E2G slot */
if (dm->tdma_now.type == CXTDMA_OFF &&
- dm->tdma_now.ext_ctrl == CXECTL_EXT)
- wl_slot_set = le16_to_cpu(dm->slot_now[CXST_E2G].dur);
- else
- wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur);
+ dm->tdma_now.ext_ctrl == CXECTL_EXT) {
+ if (ver->fcxslots == 1)
+ wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_E2G].dur);
+ else if (ver->fcxslots == 7)
+ wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_E2G].dur);
+ } else {
+ if (ver->fcxslots == 1)
+ wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur);
+ else if (ver->fcxslots == 7)
+ wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur);
+ }
if (le16_to_cpu(pcysta->v2.tavg_cycle[CXT_WL]) > wl_slot_set) {
diff_t = le16_to_cpu(pcysta->v2.tavg_cycle[CXT_WL]) - wl_slot_set;
@@ -1539,7 +1857,10 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
/* Check diff time between real WL slot and W1 slot */
if (dm->tdma_now.type == CXTDMA_OFF) {
- wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur);
+ if (ver->fcxslots == 1)
+ wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur);
+ else if (ver->fcxslots == 7)
+ wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur);
wl_slot_real = le16_to_cpu(pcysta->v3.cycle_time.tavg[CXT_WL]);
if (wl_slot_real > wl_slot_set) {
diff_t = wl_slot_real - wl_slot_set;
@@ -1580,7 +1901,10 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
/* Check diff time between real WL slot and W1 slot */
if (dm->tdma_now.type == CXTDMA_OFF) {
- wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur);
+ if (ver->fcxslots == 1)
+ wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur);
+ else if (ver->fcxslots == 7)
+ wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur);
wl_slot_real = le16_to_cpu(pcysta->v4.cycle_time.tavg[CXT_WL]);
if (wl_slot_real > wl_slot_set) {
diff_t = wl_slot_real - wl_slot_set;
@@ -1622,7 +1946,10 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
/* Check diff time between real WL slot and W1 slot */
if (dm->tdma_now.type == CXTDMA_OFF) {
- wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur);
+ if (ver->fcxslots == 1)
+ wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur);
+ else if (ver->fcxslots == 7)
+ wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur);
wl_slot_real = le16_to_cpu(pcysta->v5.cycle_time.tavg[CXT_WL]);
if (wl_slot_real > wl_slot_set)
@@ -1654,11 +1981,62 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
le16_to_cpu(pcysta->v5.slot_cnt[CXST_B1]));
_chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG,
le16_to_cpu(pcysta->v5.cycles));
+ } else if (ver->fcxcysta == 7) {
+ if (dm->fddt_train == BTC_FDDT_ENABLE)
+ break;
+
+ pcysta = &pfwinfo->rpt_fbtc_cysta.finfo;
+
+ if (dm->tdma_now.type != CXTDMA_OFF) {
+ /* Check diff time between real WL slot and W1 slot */
+ val16 = le16_to_cpu(pcysta->v7.cycle_time.tavg[CXT_WL]);
+ _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, val16);
+
+ /* Check Leak-AP */
+ val1 = le32_to_cpu(pcysta->v7.leak_slot.cnt_rximr) *
+ BTC_LEAK_AP_TH;
+ val2 = le16_to_cpu(pcysta->v7.slot_cnt[CXST_LK]);
+
+ val16 = le16_to_cpu(pcysta->v7.cycles);
+ if (dm->tdma_now.rxflctrl &&
+ val16 >= BTC_CYSTA_CHK_PERIOD && val1 > val2)
+ dm->leak_ap = 1;
+ } else if (dm->tdma_now.ext_ctrl == CXECTL_EXT) {
+ val16 = le16_to_cpu(pcysta->v7.cycle_time.tavg[CXT_BT]);
+ /* Check diff between real BT slot and EBT/E5G slot */
+ _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, val16);
+
+ /* Check bt slot length for P2P mode*/
+ val1 = le16_to_cpu(pcysta->v7.a2dp_ept.cnt_timeout) *
+ BTC_SLOT_REQ_TH;
+ val2 = le16_to_cpu(pcysta->v7.a2dp_ept.cnt);
+
+ val16 = le16_to_cpu(pcysta->v7.cycles);
+ if (val16 >= BTC_CYSTA_CHK_PERIOD && val1 > val2)
+ dm->slot_req_more = 1;
+ else if (bt->link_info.status.map.connect == 0)
+ dm->slot_req_more = 0;
+ }
+
+ _chk_btc_err(rtwdev, BTC_DCNT_E2G_HANG,
+ le16_to_cpu(pcysta->v7.slot_cnt[CXST_E2G]));
+ _chk_btc_err(rtwdev, BTC_DCNT_W1_HANG,
+ le16_to_cpu(pcysta->v7.slot_cnt[CXST_W1]));
+ _chk_btc_err(rtwdev, BTC_DCNT_B1_HANG,
+ le16_to_cpu(pcysta->v7.slot_cnt[CXST_B1]));
+
+ /* "BT_SLOT_FLOOD" error-check MUST before "CYCLE_HANG" */
+ _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_FLOOD,
+ le16_to_cpu(pcysta->v7.cycles));
+ _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_HANG,
+ le16_to_cpu(pcysta->v7.cycles));
} else {
goto err;
}
break;
case BTC_RPT_TYPE_MREG:
+ if (ver->fcxmreg == 7)
+ break;
_get_reg_status(rtwdev, BTC_CSTATUS_BB_GNT_MUX_MON, &val);
if (dm->wl_btg_rx == BTC_BTGCTRL_BB_GNT_FWCTRL)
dm->wl_btg_rx_rb = BTC_BTGCTRL_BB_GNT_FWCTRL;
@@ -1715,6 +2093,7 @@ static void _parse_btc_report(struct rtw89_dev *rtwdev,
}
#define BTC_TLV_HDR_LEN 2
+#define BTC_TLV_HDR_LEN_V7 3
static void _append_tdma(struct rtw89_dev *rtwdev)
{
@@ -1722,6 +2101,7 @@ static void _append_tdma(struct rtw89_dev *rtwdev)
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_btf_tlv *tlv;
+ struct rtw89_btc_btf_tlv_v7 *tlv_v7;
struct rtw89_btc_fbtc_tdma *v;
struct rtw89_btc_fbtc_tdma_v3 *v3;
u16 len = btc->policy_len;
@@ -1741,6 +2121,13 @@ static void _append_tdma(struct rtw89_dev *rtwdev)
tlv->len = sizeof(*v);
*v = dm->tdma;
btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v);
+ } else if (ver->fcxtdma == 7) {
+ tlv_v7 = (struct rtw89_btc_btf_tlv_v7 *)&btc->policy[len];
+ tlv_v7->len = sizeof(dm->tdma);
+ tlv_v7->ver = ver->fcxtdma;
+ tlv_v7->type = CXPOLICY_TDMA;
+ memcpy(tlv_v7->val, &dm->tdma, tlv_v7->len);
+ btc->policy_len += BTC_TLV_HDR_LEN_V7 + tlv_v7->len;
} else {
tlv->len = sizeof(*v3);
v3 = (struct rtw89_btc_fbtc_tdma_v3 *)&tlv->val[0];
@@ -1756,7 +2143,7 @@ static void _append_tdma(struct rtw89_dev *rtwdev)
dm->tdma.ext_ctrl);
}
-static void _append_slot(struct rtw89_dev *rtwdev)
+static void _append_slot_v1(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &btc->dm;
@@ -1771,8 +2158,8 @@ static void _append_slot(struct rtw89_dev *rtwdev)
for (i = 0; i < CXST_MAX; i++) {
if (!btc->update_policy_force &&
- !memcmp(&dm->slot[i], &dm->slot_now[i],
- sizeof(dm->slot[i])))
+ !memcmp(&dm->slot.v1[i], &dm->slot_now.v1[i],
+ sizeof(dm->slot.v1[i])))
continue;
len = btc->policy_len;
@@ -1782,14 +2169,14 @@ static void _append_slot(struct rtw89_dev *rtwdev)
tlv->type = CXPOLICY_SLOT;
tlv->len = sizeof(*v);
- v->fver = FCXONESLOT_VER;
+ v->fver = btc->ver->fcxslots;
v->sid = i;
- v->slot = dm->slot[i];
+ v->slot = dm->slot.v1[i];
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): slot-%d: dur=%d, table=0x%08x, type=%d\n",
- __func__, i, dm->slot[i].dur, dm->slot[i].cxtbl,
- dm->slot[i].cxtype);
+ __func__, i, dm->slot.v1[i].dur, dm->slot.v1[i].cxtbl,
+ dm->slot.v1[i].cxtype);
cnt++;
btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v);
@@ -1801,6 +2188,71 @@ static void _append_slot(struct rtw89_dev *rtwdev)
__func__, cnt);
}
+static void _append_slot_v7(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_btc_btf_tlv_v7 *tlv = NULL;
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ u8 i, cnt = 0;
+ u16 len;
+
+ for (i = 0; i < CXST_MAX; i++) {
+ if (!btc->update_policy_force &&
+ !memcmp(&dm->slot.v7[i], &dm->slot_now.v7[i],
+ sizeof(dm->slot.v7[i])))
+ continue;
+
+ len = btc->policy_len;
+
+ if (!tlv) {
+ if ((len + BTC_TLV_HDR_LEN_V7) > RTW89_BTC_POLICY_MAXLEN) {
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s(): buff overflow!\n", __func__);
+ break;
+ }
+
+ tlv = (struct rtw89_btc_btf_tlv_v7 *)&btc->policy[len];
+ tlv->type = CXPOLICY_SLOT;
+ tlv->ver = btc->ver->fcxslots;
+ tlv->len = sizeof(dm->slot.v7[0]) + BTC_TLV_SLOT_ID_LEN_V7;
+ len += BTC_TLV_HDR_LEN_V7;
+ }
+
+ if ((len + (u16)tlv->len) > RTW89_BTC_POLICY_MAXLEN) {
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s(): buff overflow!\n", __func__);
+ break;
+ }
+
+ btc->policy[len] = i; /* slot-id */
+ memcpy(&btc->policy[len + 1], &dm->slot.v7[i],
+ sizeof(dm->slot.v7[0]));
+ len += tlv->len;
+
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s: policy_len=%d, slot-%d: dur=%d, type=%d, table=0x%08x\n",
+ __func__, btc->policy_len, i, dm->slot.v7[i].dur,
+ dm->slot.v7[i].cxtype, dm->slot.v7[i].cxtbl);
+ cnt++;
+ btc->policy_len = len; /* update total length */
+ }
+
+ if (cnt > 0)
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s: slot update (cnt=%d, len=%d)!!\n",
+ __func__, cnt, btc->policy_len);
+}
+
+static void _append_slot(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+
+ if (btc->ver->fcxslots == 7)
+ _append_slot_v7(rtwdev);
+ else
+ _append_slot_v1(rtwdev);
+}
+
static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map)
{
struct rtw89_btc *btc = &rtwdev->btc;
@@ -1946,13 +2398,52 @@ static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map)
return bit_map;
}
+static void rtw89_btc_fw_set_slots(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ const struct rtw89_btc_ver *ver = btc->ver;
+ struct rtw89_btc_btf_tlv_v7 *tlv_v7 = NULL;
+ struct rtw89_btc_btf_set_slot_table *tbl;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ u16 n, len;
+
+ if (ver->fcxslots == 7) {
+ len = sizeof(*tlv_v7) + sizeof(dm->slot.v7);
+ tlv_v7 = kmalloc(len, GFP_KERNEL);
+ if (!tlv_v7)
+ return;
+
+ tlv_v7->type = SET_SLOT_TABLE;
+ tlv_v7->ver = ver->fcxslots;
+ tlv_v7->len = ARRAY_SIZE(dm->slot.v7);
+ memcpy(tlv_v7->val, dm->slot.v7, sizeof(dm->slot.v7));
+
+ _send_fw_cmd(rtwdev, BTFC_SET, SET_SLOT_TABLE, (u8 *)tlv_v7, len);
+
+ kfree(tlv_v7);
+ } else {
+ n = struct_size(tbl, tbls, CXST_MAX);
+ tbl = kmalloc(n, GFP_KERNEL);
+ if (!tbl)
+ return;
+
+ tbl->fver = BTF_SET_SLOT_TABLE_VER;
+ tbl->tbl_num = CXST_MAX;
+ memcpy(tbl->tbls, dm->slot.v1, flex_array_size(tbl, tbls, CXST_MAX));
+
+ _send_fw_cmd(rtwdev, BTFC_SET, SET_SLOT_TABLE, tbl, n);
+
+ kfree(tbl);
+ }
+}
+
static void rtw89_btc_fw_en_rpt(struct rtw89_dev *rtwdev,
u32 rpt_map, bool rpt_state)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_smap *wl_smap = &btc->cx.wl.status.map;
struct rtw89_btc_btf_fwinfo *fwinfo = &btc->fwinfo;
- struct rtw89_btc_btf_set_report r = {0};
+ union rtw89_fbtc_rtp_ctrl r;
u32 val, bit_map;
int ret;
@@ -1973,41 +2464,35 @@ static void rtw89_btc_fw_en_rpt(struct rtw89_dev *rtwdev,
if (val == fwinfo->rpt_en_map)
return;
- r.fver = BTF_SET_REPORT_VER;
- r.enable = cpu_to_le32(val);
- r.para = cpu_to_le32(rpt_state);
+ if (btc->ver->fcxbtcrpt == 7 || btc->ver->fcxbtcrpt == 8) {
+ r.v8.type = SET_REPORT_EN;
+ r.v8.fver = btc->ver->fcxbtcrpt;
+ r.v8.len = sizeof(r.v8.map);
+ r.v8.map = cpu_to_le32(val);
+ ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_REPORT_EN, &r.v8,
+ sizeof(r.v8));
+ } else {
+ if (btc->ver->fcxbtcrpt == 105)
+ r.v1.fver = 5;
+ else
+ r.v1.fver = btc->ver->fcxbtcrpt;
+ r.v1.enable = cpu_to_le32(val);
+ r.v1.para = cpu_to_le32(rpt_state);
+ ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_REPORT_EN, &r.v1,
+ sizeof(r.v1));
+ }
- ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_REPORT_EN, &r, sizeof(r));
if (!ret)
fwinfo->rpt_en_map = val;
}
-static void rtw89_btc_fw_set_slots(struct rtw89_dev *rtwdev, u8 num,
- struct rtw89_btc_fbtc_slot *s)
-{
- struct rtw89_btc_btf_set_slot_table *tbl;
- u16 n;
-
- n = struct_size(tbl, tbls, num);
- tbl = kmalloc(n, GFP_KERNEL);
- if (!tbl)
- return;
-
- tbl->fver = BTF_SET_SLOT_TABLE_VER;
- tbl->tbl_num = num;
- memcpy(tbl->tbls, s, flex_array_size(tbl, tbls, num));
-
- _send_fw_cmd(rtwdev, BTFC_SET, SET_SLOT_TABLE, tbl, n);
-
- kfree(tbl);
-}
-
static void btc_fw_set_monreg(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_btc_ver *ver = rtwdev->btc.ver;
- struct rtw89_btc_btf_set_mon_reg *monreg = NULL;
- u8 n, ulen, cxmreg_max;
+ struct rtw89_btc_btf_set_mon_reg_v1 *v1 = NULL;
+ struct rtw89_btc_btf_set_mon_reg_v7 *v7 = NULL;
+ u8 i, n, ulen, cxmreg_max;
u16 sz = 0;
n = chip->mon_reg_num;
@@ -2016,10 +2501,8 @@ static void btc_fw_set_monreg(struct rtw89_dev *rtwdev)
if (ver->fcxmreg == 1)
cxmreg_max = CXMREG_MAX;
- else if (ver->fcxmreg == 2)
- cxmreg_max = CXMREG_MAX_V2;
else
- return;
+ cxmreg_max = CXMREG_MAX_V2;
if (n > cxmreg_max) {
rtw89_debug(rtwdev, RTW89_DBG_BTC,
@@ -2028,21 +2511,41 @@ static void btc_fw_set_monreg(struct rtw89_dev *rtwdev)
return;
}
- ulen = sizeof(monreg->regs[0]);
- sz = struct_size(monreg, regs, n);
- monreg = kmalloc(sz, GFP_KERNEL);
- if (!monreg)
- return;
+ ulen = sizeof(struct rtw89_btc_fbtc_mreg);
+
+ if (ver->fcxmreg == 7) {
+ sz = struct_size(v7, regs, n);
+ v7 = kmalloc(sz, GFP_KERNEL);
+ if (!v7)
+ return;
+ v7->type = RPT_EN_MREG;
+ v7->fver = ver->fcxmreg;
+ v7->len = n;
+ for (i = 0; i < n; i++) {
+ v7->regs[i].type = chip->mon_reg[i].type;
+ v7->regs[i].bytes = chip->mon_reg[i].bytes;
+ v7->regs[i].offset = chip->mon_reg[i].offset;
+ }
+
+ _send_fw_cmd(rtwdev, BTFC_SET, SET_MREG_TABLE, v7, sz);
+ kfree(v7);
+ } else {
+ sz = struct_size(v1, regs, n);
+ v1 = kmalloc(sz, GFP_KERNEL);
+ if (!v1)
+ return;
+ v1->fver = ver->fcxmreg;
+ v1->reg_num = n;
+ memcpy(v1->regs, chip->mon_reg, flex_array_size(v1, regs, n));
+
+ _send_fw_cmd(rtwdev, BTFC_SET, SET_MREG_TABLE, v1, sz);
+ kfree(v1);
+ }
- monreg->fver = ver->fcxmreg;
- monreg->reg_num = n;
- memcpy(monreg->regs, chip->mon_reg, flex_array_size(monreg, regs, n));
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): sz=%d ulen=%d n=%d\n",
__func__, sz, ulen, n);
- _send_fw_cmd(rtwdev, BTFC_SET, SET_MREG_TABLE, (u8 *)monreg, sz);
- kfree(monreg);
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, 1);
}
@@ -2100,7 +2603,10 @@ static void _fw_set_policy(struct rtw89_dev *rtwdev, u16 policy_type,
btc->policy, btc->policy_len);
if (!ret) {
memcpy(&dm->tdma_now, &dm->tdma, sizeof(dm->tdma_now));
- memcpy(&dm->slot_now, &dm->slot, sizeof(dm->slot_now));
+ if (btc->ver->fcxslots == 7)
+ memcpy(&dm->slot_now.v7, &dm->slot.v7, sizeof(dm->slot_now.v7));
+ else
+ memcpy(&dm->slot_now.v1, &dm->slot.v1, sizeof(dm->slot_now.v1));
}
if (btc->update_policy_force)
@@ -2132,6 +2638,10 @@ static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 type)
rtw89_fw_h2c_cxdrv_role_v1(rtwdev, type);
else if (ver->fwlrole == 2)
rtw89_fw_h2c_cxdrv_role_v2(rtwdev, type);
+ else if (ver->fwlrole == 7)
+ rtw89_fw_h2c_cxdrv_role_v7(rtwdev, type);
+ else if (ver->fwlrole == 8)
+ rtw89_fw_h2c_cxdrv_role_v8(rtwdev, type);
break;
case CXDRVINFO_CTRL:
if (ver->drvinfo_type == 1)
@@ -2205,7 +2715,7 @@ static void _set_gnt(struct rtw89_dev *rtwdev, u8 phy_map, u8 wl_state, u8 bt_st
if (phy_map > BTC_PHY_ALL)
return;
- for (i = 0; i < RTW89_PHY_MAX; i++) {
+ for (i = 0; i < RTW89_PHY_NUM; i++) {
if (!(phy_map & BIT(i)))
continue;
@@ -2243,7 +2753,77 @@ static void _set_gnt(struct rtw89_dev *rtwdev, u8 phy_map, u8 wl_state, u8 bt_st
rtw89_chip_mac_cfg_gnt(rtwdev, &dm->gnt);
}
-#define BTC_TDMA_WLROLE_MAX 2
+static void _set_gnt_v1(struct rtw89_dev *rtwdev, u8 phy_map,
+ u8 wl_state, u8 bt_state, u8 wlact_state)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ struct rtw89_mac_ax_gnt *g = dm->gnt.band;
+ u8 i, bt_idx = dm->bt_select + 1;
+
+ if (phy_map > BTC_PHY_ALL)
+ return;
+
+ for (i = 0; i < RTW89_PHY_NUM; i++) {
+ if (!(phy_map & BIT(i)))
+ continue;
+
+ switch (wl_state) {
+ case BTC_GNT_HW:
+ g[i].gnt_wl_sw_en = 0;
+ g[i].gnt_wl = 0;
+ break;
+ case BTC_GNT_SW_LO:
+ g[i].gnt_wl_sw_en = 1;
+ g[i].gnt_wl = 0;
+ break;
+ case BTC_GNT_SW_HI:
+ g[i].gnt_wl_sw_en = 1;
+ g[i].gnt_wl = 1;
+ break;
+ }
+
+ switch (bt_state) {
+ case BTC_GNT_HW:
+ g[i].gnt_bt_sw_en = 0;
+ g[i].gnt_bt = 0;
+ break;
+ case BTC_GNT_SW_LO:
+ g[i].gnt_bt_sw_en = 1;
+ g[i].gnt_bt = 0;
+ break;
+ case BTC_GNT_SW_HI:
+ g[i].gnt_bt_sw_en = 1;
+ g[i].gnt_bt = 1;
+ break;
+ }
+ }
+
+ if (rtwdev->chip->para_ver & BTC_FEAT_WLAN_ACT_MUX) {
+ for (i = 0; i < 2; i++) {
+ if (!(bt_idx & BIT(i)))
+ continue;
+
+ switch (wlact_state) {
+ case BTC_WLACT_HW:
+ dm->gnt.bt[i].wlan_act_en = 0;
+ dm->gnt.bt[i].wlan_act = 0;
+ break;
+ case BTC_WLACT_SW_LO:
+ dm->gnt.bt[i].wlan_act_en = 1;
+ dm->gnt.bt[i].wlan_act = 0;
+ break;
+ case BTC_WLACT_SW_HI:
+ dm->gnt.bt[i].wlan_act_en = 1;
+ dm->gnt.bt[i].wlan_act = 1;
+ break;
+ }
+ }
+ }
+ rtw89_mac_cfg_gnt_v2(rtwdev, &dm->gnt);
+}
+
+#define BTC_TDMA_WLROLE_MAX 3
static void _set_bt_ignore_wlan_act(struct rtw89_dev *rtwdev, u8 enable)
{
@@ -2384,7 +2964,7 @@ static void _set_rf_trx_para(struct rtw89_dev *rtwdev)
if (ver->fwlrole == 0) {
link_mode = wl->role_info.link_mode;
- for (i = 0; i < RTW89_PHY_MAX; i++) {
+ for (i = 0; i < RTW89_PHY_NUM; i++) {
if (wl->dbcc_info.real_band[i] == RTW89_BAND_2G)
dbcc_2g_phy = i;
}
@@ -2465,7 +3045,7 @@ static void _update_btc_state_map(struct rtw89_dev *rtwdev)
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
if (wl->status.map.connecting || wl->status.map._4way ||
- wl->status.map.roaming) {
+ wl->status.map.roaming || wl->status.map.dbccing) {
cx->state_map = BTC_WLINKING;
} else if (wl->status.map.scan) { /* wl scan */
if (bt_linfo->status.map.inq_pag)
@@ -2493,9 +3073,13 @@ static void _set_bt_afh_info(struct rtw89_dev *rtwdev)
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
+ struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
+ struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
struct rtw89_btc_wl_active_role *r;
struct rtw89_btc_wl_active_role_v1 *r1;
struct rtw89_btc_wl_active_role_v2 *r2;
+ struct rtw89_btc_wl_active_role_v7 *r7;
+ struct rtw89_btc_wl_rlink *rlink;
u8 en = 0, i, ch = 0, bw = 0;
u8 mode, connect_cnt;
@@ -2511,6 +3095,12 @@ static void _set_bt_afh_info(struct rtw89_dev *rtwdev)
} else if (ver->fwlrole == 2) {
mode = wl_rinfo_v2->link_mode;
connect_cnt = wl_rinfo_v2->connect_cnt;
+ } else if (ver->fwlrole == 7) {
+ mode = wl_rinfo_v7->link_mode;
+ connect_cnt = wl_rinfo_v7->connect_cnt;
+ } else if (ver->fwlrole == 8) {
+ mode = wl_rinfo_v8->link_mode;
+ connect_cnt = wl_rinfo_v8->connect_cnt;
} else {
return;
}
@@ -2526,6 +3116,8 @@ static void _set_bt_afh_info(struct rtw89_dev *rtwdev)
r = &wl_rinfo->active_role[i];
r1 = &wl_rinfo_v1->active_role_v1[i];
r2 = &wl_rinfo_v2->active_role_v2[i];
+ r7 = &wl_rinfo_v7->active_role[i];
+ rlink = &wl_rinfo_v8->rlink[i][0];
if (ver->fwlrole == 0 &&
(r->role == RTW89_WIFI_ROLE_P2P_GO ||
@@ -2545,6 +3137,18 @@ static void _set_bt_afh_info(struct rtw89_dev *rtwdev)
ch = r2->ch;
bw = r2->bw;
break;
+ } else if (ver->fwlrole == 7 &&
+ (r7->role == RTW89_WIFI_ROLE_P2P_GO ||
+ r7->role == RTW89_WIFI_ROLE_P2P_CLIENT)) {
+ ch = r7->ch;
+ bw = r7->bw;
+ break;
+ } else if (ver->fwlrole == 8 &&
+ (rlink->role == RTW89_WIFI_ROLE_P2P_GO ||
+ rlink->role == RTW89_WIFI_ROLE_P2P_CLIENT)) {
+ ch = rlink->ch;
+ bw = rlink->bw;
+ break;
}
}
} else {
@@ -2554,6 +3158,8 @@ static void _set_bt_afh_info(struct rtw89_dev *rtwdev)
r = &wl_rinfo->active_role[i];
r1 = &wl_rinfo_v1->active_role_v1[i];
r2 = &wl_rinfo_v2->active_role_v2[i];
+ r7 = &wl_rinfo_v7->active_role[i];
+ rlink = &wl_rinfo_v8->rlink[i][0];
if (ver->fwlrole == 0 &&
r->connected && r->band == RTW89_BAND_2G) {
@@ -2570,6 +3176,16 @@ static void _set_bt_afh_info(struct rtw89_dev *rtwdev)
ch = r2->ch;
bw = r2->bw;
break;
+ } else if (ver->fwlrole == 7 &&
+ r7->connected && r7->band == RTW89_BAND_2G) {
+ ch = r7->ch;
+ bw = r7->bw;
+ break;
+ } else if (ver->fwlrole == 8 &&
+ rlink->connected && rlink->rf_band == RTW89_BAND_2G) {
+ ch = rlink->ch;
+ bw = rlink->bw;
+ break;
}
}
}
@@ -2622,25 +3238,38 @@ static bool _check_freerun(struct rtw89_dev *rtwdev)
struct rtw89_btc_bt_info *bt = &btc->cx.bt;
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
+ struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
+ struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
+ struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
struct rtw89_btc_bt_hid_desc *hid = &bt_linfo->hid_desc;
union rtw89_btc_module_info *md = &btc->mdinfo;
const struct rtw89_btc_ver *ver = btc->ver;
- u8 isolation;
+ u8 isolation, connect_cnt = 0;
if (ver->fcxinit == 7)
isolation = md->md_v7.ant.isolation;
else
isolation = md->md.ant.isolation;
+ if (ver->fwlrole == 0)
+ connect_cnt = wl_rinfo->connect_cnt;
+ else if (ver->fwlrole == 1)
+ connect_cnt = wl_rinfo_v1->connect_cnt;
+ else if (ver->fwlrole == 2)
+ connect_cnt = wl_rinfo_v2->connect_cnt;
+ else if (ver->fwlrole == 7)
+ connect_cnt = wl_rinfo_v7->connect_cnt;
+ else if (ver->fwlrole == 8)
+ connect_cnt = wl_rinfo_v8->connect_cnt;
+
if (btc->ant_type == BTC_ANT_SHARED) {
btc->dm.trx_para_level = 0;
return false;
}
/* The below is dedicated antenna case */
- if (wl_rinfo->connect_cnt > BTC_TDMA_WLROLE_MAX ||
- wl_rinfo_v1->connect_cnt > BTC_TDMA_WLROLE_MAX) {
+ if (connect_cnt > BTC_TDMA_WLROLE_MAX) {
btc->dm.trx_para_level = 5;
return true;
}
@@ -2693,19 +3322,6 @@ static bool _check_freerun(struct rtw89_dev *rtwdev)
#define _tdma_set_tog(btc, wtg) ({(btc)->dm.tdma.wtgle_n = wtg; })
#define _tdma_set_lek(btc, lek) ({(btc)->dm.tdma.leak_n = lek; })
-#define _slot_set(btc, sid, dura, tbl, type) \
- do { \
- typeof(sid) _sid = (sid); \
- typeof(btc) _btc = (btc); \
- _btc->dm.slot[_sid].dur = cpu_to_le16(dura);\
- _btc->dm.slot[_sid].cxtbl = cpu_to_le32(tbl); \
- _btc->dm.slot[_sid].cxtype = cpu_to_le16(type); \
- } while (0)
-
-#define _slot_set_dur(btc, sid, dura) (btc)->dm.slot[sid].dur = cpu_to_le16(dura)
-#define _slot_set_tbl(btc, sid, tbl) (btc)->dm.slot[sid].cxtbl = cpu_to_le32(tbl)
-#define _slot_set_type(btc, sid, type) (btc)->dm.slot[sid].cxtype = cpu_to_le16(type)
-
struct btc_btinfo_lb2 {
u8 connect: 1;
u8 sco_busy: 1;
@@ -2780,7 +3396,7 @@ void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type)
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_fbtc_tdma *t = &dm->tdma;
- struct rtw89_btc_fbtc_slot *s = dm->slot;
+ struct rtw89_btc_fbtc_slot *s = dm->slot.v1;
u8 type;
u32 tbl_w1, tbl_b1, tbl_b4;
@@ -3091,13 +3707,14 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_fbtc_tdma *t = &dm->tdma;
- struct rtw89_btc_fbtc_slot *s = dm->slot;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &btc->cx.wl.role_info_v1;
+ struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
struct rtw89_btc_bt_hid_desc *hid = &btc->cx.bt.link_info.hid_desc;
struct rtw89_btc_bt_hfp_desc *hfp = &btc->cx.bt.link_info.hfp_desc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
u8 type, null_role;
u32 tbl_w1, tbl_b1, tbl_b4;
+ u16 dur_2;
type = FIELD_GET(BTC_CXP_MASK, policy_type);
@@ -3133,19 +3750,19 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
tbl_w1 = cxtbl[16];
}
- btc->bt_req_en = false;
-
switch (type) {
case BTC_CXP_USERDEF0:
btc->update_policy_force = true;
*t = t_def[CXTD_OFF];
- s[CXST_OFF] = s_def[CXST_OFF];
+ _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur,
+ s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype);
_slot_set_tbl(btc, CXST_OFF, cxtbl[2]);
break;
case BTC_CXP_OFF: /* TDMA off */
_write_scbd(rtwdev, BTC_WSCB_TDMA, false);
*t = t_def[CXTD_OFF];
- s[CXST_OFF] = s_def[CXST_OFF];
+ _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur,
+ s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype);
switch (policy_type) {
case BTC_CXP_OFF_BT:
@@ -3154,6 +3771,10 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
case BTC_CXP_OFF_WL:
_slot_set_tbl(btc, CXST_OFF, cxtbl[1]);
break;
+ case BTC_CXP_OFF_WL2:
+ _slot_set_tbl(btc, CXST_OFF, cxtbl[1]);
+ _slot_set_type(btc, CXST_OFF, SLOT_ISO);
+ break;
case BTC_CXP_OFF_EQ0:
_slot_set_tbl(btc, CXST_OFF, cxtbl[0]);
_slot_set_type(btc, CXST_OFF, SLOT_ISO);
@@ -3167,6 +3788,12 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
case BTC_CXP_OFF_EQ3:
_slot_set_tbl(btc, CXST_OFF, cxtbl[24]);
break;
+ case BTC_CXP_OFF_EQ4:
+ _slot_set_tbl(btc, CXST_OFF, cxtbl[26]);
+ break;
+ case BTC_CXP_OFF_EQ5:
+ _slot_set_tbl(btc, CXST_OFF, cxtbl[27]);
+ break;
case BTC_CXP_OFF_BWB0:
_slot_set_tbl(btc, CXST_OFF, cxtbl[5]);
break;
@@ -3186,7 +3813,8 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
case BTC_CXP_OFFB: /* TDMA off + beacon protect */
_write_scbd(rtwdev, BTC_WSCB_TDMA, false);
*t = t_def[CXTD_OFF_B2];
- s[CXST_OFF] = s_def[CXST_OFF];
+ _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur,
+ s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype);
switch (policy_type) {
case BTC_CXP_OFFB_BWB0:
@@ -3197,7 +3825,6 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
}
break;
case BTC_CXP_OFFE: /* TDMA off + beacon protect + Ext_control */
- btc->bt_req_en = true;
_write_scbd(rtwdev, BTC_WSCB_TDMA, true);
*t = t_def[CXTD_OFF_EXT];
@@ -3205,23 +3832,59 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
if (hid->exist || hfp->exist)
tbl_w1 = cxtbl[16];
+ dur_2 = dm->e2g_slot_limit;
+
switch (policy_type) {
+ case BTC_CXP_OFFE_2GBWISOB: /* for normal-case */
+ _slot_set(btc, CXST_E2G, 0, tbl_w1, SLOT_ISO);
+ _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur,
+ s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype);
+ _slot_set_dur(btc, CXST_EBT, dur_2);
+ break;
+ case BTC_CXP_OFFE_2GISOB: /* for bt no-link */
+ _slot_set(btc, CXST_E2G, 0, cxtbl[1], SLOT_ISO);
+ _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur,
+ s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype);
+ _slot_set_dur(btc, CXST_EBT, dur_2);
+ break;
case BTC_CXP_OFFE_DEF:
- s[CXST_E2G] = s_def[CXST_E2G];
- s[CXST_E5G] = s_def[CXST_E5G];
- s[CXST_EBT] = s_def[CXST_EBT];
- s[CXST_ENULL] = s_def[CXST_ENULL];
+ _slot_set_le(btc, CXST_E2G, s_def[CXST_E2G].dur,
+ s_def[CXST_E2G].cxtbl, s_def[CXST_E2G].cxtype);
+ _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur,
+ s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype);
+ _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur,
+ s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype);
+ _slot_set_le(btc, CXST_ENULL, s_def[CXST_ENULL].dur,
+ s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype);
break;
case BTC_CXP_OFFE_DEF2:
_slot_set(btc, CXST_E2G, 20, cxtbl[1], SLOT_ISO);
- s[CXST_E5G] = s_def[CXST_E5G];
- s[CXST_EBT] = s_def[CXST_EBT];
- s[CXST_ENULL] = s_def[CXST_ENULL];
+ _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur,
+ s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype);
+ _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur,
+ s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype);
+ _slot_set_le(btc, CXST_ENULL, s_def[CXST_ENULL].dur,
+ s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype);
+ break;
+ case BTC_CXP_OFFE_2GBWMIXB:
+ if (a2dp->exist)
+ _slot_set(btc, CXST_E2G, 0, cxtbl[2], SLOT_MIX);
+ else
+ _slot_set(btc, CXST_E2G, 0, tbl_w1, SLOT_MIX);
+ _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur,
+ s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype);
+ break;
+ case BTC_CXP_OFFE_WL: /* for 4-way */
+ _slot_set(btc, CXST_E2G, 0, cxtbl[1], SLOT_MIX);
+ _slot_set(btc, CXST_EBT, 0, cxtbl[1], SLOT_MIX);
break;
default:
break;
}
- s[CXST_OFF] = s_def[CXST_OFF];
+ _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur,
+ s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype);
+ _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur,
+ s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype);
break;
case BTC_CXP_FIX: /* TDMA Fix-Slot */
_write_scbd(rtwdev, BTC_WSCB_TDMA, true);
@@ -3481,25 +4144,36 @@ EXPORT_SYMBOL(rtw89_btc_set_policy_v1);
static void _set_bt_plut(struct rtw89_dev *rtwdev, u8 phy_map,
u8 tx_val, u8 rx_val)
{
+ struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl;
struct rtw89_mac_ax_plt plt;
- plt.band = RTW89_MAC_0;
plt.tx = tx_val;
plt.rx = rx_val;
- if (phy_map & BTC_PHY_0)
+ if (rtwdev->btc.ver->fwlrole == 8) {
+ plt.band = wl->pta_req_mac;
+ if (wl->bt_polut_type[plt.band] == tx_val)
+ return;
+
+ wl->bt_polut_type[plt.band] = tx_val;
rtw89_mac_cfg_plt(rtwdev, &plt);
+ } else {
+ plt.band = RTW89_MAC_0;
- if (!rtwdev->dbcc_en)
- return;
+ if (phy_map & BTC_PHY_0)
+ rtw89_mac_cfg_plt(rtwdev, &plt);
- plt.band = RTW89_MAC_1;
- if (phy_map & BTC_PHY_1)
- rtw89_mac_cfg_plt(rtwdev, &plt);
+ if (!rtwdev->dbcc_en)
+ return;
+
+ plt.band = RTW89_MAC_1;
+ if (phy_map & BTC_PHY_1)
+ rtw89_mac_cfg_plt(rtwdev, &plt);
+ }
}
-static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec,
- u8 phy_map, u8 type)
+static void _set_ant_v0(struct rtw89_dev *rtwdev, bool force_exec,
+ u8 phy_map, u8 type)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &btc->dm;
@@ -3508,13 +4182,23 @@ static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec,
struct rtw89_btc_bt_info *bt = &cx->bt;
struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
u8 gnt_wl_ctrl, gnt_bt_ctrl, plt_ctrl, i, b2g = 0;
+ bool dbcc_chg = false;
u32 ant_path_type;
ant_path_type = ((phy_map << 8) + type);
+ if (btc->ver->fwlrole == 1)
+ dbcc_chg = wl->role_info_v1.dbcc_chg;
+ else if (btc->ver->fwlrole == 2)
+ dbcc_chg = wl->role_info_v2.dbcc_chg;
+ else if (btc->ver->fwlrole == 7)
+ dbcc_chg = wl->role_info_v7.dbcc_chg;
+ else if (btc->ver->fwlrole == 8)
+ dbcc_chg = wl->role_info_v8.dbcc_chg;
+
if (btc->dm.run_reason == BTC_RSN_NTFY_POWEROFF ||
btc->dm.run_reason == BTC_RSN_NTFY_RADIO_STATE ||
- btc->dm.run_reason == BTC_RSN_CMD_SET_COEX)
+ btc->dm.run_reason == BTC_RSN_CMD_SET_COEX || dbcc_chg)
force_exec = FC_EXEC;
if (!force_exec && ant_path_type == dm->set_ant_path) {
@@ -3565,7 +4249,7 @@ static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec,
case BTC_ANT_W2G:
rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
if (rtwdev->dbcc_en) {
- for (i = 0; i < RTW89_PHY_MAX; i++) {
+ for (i = 0; i < RTW89_PHY_NUM; i++) {
b2g = (wl_dinfo->real_band[i] == RTW89_BAND_2G);
gnt_wl_ctrl = b2g ? BTC_GNT_HW : BTC_GNT_SW_HI;
@@ -3603,6 +4287,7 @@ static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec,
_set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE);
break;
case BTC_ANT_WRFK:
+ case BTC_ANT_WRFK2:
rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
_set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO);
_set_bt_plut(rtwdev, phy_map, BTC_PLT_NONE, BTC_PLT_NONE);
@@ -3617,6 +4302,117 @@ static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec,
}
}
+static void _set_ant_v1(struct rtw89_dev *rtwdev, bool force_exec,
+ u8 phy_map, u8 type)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8;
+ u32 ant_path_type = rtw89_get_antpath_type(phy_map, type);
+ struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ u8 gwl = BTC_GNT_HW;
+
+ if (btc->dm.run_reason == BTC_RSN_NTFY_POWEROFF ||
+ btc->dm.run_reason == BTC_RSN_NTFY_RADIO_STATE ||
+ btc->dm.run_reason == BTC_RSN_CMD_SET_COEX || wl_rinfo->dbcc_chg)
+ force_exec = FC_EXEC;
+
+ if (wl_rinfo->link_mode != BTC_WLINK_25G_MCC &&
+ btc->dm.wl_btg_rx == 2)
+ force_exec = FC_EXEC;
+
+ if (!force_exec && ant_path_type == dm->set_ant_path) {
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s(): return by no change!!\n",
+ __func__);
+ return;
+ } else if (bt->rfk_info.map.run) {
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s(): return by bt rfk!!\n", __func__);
+ return;
+ } else if (btc->dm.run_reason != BTC_RSN_NTFY_WL_RFK &&
+ wl->rfk_info.state != BTC_WRFK_STOP) {
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s(): return by wl rfk!!\n", __func__);
+ return;
+ }
+
+ dm->set_ant_path = ant_path_type;
+
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s(): path=0x%x, set_type=0x%x\n",
+ __func__, phy_map, dm->set_ant_path & 0xff);
+
+ switch (type) {
+ case BTC_ANT_WINIT:
+ /* To avoid BT MP driver case (bt_enable but no mailbox) */
+ if (bt->enable.now && bt->run_patch_code)
+ _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI,
+ BTC_WLACT_SW_LO);
+ else
+ _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO,
+ BTC_WLACT_SW_HI);
+ break;
+ case BTC_ANT_WONLY:
+ _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO,
+ BTC_WLACT_SW_HI);
+ break;
+ case BTC_ANT_WOFF:
+ _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI,
+ BTC_WLACT_SW_LO);
+ break;
+ case BTC_ANT_W2G:
+ case BTC_ANT_W25G:
+ if (wl_rinfo->dbcc_en) {
+ if (wl_dinfo->real_band[RTW89_PHY_0] == RTW89_BAND_2G)
+ gwl = BTC_GNT_HW;
+ else
+ gwl = BTC_GNT_SW_HI;
+ _set_gnt_v1(rtwdev, BTC_PHY_0, gwl, BTC_GNT_HW, BTC_WLACT_HW);
+
+ if (wl_dinfo->real_band[RTW89_PHY_1] == RTW89_BAND_2G)
+ gwl = BTC_GNT_HW;
+ else
+ gwl = BTC_GNT_SW_HI;
+ _set_gnt_v1(rtwdev, BTC_PHY_1, gwl, BTC_GNT_HW, BTC_WLACT_HW);
+ } else {
+ gwl = BTC_GNT_HW;
+ _set_gnt_v1(rtwdev, phy_map, gwl, BTC_GNT_HW, BTC_WLACT_HW);
+ }
+ break;
+ case BTC_ANT_W5G:
+ _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_HW, BTC_WLACT_HW);
+ break;
+ case BTC_ANT_FREERUN:
+ _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_HI,
+ BTC_WLACT_SW_LO);
+ break;
+ case BTC_ANT_WRFK:
+ _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO,
+ BTC_WLACT_HW);
+ break;
+ case BTC_ANT_WRFK2:
+ _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO,
+ BTC_WLACT_SW_HI); /* no BT-Tx */
+ break;
+ default:
+ return;
+ }
+
+ _set_bt_plut(rtwdev, phy_map, BTC_PLT_GNT_WL, BTC_PLT_GNT_WL);
+}
+
+static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec,
+ u8 phy_map, u8 type)
+{
+ if (rtwdev->chip->chip_id == RTL8922A)
+ _set_ant_v1(rtwdev, force_exec, phy_map, type);
+ else
+ _set_ant_v0(rtwdev, force_exec, phy_map, type);
+}
+
static void _action_wl_only(struct rtw89_dev *rtwdev)
{
_set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WONLY);
@@ -3641,7 +4437,7 @@ static void _action_wl_off(struct rtw89_dev *rtwdev, u8 mode)
if (wl->status.map.rf_off || btc->dm.bt_only) {
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_WOFF);
} else if (wl->status.map.lps == BTC_LPS_RF_ON) {
- if (wl->role_info.link_mode == BTC_WLINK_5G)
+ if (mode == BTC_WLINK_5G)
_set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_W5G);
else
_set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
@@ -3796,23 +4592,16 @@ static void _action_bt_hid(struct rtw89_dev *rtwdev)
static void _action_bt_a2dp(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info;
- struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
struct rtw89_btc_dm *dm = &btc->dm;
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
+ dm->slot_dur[CXST_W1] = 20;
+ dm->slot_dur[CXST_B1] = BTC_B1_MAX;
+
switch (btc->cx.state_map) {
case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP */
- if (a2dp.vendor_id == 0x4c || dm->leak_ap) {
- dm->slot_dur[CXST_W1] = 40;
- dm->slot_dur[CXST_B1] = 200;
- _set_policy(rtwdev,
- BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP);
- } else {
- _set_policy(rtwdev,
- BTC_CXP_PAUTO_TD50B1, BTC_ACT_BT_A2DP);
- }
+ _set_policy(rtwdev, BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP);
break;
case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP */
_set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP);
@@ -3822,15 +4611,10 @@ static void _action_bt_a2dp(struct rtw89_dev *rtwdev)
break;
case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP */
case BTC_WLINKING: /* wl-connecting + bt-A2DP */
- if (a2dp.vendor_id == 0x4c || dm->leak_ap) {
- dm->slot_dur[CXST_W1] = 40;
- dm->slot_dur[CXST_B1] = 200;
- _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1,
- BTC_ACT_BT_A2DP);
- } else {
- _set_policy(rtwdev, BTC_CXP_AUTO_TD50B1,
- BTC_ACT_BT_A2DP);
- }
+ if (btc->cx.wl.rfk_info.con_rfk)
+ _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DP);
+ else
+ _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, BTC_ACT_BT_A2DP);
break;
case BTC_WIDLE: /* wl-idle + bt-A2DP */
_set_policy(rtwdev, BTC_CXP_AUTO_TD20B1, BTC_ACT_BT_A2DP);
@@ -3858,7 +4642,10 @@ static void _action_bt_a2dpsink(struct rtw89_dev *rtwdev)
_set_policy(rtwdev, BTC_CXP_FIX_TD2060, BTC_ACT_BT_A2DPSINK);
break;
case BTC_WLINKING: /* wl-connecting + bt-A2dp_Sink */
- _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_A2DPSINK);
+ if (btc->cx.wl.rfk_info.con_rfk)
+ _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DPSINK);
+ else
+ _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_A2DPSINK);
break;
case BTC_WIDLE: /* wl-idle + bt-A2dp_Sink */
_set_policy(rtwdev, BTC_CXP_FIX_TD2080, BTC_ACT_BT_A2DPSINK);
@@ -3869,12 +4656,21 @@ static void _action_bt_a2dpsink(struct rtw89_dev *rtwdev)
static void _action_bt_pan(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info;
+ struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
+ struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc;
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
switch (btc->cx.state_map) {
case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-PAN */
- _set_policy(rtwdev, BTC_CXP_PFIX_TD5050, BTC_ACT_BT_PAN);
+ if (a2dp.active || !pan.exist) {
+ btc->dm.slot_dur[CXST_W1] = 80;
+ btc->dm.slot_dur[CXST_B1] = 20;
+ _set_policy(rtwdev, BTC_CXP_PFIX_TDW1B1, BTC_ACT_BT_PAN);
+ } else {
+ _set_policy(rtwdev, BTC_CXP_PFIX_TD5050, BTC_ACT_BT_PAN);
+ }
break;
case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-PAN */
_set_policy(rtwdev, BTC_CXP_PFIX_TD3070, BTC_ACT_BT_PAN);
@@ -3897,27 +4693,20 @@ static void _action_bt_pan(struct rtw89_dev *rtwdev)
static void _action_bt_a2dp_hid(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info;
- struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
struct rtw89_btc_dm *dm = &btc->dm;
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
+ dm->slot_dur[CXST_W1] = 20;
+ dm->slot_dur[CXST_B1] = BTC_B1_MAX;
+
switch (btc->cx.state_map) {
case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+HID */
case BTC_WIDLE: /* wl-idle + bt-A2DP */
- if (a2dp.vendor_id == 0x4c || dm->leak_ap) {
- dm->slot_dur[CXST_W1] = 40;
- dm->slot_dur[CXST_B1] = 200;
- _set_policy(rtwdev,
- BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP_HID);
- } else {
- _set_policy(rtwdev,
- BTC_CXP_PAUTO_TD50B1, BTC_ACT_BT_A2DP_HID);
- }
+ _set_policy(rtwdev, BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP_HID);
break;
case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+HID */
- _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP_HID);
+ _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, BTC_ACT_BT_A2DP_HID);
break;
case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+HID */
@@ -3925,15 +4714,10 @@ static void _action_bt_a2dp_hid(struct rtw89_dev *rtwdev)
break;
case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+HID */
case BTC_WLINKING: /* wl-connecting + bt-A2DP+HID */
- if (a2dp.vendor_id == 0x4c || dm->leak_ap) {
- dm->slot_dur[CXST_W1] = 40;
- dm->slot_dur[CXST_B1] = 200;
- _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1,
- BTC_ACT_BT_A2DP_HID);
- } else {
- _set_policy(rtwdev, BTC_CXP_AUTO_TD50B1,
- BTC_ACT_BT_A2DP_HID);
- }
+ if (btc->cx.wl.rfk_info.con_rfk)
+ _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DP_HID);
+ else
+ _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, BTC_ACT_BT_A2DP_HID);
break;
}
}
@@ -4060,8 +4844,16 @@ static void _action_wl_rfk(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): band = %d\n",
__func__, rfk.band);
- _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK);
- _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_WL_RFK);
+ btc->dm.tdma_instant_excute = 1;
+
+ if (rfk.state == BTC_WRFK_ONESHOT_START ||
+ btc->ant_type == BTC_ANT_SHARED) {
+ _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK2);
+ _set_policy(rtwdev, BTC_CXP_OFF_WL2, BTC_ACT_WL_RFK);
+ } else {
+ _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK);
+ _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_WL_RFK);
+ }
}
static void _set_btg_ctrl(struct rtw89_dev *rtwdev)
@@ -4070,6 +4862,8 @@ static void _set_btg_ctrl(struct rtw89_dev *rtwdev)
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
+ struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
+ struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
struct rtw89_btc_wl_role_info *wl_rinfo_v0 = &wl->role_info;
struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
const struct rtw89_chip_info *chip = rtwdev->chip;
@@ -4090,12 +4884,18 @@ static void _set_btg_ctrl(struct rtw89_dev *rtwdev)
wl_rinfo.link_mode = wl_rinfo_v1->link_mode;
else if (ver->fwlrole == 2)
wl_rinfo.link_mode = wl_rinfo_v2->link_mode;
+ else if (ver->fwlrole == 7)
+ wl_rinfo.link_mode = wl_rinfo_v7->link_mode;
+ else if (ver->fwlrole == 8)
+ wl_rinfo.link_mode = wl_rinfo_v8->link_mode;
else
return;
if (rtwdev->dbcc_en) {
if (ver->fwlrole == 0) {
- for (i = 0; i < RTW89_PHY_MAX; i++) {
+ wl_rinfo.dbcc_2g_phy = RTW89_PHY_NUM;
+
+ for (i = 0; i < RTW89_PHY_NUM; i++) {
if (wl_dinfo->real_band[i] == RTW89_BAND_2G)
wl_rinfo.dbcc_2g_phy = i;
}
@@ -4103,6 +4903,10 @@ static void _set_btg_ctrl(struct rtw89_dev *rtwdev)
wl_rinfo.dbcc_2g_phy = wl_rinfo_v1->dbcc_2g_phy;
} else if (ver->fwlrole == 2) {
wl_rinfo.dbcc_2g_phy = wl_rinfo_v2->dbcc_2g_phy;
+ } else if (ver->fwlrole == 7) {
+ wl_rinfo.dbcc_2g_phy = wl_rinfo_v7->dbcc_2g_phy;
+ } else if (ver->fwlrole == 8) {
+ wl_rinfo.dbcc_2g_phy = wl_rinfo_v8->dbcc_2g_phy;
} else {
return;
}
@@ -4146,37 +4950,56 @@ static void _set_wl_preagc_ctrl(struct rtw89_dev *rtwdev)
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_wl_role_info_v2 *wl_rinfo = &wl->role_info_v2;
+ struct rtw89_btc_wl_role_info_v2 *rinfo_v2 = &wl->role_info_v2;
+ struct rtw89_btc_wl_role_info_v7 *rinfo_v7 = &wl->role_info_v7;
+ struct rtw89_btc_wl_role_info_v8 *rinfo_v8 = &wl->role_info_v8;
const struct rtw89_chip_info *chip = rtwdev->chip;
- const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_bt_info *bt = &btc->cx.bt;
struct rtw89_btc_dm *dm = &btc->dm;
- u8 is_preagc, val;
+ u8 is_preagc, val, link_mode, dbcc_2g_phy;
+ u8 role_ver = rtwdev->btc.ver->fwlrole;
+ bool dbcc_en;
if (btc->manual_ctrl)
return;
- if (wl_rinfo->link_mode == BTC_WLINK_25G_MCC)
+ if (role_ver == 2) {
+ dbcc_en = rinfo_v2->dbcc_en;
+ link_mode = rinfo_v2->link_mode;
+ dbcc_2g_phy = rinfo_v2->dbcc_2g_phy;
+ } else if (role_ver == 7) {
+ dbcc_en = rinfo_v7->dbcc_en;
+ link_mode = rinfo_v7->link_mode;
+ dbcc_2g_phy = rinfo_v7->dbcc_2g_phy;
+ } else if (role_ver == 8) {
+ dbcc_en = rinfo_v8->dbcc_en;
+ link_mode = rinfo_v8->link_mode;
+ dbcc_2g_phy = rinfo_v7->dbcc_2g_phy;
+ } else {
+ return;
+ }
+
+ if (link_mode == BTC_WLINK_25G_MCC) {
is_preagc = BTC_PREAGC_BB_FWCTRL;
- else if (!(bt->run_patch_code && bt->enable.now))
+ } else if (!(bt->run_patch_code && bt->enable.now)) {
is_preagc = BTC_PREAGC_DISABLE;
- else if (wl_rinfo->link_mode == BTC_WLINK_5G)
+ } else if (link_mode == BTC_WLINK_5G) {
is_preagc = BTC_PREAGC_DISABLE;
- else if (wl_rinfo->link_mode == BTC_WLINK_NOLINK ||
- btc->cx.bt.link_info.profile_cnt.now == 0)
+ } else if (link_mode == BTC_WLINK_NOLINK ||
+ btc->cx.bt.link_info.profile_cnt.now == 0) {
is_preagc = BTC_PREAGC_DISABLE;
- else if (dm->tdma_now.type != CXTDMA_OFF &&
+ } else if (dm->tdma_now.type != CXTDMA_OFF &&
!bt_linfo->hfp_desc.exist &&
!bt_linfo->hid_desc.exist &&
- dm->fddt_train == BTC_FDDT_DISABLE)
+ dm->fddt_train == BTC_FDDT_DISABLE) {
is_preagc = BTC_PREAGC_DISABLE;
- else if (ver->fwlrole == 2 && wl_rinfo->dbcc_en &&
- wl_rinfo->dbcc_2g_phy != RTW89_PHY_1)
+ } else if (dbcc_en && (dbcc_2g_phy != RTW89_PHY_1)) {
is_preagc = BTC_PREAGC_DISABLE;
- else if (btc->ant_type == BTC_ANT_SHARED)
+ } else if (btc->ant_type == BTC_ANT_SHARED) {
is_preagc = BTC_PREAGC_DISABLE;
- else
+ } else {
is_preagc = BTC_PREAGC_ENABLE;
+ }
if (dm->wl_pre_agc_rb != dm->wl_pre_agc &&
dm->wl_pre_agc_rb != BTC_PREAGC_NOTFOUND) {
@@ -4206,24 +5029,25 @@ struct rtw89_txtime_data {
bool reenable;
};
-static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta)
+static void __rtw89_tx_time_iter(struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ struct rtw89_txtime_data *iter_data)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_txtime_data *iter_data =
- (struct rtw89_txtime_data *)data;
struct rtw89_dev *rtwdev = iter_data->rtwdev;
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &cx->wl;
struct rtw89_btc_wl_link_info *plink = NULL;
- u8 port = rtwvif->port;
+ u8 port = rtwvif_link->port;
u32 tx_time = iter_data->tx_time;
u8 tx_retry = iter_data->tx_retry;
u16 enable = iter_data->enable;
bool reenable = iter_data->reenable;
- plink = &wl->link_info[port];
+ if (btc->ver->fwlrole == 8)
+ plink = &wl->rlink_info[port][0];
+ else
+ plink = &wl->link_info[port];
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): port = %d\n", __func__, port);
@@ -4237,8 +5061,8 @@ static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta)
/* backup the original tx time before tx-limit on */
if (reenable) {
- rtw89_mac_get_tx_time(rtwdev, rtwsta, &plink->tx_time);
- rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta, &plink->tx_retry);
+ rtw89_mac_get_tx_time(rtwdev, rtwsta_link, &plink->tx_time);
+ rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta_link, &plink->tx_retry);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): reenable, tx_time=%d tx_retry= %d\n",
__func__, plink->tx_time, plink->tx_retry);
@@ -4246,22 +5070,37 @@ static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta)
/* restore the original tx time if no tx-limit */
if (!enable) {
- rtw89_mac_set_tx_time(rtwdev, rtwsta, true, plink->tx_time);
- rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta, true,
+ rtw89_mac_set_tx_time(rtwdev, rtwsta_link, true, plink->tx_time);
+ rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, true,
plink->tx_retry);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): restore, tx_time=%d tx_retry= %d\n",
__func__, plink->tx_time, plink->tx_retry);
} else {
- rtw89_mac_set_tx_time(rtwdev, rtwsta, false, tx_time);
- rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta, false, tx_retry);
+ rtw89_mac_set_tx_time(rtwdev, rtwsta_link, false, tx_time);
+ rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false, tx_retry);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): set, tx_time=%d tx_retry= %d\n",
__func__, tx_time, tx_retry);
}
}
+static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_txtime_data *iter_data =
+ (struct rtw89_txtime_data *)data;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ __rtw89_tx_time_iter(rtwvif_link, rtwsta_link, iter_data);
+ }
+}
+
static void _set_wl_tx_limit(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
@@ -4276,6 +5115,8 @@ static void _set_wl_tx_limit(struct rtw89_dev *rtwdev)
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
+ struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
+ struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
struct rtw89_txtime_data data = {.rtwdev = rtwdev};
u8 mode, igno_bt, tx_retry;
u32 tx_time;
@@ -4291,6 +5132,10 @@ static void _set_wl_tx_limit(struct rtw89_dev *rtwdev)
mode = wl_rinfo_v1->link_mode;
else if (ver->fwlrole == 2)
mode = wl_rinfo_v2->link_mode;
+ else if (ver->fwlrole == 7)
+ mode = wl_rinfo_v7->link_mode;
+ else if (ver->fwlrole == 8)
+ mode = wl_rinfo_v8->link_mode;
else
return;
@@ -4348,6 +5193,8 @@ static void _set_bt_rx_agc(struct rtw89_dev *rtwdev)
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
+ struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
+ struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
struct rtw89_btc_bt_info *bt = &btc->cx.bt;
bool bt_hi_lna_rx = false;
u8 mode;
@@ -4358,6 +5205,10 @@ static void _set_bt_rx_agc(struct rtw89_dev *rtwdev)
mode = wl_rinfo_v1->link_mode;
else if (ver->fwlrole == 2)
mode = wl_rinfo_v2->link_mode;
+ else if (ver->fwlrole == 7)
+ mode = wl_rinfo_v7->link_mode;
+ else if (ver->fwlrole == 8)
+ mode = wl_rinfo_v8->link_mode;
else
return;
@@ -4378,11 +5229,14 @@ static void _set_bt_rx_scan_pri(struct rtw89_dev *rtwdev)
_write_scbd(rtwdev, BTC_WSCB_RXSCAN_PRI, (bool)(!!bt->scan_rx_low_pri));
}
-/* TODO add these functions */
static void _action_common(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_wl_smap *wl_smap = &wl->status.map;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ u32 bt_rom_code_id, bt_fw_ver;
_set_btg_ctrl(rtwdev);
_set_wl_preagc_ctrl(rtwdev);
@@ -4392,6 +5246,26 @@ static void _action_common(struct rtw89_dev *rtwdev)
_set_rf_trx_para(rtwdev);
_set_bt_rx_scan_pri(rtwdev);
+ bt_rom_code_id = chip_id_to_bt_rom_code_id(rtwdev->btc.ver->chip_id);
+ bt_fw_ver = bt->ver_info.fw & 0xffff;
+ if (bt->enable.now &&
+ (bt_fw_ver == 0 ||
+ (bt_fw_ver == bt_rom_code_id && bt->run_patch_code && rtwdev->chip->scbd)))
+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, 1);
+ else
+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, 0);
+
+ if (dm->run_reason == BTC_RSN_NTFY_INIT ||
+ dm->run_reason == BTC_RSN_NTFY_RADIO_STATE ||
+ dm->run_reason == BTC_RSN_NTFY_POWEROFF) {
+ _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE);
+
+ if (wl_smap->rf_off == 1 || wl_smap->lps != BTC_LPS_OFF)
+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, 0);
+ else
+ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, 1);
+ }
+
if (wl->scbd_change) {
rtw89_mac_cfg_sb(rtwdev, wl->scbd);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], write scbd: 0x%08x\n",
@@ -4410,8 +5284,14 @@ static void _action_by_bt(struct rtw89_dev *rtwdev)
struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc;
struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc;
+ struct rtw89_btc_dm *dm = &btc->dm;
u8 profile_map = 0;
+ if (dm->freerun_chk) {
+ _action_freerun(rtwdev);
+ return;
+ }
+
if (bt_linfo->hfp_desc.exist)
profile_map |= BTC_BT_HFP;
@@ -4426,30 +5306,20 @@ static void _action_by_bt(struct rtw89_dev *rtwdev)
switch (profile_map) {
case BTC_BT_NOPROFILE:
- if (_check_freerun(rtwdev))
- _action_freerun(rtwdev);
- else if (pan.active)
+ if (pan.active)
_action_bt_pan(rtwdev);
else
_action_bt_idle(rtwdev);
break;
case BTC_BT_HFP:
- if (_check_freerun(rtwdev))
- _action_freerun(rtwdev);
- else
- _action_bt_hfp(rtwdev);
+ _action_bt_hfp(rtwdev);
break;
case BTC_BT_HFP | BTC_BT_HID:
case BTC_BT_HID:
- if (_check_freerun(rtwdev))
- _action_freerun(rtwdev);
- else
- _action_bt_hid(rtwdev);
+ _action_bt_hid(rtwdev);
break;
case BTC_BT_A2DP:
- if (_check_freerun(rtwdev))
- _action_freerun(rtwdev);
- else if (a2dp.sink)
+ if (a2dp.sink)
_action_bt_a2dpsink(rtwdev);
else if (bt_linfo->multi_link.now && !hid.pair_cnt)
_action_bt_a2dp_pan(rtwdev);
@@ -4462,13 +5332,18 @@ static void _action_by_bt(struct rtw89_dev *rtwdev)
case BTC_BT_A2DP | BTC_BT_HFP:
case BTC_BT_A2DP | BTC_BT_HID:
case BTC_BT_A2DP | BTC_BT_HFP | BTC_BT_HID:
- if (_check_freerun(rtwdev))
- _action_freerun(rtwdev);
+ if (a2dp.sink)
+ _action_bt_a2dpsink(rtwdev);
+ else if (pan.active)
+ _action_bt_a2dp_pan_hid(rtwdev);
else
_action_bt_a2dp_hid(rtwdev);
break;
case BTC_BT_A2DP | BTC_BT_PAN:
- _action_bt_a2dp_pan(rtwdev);
+ if (a2dp.sink)
+ _action_bt_a2dpsink(rtwdev);
+ else
+ _action_bt_a2dp_pan(rtwdev);
break;
case BTC_BT_PAN | BTC_BT_HFP:
case BTC_BT_PAN | BTC_BT_HID:
@@ -4478,7 +5353,10 @@ static void _action_by_bt(struct rtw89_dev *rtwdev)
case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HID:
case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HFP:
default:
- _action_bt_a2dp_pan_hid(rtwdev);
+ if (a2dp.sink)
+ _action_bt_a2dpsink(rtwdev);
+ else
+ _action_bt_a2dp_pan_hid(rtwdev);
break;
}
}
@@ -4488,21 +5366,39 @@ static void _action_wl_2g_sta(struct rtw89_dev *rtwdev)
_action_by_bt(rtwdev);
}
+static void _action_wl_25g_mcc(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ u16 policy_type = BTC_CXP_OFF_BT;
+
+ if (btc->ant_type == BTC_ANT_SHARED) {
+ if (btc->cx.wl.status.map._4way)
+ policy_type = BTC_CXP_OFFE_WL;
+ else if (btc->cx.wl.status.val & btc_scanning_map.val)
+ policy_type = BTC_CXP_OFFE_2GBWMIXB;
+ else if (btc->cx.bt.link_info.status.map.connect == 0)
+ policy_type = BTC_CXP_OFFE_2GISOB;
+ else
+ policy_type = BTC_CXP_OFFE_2GBWISOB;
+ } else { /* dedicated-antenna */
+ policy_type = BTC_CXP_OFF_EQ0;
+ }
+
+ btc->dm.e2g_slot_limit = BTC_E2G_LIMIT_DEF;
+
+ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W25G);
+ _set_policy(rtwdev, policy_type, BTC_ACT_WL_25G_MCC);
+}
+
static void _action_wl_scan(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
- if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) {
- _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W25G);
- if (btc->ant_type == BTC_ANT_SHARED)
- _set_policy(rtwdev, BTC_CXP_OFFE_DEF,
- BTC_RSN_NTFY_SCAN_START);
- else
- _set_policy(rtwdev, BTC_CXP_OFF_EQ0,
- BTC_RSN_NTFY_SCAN_START);
-
+ if (btc->cx.state_map != BTC_WLINKING &&
+ RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) {
+ _action_wl_25g_mcc(rtwdev);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], Scan offload!\n");
} else if (rtwdev->dbcc_en) {
if (wl_dinfo->real_band[RTW89_PHY_0] != RTW89_BAND_2G &&
@@ -4518,24 +5414,6 @@ static void _action_wl_scan(struct rtw89_dev *rtwdev)
}
}
-static void _action_wl_25g_mcc(struct rtw89_dev *rtwdev)
-{
- struct rtw89_btc *btc = &rtwdev->btc;
-
- _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W25G);
-
- if (btc->ant_type == BTC_ANT_SHARED) {
- if (btc->cx.bt.link_info.profile_cnt.now == 0)
- _set_policy(rtwdev, BTC_CXP_OFFE_DEF2,
- BTC_ACT_WL_25G_MCC);
- else
- _set_policy(rtwdev, BTC_CXP_OFFE_DEF,
- BTC_ACT_WL_25G_MCC);
- } else { /* dedicated-antenna */
- _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_25G_MCC);
- }
-}
-
static void _action_wl_2g_mcc(struct rtw89_dev *rtwdev)
{ struct rtw89_btc *btc = &rtwdev->btc;
@@ -4639,15 +5517,26 @@ static void _action_wl_2g_scc_v2(struct rtw89_dev *rtwdev)
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_bt_info *bt = &btc->cx.bt;
struct rtw89_btc_dm *dm = &btc->dm;
- struct rtw89_btc_wl_role_info_v2 *wl_rinfo = &wl->role_info_v2;
+ struct rtw89_btc_wl_role_info_v2 *rinfo_v2 = &wl->role_info_v2;
+ struct rtw89_btc_wl_role_info_v7 *rinfo_v7 = &wl->role_info_v7;
+ u32 dur, mrole_type, mrole_noa_duration;
u16 policy_type = BTC_CXP_OFF_BT;
- u32 dur;
+
+ if (btc->ver->fwlrole == 2) {
+ mrole_type = rinfo_v2->mrole_type;
+ mrole_noa_duration = rinfo_v2->mrole_noa_duration;
+ } else if (btc->ver->fwlrole == 7) {
+ mrole_type = rinfo_v7->mrole_type;
+ mrole_noa_duration = rinfo_v7->mrole_noa_duration;
+ } else {
+ return;
+ }
if (btc->ant_type == BTC_ANT_DEDICATED) {
policy_type = BTC_CXP_OFF_EQ0;
} else {
/* shared-antenna */
- switch (wl_rinfo->mrole_type) {
+ switch (mrole_type) {
case BTC_WLMROLE_STA_GC:
dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION;
dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_P2P_CLIENT;
@@ -4665,7 +5554,7 @@ static void _action_wl_2g_scc_v2(struct rtw89_dev *rtwdev)
case BTC_WLMROLE_STA_GO_NOA:
dm->wl_scc.null_role1 = RTW89_WIFI_ROLE_STATION;
dm->wl_scc.null_role2 = RTW89_WIFI_ROLE_NONE;
- dur = wl_rinfo->mrole_noa_duration;
+ dur = mrole_noa_duration;
if (wl->status.map._4way) {
dm->wl_scc.ebt_null = 0;
@@ -4695,6 +5584,31 @@ static void _action_wl_2g_scc_v2(struct rtw89_dev *rtwdev)
_set_policy(rtwdev, policy_type, BTC_ACT_WL_2G_SCC);
}
+static void _action_wl_2g_scc_v8(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ u16 policy_type = BTC_CXP_OFF_BT;
+
+ if (btc->ant_type == BTC_ANT_SHARED) {
+ if (wl->status.map._4way)
+ policy_type = BTC_CXP_OFFE_WL;
+ else if (bt->link_info.status.map.connect == 0)
+ policy_type = BTC_CXP_OFFE_2GISOB;
+ else
+ policy_type = BTC_CXP_OFFE_2GBWISOB;
+ } else {
+ policy_type = BTC_CXP_OFF_EQ0;
+ }
+
+ dm->e2g_slot_limit = BTC_E2G_LIMIT_DEF;
+
+ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
+ _set_policy(rtwdev, policy_type, BTC_ACT_WL_2G_SCC);
+}
+
static void _action_wl_2g_ap(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
@@ -4822,6 +5736,14 @@ _update_rssi_state(struct rtw89_dev *rtwdev, u8 pre_state, u8 rssi, u8 thresh)
return next_state;
}
+static void _wl_req_mac(struct rtw89_dev *rtwdev, u8 mac)
+{
+ if (mac == RTW89_MAC_0)
+ rtw89_write32_clr(rtwdev, R_AX_BTC_CFG, B_AX_WL_SRC);
+ else
+ rtw89_write32_set(rtwdev, R_AX_BTC_CFG, B_AX_WL_SRC);
+}
+
static
void _update_dbcc_band(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
@@ -4865,7 +5787,7 @@ static void _update_wl_info(struct rtw89_dev *rtwdev)
phy = wl_linfo[i].phy;
/* check dbcc role */
- if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) {
+ if (rtwdev->dbcc_en && phy < RTW89_PHY_NUM) {
wl_dinfo->role[phy] = wl_linfo[i].role;
wl_dinfo->op_band[phy] = wl_linfo[i].band;
_update_dbcc_band(rtwdev, phy);
@@ -5015,7 +5937,7 @@ static void _update_wl_info_v1(struct rtw89_dev *rtwdev)
phy = wl_linfo[i].phy;
- if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) {
+ if (rtwdev->dbcc_en && phy < RTW89_PHY_NUM) {
wl_dinfo->role[phy] = wl_linfo[i].role;
wl_dinfo->op_band[phy] = wl_linfo[i].band;
_update_dbcc_band(rtwdev, phy);
@@ -5165,7 +6087,7 @@ static void _update_wl_info_v2(struct rtw89_dev *rtwdev)
phy = wl_linfo[i].phy;
- if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) {
+ if (rtwdev->dbcc_en && phy < RTW89_PHY_NUM) {
wl_dinfo->role[phy] = wl_linfo[i].role;
wl_dinfo->op_band[phy] = wl_linfo[i].band;
_update_dbcc_band(rtwdev, phy);
@@ -5287,7 +6209,507 @@ static void _update_wl_info_v2(struct rtw89_dev *rtwdev)
#define BTC_CHK_HANG_MAX 3
#define BTC_SCB_INV_VALUE GENMASK(31, 0)
-void rtw89_coex_act1_work(struct work_struct *work)
+static u8 _get_role_link_mode(u8 role)
+{
+ switch (role) {
+ case RTW89_WIFI_ROLE_STATION:
+ return BTC_WLINK_2G_STA;
+ case RTW89_WIFI_ROLE_P2P_GO:
+ return BTC_WLINK_2G_GO;
+ case RTW89_WIFI_ROLE_P2P_CLIENT:
+ return BTC_WLINK_2G_GC;
+ case RTW89_WIFI_ROLE_AP:
+ return BTC_WLINK_2G_AP;
+ default:
+ return BTC_WLINK_OTHER;
+ }
+}
+
+static bool _chk_role_ch_group(const struct rtw89_btc_chdef *r1,
+ const struct rtw89_btc_chdef *r2)
+{
+ if (r1->chan != r2->chan) { /* primary ch is different */
+ return false;
+ } else if (r1->bw == RTW89_CHANNEL_WIDTH_40 &&
+ r2->bw == RTW89_CHANNEL_WIDTH_40) {
+ if (r1->offset != r2->offset)
+ return false;
+ }
+ return true;
+}
+
+static u8 _chk_dbcc(struct rtw89_dev *rtwdev, struct rtw89_btc_chdef *ch,
+ u8 *phy, u8 *role, u8 *dbcc_2g_phy)
+{
+ struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl;
+ struct rtw89_btc_wl_role_info_v7 *rinfo_v7 = &wl->role_info_v7;
+ struct rtw89_btc_wl_role_info_v8 *rinfo_v8 = &wl->role_info_v8;
+ bool is_2g_ch_exist = false, is_multi_role_in_2g_phy = false;
+ u8 j, k, dbcc_2g_cid, dbcc_2g_cid2, connect_cnt;
+
+ if (rtwdev->btc.ver->fwlrole == 7)
+ connect_cnt = rinfo_v7->connect_cnt;
+ else if (rtwdev->btc.ver->fwlrole == 8)
+ connect_cnt = rinfo_v8->connect_cnt;
+ else
+ return BTC_WLINK_NOLINK;
+
+ /* find out the 2G-PHY by connect-id ->ch */
+ for (j = 0; j < connect_cnt; j++) {
+ if (ch[j].center_ch <= 14) {
+ is_2g_ch_exist = true;
+ break;
+ }
+ }
+
+ /* If no any 2G-port exist, it's impossible because 5G-exclude */
+ if (!is_2g_ch_exist)
+ return BTC_WLINK_OTHER;
+
+ dbcc_2g_cid = j;
+ *dbcc_2g_phy = phy[dbcc_2g_cid];
+
+ /* connect_cnt <= 2 */
+ if (connect_cnt < BTC_TDMA_WLROLE_MAX)
+ return (_get_role_link_mode((role[dbcc_2g_cid])));
+
+ /* find the other-port in the 2G-PHY, ex: PHY-0:6G, PHY1: mcc/scc */
+ for (k = 0; k < connect_cnt; k++) {
+ if (k == dbcc_2g_cid)
+ continue;
+
+ if (phy[k] == *dbcc_2g_phy) {
+ is_multi_role_in_2g_phy = true;
+ dbcc_2g_cid2 = k;
+ break;
+ }
+ }
+
+ /* Single-role in 2G-PHY */
+ if (!is_multi_role_in_2g_phy)
+ return (_get_role_link_mode(role[dbcc_2g_cid]));
+
+ /* 2-role in 2G-PHY */
+ if (ch[dbcc_2g_cid2].center_ch > 14)
+ return BTC_WLINK_25G_MCC;
+ else if (_chk_role_ch_group(&ch[dbcc_2g_cid], &ch[dbcc_2g_cid2]))
+ return BTC_WLINK_2G_SCC;
+ else
+ return BTC_WLINK_2G_MCC;
+}
+
+static void _update_role_link_mode(struct rtw89_dev *rtwdev,
+ bool client_joined, u32 noa)
+{
+ struct rtw89_btc_wl_role_info_v8 *rinfo_v8 = &rtwdev->btc.cx.wl.role_info_v8;
+ struct rtw89_btc_wl_role_info_v7 *rinfo_v7 = &rtwdev->btc.cx.wl.role_info_v7;
+ u8 role_ver = rtwdev->btc.ver->fwlrole;
+ u32 type = BTC_WLMROLE_NONE, dur = 0;
+ u8 link_mode, connect_cnt;
+ u32 wl_role;
+
+ if (role_ver == 7) {
+ wl_role = rinfo_v7->role_map;
+ link_mode = rinfo_v7->link_mode;
+ connect_cnt = rinfo_v7->connect_cnt;
+ } else if (role_ver == 8) {
+ wl_role = rinfo_v8->role_map;
+ link_mode = rinfo_v8->link_mode;
+ connect_cnt = rinfo_v8->connect_cnt;
+ } else {
+ return;
+ }
+
+ /* if no client_joined, don't care P2P-GO/AP role */
+ if (((wl_role & BIT(RTW89_WIFI_ROLE_P2P_GO)) ||
+ (wl_role & BIT(RTW89_WIFI_ROLE_AP))) && !client_joined) {
+ if (link_mode == BTC_WLINK_2G_SCC) {
+ if (role_ver == 7) {
+ rinfo_v7->link_mode = BTC_WLINK_2G_STA;
+ rinfo_v7->connect_cnt--;
+ } else if (role_ver == 8) {
+ rinfo_v8->link_mode = BTC_WLINK_2G_STA;
+ rinfo_v8->connect_cnt--;
+ }
+ } else if (link_mode == BTC_WLINK_2G_GO ||
+ link_mode == BTC_WLINK_2G_AP) {
+ if (role_ver == 7) {
+ rinfo_v7->link_mode = BTC_WLINK_NOLINK;
+ rinfo_v7->connect_cnt--;
+ } else if (role_ver == 8) {
+ rinfo_v8->link_mode = BTC_WLINK_NOLINK;
+ rinfo_v8->connect_cnt--;
+ }
+ }
+ }
+
+ /* Identify 2-Role type */
+ if (connect_cnt >= 2 &&
+ (link_mode == BTC_WLINK_2G_SCC ||
+ link_mode == BTC_WLINK_2G_MCC ||
+ link_mode == BTC_WLINK_25G_MCC ||
+ link_mode == BTC_WLINK_5G)) {
+ if ((wl_role & BIT(RTW89_WIFI_ROLE_P2P_GO)) ||
+ (wl_role & BIT(RTW89_WIFI_ROLE_AP)))
+ type = noa ? BTC_WLMROLE_STA_GO_NOA : BTC_WLMROLE_STA_GO;
+ else if (wl_role & BIT(RTW89_WIFI_ROLE_P2P_CLIENT))
+ type = noa ? BTC_WLMROLE_STA_GC_NOA : BTC_WLMROLE_STA_GC;
+ else
+ type = BTC_WLMROLE_STA_STA;
+
+ dur = noa;
+ }
+
+ if (role_ver == 7) {
+ rinfo_v7->mrole_type = type;
+ rinfo_v7->mrole_noa_duration = dur;
+ } else if (role_ver == 8) {
+ rinfo_v8->mrole_type = type;
+ rinfo_v8->mrole_noa_duration = dur;
+ }
+}
+
+static void _update_wl_info_v7(struct rtw89_dev *rtwdev, u8 rid)
+{
+ struct rtw89_btc_chdef cid_ch[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER];
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_wl_role_info_v7 *wl_rinfo = &wl->role_info_v7;
+ struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
+ struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info;
+ struct rtw89_btc_wl_active_role_v7 *act_role = NULL;
+ u8 i, mode, cnt = 0, cnt_2g = 0, cnt_5g = 0, phy_now = RTW89_PHY_NUM, phy_dbcc;
+ bool b2g = false, b5g = false, client_joined = false, client_inc_2g = false;
+ u8 client_cnt_last[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {};
+ u8 cid_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {};
+ u8 cid_phy[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {};
+ u8 mac = RTW89_MAC_0, dbcc_2g_phy = RTW89_PHY_0;
+ u32 noa_duration = 0;
+
+ memset(wl_rinfo, 0, sizeof(*wl_rinfo));
+
+ for (i = 0; i < RTW89_PORT_NUM; i++) {
+ if (!wl_linfo[i].active || wl_linfo[i].phy >= RTW89_PHY_NUM)
+ continue;
+
+ act_role = &wl_rinfo->active_role[i];
+ act_role->role = wl_linfo[i].role;
+
+ /* check if role connect? */
+ if (wl_linfo[i].connected == MLME_NO_LINK) {
+ act_role->connected = 0;
+ continue;
+ } else if (wl_linfo[i].connected == MLME_LINKING) {
+ continue;
+ }
+
+ cnt++;
+ act_role->connected = 1;
+ act_role->pid = wl_linfo[i].pid;
+ act_role->phy = wl_linfo[i].phy;
+ act_role->band = wl_linfo[i].band;
+ act_role->ch = wl_linfo[i].ch;
+ act_role->bw = wl_linfo[i].bw;
+ act_role->noa = wl_linfo[i].noa;
+ act_role->noa_dur = wl_linfo[i].noa_duration;
+ cid_ch[cnt - 1] = wl_linfo[i].chdef;
+ cid_phy[cnt - 1] = wl_linfo[i].phy;
+ cid_role[cnt - 1] = wl_linfo[i].role;
+ wl_rinfo->role_map |= BIT(wl_linfo[i].role);
+
+ if (rid == i)
+ phy_now = act_role->phy;
+
+ if (wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO ||
+ wl_linfo[i].role == RTW89_WIFI_ROLE_AP) {
+ if (wl_linfo[i].client_cnt > 1)
+ client_joined = true;
+ if (client_cnt_last[i] < wl_linfo[i].client_cnt &&
+ wl_linfo[i].chdef.band == RTW89_BAND_2G)
+ client_inc_2g = true;
+ act_role->client_cnt = wl_linfo[i].client_cnt;
+ } else {
+ act_role->client_cnt = 0;
+ }
+
+ if (act_role->noa && act_role->noa_dur > 0)
+ noa_duration = act_role->noa_dur;
+
+ if (rtwdev->dbcc_en) {
+ phy_dbcc = wl_linfo[i].phy;
+ wl_dinfo->role[phy_dbcc] |= BIT(wl_linfo[i].role);
+ wl_dinfo->op_band[phy_dbcc] = wl_linfo[i].chdef.band;
+ }
+
+ if (wl_linfo[i].chdef.band != RTW89_BAND_2G) {
+ cnt_5g++;
+ b5g = true;
+ } else {
+ if (((wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO ||
+ wl_linfo[i].role == RTW89_WIFI_ROLE_AP) &&
+ client_joined) ||
+ wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_CLIENT)
+ wl_rinfo->p2p_2g = 1;
+
+ if ((wl_linfo[i].mode & BIT(BTC_WL_MODE_11B)) ||
+ (wl_linfo[i].mode & BIT(BTC_WL_MODE_11G)))
+ wl->bg_mode = 1;
+ else if (wl_linfo[i].mode & BIT(BTC_WL_MODE_HE))
+ wl->he_mode = true;
+
+ cnt_2g++;
+ b2g = true;
+ }
+
+ if (act_role->band == RTW89_BAND_5G && act_role->ch >= 100)
+ wl->is_5g_hi_channel = 1;
+ else
+ wl->is_5g_hi_channel = 0;
+ }
+
+ wl_rinfo->connect_cnt = cnt;
+ wl->client_cnt_inc_2g = client_inc_2g;
+
+ if (cnt == 0) {
+ mode = BTC_WLINK_NOLINK;
+ wl_rinfo->role_map = BIT(RTW89_WIFI_ROLE_NONE);
+ } else if (!b2g && b5g) {
+ mode = BTC_WLINK_5G;
+ } else if (wl_rinfo->role_map & BIT(RTW89_WIFI_ROLE_NAN)) {
+ mode = BTC_WLINK_2G_NAN;
+ } else if (cnt > BTC_TDMA_WLROLE_MAX) {
+ mode = BTC_WLINK_OTHER;
+ } else if (rtwdev->dbcc_en) {
+ mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role, &dbcc_2g_phy);
+
+ /* correct 2G-located PHY band for gnt ctrl */
+ if (dbcc_2g_phy < RTW89_PHY_NUM)
+ wl_dinfo->op_band[dbcc_2g_phy] = RTW89_BAND_2G;
+ } else if (b2g && b5g && cnt == 2) {
+ mode = BTC_WLINK_25G_MCC;
+ } else if (!b5g && cnt == 2) { /* cnt_connect = 2 */
+ if (_chk_role_ch_group(&cid_ch[0], &cid_ch[cnt - 1]))
+ mode = BTC_WLINK_2G_SCC;
+ else
+ mode = BTC_WLINK_2G_MCC;
+ } else if (!b5g && cnt == 1) { /* cnt_connect = 1 */
+ mode = _get_role_link_mode(cid_role[0]);
+ } else {
+ mode = BTC_WLINK_NOLINK;
+ }
+
+ wl_rinfo->link_mode = mode;
+ _update_role_link_mode(rtwdev, client_joined, noa_duration);
+
+ /* todo DBCC related event */
+ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] wl_info phy_now=%d\n", phy_now);
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC] rlink cnt_2g=%d cnt_5g=%d\n", cnt_2g, cnt_5g);
+
+ if (wl_rinfo->dbcc_en != rtwdev->dbcc_en) {
+ wl_rinfo->dbcc_chg = 1;
+ wl_rinfo->dbcc_en = rtwdev->dbcc_en;
+ btc->cx.cnt_wl[BTC_WCNT_DBCC_CHG]++;
+ }
+
+ if (rtwdev->dbcc_en) {
+ wl_rinfo->dbcc_2g_phy = dbcc_2g_phy;
+
+ if (dbcc_2g_phy == RTW89_PHY_1)
+ mac = RTW89_MAC_1;
+
+ _update_dbcc_band(rtwdev, RTW89_PHY_0);
+ _update_dbcc_band(rtwdev, RTW89_PHY_1);
+ }
+ _wl_req_mac(rtwdev, mac);
+ _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE);
+}
+
+static void _update_wl_info_v8(struct rtw89_dev *rtwdev, u8 role_id, u8 rlink_id,
+ enum btc_role_state state)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_chdef cid_ch[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER];
+ struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8;
+ struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
+ bool client_joined = false, b2g = false, b5g = false;
+ u8 cid_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {};
+ u8 cid_phy[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {};
+ u8 dbcc_en = 0, pta_req_band = RTW89_MAC_0;
+ u8 i, j, cnt = 0, cnt_2g = 0, cnt_5g = 0;
+ struct rtw89_btc_wl_link_info *wl_linfo;
+ struct rtw89_btc_wl_rlink *rlink = NULL;
+ u8 dbcc_2g_phy = RTW89_PHY_0;
+ u8 mode = BTC_WLINK_NOLINK;
+ u32 noa_dur = 0;
+
+ if (role_id >= RTW89_BE_BTC_WL_MAX_ROLE_NUMBER || rlink_id > RTW89_MAC_1)
+ return;
+
+ /* Extract wl->link_info[role_id][rlink_id] to wl->role_info
+ * role_id: role index
+ * rlink_id: rlink index (= HW-band index)
+ * pid: port_index
+ */
+
+ wl_linfo = &wl->rlink_info[role_id][rlink_id];
+ if (wl_linfo->connected == MLME_LINKING)
+ return;
+
+ rlink = &wl_rinfo->rlink[role_id][rlink_id];
+ rlink->role = wl_linfo->role;
+ rlink->active = wl_linfo->active; /* Doze or not */
+ rlink->pid = wl_linfo->pid;
+ rlink->phy = wl_linfo->phy;
+ rlink->rf_band = wl_linfo->band;
+ rlink->ch = wl_linfo->ch;
+ rlink->bw = wl_linfo->bw;
+ rlink->noa = wl_linfo->noa;
+ rlink->noa_dur = wl_linfo->noa_duration / 1000;
+ rlink->client_cnt = wl_linfo->client_cnt;
+ rlink->mode = wl_linfo->mode;
+
+ switch (wl_linfo->connected) {
+ case MLME_NO_LINK:
+ rlink->connected = 0;
+ if (rlink->role == RTW89_WIFI_ROLE_STATION)
+ btc->dm.leak_ap = 0;
+ break;
+ case MLME_LINKED:
+ rlink->connected = 1;
+ break;
+ default:
+ return;
+ }
+
+ wl->is_5g_hi_channel = false;
+ wl->bg_mode = false;
+ wl_rinfo->role_map = 0;
+ wl_rinfo->p2p_2g = 0;
+ memset(cid_ch, 0, sizeof(cid_ch));
+
+ for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) {
+ for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) {
+ rlink = &wl_rinfo->rlink[i][j];
+
+ if (!rlink->active || !rlink->connected)
+ continue;
+
+ cnt++;
+ wl_rinfo->role_map |= BIT(rlink->role);
+
+ /* only if client connect for p2p-Go/AP */
+ if ((rlink->role == RTW89_WIFI_ROLE_P2P_GO ||
+ rlink->role == RTW89_WIFI_ROLE_AP) &&
+ rlink->client_cnt > 1)
+ client_joined = true;
+
+ /* Identufy if P2P-Go (GO/GC/AP) exist at 2G band*/
+ if (rlink->rf_band == RTW89_BAND_2G &&
+ (client_joined || rlink->role == RTW89_WIFI_ROLE_P2P_CLIENT))
+ wl_rinfo->p2p_2g = 1;
+
+ /* only one noa-role exist */
+ if (rlink->noa && rlink->noa_dur > 0)
+ noa_dur = rlink->noa_dur;
+
+ /* for WL 5G-Rx interfered with BT issue */
+ if (rlink->rf_band == RTW89_BAND_5G && rlink->ch >= 100)
+ wl->is_5g_hi_channel = 1;
+
+ if ((rlink->mode & BIT(BTC_WL_MODE_11B)) ||
+ (rlink->mode & BIT(BTC_WL_MODE_11G)))
+ wl->bg_mode = 1;
+
+ if (rtwdev->chip->para_ver & BTC_FEAT_MLO_SUPPORT)
+ continue;
+
+ cid_ch[cnt - 1] = wl_linfo->chdef;
+ cid_phy[cnt - 1] = rlink->phy;
+ cid_role[cnt - 1] = rlink->role;
+
+ if (rlink->rf_band != RTW89_BAND_2G) {
+ cnt_5g++;
+ b5g = true;
+ } else {
+ cnt_2g++;
+ b2g = true;
+ }
+ }
+ }
+
+ if (rtwdev->chip->para_ver & BTC_FEAT_MLO_SUPPORT) {
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC] rlink cnt_2g=%d cnt_5g=%d\n", cnt_2g, cnt_5g);
+ rtw89_warn(rtwdev, "not support MLO feature yet");
+ } else {
+ dbcc_en = rtwdev->dbcc_en;
+
+ /* Be careful to change the following sequence!! */
+ if (cnt == 0) {
+ mode = BTC_WLINK_NOLINK;
+ } else if (!b2g && b5g) {
+ mode = BTC_WLINK_5G;
+ } else if (wl_rinfo->role_map & BIT(RTW89_WIFI_ROLE_NAN)) {
+ mode = BTC_WLINK_2G_NAN;
+ } else if (cnt > BTC_TDMA_WLROLE_MAX) {
+ mode = BTC_WLINK_OTHER;
+ } else if (dbcc_en) {
+ mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role,
+ &dbcc_2g_phy);
+ } else if (b2g && b5g && cnt == 2) {
+ mode = BTC_WLINK_25G_MCC;
+ } else if (!b5g && cnt == 2) { /* cnt_connect = 2 */
+ if (_chk_role_ch_group(&cid_ch[0], &cid_ch[cnt - 1]))
+ mode = BTC_WLINK_2G_SCC;
+ else
+ mode = BTC_WLINK_2G_MCC;
+ } else if (!b5g && cnt == 1) { /* cnt_connect = 1 */
+ mode = _get_role_link_mode(cid_role[0]);
+ }
+ }
+
+ wl_rinfo->link_mode = mode;
+ wl_rinfo->connect_cnt = cnt;
+ if (wl_rinfo->connect_cnt == 0)
+ wl_rinfo->role_map = BIT(RTW89_WIFI_ROLE_NONE);
+ _update_role_link_mode(rtwdev, client_joined, noa_dur);
+
+ wl_rinfo->dbcc_2g_phy = dbcc_2g_phy;
+ if (wl_rinfo->dbcc_en != dbcc_en) {
+ wl_rinfo->dbcc_en = dbcc_en;
+ wl_rinfo->dbcc_chg = 1;
+ btc->cx.cnt_wl[BTC_WCNT_DBCC_CHG]++;
+ } else {
+ wl_rinfo->dbcc_chg = 0;
+ }
+
+ if (wl_rinfo->dbcc_en) {
+ memset(wl_dinfo, 0, sizeof(struct rtw89_btc_wl_dbcc_info));
+
+ if (mode == BTC_WLINK_5G) {
+ pta_req_band = RTW89_PHY_0;
+ wl_dinfo->op_band[RTW89_PHY_0] = RTW89_BAND_5G;
+ wl_dinfo->op_band[RTW89_PHY_1] = RTW89_BAND_2G;
+ } else if (wl_rinfo->dbcc_2g_phy == RTW89_PHY_1) {
+ pta_req_band = RTW89_PHY_1;
+ wl_dinfo->op_band[RTW89_PHY_0] = RTW89_BAND_5G;
+ wl_dinfo->op_band[RTW89_PHY_1] = RTW89_BAND_2G;
+ } else {
+ pta_req_band = RTW89_PHY_0;
+ wl_dinfo->op_band[RTW89_PHY_0] = RTW89_BAND_2G;
+ wl_dinfo->op_band[RTW89_PHY_1] = RTW89_BAND_5G;
+ }
+ _update_dbcc_band(rtwdev, RTW89_PHY_0);
+ _update_dbcc_band(rtwdev, RTW89_PHY_1);
+ }
+
+ wl_rinfo->pta_req_band = pta_req_band;
+ _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE);
+}
+
+void rtw89_coex_act1_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
coex_act1_work.work);
@@ -5296,7 +6718,8 @@ void rtw89_coex_act1_work(struct work_struct *work)
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &cx->wl;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(wiphy);
+
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__);
dm->cnt_notify[BTC_NCNT_TIMER]++;
if (wl->status.map._4way)
@@ -5305,10 +6728,9 @@ void rtw89_coex_act1_work(struct work_struct *work)
wl->status.map.connecting = false;
_run_coex(rtwdev, BTC_RSN_ACT1_WORK);
- mutex_unlock(&rtwdev->mutex);
}
-void rtw89_coex_bt_devinfo_work(struct work_struct *work)
+void rtw89_coex_bt_devinfo_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
coex_bt_devinfo_work.work);
@@ -5316,15 +6738,15 @@ void rtw89_coex_bt_devinfo_work(struct work_struct *work)
struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(wiphy);
+
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__);
dm->cnt_notify[BTC_NCNT_TIMER]++;
a2dp->play_latency = 0;
_run_coex(rtwdev, BTC_RSN_BT_DEVINFO_WORK);
- mutex_unlock(&rtwdev->mutex);
}
-void rtw89_coex_rfk_chk_work(struct work_struct *work)
+void rtw89_coex_rfk_chk_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
coex_rfk_chk_work.work);
@@ -5333,7 +6755,8 @@ void rtw89_coex_rfk_chk_work(struct work_struct *work)
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &cx->wl;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(wiphy);
+
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__);
dm->cnt_notify[BTC_NCNT_TIMER]++;
if (wl->rfk_info.state != BTC_WRFK_STOP) {
@@ -5345,7 +6768,6 @@ void rtw89_coex_rfk_chk_work(struct work_struct *work)
_write_scbd(rtwdev, BTC_WSCB_WLRFK, false);
_run_coex(rtwdev, BTC_RSN_RFK_CHK_WORK);
}
- mutex_unlock(&rtwdev->mutex);
}
static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update)
@@ -5445,9 +6867,11 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
+ struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
+ struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
u8 mode, igno_bt, always_freerun;
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
dm->run_reason = reason;
_update_dm_step(rtwdev, reason);
@@ -5459,6 +6883,10 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
mode = wl_rinfo_v1->link_mode;
else if (ver->fwlrole == 2)
mode = wl_rinfo_v2->link_mode;
+ else if (ver->fwlrole == 7)
+ mode = wl_rinfo_v7->link_mode;
+ else if (ver->fwlrole == 8)
+ mode = wl_rinfo_v8->link_mode;
else
return;
@@ -5523,6 +6951,8 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
bt->scan_rx_low_pri = false;
igno_bt = false;
+ dm->freerun_chk = _check_freerun(rtwdev); /* check if meet freerun */
+
if (always_freerun) {
_action_freerun(rtwdev);
igno_bt = true;
@@ -5561,18 +6991,9 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
goto exit;
}
- if (cx->state_map == BTC_WLINKING) {
- if (mode == BTC_WLINK_NOLINK || mode == BTC_WLINK_2G_STA ||
- mode == BTC_WLINK_5G) {
- _action_wl_scan(rtwdev);
- bt->scan_rx_low_pri = false;
- goto exit;
- }
- }
-
- if (wl->status.map.scan) {
+ if (wl->status.val & btc_scanning_map.val && !wl->rfk_info.con_rfk) {
_action_wl_scan(rtwdev);
- bt->scan_rx_low_pri = false;
+ bt->scan_rx_low_pri = true;
goto exit;
}
@@ -5603,8 +7024,10 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
_action_wl_2g_scc(rtwdev);
else if (ver->fwlrole == 1)
_action_wl_2g_scc_v1(rtwdev);
- else if (ver->fwlrole == 2)
+ else if (ver->fwlrole == 2 || ver->fwlrole == 7)
_action_wl_2g_scc_v2(rtwdev);
+ else if (ver->fwlrole == 8)
+ _action_wl_2g_scc_v8(rtwdev);
break;
case BTC_WLINK_2G_MCC:
bt->scan_rx_low_pri = true;
@@ -5736,8 +7159,8 @@ void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode)
_set_init_info(rtwdev);
_set_wl_tx_power(rtwdev, RTW89_BTC_WL_DEF_TX_PWR);
- rtw89_btc_fw_set_slots(rtwdev, CXST_MAX, dm->slot);
btc_fw_set_monreg(rtwdev);
+ rtw89_btc_fw_set_slots(rtwdev);
_fw_set_drv_info(rtwdev, CXDRVINFO_INIT);
_fw_set_drv_info(rtwdev, CXDRVINFO_CTRL);
@@ -5753,7 +7176,7 @@ void rtw89_btc_ntfy_scan_start(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band)
"[BTC], %s(): phy_idx=%d, band=%d\n",
__func__, phy_idx, band);
- if (phy_idx >= RTW89_PHY_MAX)
+ if (phy_idx >= RTW89_PHY_NUM)
return;
btc->dm.cnt_notify[BTC_NCNT_SCAN_START]++;
@@ -5789,6 +7212,8 @@ void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx)
_fw_set_drv_info(rtwdev, CXDRVINFO_DBCC);
}
+ btc->dm.tdma_instant_excute = 1;
+
_run_coex(rtwdev, BTC_RSN_NTFY_SCAN_FINISH);
}
@@ -5801,15 +7226,11 @@ void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band)
"[BTC], %s(): phy_idx=%d, band=%d\n",
__func__, phy_idx, band);
- if (phy_idx >= RTW89_PHY_MAX)
+ if (phy_idx >= RTW89_PHY_NUM)
return;
btc->dm.cnt_notify[BTC_NCNT_SWITCH_BAND]++;
- wl->scan_info.band[phy_idx] = band;
- wl->scan_info.phy_map |= BIT(phy_idx);
- _fw_set_drv_info(rtwdev, CXDRVINFO_SCAN);
-
if (rtwdev->dbcc_en) {
wl->dbcc_info.scan_band[phy_idx] = band;
_update_dbcc_band(rtwdev, phy_idx);
@@ -5854,7 +7275,7 @@ void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev,
"[BTC], %s(): EAPOL_End cnt=%d\n",
__func__, cnt);
wl->status.map._4way = false;
- cancel_delayed_work(&rtwdev->coex_act1_work);
+ wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->coex_act1_work);
break;
case PACKET_ARP:
cnt = ++cx->cnt_wl[BTC_WCNT_ARP];
@@ -5873,56 +7294,56 @@ void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev,
}
if (delay_work) {
- cancel_delayed_work(&rtwdev->coex_act1_work);
- ieee80211_queue_delayed_work(rtwdev->hw,
- &rtwdev->coex_act1_work, delay);
+ wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->coex_act1_work);
+ wiphy_delayed_work_queue(rtwdev->hw->wiphy,
+ &rtwdev->coex_act1_work, delay);
}
btc->dm.cnt_notify[BTC_NCNT_SPECIAL_PACKET]++;
_run_coex(rtwdev, BTC_RSN_NTFY_SPECIFIC_PACKET);
}
-void rtw89_btc_ntfy_eapol_packet_work(struct work_struct *work)
+void rtw89_btc_ntfy_eapol_packet_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
btc.eapol_notify_work);
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(wiphy);
+
rtw89_leave_ps_mode(rtwdev);
rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_EAPOL);
- mutex_unlock(&rtwdev->mutex);
}
-void rtw89_btc_ntfy_arp_packet_work(struct work_struct *work)
+void rtw89_btc_ntfy_arp_packet_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
btc.arp_notify_work);
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(wiphy);
+
rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_ARP);
- mutex_unlock(&rtwdev->mutex);
}
-void rtw89_btc_ntfy_dhcp_packet_work(struct work_struct *work)
+void rtw89_btc_ntfy_dhcp_packet_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
btc.dhcp_notify_work);
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(wiphy);
+
rtw89_leave_ps_mode(rtwdev);
rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_DHCP);
- mutex_unlock(&rtwdev->mutex);
}
-void rtw89_btc_ntfy_icmp_packet_work(struct work_struct *work)
+void rtw89_btc_ntfy_icmp_packet_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
btc.icmp_notify_work);
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(wiphy);
+
rtw89_leave_ps_mode(rtwdev);
rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_ICMP);
- mutex_unlock(&rtwdev->mutex);
}
static u8 _update_bt_rssi_level(struct rtw89_dev *rtwdev, u8 rssi)
@@ -5956,6 +7377,22 @@ static u8 _update_bt_rssi_level(struct rtw89_dev *rtwdev, u8 rssi)
return rssi_level;
}
+static void _update_zb_coex_tbl(struct rtw89_dev *rtwdev)
+{
+ u8 mode = rtwdev->btc.cx.wl.role_info.link_mode;
+ u32 zb_tbl0 = 0xda5a5a5a, zb_tbl1 = 0xda5a5a5a;
+
+ if (mode == BTC_WLINK_5G || rtwdev->btc.dm.freerun) {
+ zb_tbl0 = 0xffffffff;
+ zb_tbl1 = 0xffffffff;
+ } else if (mode == BTC_WLINK_25G_MCC) {
+ zb_tbl0 = 0xffffffff; /* for E5G slot */
+ zb_tbl1 = 0xda5a5a5a; /* for E2G slot */
+ }
+ rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_0, zb_tbl0);
+ rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_1, zb_tbl1);
+}
+
#define BT_PROFILE_PROTOCOL_MASK GENMASK(7, 4)
static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
@@ -5988,13 +7425,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
"[BTC], %s(): bt_info[2]=0x%02x\n",
__func__, bt->raw_info[2]);
- /* reset to mo-connect before update */
- b->status.val = BTC_BLINK_NOCONNECT;
b->profile_cnt.last = b->profile_cnt.now;
- b->relink.last = b->relink.now;
- a2dp->exist_last = a2dp->exist;
- b->multi_link.last = b->multi_link.now;
- bt->inq_pag.last = bt->inq_pag.now;
b->profile_cnt.now = 0;
hid->type = 0;
@@ -6013,7 +7444,8 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
b->profile_cnt.now += (u8)hid->exist;
a2dp->exist = btinfo.lb2.a2dp;
b->profile_cnt.now += (u8)a2dp->exist;
- pan->active = btinfo.lb2.pan;
+ pan->exist = btinfo.lb2.pan;
+ b->profile_cnt.now += (u8)pan->exist;
btc->dm.trx_info.bt_profile = u32_get_bits(btinfo.val, BT_PROFILE_PROTOCOL_MASK);
/* parse raw info low-Byte3 */
@@ -6037,8 +7469,14 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
/* parse raw info high-Byte1 */
btinfo.val = bt->raw_info[BTC_BTINFO_H1];
b->status.map.ble_connect = btinfo.hb1.ble_connect;
- if (btinfo.hb1.ble_connect)
- hid->type |= (hid->exist ? BTC_HID_BLE : BTC_HID_RCU);
+ if (btinfo.hb1.ble_connect) {
+ if (hid->exist)
+ hid->type |= BTC_HID_BLE;
+ else if (btinfo.hb1.voice)
+ hid->type |= BTC_HID_RCU_VOICE;
+ else
+ hid->type |= BTC_HID_RCU;
+ }
cx->cnt_bt[BTC_BCNT_REINIT] += !!(btinfo.hb1.reinit && !bt->reinit);
bt->reinit = btinfo.hb1.reinit;
@@ -6050,7 +7488,6 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
if (bt->igno_wl && !cx->wl.status.map.rf_off)
_set_bt_ignore_wlan_act(rtwdev, false);
- hid->type |= (btinfo.hb1.voice ? BTC_HID_RCU_VOICE : 0);
bt->ble_scan_en = btinfo.hb1.ble_scan;
cx->cnt_bt[BTC_BCNT_ROLESW] += !!(btinfo.hb1.role_sw && !b->role_sw);
@@ -6060,8 +7497,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
/* parse raw info high-Byte2 */
btinfo.val = bt->raw_info[BTC_BTINFO_H2];
- pan->exist = btinfo.hb2.pan_active;
- b->profile_cnt.now += (u8)pan->exist;
+ pan->active = !!btinfo.hb2.pan_active;
cx->cnt_bt[BTC_BCNT_AFH] += !!(btinfo.hb2.afh_update && !b->afh_update);
b->afh_update = btinfo.hb2.afh_update;
@@ -6069,8 +7505,9 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
b->slave_role = btinfo.hb2.slave;
hid->slot_info = btinfo.hb2.hid_slot;
hid->pair_cnt = btinfo.hb2.hid_cnt;
- hid->type |= (hid->slot_info == BTC_HID_218 ?
- BTC_HID_218 : BTC_HID_418);
+ if (!b->status.map.ble_connect || hid->pair_cnt > 1)
+ hid->type |= (hid->slot_info == BTC_HID_218 ?
+ BTC_HID_218 : BTC_HID_418);
/* parse raw info high-Byte3 */
btinfo.val = bt->raw_info[BTC_BTINFO_H3];
a2dp->bitpool = btinfo.hb3.a2dp_bitpool;
@@ -6085,99 +7522,136 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
a2dp->vendor_id = 0;
a2dp->flush_time = 0;
a2dp->play_latency = 1;
- ieee80211_queue_delayed_work(rtwdev->hw,
- &rtwdev->coex_bt_devinfo_work,
- RTW89_COEX_BT_DEVINFO_WORK_PERIOD);
+ wiphy_delayed_work_queue(rtwdev->hw->wiphy,
+ &rtwdev->coex_bt_devinfo_work,
+ RTW89_COEX_BT_DEVINFO_WORK_PERIOD);
}
_run_coex(rtwdev, BTC_RSN_UPDATE_BT_INFO);
}
-enum btc_wl_mode {
- BTC_WL_MODE_HT = 0,
- BTC_WL_MODE_VHT = 1,
- BTC_WL_MODE_HE = 2,
- BTC_WL_MODE_NUM,
-};
-
-void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta, enum btc_role_state state)
+void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ enum btc_role_state state)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->sub_entity_idx);
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
- struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
+ rtwvif_link->chanctx_idx);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct ieee80211_bss_conf *bss_conf;
+ struct ieee80211_link_sta *link_sta;
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_link_info r = {0};
struct rtw89_btc_wl_link_info *wlinfo = NULL;
- u8 mode = 0;
+ u8 mode = 0, rlink_id, link_mode_ori, pta_req_mac_ori, wa_type;
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], state=%d\n", state);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], role is STA=%d\n",
vif->type == NL80211_IFTYPE_STATION);
- rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", rtwvif->port);
+ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", rtwvif_link->port);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], band=%d ch=%d bw=%d\n",
chan->band_type, chan->channel, chan->band_width);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], associated=%d\n",
state == BTC_ROLE_MSTS_STA_CONN_END);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], bcn_period=%d dtim_period=%d\n",
- vif->bss_conf.beacon_int, vif->bss_conf.dtim_period);
+ bss_conf->beacon_int, bss_conf->dtim_period);
+
+ if (rtwsta_link) {
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
- if (rtwsta) {
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], STA mac_id=%d\n",
- rtwsta->mac_id);
+ rtwsta_link->mac_id);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], STA support HE=%d VHT=%d HT=%d\n",
- sta->deflink.he_cap.has_he,
- sta->deflink.vht_cap.vht_supported,
- sta->deflink.ht_cap.ht_supported);
- if (sta->deflink.he_cap.has_he)
+ link_sta->he_cap.has_he,
+ link_sta->vht_cap.vht_supported,
+ link_sta->ht_cap.ht_supported);
+ if (link_sta->he_cap.has_he)
mode |= BIT(BTC_WL_MODE_HE);
- if (sta->deflink.vht_cap.vht_supported)
+ if (link_sta->vht_cap.vht_supported)
mode |= BIT(BTC_WL_MODE_VHT);
- if (sta->deflink.ht_cap.ht_supported)
+ if (link_sta->ht_cap.ht_supported)
mode |= BIT(BTC_WL_MODE_HT);
r.mode = mode;
}
- if (rtwvif->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX)
+ if (rtwvif_link->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX) {
+ rcu_read_unlock();
return;
+ }
rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], wifi_role=%d\n", rtwvif->wifi_role);
+ "[BTC], wifi_role=%d\n", rtwvif_link->wifi_role);
- r.role = rtwvif->wifi_role;
- r.phy = rtwvif->phy_idx;
- r.pid = rtwvif->port;
+ r.role = rtwvif_link->wifi_role;
+ r.phy = rtwvif_link->phy_idx;
+ r.pid = rtwvif_link->port;
r.active = true;
r.connected = MLME_LINKED;
- r.bcn_period = vif->bss_conf.beacon_int;
- r.dtim_period = vif->bss_conf.dtim_period;
+ r.bcn_period = bss_conf->beacon_int;
+ r.dtim_period = bss_conf->dtim_period;
r.band = chan->band_type;
r.ch = chan->channel;
r.bw = chan->band_width;
- ether_addr_copy(r.mac_addr, rtwvif->mac_addr);
+ r.chdef.band = chan->band_type;
+ r.chdef.center_ch = chan->channel;
+ r.chdef.bw = chan->band_width;
+ r.chdef.chan = chan->primary_channel;
+ ether_addr_copy(r.mac_addr, rtwvif_link->mac_addr);
+
+ rcu_read_unlock();
- if (rtwsta && vif->type == NL80211_IFTYPE_STATION)
- r.mac_id = rtwsta->mac_id;
+ if (rtwsta_link && vif->type == NL80211_IFTYPE_STATION)
+ r.mac_id = rtwsta_link->mac_id;
btc->dm.cnt_notify[BTC_NCNT_ROLE_INFO]++;
wlinfo = &wl->link_info[r.pid];
- memcpy(wlinfo, &r, sizeof(*wlinfo));
- if (ver->fwlrole == 0)
+ rlink_id = 0; /* to do */
+ if (ver->fwlrole == 0) {
+ *wlinfo = r;
_update_wl_info(rtwdev);
- else if (ver->fwlrole == 1)
+ } else if (ver->fwlrole == 1) {
+ *wlinfo = r;
_update_wl_info_v1(rtwdev);
- else if (ver->fwlrole == 2)
+ } else if (ver->fwlrole == 2) {
+ *wlinfo = r;
_update_wl_info_v2(rtwdev);
+ } else if (ver->fwlrole == 7) {
+ *wlinfo = r;
+ _update_wl_info_v7(rtwdev, r.pid);
+ } else if (ver->fwlrole == 8) {
+ wlinfo = &wl->rlink_info[r.pid][rlink_id];
+ *wlinfo = r;
+ link_mode_ori = wl->role_info_v8.link_mode;
+ pta_req_mac_ori = wl->pta_req_mac;
+ _update_wl_info_v8(rtwdev, r.pid, rlink_id, state);
+
+ if (wl->role_info_v8.link_mode != link_mode_ori) {
+ wl->role_info_v8.link_mode_chg = 1;
+ if (ver->fcxinit == 7)
+ wa_type = btc->mdinfo.md_v7.wa_type;
+ else
+ wa_type = btc->mdinfo.md.wa_type;
+
+ if (wa_type & BTC_WA_HFP_ZB)
+ _update_zb_coex_tbl(rtwdev);
+ }
+
+ if (wl->pta_req_mac != pta_req_mac_ori)
+ wl->pta_reg_mac_chg = 1;
+ }
if (wlinfo->role == RTW89_WIFI_ROLE_STATION &&
wlinfo->connected == MLME_NO_LINK)
@@ -6188,7 +7662,8 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif
else
wl->status.map.connecting = 0;
- if (state == BTC_ROLE_MSTS_STA_DIS_CONN)
+ if (state == BTC_ROLE_MSTS_STA_DIS_CONN ||
+ state == BTC_ROLE_MSTS_STA_CONN_END)
wl->status.map._4way = false;
_run_coex(rtwdev, BTC_RSN_NTFY_ROLE_INFO);
@@ -6298,7 +7773,7 @@ static bool _ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_path,
wl->rfk_info.state = BTC_WRFK_STOP;
_write_scbd(rtwdev, BTC_WSCB_WLRFK, false);
- cancel_delayed_work(&rtwdev->coex_rfk_chk_work);
+ wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->coex_rfk_chk_work);
break;
default:
rtw89_debug(rtwdev, RTW89_DBG_BTC,
@@ -6312,9 +7787,9 @@ static bool _ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_path,
_run_coex(rtwdev, BTC_RSN_NTFY_WL_RFK);
if (wl->rfk_info.state == BTC_WRFK_START)
- ieee80211_queue_delayed_work(rtwdev->hw,
- &rtwdev->coex_rfk_chk_work,
- RTW89_COEX_RFK_CHK_WORK_PERIOD);
+ wiphy_delayed_work_queue(rtwdev->hw->wiphy,
+ &rtwdev->coex_rfk_chk_work,
+ RTW89_COEX_RFK_CHK_WORK_PERIOD);
}
rtw89_debug(rtwdev, RTW89_DBG_BTC,
@@ -6332,6 +7807,8 @@ void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map,
bool allow;
int ret;
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
band = FIELD_GET(BTC_RFK_BAND_MAP, phy_map);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
@@ -6369,26 +7846,26 @@ struct rtw89_btc_wl_sta_iter_data {
bool is_traffic_change;
};
-static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
+static
+void __rtw89_btc_ntfy_wl_sta_iter(struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ struct rtw89_btc_wl_sta_iter_data *iter_data)
{
- struct rtw89_btc_wl_sta_iter_data *iter_data =
- (struct rtw89_btc_wl_sta_iter_data *)data;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_dev *rtwdev = iter_data->rtwdev;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &btc->dm;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_link_info *link_info = NULL;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_traffic_stats *link_info_t = NULL;
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_traffic_stats *stats = &rtwvif->stats;
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc_wl_role_info *r;
struct rtw89_btc_wl_role_info_v1 *r1;
u32 last_tx_rate, last_rx_rate;
u16 last_tx_lvl, last_rx_lvl;
- u8 port = rtwvif->port;
+ u8 port = rtwvif_link->port;
u8 rssi;
u8 busy = 0;
u8 dir = 0;
@@ -6396,11 +7873,11 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
u8 i = 0;
bool is_sta_change = false, is_traffic_change = false;
- rssi = ewma_rssi_read(&rtwsta->avg_rssi) >> RSSI_FACTOR;
+ rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR;
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], rssi=%d\n", rssi);
link_info = &wl->link_info[port];
- link_info->stat.traffic = rtwvif->stats;
+ link_info->stat.traffic = *stats;
link_info_t = &link_info->stat.traffic;
if (link_info->connected == MLME_NO_LINK) {
@@ -6448,19 +7925,19 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
iter_data->busy_all |= busy;
iter_data->dir_all |= BIT(dir);
- if (rtwsta->rx_hw_rate <= RTW89_HW_RATE_CCK2 &&
+ if (rtwsta_link->rx_hw_rate <= RTW89_HW_RATE_CCK2 &&
last_rx_rate > RTW89_HW_RATE_CCK2 &&
link_info_t->rx_tfc_lv > RTW89_TFC_IDLE)
link_info->rx_rate_drop_cnt++;
- if (last_tx_rate != rtwsta->ra_report.hw_rate ||
- last_rx_rate != rtwsta->rx_hw_rate ||
+ if (last_tx_rate != rtwsta_link->ra_report.hw_rate ||
+ last_rx_rate != rtwsta_link->rx_hw_rate ||
last_tx_lvl != link_info_t->tx_tfc_lv ||
last_rx_lvl != link_info_t->rx_tfc_lv)
is_traffic_change = true;
- link_info_t->tx_rate = rtwsta->ra_report.hw_rate;
- link_info_t->rx_rate = rtwsta->rx_hw_rate;
+ link_info_t->tx_rate = rtwsta_link->ra_report.hw_rate;
+ link_info_t->rx_rate = rtwsta_link->rx_hw_rate;
if (link_info->role == RTW89_WIFI_ROLE_STATION ||
link_info->role == RTW89_WIFI_ROLE_P2P_CLIENT) {
@@ -6472,19 +7949,19 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
r = &wl->role_info;
r->active_role[port].tx_lvl = stats->tx_tfc_lv;
r->active_role[port].rx_lvl = stats->rx_tfc_lv;
- r->active_role[port].tx_rate = rtwsta->ra_report.hw_rate;
- r->active_role[port].rx_rate = rtwsta->rx_hw_rate;
+ r->active_role[port].tx_rate = rtwsta_link->ra_report.hw_rate;
+ r->active_role[port].rx_rate = rtwsta_link->rx_hw_rate;
} else if (ver->fwlrole == 1) {
r1 = &wl->role_info_v1;
r1->active_role_v1[port].tx_lvl = stats->tx_tfc_lv;
r1->active_role_v1[port].rx_lvl = stats->rx_tfc_lv;
- r1->active_role_v1[port].tx_rate = rtwsta->ra_report.hw_rate;
- r1->active_role_v1[port].rx_rate = rtwsta->rx_hw_rate;
+ r1->active_role_v1[port].tx_rate = rtwsta_link->ra_report.hw_rate;
+ r1->active_role_v1[port].rx_rate = rtwsta_link->rx_hw_rate;
} else if (ver->fwlrole == 2) {
dm->trx_info.tx_lvl = stats->tx_tfc_lv;
dm->trx_info.rx_lvl = stats->rx_tfc_lv;
- dm->trx_info.tx_rate = rtwsta->ra_report.hw_rate;
- dm->trx_info.rx_rate = rtwsta->rx_hw_rate;
+ dm->trx_info.tx_rate = rtwsta_link->ra_report.hw_rate;
+ dm->trx_info.rx_rate = rtwsta_link->rx_hw_rate;
}
dm->trx_info.tx_tp = link_info_t->tx_throughput;
@@ -6504,6 +7981,21 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
iter_data->is_traffic_change = true;
}
+static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_btc_wl_sta_iter_data *iter_data =
+ (struct rtw89_btc_wl_sta_iter_data *)data;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ __rtw89_btc_ntfy_wl_sta_iter(rtwvif_link, rtwsta_link, iter_data);
+ }
+}
+
#define BTC_NHM_CHK_INTVL 20
void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev)
@@ -6553,6 +8045,53 @@ void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev)
}
}
+static u8 rtw89_btc_c2h_get_index_by_ver(struct rtw89_dev *rtwdev, u8 func)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ const struct rtw89_btc_ver *ver = btc->ver;
+
+ switch (func) {
+ case BTF_EVNT_RPT:
+ case BTF_EVNT_BT_INFO:
+ case BTF_EVNT_BT_SCBD:
+ case BTF_EVNT_BT_REG:
+ case BTF_EVNT_CX_RUNINFO:
+ case BTF_EVNT_BT_PSD:
+ return func;
+ case BTF_EVNT_BT_DEV_INFO:
+ if (ver->fwc2hfunc == 0)
+ return BTF_EVNT_BUF_OVERFLOW;
+ else
+ return BTF_EVNT_BT_DEV_INFO;
+ case BTF_EVNT_BT_LEAUDIO_INFO:
+ if (ver->fwc2hfunc == 0)
+ return BTF_EVNT_C2H_LOOPBACK;
+ else if (ver->fwc2hfunc == 1)
+ return BTF_EVNT_BUF_OVERFLOW;
+ else if (ver->fwc2hfunc == 2)
+ return func;
+ else
+ return BTF_EVNT_MAX;
+ case BTF_EVNT_BUF_OVERFLOW:
+ if (ver->fwc2hfunc == 0)
+ return BTF_EVNT_MAX;
+ else if (ver->fwc2hfunc == 1)
+ return BTF_EVNT_C2H_LOOPBACK;
+ else if (ver->fwc2hfunc == 2)
+ return func;
+ else
+ return BTF_EVNT_MAX;
+ case BTF_EVNT_C2H_LOOPBACK:
+ if (ver->fwc2hfunc == 2)
+ return func;
+ else
+ return BTF_EVNT_MAX;
+ case BTF_EVNT_MAX:
+ default:
+ return BTF_EVNT_MAX;
+ }
+}
+
void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u32 len, u8 class, u8 func)
{
@@ -6569,10 +8108,15 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
if (class != BTFC_FW_EVENT)
return;
+ func = rtw89_btc_c2h_get_index_by_ver(rtwdev, func);
+ pfwinfo->cnt_c2h++;
+
switch (func) {
- case BTF_EVNT_RPT:
case BTF_EVNT_BUF_OVERFLOW:
pfwinfo->event[func]++;
+ break;
+ case BTF_EVNT_RPT:
+ pfwinfo->event[func]++;
/* Don't need rtw89_leave_ps_mode() */
btc_fw_event(rtwdev, func, buf, len);
break;
@@ -6607,7 +8151,7 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
#define BTC_CX_FW_OFFLOAD 0
-static void _show_cx_info(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_cx_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
union rtw89_btc_module_info *md = &rtwdev->btc.mdinfo;
const struct rtw89_chip_info *chip = rtwdev->chip;
@@ -6619,40 +8163,43 @@ static void _show_cx_info(struct rtw89_dev *rtwdev, struct seq_file *m)
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
u32 ver_main = 0, ver_sub = 0, ver_hotfix = 0, id_branch = 0;
u8 cv, rfe, iso, ant_num, ant_single_pos;
+ char *p = buf, *end = buf + bufsz;
if (!(dm->coex_info_map & BTC_COEX_INFO_CX))
- return;
+ return 0;
dm->cnt_notify[BTC_NCNT_SHOW_COEX_INFO]++;
- seq_printf(m, "========== [BTC COEX INFO (%d)] ==========\n",
- chip->chip_id);
+ p += scnprintf(p, end - p,
+ "========== [BTC COEX INFO (%d)] ==========\n",
+ chip->chip_id);
ver_main = FIELD_GET(GENMASK(31, 24), RTW89_COEX_VERSION);
ver_sub = FIELD_GET(GENMASK(23, 16), RTW89_COEX_VERSION);
ver_hotfix = FIELD_GET(GENMASK(15, 8), RTW89_COEX_VERSION);
id_branch = FIELD_GET(GENMASK(7, 0), RTW89_COEX_VERSION);
- seq_printf(m, " %-15s : Coex:%d.%d.%d(branch:%d), ",
- "[coex_version]", ver_main, ver_sub, ver_hotfix, id_branch);
+ p += scnprintf(p, end - p, " %-15s : Coex:%d.%d.%d(branch:%d), ",
+ "[coex_version]", ver_main, ver_sub, ver_hotfix,
+ id_branch);
ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw_coex);
ver_sub = FIELD_GET(GENMASK(23, 16), wl->ver_info.fw_coex);
ver_hotfix = FIELD_GET(GENMASK(15, 8), wl->ver_info.fw_coex);
id_branch = FIELD_GET(GENMASK(7, 0), wl->ver_info.fw_coex);
- seq_printf(m, "WL_FW_coex:%d.%d.%d(branch:%d)",
- ver_main, ver_sub, ver_hotfix, id_branch);
+ p += scnprintf(p, end - p, "WL_FW_coex:%d.%d.%d(branch:%d)",
+ ver_main, ver_sub, ver_hotfix, id_branch);
ver_main = FIELD_GET(GENMASK(31, 24), chip->wlcx_desired);
ver_sub = FIELD_GET(GENMASK(23, 16), chip->wlcx_desired);
ver_hotfix = FIELD_GET(GENMASK(15, 8), chip->wlcx_desired);
- seq_printf(m, "(%s, desired:%d.%d.%d), ",
- (wl->ver_info.fw_coex >= chip->wlcx_desired ?
- "Match" : "Mismatch"), ver_main, ver_sub, ver_hotfix);
+ p += scnprintf(p, end - p, "(%s, desired:%d.%d.%d), ",
+ (wl->ver_info.fw_coex >= chip->wlcx_desired ?
+ "Match" : "Mismatch"), ver_main, ver_sub, ver_hotfix);
- seq_printf(m, "BT_FW_coex:%d(%s, desired:%d)\n",
- bt->ver_info.fw_coex,
- (bt->ver_info.fw_coex >= chip->btcx_desired ?
- "Match" : "Mismatch"), chip->btcx_desired);
+ p += scnprintf(p, end - p, "BT_FW_coex:%d(%s, desired:%d)\n",
+ bt->ver_info.fw_coex,
+ (bt->ver_info.fw_coex >= chip->btcx_desired ?
+ "Match" : "Mismatch"), chip->btcx_desired);
if (bt->enable.now && bt->ver_info.fw == 0)
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, true);
@@ -6663,10 +8210,11 @@ static void _show_cx_info(struct rtw89_dev *rtwdev, struct seq_file *m)
ver_sub = FIELD_GET(GENMASK(23, 16), wl->ver_info.fw);
ver_hotfix = FIELD_GET(GENMASK(15, 8), wl->ver_info.fw);
id_branch = FIELD_GET(GENMASK(7, 0), wl->ver_info.fw);
- seq_printf(m, " %-15s : WL_FW:%d.%d.%d.%d, BT_FW:0x%x(%s)\n",
- "[sub_module]",
- ver_main, ver_sub, ver_hotfix, id_branch,
- bt->ver_info.fw, bt->run_patch_code ? "patch" : "ROM");
+ p += scnprintf(p, end - p,
+ " %-15s : WL_FW:%d.%d.%d.%d, BT_FW:0x%x(%s)\n",
+ "[sub_module]",
+ ver_main, ver_sub, ver_hotfix, id_branch,
+ bt->ver_info.fw, bt->run_patch_code ? "patch" : "ROM");
if (ver->fcxinit == 7) {
cv = md->md_v7.kt_ver;
@@ -6682,76 +8230,87 @@ static void _show_cx_info(struct rtw89_dev *rtwdev, struct seq_file *m)
ant_single_pos = md->md.ant.single_pos;
}
- seq_printf(m, " %-15s : cv:%x, rfe_type:0x%x, ant_iso:%d, ant_pg:%d, %s",
- "[hw_info]", cv, rfe, iso, ant_num,
- ant_num > 1 ? "" :
- ant_single_pos ? "1Ant_Pos:S1, " : "1Ant_Pos:S0, ");
+ p += scnprintf(p, end - p,
+ " %-15s : cv:%x, rfe_type:0x%x, ant_iso:%d, ant_pg:%d, %s",
+ "[hw_info]", cv, rfe, iso, ant_num,
+ ant_num > 1 ? "" :
+ ant_single_pos ? "1Ant_Pos:S1, " : "1Ant_Pos:S0, ");
+
+ p += scnprintf(p, end - p,
+ "3rd_coex:%d, dbcc:%d, tx_num:%d, rx_num:%d\n",
+ btc->cx.other.type, rtwdev->dbcc_en, hal->tx_nss,
+ hal->rx_nss);
- seq_printf(m, "3rd_coex:%d, dbcc:%d, tx_num:%d, rx_num:%d\n",
- btc->cx.other.type, rtwdev->dbcc_en, hal->tx_nss,
- hal->rx_nss);
+ return p - buf;
}
-static void _show_wl_role_info(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_wl_role_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_link_info *plink = NULL;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
struct rtw89_traffic_stats *t;
+ char *p = buf, *end = buf + bufsz;
u8 i;
if (rtwdev->dbcc_en) {
- seq_printf(m,
- " %-15s : PHY0_band(op:%d/scan:%d/real:%d), ",
- "[dbcc_info]", wl_dinfo->op_band[RTW89_PHY_0],
- wl_dinfo->scan_band[RTW89_PHY_0],
- wl_dinfo->real_band[RTW89_PHY_0]);
- seq_printf(m,
- "PHY1_band(op:%d/scan:%d/real:%d)\n",
- wl_dinfo->op_band[RTW89_PHY_1],
- wl_dinfo->scan_band[RTW89_PHY_1],
- wl_dinfo->real_band[RTW89_PHY_1]);
+ p += scnprintf(p, end - p,
+ " %-15s : PHY0_band(op:%d/scan:%d/real:%d), ",
+ "[dbcc_info]", wl_dinfo->op_band[RTW89_PHY_0],
+ wl_dinfo->scan_band[RTW89_PHY_0],
+ wl_dinfo->real_band[RTW89_PHY_0]);
+ p += scnprintf(p, end - p,
+ "PHY1_band(op:%d/scan:%d/real:%d)\n",
+ wl_dinfo->op_band[RTW89_PHY_1],
+ wl_dinfo->scan_band[RTW89_PHY_1],
+ wl_dinfo->real_band[RTW89_PHY_1]);
}
for (i = 0; i < RTW89_PORT_NUM; i++) {
- plink = &btc->cx.wl.link_info[i];
+ if (btc->ver->fwlrole == 8)
+ plink = &btc->cx.wl.rlink_info[i][0];
+ else
+ plink = &btc->cx.wl.link_info[i];
if (!plink->active)
continue;
- seq_printf(m,
- " [port_%d] : role=%d(phy-%d), connect=%d(client_cnt=%d), mode=%d, center_ch=%d, bw=%d",
- plink->pid, (u32)plink->role, plink->phy,
- (u32)plink->connected, plink->client_cnt - 1,
- (u32)plink->mode, plink->ch, (u32)plink->bw);
+ p += scnprintf(p, end - p,
+ " [port_%d] : role=%d(phy-%d), connect=%d(client_cnt=%d), mode=%d, center_ch=%d, bw=%d",
+ plink->pid, (u32)plink->role, plink->phy,
+ (u32)plink->connected, plink->client_cnt - 1,
+ (u32)plink->mode, plink->ch, (u32)plink->bw);
if (plink->connected == MLME_NO_LINK)
continue;
- seq_printf(m,
- ", mac_id=%d, max_tx_time=%dus, max_tx_retry=%d\n",
- plink->mac_id, plink->tx_time, plink->tx_retry);
+ p += scnprintf(p, end - p,
+ ", mac_id=%d, max_tx_time=%dus, max_tx_retry=%d\n",
+ plink->mac_id, plink->tx_time, plink->tx_retry);
- seq_printf(m,
- " [port_%d] : rssi=-%ddBm(%d), busy=%d, dir=%s, ",
- plink->pid, 110 - plink->stat.rssi,
- plink->stat.rssi, plink->busy,
- plink->dir == RTW89_TFC_UL ? "UL" : "DL");
+ p += scnprintf(p, end - p,
+ " [port_%d] : rssi=-%ddBm(%d), busy=%d, dir=%s, ",
+ plink->pid, 110 - plink->stat.rssi,
+ plink->stat.rssi, plink->busy,
+ plink->dir == RTW89_TFC_UL ? "UL" : "DL");
t = &plink->stat.traffic;
- seq_printf(m,
- "tx[rate:%d/busy_level:%d], ",
- (u32)t->tx_rate, t->tx_tfc_lv);
+ p += scnprintf(p, end - p,
+ "tx[rate:%d/busy_level:%d], ",
+ (u32)t->tx_rate, t->tx_tfc_lv);
- seq_printf(m, "rx[rate:%d/busy_level:%d/drop:%d]\n",
- (u32)t->rx_rate,
- t->rx_tfc_lv, plink->rx_rate_drop_cnt);
+ p += scnprintf(p, end - p,
+ "rx[rate:%d/busy_level:%d/drop:%d]\n",
+ (u32)t->rx_rate,
+ t->rx_tfc_lv, plink->rx_rate_drop_cnt);
}
+
+ return p - buf;
}
-static void _show_wl_info(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_wl_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
@@ -6760,12 +8319,15 @@ static void _show_wl_info(struct rtw89_dev *rtwdev, struct seq_file *m)
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
+ struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
+ struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
+ char *p = buf, *end = buf + bufsz;
u8 mode;
if (!(btc->dm.coex_info_map & BTC_COEX_INFO_WL))
- return;
+ return 0;
- seq_puts(m, "========== [WL Status] ==========\n");
+ p += scnprintf(p, end - p, "========== [WL Status] ==========\n");
if (ver->fwlrole == 0)
mode = wl_rinfo->link_mode;
@@ -6773,25 +8335,33 @@ static void _show_wl_info(struct rtw89_dev *rtwdev, struct seq_file *m)
mode = wl_rinfo_v1->link_mode;
else if (ver->fwlrole == 2)
mode = wl_rinfo_v2->link_mode;
+ else if (ver->fwlrole == 7)
+ mode = wl_rinfo_v7->link_mode;
+ else if (ver->fwlrole == 8)
+ mode = wl_rinfo_v8->link_mode;
else
- return;
+ goto out;
+
+ p += scnprintf(p, end - p, " %-15s : link_mode:%d, ", "[status]",
+ mode);
- seq_printf(m, " %-15s : link_mode:%d, ", "[status]", mode);
+ p += scnprintf(p, end - p,
+ "rf_off:%d, power_save:%d, scan:%s(band:%d/phy_map:0x%x), ",
+ wl->status.map.rf_off, wl->status.map.lps,
+ wl->status.map.scan ? "Y" : "N",
+ wl->scan_info.band[RTW89_PHY_0], wl->scan_info.phy_map);
- seq_printf(m,
- "rf_off:%d, power_save:%d, scan:%s(band:%d/phy_map:0x%x), ",
- wl->status.map.rf_off, wl->status.map.lps,
- wl->status.map.scan ? "Y" : "N",
- wl->scan_info.band[RTW89_PHY_0], wl->scan_info.phy_map);
+ p += scnprintf(p, end - p,
+ "connecting:%s, roam:%s, 4way:%s, init_ok:%s\n",
+ wl->status.map.connecting ? "Y" : "N",
+ wl->status.map.roaming ? "Y" : "N",
+ wl->status.map._4way ? "Y" : "N",
+ wl->status.map.init_ok ? "Y" : "N");
- seq_printf(m,
- "connecting:%s, roam:%s, 4way:%s, init_ok:%s\n",
- wl->status.map.connecting ? "Y" : "N",
- wl->status.map.roaming ? "Y" : "N",
- wl->status.map._4way ? "Y" : "N",
- wl->status.map.init_ok ? "Y" : "N");
+ p += _show_wl_role_info(rtwdev, p, end - p);
- _show_wl_role_info(rtwdev, m);
+out:
+ return p - buf;
}
enum btc_bt_a2dp_type {
@@ -6800,7 +8370,7 @@ enum btc_bt_a2dp_type {
BTC_A2DP_TWS_RELAY = 2,
};
-static void _show_bt_profile_info(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_bt_profile_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info;
@@ -6808,50 +8378,55 @@ static void _show_bt_profile_info(struct rtw89_dev *rtwdev, struct seq_file *m)
struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc;
struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc;
+ char *p = buf, *end = buf + bufsz;
if (hfp.exist) {
- seq_printf(m, " %-15s : type:%s, sut_pwr:%d, golden-rx:%d",
- "[HFP]", (hfp.type == 0 ? "SCO" : "eSCO"),
- bt_linfo->sut_pwr_level[0],
- bt_linfo->golden_rx_shift[0]);
+ p += scnprintf(p, end - p,
+ " %-15s : type:%s, sut_pwr:%d, golden-rx:%d",
+ "[HFP]", (hfp.type == 0 ? "SCO" : "eSCO"),
+ bt_linfo->sut_pwr_level[0],
+ bt_linfo->golden_rx_shift[0]);
}
if (hid.exist) {
- seq_printf(m,
- "\n\r %-15s : type:%s%s%s%s%s pair-cnt:%d, sut_pwr:%d, golden-rx:%d\n",
- "[HID]",
- hid.type & BTC_HID_218 ? "2/18," : "",
- hid.type & BTC_HID_418 ? "4/18," : "",
- hid.type & BTC_HID_BLE ? "BLE," : "",
- hid.type & BTC_HID_RCU ? "RCU," : "",
- hid.type & BTC_HID_RCU_VOICE ? "RCU-Voice," : "",
- hid.pair_cnt, bt_linfo->sut_pwr_level[1],
- bt_linfo->golden_rx_shift[1]);
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : type:%s%s%s%s%s pair-cnt:%d, sut_pwr:%d, golden-rx:%d\n",
+ "[HID]",
+ hid.type & BTC_HID_218 ? "2/18," : "",
+ hid.type & BTC_HID_418 ? "4/18," : "",
+ hid.type & BTC_HID_BLE ? "BLE," : "",
+ hid.type & BTC_HID_RCU ? "RCU," : "",
+ hid.type & BTC_HID_RCU_VOICE ? "RCU-Voice," : "",
+ hid.pair_cnt, bt_linfo->sut_pwr_level[1],
+ bt_linfo->golden_rx_shift[1]);
}
if (a2dp.exist) {
- seq_printf(m,
- " %-15s : type:%s, bit-pool:%d, flush-time:%d, ",
- "[A2DP]",
- a2dp.type == BTC_A2DP_LEGACY ? "Legacy" : "TWS",
- a2dp.bitpool, a2dp.flush_time);
+ p += scnprintf(p, end - p,
+ " %-15s : type:%s, bit-pool:%d, flush-time:%d, ",
+ "[A2DP]",
+ a2dp.type == BTC_A2DP_LEGACY ? "Legacy" : "TWS",
+ a2dp.bitpool, a2dp.flush_time);
- seq_printf(m,
- "vid:0x%x, Dev-name:0x%x, sut_pwr:%d, golden-rx:%d\n",
- a2dp.vendor_id, a2dp.device_name,
- bt_linfo->sut_pwr_level[2],
- bt_linfo->golden_rx_shift[2]);
+ p += scnprintf(p, end - p,
+ "vid:0x%x, Dev-name:0x%x, sut_pwr:%d, golden-rx:%d\n",
+ a2dp.vendor_id, a2dp.device_name,
+ bt_linfo->sut_pwr_level[2],
+ bt_linfo->golden_rx_shift[2]);
}
if (pan.exist) {
- seq_printf(m, " %-15s : sut_pwr:%d, golden-rx:%d\n",
- "[PAN]",
- bt_linfo->sut_pwr_level[3],
- bt_linfo->golden_rx_shift[3]);
+ p += scnprintf(p, end - p,
+ " %-15s : sut_pwr:%d, golden-rx:%d\n",
+ "[PAN]",
+ bt_linfo->sut_pwr_level[3],
+ bt_linfo->golden_rx_shift[3]);
}
+
+ return p - buf;
}
-static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
@@ -6860,136 +8435,138 @@ static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m)
struct rtw89_btc_wl_info *wl = &cx->wl;
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
union rtw89_btc_module_info *md = &btc->mdinfo;
+ char *p = buf, *end = buf + bufsz;
u8 *afh = bt_linfo->afh_map;
u8 *afh_le = bt_linfo->afh_map_le;
u8 bt_pos;
if (!(btc->dm.coex_info_map & BTC_COEX_INFO_BT))
- return;
+ return 0;
if (ver->fcxinit == 7)
bt_pos = md->md_v7.bt_pos;
else
bt_pos = md->md.bt_pos;
- seq_puts(m, "========== [BT Status] ==========\n");
-
- seq_printf(m, " %-15s : enable:%s, btg:%s%s, connect:%s, ",
- "[status]", bt->enable.now ? "Y" : "N",
- bt->btg_type ? "Y" : "N",
- (bt->enable.now && (bt->btg_type != bt_pos) ?
- "(efuse-mismatch!!)" : ""),
- (bt_linfo->status.map.connect ? "Y" : "N"));
-
- seq_printf(m, "igno_wl:%s, mailbox_avl:%s, rfk_state:0x%x\n",
- bt->igno_wl ? "Y" : "N",
- bt->mbx_avl ? "Y" : "N", bt->rfk_info.val);
-
- seq_printf(m, " %-15s : profile:%s%s%s%s%s ",
- "[profile]",
- (bt_linfo->profile_cnt.now == 0) ? "None," : "",
- bt_linfo->hfp_desc.exist ? "HFP," : "",
- bt_linfo->hid_desc.exist ? "HID," : "",
- bt_linfo->a2dp_desc.exist ?
- (bt_linfo->a2dp_desc.sink ? "A2DP_sink," : "A2DP,") : "",
- bt_linfo->pan_desc.exist ? "PAN," : "");
-
- seq_printf(m,
- "multi-link:%s, role:%s, ble-connect:%s, CQDDR:%s, A2DP_active:%s, PAN_active:%s\n",
- bt_linfo->multi_link.now ? "Y" : "N",
- bt_linfo->slave_role ? "Slave" : "Master",
- bt_linfo->status.map.ble_connect ? "Y" : "N",
- bt_linfo->cqddr ? "Y" : "N",
- bt_linfo->a2dp_desc.active ? "Y" : "N",
- bt_linfo->pan_desc.active ? "Y" : "N");
-
- seq_printf(m,
- " %-15s : rssi:%ddBm(lvl:%d), tx_rate:%dM, %s%s%s",
- "[link]", bt_linfo->rssi - 100,
- bt->rssi_level,
- bt_linfo->tx_3m ? 3 : 2,
- bt_linfo->status.map.inq_pag ? " inq-page!!" : "",
- bt_linfo->status.map.acl_busy ? " acl_busy!!" : "",
- bt_linfo->status.map.mesh_busy ? " mesh_busy!!" : "");
-
- seq_printf(m,
- "%s afh_map[%02x%02x_%02x%02x_%02x%02x_%02x%02x_%02x%02x], ",
- bt_linfo->relink.now ? " ReLink!!" : "",
- afh[0], afh[1], afh[2], afh[3], afh[4],
- afh[5], afh[6], afh[7], afh[8], afh[9]);
+ p += scnprintf(p, end - p, "========== [BT Status] ==========\n");
+
+ p += scnprintf(p, end - p,
+ " %-15s : enable:%s, btg:%s%s, connect:%s, ",
+ "[status]", bt->enable.now ? "Y" : "N",
+ bt->btg_type ? "Y" : "N",
+ (bt->enable.now && (bt->btg_type != bt_pos) ?
+ "(efuse-mismatch!!)" : ""),
+ (bt_linfo->status.map.connect ? "Y" : "N"));
+
+ p += scnprintf(p, end - p,
+ "igno_wl:%s, mailbox_avl:%s, rfk_state:0x%x\n",
+ bt->igno_wl ? "Y" : "N",
+ bt->mbx_avl ? "Y" : "N", bt->rfk_info.val);
+
+ p += scnprintf(p, end - p, " %-15s : profile:%s%s%s%s%s ",
+ "[profile]",
+ (bt_linfo->profile_cnt.now == 0) ? "None," : "",
+ bt_linfo->hfp_desc.exist ? "HFP," : "",
+ bt_linfo->hid_desc.exist ? "HID," : "",
+ bt_linfo->a2dp_desc.exist ?
+ (bt_linfo->a2dp_desc.sink ? "A2DP_sink," : "A2DP,") : "",
+ bt_linfo->pan_desc.exist ? "PAN," : "");
+
+ p += scnprintf(p, end - p,
+ "multi-link:%s, role:%s, ble-connect:%s, CQDDR:%s, A2DP_active:%s, PAN_active:%s\n",
+ bt_linfo->multi_link.now ? "Y" : "N",
+ bt_linfo->slave_role ? "Slave" : "Master",
+ bt_linfo->status.map.ble_connect ? "Y" : "N",
+ bt_linfo->cqddr ? "Y" : "N",
+ bt_linfo->a2dp_desc.active ? "Y" : "N",
+ bt_linfo->pan_desc.active ? "Y" : "N");
+
+ p += scnprintf(p, end - p,
+ " %-15s : rssi:%ddBm(lvl:%d), tx_rate:%dM, %s%s%s",
+ "[link]", bt_linfo->rssi - 100,
+ bt->rssi_level,
+ bt_linfo->tx_3m ? 3 : 2,
+ bt_linfo->status.map.inq_pag ? " inq-page!!" : "",
+ bt_linfo->status.map.acl_busy ? " acl_busy!!" : "",
+ bt_linfo->status.map.mesh_busy ? " mesh_busy!!" : "");
+
+ p += scnprintf(p, end - p,
+ "%s afh_map[%02x%02x_%02x%02x_%02x%02x_%02x%02x_%02x%02x], ",
+ bt_linfo->relink.now ? " ReLink!!" : "",
+ afh[0], afh[1], afh[2], afh[3], afh[4],
+ afh[5], afh[6], afh[7], afh[8], afh[9]);
if (ver->fcxbtafh == 2 && bt_linfo->status.map.ble_connect)
- seq_printf(m,
- "LE[%02x%02x_%02x_%02x%02x]",
- afh_le[0], afh_le[1], afh_le[2],
- afh_le[3], afh_le[4]);
-
- seq_printf(m, "wl_ch_map[en:%d/ch:%d/bw:%d]\n",
- wl->afh_info.en, wl->afh_info.ch, wl->afh_info.bw);
-
- seq_printf(m,
- " %-15s : retry:%d, relink:%d, rate_chg:%d, reinit:%d, reenable:%d, ",
- "[stat_cnt]", cx->cnt_bt[BTC_BCNT_RETRY],
- cx->cnt_bt[BTC_BCNT_RELINK], cx->cnt_bt[BTC_BCNT_RATECHG],
- cx->cnt_bt[BTC_BCNT_REINIT], cx->cnt_bt[BTC_BCNT_REENABLE]);
-
- seq_printf(m,
- "role-switch:%d, afh:%d, inq_page:%d(inq:%d/page:%d), igno_wl:%d\n",
- cx->cnt_bt[BTC_BCNT_ROLESW], cx->cnt_bt[BTC_BCNT_AFH],
- cx->cnt_bt[BTC_BCNT_INQPAG], cx->cnt_bt[BTC_BCNT_INQ],
- cx->cnt_bt[BTC_BCNT_PAGE], cx->cnt_bt[BTC_BCNT_IGNOWL]);
-
- _show_bt_profile_info(rtwdev, m);
-
- seq_printf(m,
- " %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)\n",
- "[bt_info]", bt->raw_info[2], bt->raw_info[3],
- bt->raw_info[4], bt->raw_info[5], bt->raw_info[6],
- bt->raw_info[7],
- bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply",
- cx->cnt_bt[BTC_BCNT_INFOUPDATE],
- cx->cnt_bt[BTC_BCNT_INFOSAME]);
-
- seq_printf(m,
- " %-15s : Hi-rx = %d, Hi-tx = %d, Lo-rx = %d, Lo-tx = %d (bt_polut_wl_tx = %d)",
- "[trx_req_cnt]", cx->cnt_bt[BTC_BCNT_HIPRI_RX],
- cx->cnt_bt[BTC_BCNT_HIPRI_TX], cx->cnt_bt[BTC_BCNT_LOPRI_RX],
- cx->cnt_bt[BTC_BCNT_LOPRI_TX], cx->cnt_bt[BTC_BCNT_POLUT]);
+ p += scnprintf(p, end - p,
+ "LE[%02x%02x_%02x_%02x%02x]",
+ afh_le[0], afh_le[1], afh_le[2],
+ afh_le[3], afh_le[4]);
+
+ p += scnprintf(p, end - p, "wl_ch_map[en:%d/ch:%d/bw:%d]\n",
+ wl->afh_info.en, wl->afh_info.ch, wl->afh_info.bw);
+
+ p += scnprintf(p, end - p,
+ " %-15s : retry:%d, relink:%d, rate_chg:%d, reinit:%d, reenable:%d, ",
+ "[stat_cnt]", cx->cnt_bt[BTC_BCNT_RETRY],
+ cx->cnt_bt[BTC_BCNT_RELINK],
+ cx->cnt_bt[BTC_BCNT_RATECHG],
+ cx->cnt_bt[BTC_BCNT_REINIT],
+ cx->cnt_bt[BTC_BCNT_REENABLE]);
+
+ p += scnprintf(p, end - p,
+ "role-switch:%d, afh:%d, inq_page:%d(inq:%d/page:%d), igno_wl:%d\n",
+ cx->cnt_bt[BTC_BCNT_ROLESW], cx->cnt_bt[BTC_BCNT_AFH],
+ cx->cnt_bt[BTC_BCNT_INQPAG], cx->cnt_bt[BTC_BCNT_INQ],
+ cx->cnt_bt[BTC_BCNT_PAGE], cx->cnt_bt[BTC_BCNT_IGNOWL]);
+
+ p += _show_bt_profile_info(rtwdev, p, end - p);
+
+ p += scnprintf(p, end - p,
+ " %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)\n",
+ "[bt_info]", bt->raw_info[2], bt->raw_info[3],
+ bt->raw_info[4], bt->raw_info[5], bt->raw_info[6],
+ bt->raw_info[7],
+ bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply",
+ cx->cnt_bt[BTC_BCNT_INFOUPDATE],
+ cx->cnt_bt[BTC_BCNT_INFOSAME]);
+
+ p += scnprintf(p, end - p,
+ " %-15s : Hi-rx = %d, Hi-tx = %d, Lo-rx = %d, Lo-tx = %d (bt_polut_wl_tx = %d)",
+ "[trx_req_cnt]", cx->cnt_bt[BTC_BCNT_HIPRI_RX],
+ cx->cnt_bt[BTC_BCNT_HIPRI_TX],
+ cx->cnt_bt[BTC_BCNT_LOPRI_RX],
+ cx->cnt_bt[BTC_BCNT_LOPRI_TX],
+ cx->cnt_bt[BTC_BCNT_POLUT]);
if (!bt->scan_info_update) {
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_SCAN_INFO, true);
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
} else {
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_SCAN_INFO, false);
if (ver->fcxbtscan == 1) {
- seq_printf(m,
- "(INQ:%d-%d/PAGE:%d-%d/LE:%d-%d/INIT:%d-%d)",
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].win),
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].intvl),
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].win),
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].intvl),
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].win),
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].intvl),
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].win),
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].intvl));
+ p += scnprintf(p, end - p,
+ "(INQ:%d-%d/PAGE:%d-%d/LE:%d-%d/INIT:%d-%d)",
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].win),
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].intvl),
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].win),
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].intvl),
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].win),
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].intvl),
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].win),
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].intvl));
} else if (ver->fcxbtscan == 2) {
- seq_printf(m,
- "(BG:%d-%d/INIT:%d-%d/LE:%d-%d)",
- le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].win),
- le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].intvl),
- le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].win),
- le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].intvl),
- le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].win),
- le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].intvl));
+ p += scnprintf(p, end - p,
+ "(BG:%d-%d/INIT:%d-%d/LE:%d-%d)",
+ le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].win),
+ le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].intvl),
+ le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].win),
+ le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].intvl),
+ le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].win),
+ le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].intvl));
}
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
- if (bt->enable.now && bt->ver_info.fw == 0)
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, true);
- else
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, false);
-
if (bt_linfo->profile_cnt.now || bt_linfo->status.map.ble_connect)
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, true);
else
@@ -7007,6 +8584,8 @@ static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m)
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, true);
else
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, false);
+
+ return p - buf;
}
#define CASE_BTC_RSN_STR(e) case BTC_RSN_ ## e: return #e
@@ -7017,6 +8596,79 @@ static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m)
#define CASE_BTC_EVT_STR(e) case CXEVNT_## e: return #e
#define CASE_BTC_INIT(e) case BTC_MODE_## e: return #e
#define CASE_BTC_ANTPATH_STR(e) case BTC_ANT_##e: return #e
+#define CASE_BTC_POLUT_STR(e) case BTC_PLT_## e: return #e
+#define CASE_BTC_REGTYPE_STR(e) case REG_## e: return #e
+#define CASE_BTC_GDBG_STR(e) case BTC_DBG_## e: return #e
+
+static const char *id_to_polut(u32 id)
+{
+ switch (id) {
+ CASE_BTC_POLUT_STR(NONE);
+ CASE_BTC_POLUT_STR(GNT_BT_TX);
+ CASE_BTC_POLUT_STR(GNT_BT_RX);
+ CASE_BTC_POLUT_STR(GNT_WL);
+ CASE_BTC_POLUT_STR(BT);
+ CASE_BTC_POLUT_STR(ALL);
+ default:
+ return "unknown";
+ }
+}
+
+static const char *id_to_regtype(u32 id)
+{
+ switch (id) {
+ CASE_BTC_REGTYPE_STR(MAC);
+ CASE_BTC_REGTYPE_STR(BB);
+ CASE_BTC_REGTYPE_STR(RF);
+ CASE_BTC_REGTYPE_STR(BT_RF);
+ CASE_BTC_REGTYPE_STR(BT_MODEM);
+ CASE_BTC_REGTYPE_STR(BT_BLUEWIZE);
+ CASE_BTC_REGTYPE_STR(BT_VENDOR);
+ CASE_BTC_REGTYPE_STR(BT_LE);
+ default:
+ return "unknown";
+ }
+}
+
+static const char *id_to_gdbg(u32 id)
+{
+ switch (id) {
+ CASE_BTC_GDBG_STR(GNT_BT);
+ CASE_BTC_GDBG_STR(GNT_WL);
+ CASE_BTC_GDBG_STR(BCN_EARLY);
+ CASE_BTC_GDBG_STR(WL_NULL0);
+ CASE_BTC_GDBG_STR(WL_NULL1);
+ CASE_BTC_GDBG_STR(WL_RXISR);
+ CASE_BTC_GDBG_STR(TDMA_ENTRY);
+ CASE_BTC_GDBG_STR(A2DP_EMPTY);
+ CASE_BTC_GDBG_STR(BT_RETRY);
+ CASE_BTC_GDBG_STR(BT_RELINK);
+ CASE_BTC_GDBG_STR(SLOT_WL);
+ CASE_BTC_GDBG_STR(SLOT_BT);
+ CASE_BTC_GDBG_STR(WL_ERR);
+ CASE_BTC_GDBG_STR(WL_OK);
+ CASE_BTC_GDBG_STR(SLOT_B2W);
+ CASE_BTC_GDBG_STR(SLOT_W1);
+ CASE_BTC_GDBG_STR(SLOT_W2);
+ CASE_BTC_GDBG_STR(SLOT_W2B);
+ CASE_BTC_GDBG_STR(SLOT_B1);
+ CASE_BTC_GDBG_STR(SLOT_B2);
+ CASE_BTC_GDBG_STR(SLOT_B3);
+ CASE_BTC_GDBG_STR(SLOT_B4);
+ CASE_BTC_GDBG_STR(SLOT_LK);
+ CASE_BTC_GDBG_STR(SLOT_E2G);
+ CASE_BTC_GDBG_STR(SLOT_E5G);
+ CASE_BTC_GDBG_STR(SLOT_EBT);
+ CASE_BTC_GDBG_STR(SLOT_WLK);
+ CASE_BTC_GDBG_STR(SLOT_B1FDD);
+ CASE_BTC_GDBG_STR(BT_CHANGE);
+ CASE_BTC_GDBG_STR(WL_CCA);
+ CASE_BTC_GDBG_STR(BT_LEAUDIO);
+ CASE_BTC_GDBG_STR(USER_DEF);
+ default:
+ return "unknown";
+ }
+}
static const char *steps_to_str(u16 step)
{
@@ -7227,114 +8879,132 @@ static const char *id_to_ant(u32 id)
}
static
-void seq_print_segment(struct seq_file *m, const char *prefix, u16 *data,
- u8 len, u8 seg_len, u8 start_idx, u8 ring_len)
+int scnprintf_segment(char *buf, size_t bufsz, const char *prefix, const u16 *data,
+ u8 len, u8 seg_len, u8 start_idx, u8 ring_len)
{
- u8 i;
+ char *p = buf, *end = buf + bufsz;
u8 cur_index;
+ u8 i;
for (i = 0; i < len ; i++) {
if ((i % seg_len) == 0)
- seq_printf(m, " %-15s : ", prefix);
+ p += scnprintf(p, end - p, " %-15s : ", prefix);
cur_index = (start_idx + i) % ring_len;
if (i % 3 == 0)
- seq_printf(m, "-> %-20s",
- steps_to_str(*(data + cur_index)));
+ p += scnprintf(p, end - p, "-> %-20s",
+ steps_to_str(*(data + cur_index)));
else if (i % 3 == 1)
- seq_printf(m, "-> %-15s",
- steps_to_str(*(data + cur_index)));
+ p += scnprintf(p, end - p, "-> %-15s",
+ steps_to_str(*(data + cur_index)));
else
- seq_printf(m, "-> %-13s",
- steps_to_str(*(data + cur_index)));
+ p += scnprintf(p, end - p, "-> %-13s",
+ steps_to_str(*(data + cur_index)));
if (i == (len - 1) || (i % seg_len) == (seg_len - 1))
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
+
+ return p - buf;
}
-static void _show_dm_step(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_dm_step(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &btc->dm;
+ char *p = buf, *end = buf + bufsz;
u8 start_idx;
u8 len;
len = dm->dm_step.step_ov ? RTW89_BTC_DM_MAXSTEP : dm->dm_step.step_pos;
start_idx = dm->dm_step.step_ov ? dm->dm_step.step_pos : 0;
- seq_print_segment(m, "[dm_steps]", dm->dm_step.step, len, 6, start_idx,
- ARRAY_SIZE(dm->dm_step.step));
+ p += scnprintf_segment(p, end - p, "[dm_steps]", dm->dm_step.step, len,
+ 6, start_idx, ARRAY_SIZE(dm->dm_step.step));
+
+ return p - buf;
}
-static void _show_dm_info(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_dm_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_bt_info *bt = &btc->cx.bt;
+ char *p = buf, *end = buf + bufsz;
u8 igno_bt;
if (!(dm->coex_info_map & BTC_COEX_INFO_DM))
- return;
+ return 0;
- seq_printf(m, "========== [Mechanism Status %s] ==========\n",
- (btc->manual_ctrl ? "(Manual)" : "(Auto)"));
+ p += scnprintf(p, end - p,
+ "========== [Mechanism Status %s] ==========\n",
+ (btc->manual_ctrl ? "(Manual)" : "(Auto)"));
- seq_printf(m,
- " %-15s : type:%s, reason:%s(), action:%s(), ant_path:%s, init_mode:%s, run_cnt:%d\n",
- "[status]",
- btc->ant_type == BTC_ANT_SHARED ? "shared" : "dedicated",
- steps_to_str(dm->run_reason),
- steps_to_str(dm->run_action | BTC_ACT_EXT_BIT),
- id_to_ant(FIELD_GET(GENMASK(7, 0), dm->set_ant_path)),
- id_to_mode(wl->coex_mode),
- dm->cnt_dm[BTC_DCNT_RUN]);
+ p += scnprintf(p, end - p,
+ " %-15s : type:%s, reason:%s(), action:%s(), ant_path:%s, init_mode:%s, run_cnt:%d\n",
+ "[status]",
+ btc->ant_type == BTC_ANT_SHARED ? "shared" : "dedicated",
+ steps_to_str(dm->run_reason),
+ steps_to_str(dm->run_action | BTC_ACT_EXT_BIT),
+ id_to_ant(FIELD_GET(GENMASK(7, 0), dm->set_ant_path)),
+ id_to_mode(wl->coex_mode),
+ dm->cnt_dm[BTC_DCNT_RUN]);
- _show_dm_step(rtwdev, m);
+ p += _show_dm_step(rtwdev, p, end - p);
if (ver->fcxctrl == 7)
igno_bt = btc->ctrl.ctrl_v7.igno_bt;
else
igno_bt = btc->ctrl.ctrl.igno_bt;
- seq_printf(m, " %-15s : wl_only:%d, bt_only:%d, igno_bt:%d, free_run:%d, wl_ps_ctrl:%d, wl_mimo_ps:%d, ",
- "[dm_flag]", dm->wl_only, dm->bt_only, igno_bt,
- dm->freerun, btc->lps, dm->wl_mimo_ps);
+ p += scnprintf(p, end - p,
+ " %-15s : wl_only:%d, bt_only:%d, igno_bt:%d, free_run:%d, wl_ps_ctrl:%d, wl_mimo_ps:%d, ",
+ "[dm_flag]", dm->wl_only, dm->bt_only, igno_bt,
+ dm->freerun, btc->lps, dm->wl_mimo_ps);
- seq_printf(m, "leak_ap:%d, fw_offload:%s%s\n", dm->leak_ap,
- (BTC_CX_FW_OFFLOAD ? "Y" : "N"),
- (dm->wl_fw_cx_offload == BTC_CX_FW_OFFLOAD ?
- "" : "(Mismatch!!)"));
+ p += scnprintf(p, end - p, "leak_ap:%d, fw_offload:%s%s\n",
+ dm->leak_ap,
+ (BTC_CX_FW_OFFLOAD ? "Y" : "N"),
+ (dm->wl_fw_cx_offload == BTC_CX_FW_OFFLOAD ?
+ "" : "(Mismatch!!)"));
if (dm->rf_trx_para.wl_tx_power == 0xff)
- seq_printf(m,
- " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:orig, ",
- "[trx_ctrl]", wl->rssi_level, dm->trx_para_level);
+ p += scnprintf(p, end - p,
+ " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:orig, ",
+ "[trx_ctrl]", wl->rssi_level,
+ dm->trx_para_level);
else
- seq_printf(m,
- " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:%d, ",
- "[trx_ctrl]", wl->rssi_level, dm->trx_para_level,
- dm->rf_trx_para.wl_tx_power);
+ p += scnprintf(p, end - p,
+ " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:%d, ",
+ "[trx_ctrl]", wl->rssi_level,
+ dm->trx_para_level,
+ dm->rf_trx_para.wl_tx_power);
+
+ p += scnprintf(p, end - p,
+ "wl_rx_lvl:%d, bt_tx_pwr_dec:%d, bt_rx_lna:%d(%s-tbl), wl_btg_rx:%d\n",
+ dm->rf_trx_para.wl_rx_gain,
+ dm->rf_trx_para.bt_tx_power,
+ dm->rf_trx_para.bt_rx_gain,
+ (bt->hi_lna_rx ? "Hi" : "Ori"), dm->wl_btg_rx);
- seq_printf(m,
- "wl_rx_lvl:%d, bt_tx_pwr_dec:%d, bt_rx_lna:%d(%s-tbl), wl_btg_rx:%d\n",
- dm->rf_trx_para.wl_rx_gain, dm->rf_trx_para.bt_tx_power,
- dm->rf_trx_para.bt_rx_gain,
- (bt->hi_lna_rx ? "Hi" : "Ori"), dm->wl_btg_rx);
+ p += scnprintf(p, end - p,
+ " %-15s : wl_tx_limit[en:%d/max_t:%dus/max_retry:%d], bt_slot_reg:%d-TU, bt_scan_rx_low_pri:%d\n",
+ "[dm_ctrl]", dm->wl_tx_limit.enable,
+ dm->wl_tx_limit.tx_time,
+ dm->wl_tx_limit.tx_retry, btc->bt_req_len,
+ bt->scan_rx_low_pri);
- seq_printf(m,
- " %-15s : wl_tx_limit[en:%d/max_t:%dus/max_retry:%d], bt_slot_reg:%d-TU, bt_scan_rx_low_pri:%d\n",
- "[dm_ctrl]", dm->wl_tx_limit.enable, dm->wl_tx_limit.tx_time,
- dm->wl_tx_limit.tx_retry, btc->bt_req_len, bt->scan_rx_low_pri);
+ return p - buf;
}
-static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_error(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
union rtw89_btc_fbtc_cysta_info *pcysta;
+ char *p = buf, *end = buf + bufsz;
u32 except_cnt, exception_map;
pcysta = &pfwinfo->rpt_fbtc_cysta.finfo;
@@ -7354,105 +9024,130 @@ static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m)
pcysta->v5 = pfwinfo->rpt_fbtc_cysta.finfo.v5;
except_cnt = pcysta->v5.except_cnt;
exception_map = le32_to_cpu(pcysta->v5.except_map);
+ } else if (ver->fcxcysta == 7) {
+ pcysta->v7 = pfwinfo->rpt_fbtc_cysta.finfo.v7;
+ except_cnt = pcysta->v7.except_cnt;
+ exception_map = le32_to_cpu(pcysta->v7.except_map);
} else {
- return;
+ return 0;
}
if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW] == 0 && except_cnt == 0 &&
!pfwinfo->len_mismch && !pfwinfo->fver_mismch)
- return;
+ return 0;
- seq_printf(m, " %-15s : ", "[error]");
+ p += scnprintf(p, end - p, " %-15s : ", "[error]");
if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]) {
- seq_printf(m,
- "overflow-cnt: %d, ",
- pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]);
+ p += scnprintf(p, end - p,
+ "overflow-cnt: %d, ",
+ pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]);
}
if (pfwinfo->len_mismch) {
- seq_printf(m,
- "len-mismatch: 0x%x, ",
- pfwinfo->len_mismch);
+ p += scnprintf(p, end - p,
+ "len-mismatch: 0x%x, ",
+ pfwinfo->len_mismch);
}
if (pfwinfo->fver_mismch) {
- seq_printf(m,
- "fver-mismatch: 0x%x, ",
- pfwinfo->fver_mismch);
+ p += scnprintf(p, end - p,
+ "fver-mismatch: 0x%x, ",
+ pfwinfo->fver_mismch);
}
/* cycle statistics exceptions */
if (exception_map || except_cnt) {
- seq_printf(m,
- "exception-type: 0x%x, exception-cnt = %d",
- exception_map, except_cnt);
+ p += scnprintf(p, end - p,
+ "exception-type: 0x%x, exception-cnt = %d",
+ exception_map, except_cnt);
}
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
+
+ return p - buf;
}
-static void _show_fbtc_tdma(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_fbtc_tdma(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_fbtc_tdma *t = NULL;
+ char *p = buf, *end = buf + bufsz;
pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo;
if (!pcinfo->valid)
- return;
+ return 0;
if (ver->fcxtdma == 1)
t = &pfwinfo->rpt_fbtc_tdma.finfo.v1;
else
t = &pfwinfo->rpt_fbtc_tdma.finfo.v3.tdma;
- seq_printf(m,
- " %-15s : ", "[tdma_policy]");
- seq_printf(m,
- "type:%d, rx_flow_ctrl:%d, tx_pause:%d, ",
- (u32)t->type,
- t->rxflctrl, t->txpause);
+ p += scnprintf(p, end - p,
+ " %-15s : ", "[tdma_policy]");
+ p += scnprintf(p, end - p,
+ "type:%d, rx_flow_ctrl:%d, tx_pause:%d, ",
+ (u32)t->type,
+ t->rxflctrl, t->txpause);
- seq_printf(m,
- "wl_toggle_n:%d, leak_n:%d, ext_ctrl:%d, ",
- t->wtgle_n, t->leak_n, t->ext_ctrl);
+ p += scnprintf(p, end - p,
+ "wl_toggle_n:%d, leak_n:%d, ext_ctrl:%d, ",
+ t->wtgle_n, t->leak_n, t->ext_ctrl);
- seq_printf(m,
- "policy_type:%d",
- (u32)btc->policy_type);
+ p += scnprintf(p, end - p,
+ "policy_type:%d",
+ (u32)btc->policy_type);
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
+
+ return p - buf;
}
-static void _show_fbtc_slots(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_fbtc_slots(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &btc->dm;
- struct rtw89_btc_fbtc_slot *s;
+ char *p = buf, *end = buf + bufsz;
+ u16 dur, cxtype;
+ u32 tbl;
u8 i = 0;
for (i = 0; i < CXST_MAX; i++) {
- s = &dm->slot_now[i];
+ if (btc->ver->fcxslots == 1) {
+ dur = le16_to_cpu(dm->slot_now.v1[i].dur);
+ tbl = le32_to_cpu(dm->slot_now.v1[i].cxtbl);
+ cxtype = le16_to_cpu(dm->slot_now.v1[i].cxtype);
+ } else if (btc->ver->fcxslots == 7) {
+ dur = le16_to_cpu(dm->slot_now.v7[i].dur);
+ tbl = le32_to_cpu(dm->slot_now.v7[i].cxtbl);
+ cxtype = le16_to_cpu(dm->slot_now.v7[i].cxtype);
+ } else {
+ return 0;
+ }
+
if (i % 5 == 0)
- seq_printf(m,
- " %-15s : %5s[%03d/0x%x/%d]",
- "[slot_list]",
- id_to_slot((u32)i),
- s->dur, s->cxtbl, s->cxtype);
+ p += scnprintf(p, end - p,
+ " %-15s : %5s[%03d/0x%x/%d]",
+ "[slot_list]",
+ id_to_slot((u32)i),
+ dur, tbl, cxtype);
else
- seq_printf(m,
- ", %5s[%03d/0x%x/%d]",
- id_to_slot((u32)i),
- s->dur, s->cxtbl, s->cxtype);
+ p += scnprintf(p, end - p,
+ ", %5s[%03d/0x%x/%d]",
+ id_to_slot((u32)i),
+ dur, tbl, cxtype);
+
if (i % 5 == 4)
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
+
+ return p - buf;
}
-static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
@@ -7461,63 +9156,64 @@ static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m)
struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_fbtc_cysta_v2 *pcysta_le32 = NULL;
union rtw89_btc_fbtc_rxflct r;
- u8 i, cnt = 0, slot_pair;
u16 cycle, c_begin, c_end, store_index;
+ char *p = buf, *end = buf + bufsz;
+ u8 i, cnt = 0, slot_pair;
pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo;
if (!pcinfo->valid)
- return;
+ return 0;
pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo.v2;
- seq_printf(m,
- " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
- "[cycle_cnt]",
- le16_to_cpu(pcysta_le32->cycles),
- le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL]),
- le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL_OK]),
- le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_SLOT]),
- le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_OK]));
+ p += scnprintf(p, end - p,
+ " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
+ "[cycle_cnt]",
+ le16_to_cpu(pcysta_le32->cycles),
+ le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL]),
+ le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_ALL_OK]),
+ le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_SLOT]),
+ le32_to_cpu(pcysta_le32->bcn_cnt[CXBCN_BT_OK]));
for (i = 0; i < CXST_MAX; i++) {
if (!le32_to_cpu(pcysta_le32->slot_cnt[i]))
continue;
- seq_printf(m, ", %s:%d", id_to_slot((u32)i),
- le32_to_cpu(pcysta_le32->slot_cnt[i]));
+ p += scnprintf(p, end - p, ", %s:%d", id_to_slot((u32)i),
+ le32_to_cpu(pcysta_le32->slot_cnt[i]));
}
if (dm->tdma_now.rxflctrl) {
- seq_printf(m, ", leak_rx:%d",
- le32_to_cpu(pcysta_le32->leakrx_cnt));
+ p += scnprintf(p, end - p, ", leak_rx:%d",
+ le32_to_cpu(pcysta_le32->leakrx_cnt));
}
if (le32_to_cpu(pcysta_le32->collision_cnt)) {
- seq_printf(m, ", collision:%d",
- le32_to_cpu(pcysta_le32->collision_cnt));
+ p += scnprintf(p, end - p, ", collision:%d",
+ le32_to_cpu(pcysta_le32->collision_cnt));
}
if (le32_to_cpu(pcysta_le32->skip_cnt)) {
- seq_printf(m, ", skip:%d",
- le32_to_cpu(pcysta_le32->skip_cnt));
- }
- seq_puts(m, "\n");
-
- seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]",
- "[cycle_time]",
- le16_to_cpu(pcysta_le32->tavg_cycle[CXT_WL]),
- le16_to_cpu(pcysta_le32->tavg_cycle[CXT_BT]),
- le16_to_cpu(pcysta_le32->tavg_lk) / 1000,
- le16_to_cpu(pcysta_le32->tavg_lk) % 1000);
- seq_printf(m, ", max_t[wl:%d/bt:%d/lk:%d.%03d]",
- le16_to_cpu(pcysta_le32->tmax_cycle[CXT_WL]),
- le16_to_cpu(pcysta_le32->tmax_cycle[CXT_BT]),
- le16_to_cpu(pcysta_le32->tmax_lk) / 1000,
- le16_to_cpu(pcysta_le32->tmax_lk) % 1000);
- seq_printf(m, ", maxdiff_t[wl:%d/bt:%d]\n",
- le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_WL]),
- le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_BT]));
+ p += scnprintf(p, end - p, ", skip:%d",
+ le32_to_cpu(pcysta_le32->skip_cnt));
+ }
+ p += scnprintf(p, end - p, "\n");
+
+ p += scnprintf(p, end - p, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]",
+ "[cycle_time]",
+ le16_to_cpu(pcysta_le32->tavg_cycle[CXT_WL]),
+ le16_to_cpu(pcysta_le32->tavg_cycle[CXT_BT]),
+ le16_to_cpu(pcysta_le32->tavg_lk) / 1000,
+ le16_to_cpu(pcysta_le32->tavg_lk) % 1000);
+ p += scnprintf(p, end - p, ", max_t[wl:%d/bt:%d/lk:%d.%03d]",
+ le16_to_cpu(pcysta_le32->tmax_cycle[CXT_WL]),
+ le16_to_cpu(pcysta_le32->tmax_cycle[CXT_BT]),
+ le16_to_cpu(pcysta_le32->tmax_lk) / 1000,
+ le16_to_cpu(pcysta_le32->tmax_lk) % 1000);
+ p += scnprintf(p, end - p, ", maxdiff_t[wl:%d/bt:%d]\n",
+ le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_WL]),
+ le16_to_cpu(pcysta_le32->tmaxdiff_cycle[CXT_BT]));
if (le16_to_cpu(pcysta_le32->cycles) <= 1)
- return;
+ goto out;
/* 1 cycle record 1 wl-slot and 1 bt-slot */
slot_pair = BTC_CYCLE_SLOT_MAX / 2;
@@ -7534,53 +9230,57 @@ static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m)
store_index = ((cycle - 1) % slot_pair) * 2;
if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 1)
- seq_printf(m,
- " %-15s : ->b%02d->w%02d", "[cycle_step]",
- le16_to_cpu(pcysta_le32->tslot_cycle[store_index]),
- le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1]));
+ p += scnprintf(p, end - p,
+ " %-15s : ->b%02d->w%02d",
+ "[cycle_step]",
+ le16_to_cpu(pcysta_le32->tslot_cycle[store_index]),
+ le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1]));
else
- seq_printf(m,
- "->b%02d->w%02d",
- le16_to_cpu(pcysta_le32->tslot_cycle[store_index]),
- le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1]));
+ p += scnprintf(p, end - p,
+ "->b%02d->w%02d",
+ le16_to_cpu(pcysta_le32->tslot_cycle[store_index]),
+ le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1]));
if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end)
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
if (a2dp->exist) {
- seq_printf(m,
- " %-15s : a2dp_ept:%d, a2dp_late:%d",
- "[a2dp_t_sta]",
- le16_to_cpu(pcysta_le32->a2dpept),
- le16_to_cpu(pcysta_le32->a2dpeptto));
-
- seq_printf(m,
- ", avg_t:%d, max_t:%d",
- le16_to_cpu(pcysta_le32->tavg_a2dpept),
- le16_to_cpu(pcysta_le32->tmax_a2dpept));
+ p += scnprintf(p, end - p,
+ " %-15s : a2dp_ept:%d, a2dp_late:%d",
+ "[a2dp_t_sta]",
+ le16_to_cpu(pcysta_le32->a2dpept),
+ le16_to_cpu(pcysta_le32->a2dpeptto));
+
+ p += scnprintf(p, end - p,
+ ", avg_t:%d, max_t:%d",
+ le16_to_cpu(pcysta_le32->tavg_a2dpept),
+ le16_to_cpu(pcysta_le32->tmax_a2dpept));
r.val = dm->tdma_now.rxflctrl;
if (r.type && r.tgln_n) {
- seq_printf(m,
- ", cycle[PSTDMA:%d/TDMA:%d], ",
- le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_ON]),
- le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_OFF]));
-
- seq_printf(m,
- "avg_t[PSTDMA:%d/TDMA:%d], ",
- le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_ON]),
- le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_OFF]));
-
- seq_printf(m,
- "max_t[PSTDMA:%d/TDMA:%d]",
- le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_ON]),
- le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_OFF]));
+ p += scnprintf(p, end - p,
+ ", cycle[PSTDMA:%d/TDMA:%d], ",
+ le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_ON]),
+ le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_OFF]));
+
+ p += scnprintf(p, end - p,
+ "avg_t[PSTDMA:%d/TDMA:%d], ",
+ le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_ON]),
+ le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_OFF]));
+
+ p += scnprintf(p, end - p,
+ "max_t[PSTDMA:%d/TDMA:%d]",
+ le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_ON]),
+ le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_OFF]));
}
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
+
+out:
+ return p - buf;
}
-static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
@@ -7591,60 +9291,64 @@ static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m)
struct rtw89_btc_rpt_cmn_info *pcinfo;
u8 i, cnt = 0, slot_pair, divide_cnt;
u16 cycle, c_begin, c_end, store_index;
+ char *p = buf, *end = buf + bufsz;
pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo;
if (!pcinfo->valid)
- return;
+ return 0;
pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v3;
- seq_printf(m,
- " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
- "[cycle_cnt]",
- le16_to_cpu(pcysta->cycles),
- le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]),
- le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]),
- le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]),
- le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK]));
+ p += scnprintf(p, end - p,
+ " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
+ "[cycle_cnt]",
+ le16_to_cpu(pcysta->cycles),
+ le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]),
+ le32_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]),
+ le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]),
+ le32_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK]));
for (i = 0; i < CXST_MAX; i++) {
if (!le32_to_cpu(pcysta->slot_cnt[i]))
continue;
- seq_printf(m, ", %s:%d", id_to_slot(i),
- le32_to_cpu(pcysta->slot_cnt[i]));
+ p += scnprintf(p, end - p, ", %s:%d", id_to_slot(i),
+ le32_to_cpu(pcysta->slot_cnt[i]));
}
if (dm->tdma_now.rxflctrl)
- seq_printf(m, ", leak_rx:%d", le32_to_cpu(pcysta->leak_slot.cnt_rximr));
+ p += scnprintf(p, end - p, ", leak_rx:%d",
+ le32_to_cpu(pcysta->leak_slot.cnt_rximr));
if (le32_to_cpu(pcysta->collision_cnt))
- seq_printf(m, ", collision:%d", le32_to_cpu(pcysta->collision_cnt));
+ p += scnprintf(p, end - p, ", collision:%d",
+ le32_to_cpu(pcysta->collision_cnt));
if (le32_to_cpu(pcysta->skip_cnt))
- seq_printf(m, ", skip:%d", le32_to_cpu(pcysta->skip_cnt));
-
- seq_puts(m, "\n");
-
- seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]",
- "[cycle_time]",
- le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]),
- le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]),
- le16_to_cpu(pcysta->leak_slot.tavg) / 1000,
- le16_to_cpu(pcysta->leak_slot.tavg) % 1000);
- seq_printf(m,
- ", max_t[wl:%d/bt:%d/lk:%d.%03d]",
- le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]),
- le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]),
- le16_to_cpu(pcysta->leak_slot.tmax) / 1000,
- le16_to_cpu(pcysta->leak_slot.tmax) % 1000);
- seq_printf(m,
- ", maxdiff_t[wl:%d/bt:%d]\n",
- le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]),
- le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT]));
+ p += scnprintf(p, end - p, ", skip:%d",
+ le32_to_cpu(pcysta->skip_cnt));
+
+ p += scnprintf(p, end - p, "\n");
+
+ p += scnprintf(p, end - p, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]",
+ "[cycle_time]",
+ le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]),
+ le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]),
+ le16_to_cpu(pcysta->leak_slot.tavg) / 1000,
+ le16_to_cpu(pcysta->leak_slot.tavg) % 1000);
+ p += scnprintf(p, end - p,
+ ", max_t[wl:%d/bt:%d/lk:%d.%03d]",
+ le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]),
+ le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]),
+ le16_to_cpu(pcysta->leak_slot.tmax) / 1000,
+ le16_to_cpu(pcysta->leak_slot.tmax) % 1000);
+ p += scnprintf(p, end - p,
+ ", maxdiff_t[wl:%d/bt:%d]\n",
+ le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]),
+ le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT]));
cycle = le16_to_cpu(pcysta->cycles);
if (cycle <= 1)
- return;
+ goto out;
/* 1 cycle record 1 wl-slot and 1 bt-slot */
slot_pair = BTC_CYCLE_SLOT_MAX / 2;
@@ -7666,51 +9370,56 @@ static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m)
store_index = ((cycle - 1) % slot_pair) * 2;
if (cnt % divide_cnt == 1)
- seq_printf(m, " %-15s : ", "[cycle_step]");
+ p += scnprintf(p, end - p, " %-15s : ",
+ "[cycle_step]");
- seq_printf(m, "->b%02d",
- le16_to_cpu(pcysta->slot_step_time[store_index]));
+ p += scnprintf(p, end - p, "->b%02d",
+ le16_to_cpu(pcysta->slot_step_time[store_index]));
if (a2dp->exist) {
a2dp_trx = &pcysta->a2dp_trx[store_index];
- seq_printf(m, "(%d/%d/%dM/%d/%d/%d)",
- a2dp_trx->empty_cnt,
- a2dp_trx->retry_cnt,
- a2dp_trx->tx_rate ? 3 : 2,
- a2dp_trx->tx_cnt,
- a2dp_trx->ack_cnt,
- a2dp_trx->nack_cnt);
+ p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)",
+ a2dp_trx->empty_cnt,
+ a2dp_trx->retry_cnt,
+ a2dp_trx->tx_rate ? 3 : 2,
+ a2dp_trx->tx_cnt,
+ a2dp_trx->ack_cnt,
+ a2dp_trx->nack_cnt);
}
- seq_printf(m, "->w%02d",
- le16_to_cpu(pcysta->slot_step_time[store_index + 1]));
+ p += scnprintf(p, end - p, "->w%02d",
+ le16_to_cpu(pcysta->slot_step_time[store_index + 1]));
if (a2dp->exist) {
a2dp_trx = &pcysta->a2dp_trx[store_index + 1];
- seq_printf(m, "(%d/%d/%dM/%d/%d/%d)",
- a2dp_trx->empty_cnt,
- a2dp_trx->retry_cnt,
- a2dp_trx->tx_rate ? 3 : 2,
- a2dp_trx->tx_cnt,
- a2dp_trx->ack_cnt,
- a2dp_trx->nack_cnt);
+ p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)",
+ a2dp_trx->empty_cnt,
+ a2dp_trx->retry_cnt,
+ a2dp_trx->tx_rate ? 3 : 2,
+ a2dp_trx->tx_cnt,
+ a2dp_trx->ack_cnt,
+ a2dp_trx->nack_cnt);
}
if (cnt % divide_cnt == 0 || cnt == c_end)
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
if (a2dp->exist) {
- seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d",
- "[a2dp_t_sta]",
- le16_to_cpu(pcysta->a2dp_ept.cnt),
- le16_to_cpu(pcysta->a2dp_ept.cnt_timeout));
+ p += scnprintf(p, end - p,
+ " %-15s : a2dp_ept:%d, a2dp_late:%d",
+ "[a2dp_t_sta]",
+ le16_to_cpu(pcysta->a2dp_ept.cnt),
+ le16_to_cpu(pcysta->a2dp_ept.cnt_timeout));
- seq_printf(m, ", avg_t:%d, max_t:%d",
- le16_to_cpu(pcysta->a2dp_ept.tavg),
- le16_to_cpu(pcysta->a2dp_ept.tmax));
+ p += scnprintf(p, end - p, ", avg_t:%d, max_t:%d",
+ le16_to_cpu(pcysta->a2dp_ept.tavg),
+ le16_to_cpu(pcysta->a2dp_ept.tmax));
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
+
+out:
+ return p - buf;
}
-static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
@@ -7721,62 +9430,64 @@ static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m)
struct rtw89_btc_rpt_cmn_info *pcinfo;
u8 i, cnt = 0, slot_pair, divide_cnt;
u16 cycle, c_begin, c_end, store_index;
+ char *p = buf, *end = buf + bufsz;
pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo;
if (!pcinfo->valid)
- return;
+ return 0;
pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v4;
- seq_printf(m,
- " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
- "[cycle_cnt]",
- le16_to_cpu(pcysta->cycles),
- le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]),
- le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]),
- le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]),
- le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK]));
+ p += scnprintf(p, end - p,
+ " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
+ "[cycle_cnt]",
+ le16_to_cpu(pcysta->cycles),
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]),
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]),
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]),
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK]));
for (i = 0; i < CXST_MAX; i++) {
if (!le16_to_cpu(pcysta->slot_cnt[i]))
continue;
- seq_printf(m, ", %s:%d", id_to_slot(i),
- le16_to_cpu(pcysta->slot_cnt[i]));
+ p += scnprintf(p, end - p, ", %s:%d", id_to_slot(i),
+ le16_to_cpu(pcysta->slot_cnt[i]));
}
if (dm->tdma_now.rxflctrl)
- seq_printf(m, ", leak_rx:%d",
- le32_to_cpu(pcysta->leak_slot.cnt_rximr));
+ p += scnprintf(p, end - p, ", leak_rx:%d",
+ le32_to_cpu(pcysta->leak_slot.cnt_rximr));
if (pcysta->collision_cnt)
- seq_printf(m, ", collision:%d", pcysta->collision_cnt);
+ p += scnprintf(p, end - p, ", collision:%d",
+ pcysta->collision_cnt);
if (le16_to_cpu(pcysta->skip_cnt))
- seq_printf(m, ", skip:%d",
- le16_to_cpu(pcysta->skip_cnt));
-
- seq_puts(m, "\n");
-
- seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]",
- "[cycle_time]",
- le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]),
- le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]),
- le16_to_cpu(pcysta->leak_slot.tavg) / 1000,
- le16_to_cpu(pcysta->leak_slot.tavg) % 1000);
- seq_printf(m,
- ", max_t[wl:%d/bt:%d/lk:%d.%03d]",
- le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]),
- le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]),
- le16_to_cpu(pcysta->leak_slot.tmax) / 1000,
- le16_to_cpu(pcysta->leak_slot.tmax) % 1000);
- seq_printf(m,
- ", maxdiff_t[wl:%d/bt:%d]\n",
- le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]),
- le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT]));
+ p += scnprintf(p, end - p, ", skip:%d",
+ le16_to_cpu(pcysta->skip_cnt));
+
+ p += scnprintf(p, end - p, "\n");
+
+ p += scnprintf(p, end - p, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]",
+ "[cycle_time]",
+ le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]),
+ le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]),
+ le16_to_cpu(pcysta->leak_slot.tavg) / 1000,
+ le16_to_cpu(pcysta->leak_slot.tavg) % 1000);
+ p += scnprintf(p, end - p,
+ ", max_t[wl:%d/bt:%d/lk:%d.%03d]",
+ le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]),
+ le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]),
+ le16_to_cpu(pcysta->leak_slot.tmax) / 1000,
+ le16_to_cpu(pcysta->leak_slot.tmax) % 1000);
+ p += scnprintf(p, end - p,
+ ", maxdiff_t[wl:%d/bt:%d]\n",
+ le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]),
+ le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT]));
cycle = le16_to_cpu(pcysta->cycles);
if (cycle <= 1)
- return;
+ goto out;
/* 1 cycle record 1 wl-slot and 1 bt-slot */
slot_pair = BTC_CYCLE_SLOT_MAX / 2;
@@ -7798,51 +9509,56 @@ static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m)
store_index = ((cycle - 1) % slot_pair) * 2;
if (cnt % divide_cnt == 1)
- seq_printf(m, " %-15s : ", "[cycle_step]");
+ p += scnprintf(p, end - p, " %-15s : ",
+ "[cycle_step]");
- seq_printf(m, "->b%02d",
- le16_to_cpu(pcysta->slot_step_time[store_index]));
+ p += scnprintf(p, end - p, "->b%02d",
+ le16_to_cpu(pcysta->slot_step_time[store_index]));
if (a2dp->exist) {
a2dp_trx = &pcysta->a2dp_trx[store_index];
- seq_printf(m, "(%d/%d/%dM/%d/%d/%d)",
- a2dp_trx->empty_cnt,
- a2dp_trx->retry_cnt,
- a2dp_trx->tx_rate ? 3 : 2,
- a2dp_trx->tx_cnt,
- a2dp_trx->ack_cnt,
- a2dp_trx->nack_cnt);
+ p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)",
+ a2dp_trx->empty_cnt,
+ a2dp_trx->retry_cnt,
+ a2dp_trx->tx_rate ? 3 : 2,
+ a2dp_trx->tx_cnt,
+ a2dp_trx->ack_cnt,
+ a2dp_trx->nack_cnt);
}
- seq_printf(m, "->w%02d",
- le16_to_cpu(pcysta->slot_step_time[store_index + 1]));
+ p += scnprintf(p, end - p, "->w%02d",
+ le16_to_cpu(pcysta->slot_step_time[store_index + 1]));
if (a2dp->exist) {
a2dp_trx = &pcysta->a2dp_trx[store_index + 1];
- seq_printf(m, "(%d/%d/%dM/%d/%d/%d)",
- a2dp_trx->empty_cnt,
- a2dp_trx->retry_cnt,
- a2dp_trx->tx_rate ? 3 : 2,
- a2dp_trx->tx_cnt,
- a2dp_trx->ack_cnt,
- a2dp_trx->nack_cnt);
+ p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)",
+ a2dp_trx->empty_cnt,
+ a2dp_trx->retry_cnt,
+ a2dp_trx->tx_rate ? 3 : 2,
+ a2dp_trx->tx_cnt,
+ a2dp_trx->ack_cnt,
+ a2dp_trx->nack_cnt);
}
if (cnt % divide_cnt == 0 || cnt == c_end)
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
if (a2dp->exist) {
- seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d",
- "[a2dp_t_sta]",
- le16_to_cpu(pcysta->a2dp_ept.cnt),
- le16_to_cpu(pcysta->a2dp_ept.cnt_timeout));
+ p += scnprintf(p, end - p,
+ " %-15s : a2dp_ept:%d, a2dp_late:%d",
+ "[a2dp_t_sta]",
+ le16_to_cpu(pcysta->a2dp_ept.cnt),
+ le16_to_cpu(pcysta->a2dp_ept.cnt_timeout));
- seq_printf(m, ", avg_t:%d, max_t:%d",
- le16_to_cpu(pcysta->a2dp_ept.tavg),
- le16_to_cpu(pcysta->a2dp_ept.tmax));
+ p += scnprintf(p, end - p, ", avg_t:%d, max_t:%d",
+ le16_to_cpu(pcysta->a2dp_ept.tavg),
+ le16_to_cpu(pcysta->a2dp_ept.tmax));
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
+
+out:
+ return p - buf;
}
-static void _show_fbtc_cysta_v5(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_fbtc_cysta_v5(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
@@ -7853,58 +9569,60 @@ static void _show_fbtc_cysta_v5(struct rtw89_dev *rtwdev, struct seq_file *m)
struct rtw89_btc_rpt_cmn_info *pcinfo;
u8 i, cnt = 0, slot_pair, divide_cnt;
u16 cycle, c_begin, c_end, store_index;
+ char *p = buf, *end = buf + bufsz;
pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo;
if (!pcinfo->valid)
- return;
+ return 0;
pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v5;
- seq_printf(m,
- " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
- "[cycle_cnt]",
- le16_to_cpu(pcysta->cycles),
- le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]),
- le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]),
- le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]),
- le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK]));
+ p += scnprintf(p, end - p,
+ " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
+ "[cycle_cnt]",
+ le16_to_cpu(pcysta->cycles),
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]),
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]),
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]),
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK]));
for (i = 0; i < CXST_MAX; i++) {
if (!le16_to_cpu(pcysta->slot_cnt[i]))
continue;
- seq_printf(m, ", %s:%d", id_to_slot(i),
- le16_to_cpu(pcysta->slot_cnt[i]));
+ p += scnprintf(p, end - p, ", %s:%d", id_to_slot(i),
+ le16_to_cpu(pcysta->slot_cnt[i]));
}
if (dm->tdma_now.rxflctrl)
- seq_printf(m, ", leak_rx:%d",
- le32_to_cpu(pcysta->leak_slot.cnt_rximr));
+ p += scnprintf(p, end - p, ", leak_rx:%d",
+ le32_to_cpu(pcysta->leak_slot.cnt_rximr));
if (pcysta->collision_cnt)
- seq_printf(m, ", collision:%d", pcysta->collision_cnt);
+ p += scnprintf(p, end - p, ", collision:%d",
+ pcysta->collision_cnt);
if (le16_to_cpu(pcysta->skip_cnt))
- seq_printf(m, ", skip:%d",
- le16_to_cpu(pcysta->skip_cnt));
-
- seq_puts(m, "\n");
-
- seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]",
- "[cycle_time]",
- le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]),
- le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]),
- le16_to_cpu(pcysta->leak_slot.tavg) / 1000,
- le16_to_cpu(pcysta->leak_slot.tavg) % 1000);
- seq_printf(m,
- ", max_t[wl:%d/bt:%d/lk:%d.%03d]\n",
- le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]),
- le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]),
- le16_to_cpu(pcysta->leak_slot.tmax) / 1000,
- le16_to_cpu(pcysta->leak_slot.tmax) % 1000);
+ p += scnprintf(p, end - p, ", skip:%d",
+ le16_to_cpu(pcysta->skip_cnt));
+
+ p += scnprintf(p, end - p, "\n");
+
+ p += scnprintf(p, end - p, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]",
+ "[cycle_time]",
+ le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]),
+ le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]),
+ le16_to_cpu(pcysta->leak_slot.tavg) / 1000,
+ le16_to_cpu(pcysta->leak_slot.tavg) % 1000);
+ p += scnprintf(p, end - p,
+ ", max_t[wl:%d/bt:%d/lk:%d.%03d]\n",
+ le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]),
+ le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]),
+ le16_to_cpu(pcysta->leak_slot.tmax) / 1000,
+ le16_to_cpu(pcysta->leak_slot.tmax) % 1000);
cycle = le16_to_cpu(pcysta->cycles);
if (cycle <= 1)
- return;
+ goto out;
/* 1 cycle record 1 wl-slot and 1 bt-slot */
slot_pair = BTC_CYCLE_SLOT_MAX / 2;
@@ -7922,124 +9640,300 @@ static void _show_fbtc_cysta_v5(struct rtw89_dev *rtwdev, struct seq_file *m)
divide_cnt = BTC_CYCLE_SLOT_MAX / 4;
if (c_begin > c_end)
- return;
+ goto out;
for (cycle = c_begin; cycle <= c_end; cycle++) {
cnt++;
store_index = ((cycle - 1) % slot_pair) * 2;
if (cnt % divide_cnt == 1)
- seq_printf(m, " %-15s : ", "[cycle_step]");
+ p += scnprintf(p, end - p, " %-15s : ",
+ "[cycle_step]");
- seq_printf(m, "->b%02d",
- le16_to_cpu(pcysta->slot_step_time[store_index]));
+ p += scnprintf(p, end - p, "->b%02d",
+ le16_to_cpu(pcysta->slot_step_time[store_index]));
if (a2dp->exist) {
a2dp_trx = &pcysta->a2dp_trx[store_index];
- seq_printf(m, "(%d/%d/%dM/%d/%d/%d)",
- a2dp_trx->empty_cnt,
- a2dp_trx->retry_cnt,
- a2dp_trx->tx_rate ? 3 : 2,
- a2dp_trx->tx_cnt,
- a2dp_trx->ack_cnt,
- a2dp_trx->nack_cnt);
+ p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)",
+ a2dp_trx->empty_cnt,
+ a2dp_trx->retry_cnt,
+ a2dp_trx->tx_rate ? 3 : 2,
+ a2dp_trx->tx_cnt,
+ a2dp_trx->ack_cnt,
+ a2dp_trx->nack_cnt);
}
- seq_printf(m, "->w%02d",
- le16_to_cpu(pcysta->slot_step_time[store_index + 1]));
+ p += scnprintf(p, end - p, "->w%02d",
+ le16_to_cpu(pcysta->slot_step_time[store_index + 1]));
if (a2dp->exist) {
a2dp_trx = &pcysta->a2dp_trx[store_index + 1];
- seq_printf(m, "(%d/%d/%dM/%d/%d/%d)",
- a2dp_trx->empty_cnt,
- a2dp_trx->retry_cnt,
- a2dp_trx->tx_rate ? 3 : 2,
- a2dp_trx->tx_cnt,
- a2dp_trx->ack_cnt,
- a2dp_trx->nack_cnt);
+ p += scnprintf(p, end - p, "(%d/%d/%dM/%d/%d/%d)",
+ a2dp_trx->empty_cnt,
+ a2dp_trx->retry_cnt,
+ a2dp_trx->tx_rate ? 3 : 2,
+ a2dp_trx->tx_cnt,
+ a2dp_trx->ack_cnt,
+ a2dp_trx->nack_cnt);
}
if (cnt % divide_cnt == 0 || cnt == c_end)
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
+ }
+
+ if (a2dp->exist) {
+ p += scnprintf(p, end - p,
+ " %-15s : a2dp_ept:%d, a2dp_late:%d",
+ "[a2dp_t_sta]",
+ le16_to_cpu(pcysta->a2dp_ept.cnt),
+ le16_to_cpu(pcysta->a2dp_ept.cnt_timeout));
+
+ p += scnprintf(p, end - p, ", avg_t:%d, max_t:%d",
+ le16_to_cpu(pcysta->a2dp_ept.tavg),
+ le16_to_cpu(pcysta->a2dp_ept.tmax));
+
+ p += scnprintf(p, end - p, "\n");
+ }
+
+out:
+ return p - buf;
+}
+
+static int _show_fbtc_cysta_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
+{
+ struct rtw89_btc_bt_info *bt = &rtwdev->btc.cx.bt;
+ struct rtw89_btc_bt_a2dp_desc *a2dp = &bt->link_info.a2dp_desc;
+ struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo;
+ struct rtw89_btc_fbtc_cysta_v7 *pcysta = NULL;
+ struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
+ struct rtw89_btc_rpt_cmn_info *pcinfo;
+ char *p = buf, *end = buf + bufsz;
+ u16 cycle, c_begin, c_end, s_id;
+ u8 i, cnt = 0, divide_cnt;
+ u8 slot_pair;
+
+ pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo;
+ if (!pcinfo->valid)
+ return 0;
+
+ pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v7;
+ p += scnprintf(p, end - p, "\n\r %-15s : cycle:%d", "[slot_stat]",
+ le16_to_cpu(pcysta->cycles));
+
+ for (i = 0; i < CXST_MAX; i++) {
+ if (!le16_to_cpu(pcysta->slot_cnt[i]))
+ continue;
+ p += scnprintf(p, end - p, ", %s:%d",
+ id_to_slot(i),
+ le16_to_cpu(pcysta->slot_cnt[i]));
}
+ if (dm->tdma_now.rxflctrl)
+ p += scnprintf(p, end - p, ", leak_rx:%d",
+ le32_to_cpu(pcysta->leak_slot.cnt_rximr));
+
+ if (pcysta->collision_cnt)
+ p += scnprintf(p, end - p, ", collision:%d",
+ pcysta->collision_cnt);
+
+ if (pcysta->skip_cnt)
+ p += scnprintf(p, end - p, ", skip:%d",
+ le16_to_cpu(pcysta->skip_cnt));
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]",
+ "[cycle_stat]",
+ le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]),
+ le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]),
+ le16_to_cpu(pcysta->leak_slot.tavg) / 1000,
+ le16_to_cpu(pcysta->leak_slot.tavg) % 1000);
+ p += scnprintf(p, end - p,
+ ", max_t[wl:%d/bt:%d(>%dms:%d)/lk:%d.%03d]",
+ le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]),
+ le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]),
+ dm->bt_slot_flood, dm->cnt_dm[BTC_DCNT_BT_SLOT_FLOOD],
+ le16_to_cpu(pcysta->leak_slot.tamx) / 1000,
+ le16_to_cpu(pcysta->leak_slot.tamx) % 1000);
+ p += scnprintf(p, end - p, ", bcn[all:%d/ok:%d/in_bt:%d/in_bt_ok:%d]",
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]),
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]),
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]),
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK]));
+
if (a2dp->exist) {
- seq_printf(m, " %-15s : a2dp_ept:%d, a2dp_late:%d",
- "[a2dp_t_sta]",
- le16_to_cpu(pcysta->a2dp_ept.cnt),
- le16_to_cpu(pcysta->a2dp_ept.cnt_timeout));
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : a2dp_ept:%d, a2dp_late:%d(streak 2S:%d/max:%d)",
+ "[a2dp_stat]",
+ le16_to_cpu(pcysta->a2dp_ept.cnt),
+ le16_to_cpu(pcysta->a2dp_ept.cnt_timeout),
+ a2dp->no_empty_streak_2s,
+ a2dp->no_empty_streak_max);
+
+ p += scnprintf(p, end - p, ", avg_t:%d, max_t:%d",
+ le16_to_cpu(pcysta->a2dp_ept.tavg),
+ le16_to_cpu(pcysta->a2dp_ept.tmax));
+ }
+
+ if (le16_to_cpu(pcysta->cycles) <= 1)
+ goto out;
+
+ /* 1 cycle = 1 wl-slot + 1 bt-slot */
+ slot_pair = BTC_CYCLE_SLOT_MAX / 2;
+
+ if (le16_to_cpu(pcysta->cycles) <= slot_pair)
+ c_begin = 1;
+ else
+ c_begin = le16_to_cpu(pcysta->cycles) - slot_pair + 1;
+
+ c_end = le16_to_cpu(pcysta->cycles);
+
+ if (a2dp->exist)
+ divide_cnt = 2;
+ else
+ divide_cnt = 6;
- seq_printf(m, ", avg_t:%d, max_t:%d",
- le16_to_cpu(pcysta->a2dp_ept.tavg),
- le16_to_cpu(pcysta->a2dp_ept.tmax));
+ if (c_begin > c_end)
+ goto out;
+
+ for (cycle = c_begin; cycle <= c_end; cycle++) {
+ cnt++;
+ s_id = ((cycle - 1) % slot_pair) * 2;
+
+ if (cnt % divide_cnt == 1) {
+ if (a2dp->exist)
+ p += scnprintf(p, end - p, "\n\r %-15s : ",
+ "[slotT_wermtan]");
+ else
+ p += scnprintf(p, end - p, "\n\r %-15s : ",
+ "[slotT_rxerr]");
+ }
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "->b%d",
+ le16_to_cpu(pcysta->slot_step_time[s_id]));
+
+ if (a2dp->exist)
+ p += scnprintf(p, end - p, "(%d/%d/%d/%dM/%d/%d/%d)",
+ pcysta->wl_rx_err_ratio[s_id],
+ pcysta->a2dp_trx[s_id].empty_cnt,
+ pcysta->a2dp_trx[s_id].retry_cnt,
+ (pcysta->a2dp_trx[s_id].tx_rate ? 3 : 2),
+ pcysta->a2dp_trx[s_id].tx_cnt,
+ pcysta->a2dp_trx[s_id].ack_cnt,
+ pcysta->a2dp_trx[s_id].nack_cnt);
+ else
+ p += scnprintf(p, end - p, "(%d)",
+ pcysta->wl_rx_err_ratio[s_id]);
+
+ p += scnprintf(p, end - p, "->w%d",
+ le16_to_cpu(pcysta->slot_step_time[s_id + 1]));
+
+ if (a2dp->exist)
+ p += scnprintf(p, end - p, "(%d/%d/%d/%dM/%d/%d/%d)",
+ pcysta->wl_rx_err_ratio[s_id + 1],
+ pcysta->a2dp_trx[s_id + 1].empty_cnt,
+ pcysta->a2dp_trx[s_id + 1].retry_cnt,
+ (pcysta->a2dp_trx[s_id + 1].tx_rate ? 3 : 2),
+ pcysta->a2dp_trx[s_id + 1].tx_cnt,
+ pcysta->a2dp_trx[s_id + 1].ack_cnt,
+ pcysta->a2dp_trx[s_id + 1].nack_cnt);
+ else
+ p += scnprintf(p, end - p, "(%d)",
+ pcysta->wl_rx_err_ratio[s_id + 1]);
}
+
+out:
+ return p - buf;
}
-static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_fbtc_nullsta(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
struct rtw89_btc_rpt_cmn_info *pcinfo;
union rtw89_btc_fbtc_cynullsta_info *ns;
+ char *p = buf, *end = buf + bufsz;
u8 i = 0;
if (!btc->dm.tdma_now.rxflctrl)
- return;
+ return 0;
pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo;
if (!pcinfo->valid)
- return;
+ return 0;
ns = &pfwinfo->rpt_fbtc_nullsta.finfo;
if (ver->fcxnullsta == 1) {
for (i = 0; i < 2; i++) {
- seq_printf(m, " %-15s : ", "[NULL-STA]");
- seq_printf(m, "null-%d", i);
- seq_printf(m, "[ok:%d/",
- le32_to_cpu(ns->v1.result[i][1]));
- seq_printf(m, "fail:%d/",
- le32_to_cpu(ns->v1.result[i][0]));
- seq_printf(m, "on_time:%d/",
- le32_to_cpu(ns->v1.result[i][2]));
- seq_printf(m, "retry:%d/",
- le32_to_cpu(ns->v1.result[i][3]));
- seq_printf(m, "avg_t:%d.%03d/",
- le32_to_cpu(ns->v1.avg_t[i]) / 1000,
- le32_to_cpu(ns->v1.avg_t[i]) % 1000);
- seq_printf(m, "max_t:%d.%03d]\n",
- le32_to_cpu(ns->v1.max_t[i]) / 1000,
- le32_to_cpu(ns->v1.max_t[i]) % 1000);
+ p += scnprintf(p, end - p, " %-15s : ", "[NULL-STA]");
+ p += scnprintf(p, end - p, "null-%d", i);
+ p += scnprintf(p, end - p, "[ok:%d/",
+ le32_to_cpu(ns->v1.result[i][1]));
+ p += scnprintf(p, end - p, "fail:%d/",
+ le32_to_cpu(ns->v1.result[i][0]));
+ p += scnprintf(p, end - p, "on_time:%d/",
+ le32_to_cpu(ns->v1.result[i][2]));
+ p += scnprintf(p, end - p, "retry:%d/",
+ le32_to_cpu(ns->v1.result[i][3]));
+ p += scnprintf(p, end - p, "avg_t:%d.%03d/",
+ le32_to_cpu(ns->v1.avg_t[i]) / 1000,
+ le32_to_cpu(ns->v1.avg_t[i]) % 1000);
+ p += scnprintf(p, end - p, "max_t:%d.%03d]\n",
+ le32_to_cpu(ns->v1.max_t[i]) / 1000,
+ le32_to_cpu(ns->v1.max_t[i]) % 1000);
+ }
+ } else if (ver->fcxnullsta == 7) {
+ for (i = 0; i < 2; i++) {
+ p += scnprintf(p, end - p, " %-15s : ", "[NULL-STA]");
+ p += scnprintf(p, end - p, "null-%d", i);
+ p += scnprintf(p, end - p, "[Tx:%d/",
+ le32_to_cpu(ns->v7.result[i][4]));
+ p += scnprintf(p, end - p, "[ok:%d/",
+ le32_to_cpu(ns->v7.result[i][1]));
+ p += scnprintf(p, end - p, "fail:%d/",
+ le32_to_cpu(ns->v7.result[i][0]));
+ p += scnprintf(p, end - p, "on_time:%d/",
+ le32_to_cpu(ns->v7.result[i][2]));
+ p += scnprintf(p, end - p, "retry:%d/",
+ le32_to_cpu(ns->v7.result[i][3]));
+ p += scnprintf(p, end - p, "avg_t:%d.%03d/",
+ le32_to_cpu(ns->v7.tavg[i]) / 1000,
+ le32_to_cpu(ns->v7.tavg[i]) % 1000);
+ p += scnprintf(p, end - p, "max_t:%d.%03d]\n",
+ le32_to_cpu(ns->v7.tmax[i]) / 1000,
+ le32_to_cpu(ns->v7.tmax[i]) % 1000);
}
} else {
for (i = 0; i < 2; i++) {
- seq_printf(m, " %-15s : ", "[NULL-STA]");
- seq_printf(m, "null-%d", i);
- seq_printf(m, "[Tx:%d/",
- le32_to_cpu(ns->v2.result[i][4]));
- seq_printf(m, "[ok:%d/",
- le32_to_cpu(ns->v2.result[i][1]));
- seq_printf(m, "fail:%d/",
- le32_to_cpu(ns->v2.result[i][0]));
- seq_printf(m, "on_time:%d/",
- le32_to_cpu(ns->v2.result[i][2]));
- seq_printf(m, "retry:%d/",
- le32_to_cpu(ns->v2.result[i][3]));
- seq_printf(m, "avg_t:%d.%03d/",
- le32_to_cpu(ns->v2.avg_t[i]) / 1000,
- le32_to_cpu(ns->v2.avg_t[i]) % 1000);
- seq_printf(m, "max_t:%d.%03d]\n",
- le32_to_cpu(ns->v2.max_t[i]) / 1000,
- le32_to_cpu(ns->v2.max_t[i]) % 1000);
+ p += scnprintf(p, end - p, " %-15s : ", "[NULL-STA]");
+ p += scnprintf(p, end - p, "null-%d", i);
+ p += scnprintf(p, end - p, "[Tx:%d/",
+ le32_to_cpu(ns->v2.result[i][4]));
+ p += scnprintf(p, end - p, "[ok:%d/",
+ le32_to_cpu(ns->v2.result[i][1]));
+ p += scnprintf(p, end - p, "fail:%d/",
+ le32_to_cpu(ns->v2.result[i][0]));
+ p += scnprintf(p, end - p, "on_time:%d/",
+ le32_to_cpu(ns->v2.result[i][2]));
+ p += scnprintf(p, end - p, "retry:%d/",
+ le32_to_cpu(ns->v2.result[i][3]));
+ p += scnprintf(p, end - p, "avg_t:%d.%03d/",
+ le32_to_cpu(ns->v2.avg_t[i]) / 1000,
+ le32_to_cpu(ns->v2.avg_t[i]) % 1000);
+ p += scnprintf(p, end - p, "max_t:%d.%03d]\n",
+ le32_to_cpu(ns->v2.max_t[i]) / 1000,
+ le32_to_cpu(ns->v2.max_t[i]) % 1000);
}
}
+
+ return p - buf;
}
-static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_fbtc_step_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_fbtc_steps_v2 *pstep = NULL;
const struct rtw89_btc_ver *ver = btc->ver;
+ char *p = buf, *end = buf + bufsz;
u8 type, val, cnt = 0, state = 0;
bool outloop = false;
u16 i, diff_t, n_start = 0, n_stop = 0;
@@ -8047,14 +9941,14 @@ static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m)
pcinfo = &pfwinfo->rpt_fbtc_step.cinfo;
if (!pcinfo->valid)
- return;
+ return 0;
pstep = &pfwinfo->rpt_fbtc_step.finfo.v2;
pos_old = le16_to_cpu(pstep->pos_old);
pos_new = le16_to_cpu(pstep->pos_new);
if (pcinfo->req_fver != pstep->fver)
- return;
+ return 0;
/* store step info by using ring instead of FIFO*/
do {
@@ -8083,13 +9977,15 @@ static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m)
continue;
if (cnt % 10 == 0)
- seq_printf(m, " %-15s : ", "[steps]");
+ p += scnprintf(p, end - p,
+ " %-15s : ", "[steps]");
- seq_printf(m, "-> %s(%02d)(%02d)",
- (type == CXSTEP_SLOT ? "SLT" :
- "EVT"), (u32)val, diff_t);
+ p += scnprintf(p, end - p,
+ "-> %s(%02d)(%02d)",
+ (type == CXSTEP_SLOT ? "SLT" :
+ "EVT"), (u32)val, diff_t);
if (cnt % 10 == 9)
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
cnt++;
}
@@ -8106,29 +10002,32 @@ static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m)
break;
}
} while (!outloop);
+
+ return p - buf;
}
-static void _show_fbtc_step_v3(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_fbtc_step_v3(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
struct rtw89_btc_rpt_cmn_info *pcinfo;
struct rtw89_btc_fbtc_steps_v3 *pstep;
u32 i, n_begin, n_end, array_idx, cnt = 0;
+ char *p = buf, *end = buf + bufsz;
u8 type, val;
u16 diff_t;
if ((pfwinfo->rpt_en_map &
rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_FW_STEP_INFO)) == 0)
- return;
+ return 0;
pcinfo = &pfwinfo->rpt_fbtc_step.cinfo;
if (!pcinfo->valid)
- return;
+ return 0;
pstep = &pfwinfo->rpt_fbtc_step.finfo.v3;
if (pcinfo->req_fver != pstep->fver)
- return;
+ return 0;
if (le32_to_cpu(pstep->cnt) <= FCXDEF_STEP)
n_begin = 1;
@@ -8138,7 +10037,7 @@ static void _show_fbtc_step_v3(struct rtw89_dev *rtwdev, struct seq_file *m)
n_end = le32_to_cpu(pstep->cnt);
if (n_begin > n_end)
- return;
+ return 0;
/* restore step info by using ring instead of FIFO */
for (i = n_begin; i <= n_end; i++) {
@@ -8151,48 +10050,55 @@ static void _show_fbtc_step_v3(struct rtw89_dev *rtwdev, struct seq_file *m)
continue;
if (cnt % 10 == 0)
- seq_printf(m, " %-15s : ", "[steps]");
+ p += scnprintf(p, end - p, " %-15s : ", "[steps]");
- seq_printf(m, "-> %s(%02d)",
- (type == CXSTEP_SLOT ?
- id_to_slot((u32)val) :
- id_to_evt((u32)val)), diff_t);
+ p += scnprintf(p, end - p, "-> %s(%02d)",
+ (type == CXSTEP_SLOT ?
+ id_to_slot((u32)val) :
+ id_to_evt((u32)val)), diff_t);
if (cnt % 10 == 9)
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
cnt++;
}
+
+ return p - buf;
}
-static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_fw_dm_msg(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
+ char *p = buf, *end = buf + bufsz;
if (!(btc->dm.coex_info_map & BTC_COEX_INFO_DM))
- return;
+ goto out;
- _show_error(rtwdev, m);
- _show_fbtc_tdma(rtwdev, m);
- _show_fbtc_slots(rtwdev, m);
+ p += _show_error(rtwdev, p, end - p);
+ p += _show_fbtc_tdma(rtwdev, p, end - p);
+ p += _show_fbtc_slots(rtwdev, p, end - p);
if (ver->fcxcysta == 2)
- _show_fbtc_cysta_v2(rtwdev, m);
+ p += _show_fbtc_cysta_v2(rtwdev, p, end - p);
else if (ver->fcxcysta == 3)
- _show_fbtc_cysta_v3(rtwdev, m);
+ p += _show_fbtc_cysta_v3(rtwdev, p, end - p);
else if (ver->fcxcysta == 4)
- _show_fbtc_cysta_v4(rtwdev, m);
+ p += _show_fbtc_cysta_v4(rtwdev, p, end - p);
else if (ver->fcxcysta == 5)
- _show_fbtc_cysta_v5(rtwdev, m);
+ p += _show_fbtc_cysta_v5(rtwdev, p, end - p);
+ else if (ver->fcxcysta == 7)
+ p += _show_fbtc_cysta_v7(rtwdev, p, end - p);
- _show_fbtc_nullsta(rtwdev, m);
+ p += _show_fbtc_nullsta(rtwdev, p, end - p);
if (ver->fcxstep == 2)
- _show_fbtc_step_v2(rtwdev, m);
+ p += _show_fbtc_step_v2(rtwdev, p, end - p);
else if (ver->fcxstep == 3)
- _show_fbtc_step_v3(rtwdev, m);
+ p += _show_fbtc_step_v3(rtwdev, p, end - p);
+out:
+ return p - buf;
}
static void _get_gnt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_coex_gnt *gnt_cfg)
@@ -8202,7 +10108,7 @@ static void _get_gnt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_coex_gnt *gnt
u32 val, status;
if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B ||
- chip->chip_id == RTL8851B) {
+ chip->chip_id == RTL8851B || chip->chip_id == RTL8852BT) {
rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_1, &val);
rtw89_mac_read_lte(rtwdev, R_AX_GNT_VAL, &status);
@@ -8237,58 +10143,105 @@ static void _get_gnt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_coex_gnt *gnt
}
}
-static void _show_mreg_v1(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_gpio_dbg(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
+{
+ struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo;
+ const struct rtw89_btc_ver *ver = rtwdev->btc.ver;
+ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
+ union rtw89_btc_fbtc_gpio_dbg *gdbg = NULL;
+ char *p = buf, *end = buf + bufsz;
+ u8 *gpio_map, i;
+ u32 en_map;
+
+ pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo;
+ gdbg = &rtwdev->btc.fwinfo.rpt_fbtc_gpio_dbg.finfo;
+ if (!pcinfo->valid) {
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s(): stop due rpt_fbtc_gpio_dbg.cinfo\n",
+ __func__);
+ p += scnprintf(p, end - p, "\n");
+ goto out;
+ }
+
+ if (ver->fcxgpiodbg == 7) {
+ en_map = le32_to_cpu(gdbg->v7.en_map);
+ gpio_map = gdbg->v7.gpio_map;
+ } else {
+ en_map = le32_to_cpu(gdbg->v1.en_map);
+ gpio_map = gdbg->v1.gpio_map;
+ }
+
+ if (!en_map)
+ goto out;
+
+ p += scnprintf(p, end - p, " %-15s : enable_map:0x%08x",
+ "[gpio_dbg]", en_map);
+
+ for (i = 0; i < BTC_DBG_MAX1; i++) {
+ if (!(en_map & BIT(i)))
+ continue;
+ p += scnprintf(p, end - p, ", %s->GPIO%d", id_to_gdbg(i),
+ gpio_map[i]);
+ }
+ p += scnprintf(p, end - p, "\n");
+
+out:
+ return p - buf;
+}
+
+static int _show_mreg_v1(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_fbtc_mreg_val_v1 *pmreg = NULL;
- struct rtw89_btc_fbtc_gpio_dbg *gdbg = NULL;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_bt_info *bt = &btc->cx.bt;
struct rtw89_mac_ax_coex_gnt gnt_cfg = {};
struct rtw89_mac_ax_gnt gnt;
+ char *p = buf, *end = buf + bufsz;
u8 i = 0, type = 0, cnt = 0;
u32 val, offset;
if (!(btc->dm.coex_info_map & BTC_COEX_INFO_MREG))
- return;
+ return 0;
- seq_puts(m, "========== [HW Status] ==========\n");
+ p += scnprintf(p, end - p, "========== [HW Status] ==========\n");
- seq_printf(m,
- " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n",
- "[scoreboard]", wl->scbd, cx->cnt_wl[BTC_WCNT_SCBDUPDATE],
- bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD],
- cx->cnt_bt[BTC_BCNT_SCBDUPDATE]);
+ p += scnprintf(p, end - p,
+ " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n",
+ "[scoreboard]", wl->scbd,
+ cx->cnt_wl[BTC_WCNT_SCBDUPDATE],
+ bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD],
+ cx->cnt_bt[BTC_BCNT_SCBDUPDATE]);
btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev);
_get_gnt(rtwdev, &gnt_cfg);
gnt = gnt_cfg.band[0];
- seq_printf(m,
- " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], ",
- "[gnt_status]",
- chip->chip_id == RTL8852C ? "HW" :
- btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT",
- gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl,
- gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt);
+ p += scnprintf(p, end - p,
+ " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], ",
+ "[gnt_status]",
+ chip->chip_id == RTL8852C ? "HW" :
+ btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT",
+ gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl,
+ gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt);
gnt = gnt_cfg.band[1];
- seq_printf(m, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n",
- gnt.gnt_wl_sw_en ? "SW" : "HW",
- gnt.gnt_wl,
- gnt.gnt_bt_sw_en ? "SW" : "HW",
- gnt.gnt_bt);
+ p += scnprintf(p, end - p, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n",
+ gnt.gnt_wl_sw_en ? "SW" : "HW",
+ gnt.gnt_wl,
+ gnt.gnt_bt_sw_en ? "SW" : "HW",
+ gnt.gnt_bt);
pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo;
if (!pcinfo->valid) {
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): stop due rpt_fbtc_mregval.cinfo\n",
__func__);
- return;
+ goto out;
}
pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v1;
@@ -8302,95 +10255,79 @@ static void _show_mreg_v1(struct rtw89_dev *rtwdev, struct seq_file *m)
val = le32_to_cpu(pmreg->mreg_val[i]);
if (cnt % 6 == 0)
- seq_printf(m, " %-15s : %d_0x%04x=0x%08x",
- "[reg]", (u32)type, offset, val);
+ p += scnprintf(p, end - p,
+ " %-15s : %d_0x%04x=0x%08x",
+ "[reg]", (u32)type, offset, val);
else
- seq_printf(m, ", %d_0x%04x=0x%08x", (u32)type,
- offset, val);
+ p += scnprintf(p, end - p, ", %d_0x%04x=0x%08x",
+ (u32)type,
+ offset, val);
if (cnt % 6 == 5)
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
cnt++;
if (i >= pmreg->reg_num)
- seq_puts(m, "\n");
- }
-
- pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo;
- if (!pcinfo->valid) {
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): stop due rpt_fbtc_gpio_dbg.cinfo\n",
- __func__);
- seq_puts(m, "\n");
- return;
+ p += scnprintf(p, end - p, "\n");
}
- gdbg = &pfwinfo->rpt_fbtc_gpio_dbg.finfo;
- if (!gdbg->en_map)
- return;
-
- seq_printf(m, " %-15s : enable_map:0x%08x",
- "[gpio_dbg]", gdbg->en_map);
-
- for (i = 0; i < BTC_DBG_MAX1; i++) {
- if (!(gdbg->en_map & BIT(i)))
- continue;
- seq_printf(m, ", %d->GPIO%d", (u32)i, gdbg->gpio_map[i]);
- }
- seq_puts(m, "\n");
+out:
+ return p - buf;
}
-static void _show_mreg_v2(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_mreg_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_fbtc_mreg_val_v2 *pmreg = NULL;
- struct rtw89_btc_fbtc_gpio_dbg *gdbg = NULL;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_bt_info *bt = &btc->cx.bt;
struct rtw89_mac_ax_coex_gnt gnt_cfg = {};
struct rtw89_mac_ax_gnt gnt;
+ char *p = buf, *end = buf + bufsz;
u8 i = 0, type = 0, cnt = 0;
u32 val, offset;
if (!(btc->dm.coex_info_map & BTC_COEX_INFO_MREG))
- return;
+ return 0;
- seq_puts(m, "========== [HW Status] ==========\n");
+ p += scnprintf(p, end - p, "========== [HW Status] ==========\n");
- seq_printf(m,
- " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n",
- "[scoreboard]", wl->scbd, cx->cnt_wl[BTC_WCNT_SCBDUPDATE],
- bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD],
- cx->cnt_bt[BTC_BCNT_SCBDUPDATE]);
+ p += scnprintf(p, end - p,
+ " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n",
+ "[scoreboard]", wl->scbd,
+ cx->cnt_wl[BTC_WCNT_SCBDUPDATE],
+ bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD],
+ cx->cnt_bt[BTC_BCNT_SCBDUPDATE]);
btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev);
_get_gnt(rtwdev, &gnt_cfg);
gnt = gnt_cfg.band[0];
- seq_printf(m,
- " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], ",
- "[gnt_status]",
- chip->chip_id == RTL8852C ? "HW" :
- btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT",
- gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl,
- gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt);
+ p += scnprintf(p, end - p,
+ " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], polut_type:%s",
+ "[gnt_status]",
+ chip->chip_id == RTL8852C ? "HW" :
+ btc->dm.pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT",
+ gnt.gnt_wl_sw_en ? "SW" : "HW", gnt.gnt_wl,
+ gnt.gnt_bt_sw_en ? "SW" : "HW", gnt.gnt_bt,
+ id_to_polut(wl->bt_polut_type[wl->pta_req_mac]));
gnt = gnt_cfg.band[1];
- seq_printf(m, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n",
- gnt.gnt_wl_sw_en ? "SW" : "HW",
- gnt.gnt_wl,
- gnt.gnt_bt_sw_en ? "SW" : "HW",
- gnt.gnt_bt);
+ p += scnprintf(p, end - p, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n",
+ gnt.gnt_wl_sw_en ? "SW" : "HW",
+ gnt.gnt_wl,
+ gnt.gnt_bt_sw_en ? "SW" : "HW",
+ gnt.gnt_bt);
pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo;
if (!pcinfo->valid) {
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): stop due rpt_fbtc_mregval.cinfo\n",
__func__);
- return;
+ goto out;
}
pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v2;
@@ -8404,44 +10341,104 @@ static void _show_mreg_v2(struct rtw89_dev *rtwdev, struct seq_file *m)
val = le32_to_cpu(pmreg->mreg_val[i]);
if (cnt % 6 == 0)
- seq_printf(m, " %-15s : %d_0x%04x=0x%08x",
- "[reg]", (u32)type, offset, val);
+ p += scnprintf(p, end - p,
+ " %-15s : %d_0x%04x=0x%08x",
+ "[reg]", (u32)type, offset, val);
else
- seq_printf(m, ", %d_0x%04x=0x%08x", (u32)type,
- offset, val);
+ p += scnprintf(p, end - p, ", %d_0x%04x=0x%08x",
+ (u32)type,
+ offset, val);
if (cnt % 6 == 5)
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
cnt++;
if (i >= pmreg->reg_num)
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
- pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo;
- if (!pcinfo->valid) {
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): stop due rpt_fbtc_gpio_dbg.cinfo\n",
- __func__);
- seq_puts(m, "\n");
- return;
+out:
+ return p - buf;
+}
+
+static int _show_mreg_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
+ struct rtw89_btc_fbtc_mreg_val_v7 *pmreg = NULL;
+ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
+ struct rtw89_btc_cx *cx = &btc->cx;
+ struct rtw89_btc_wl_info *wl = &cx->wl;
+ struct rtw89_btc_bt_info *bt = &cx->bt;
+ struct rtw89_mac_ax_gnt *gnt = NULL;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ char *p = buf, *end = buf + bufsz;
+ u8 i, type, cnt = 0;
+ u32 val, offset;
+
+ if (!(dm->coex_info_map & BTC_COEX_INFO_MREG))
+ return 0;
+
+ p += scnprintf(p, end - p, "\n\r========== [HW Status] ==========");
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)",
+ "[scoreboard]", wl->scbd,
+ cx->cnt_wl[BTC_WCNT_SCBDUPDATE],
+ bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD],
+ cx->cnt_bt[BTC_BCNT_SCBDUPDATE]);
+
+ /* To avoid I/O if WL LPS or power-off */
+ dm->pta_owner = rtw89_mac_get_ctrl_path(rtwdev);
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : pta_owner:%s, pta_req_mac:MAC%d, rf_gnt_source: polut_type:%s",
+ "[gnt_status]",
+ rtwdev->chip->para_ver & BTC_FEAT_PTA_ONOFF_CTRL ? "HW" :
+ dm->pta_owner == BTC_CTRL_BY_WL ? "WL" : "BT",
+ wl->pta_req_mac,
+ id_to_polut(wl->bt_polut_type[wl->pta_req_mac]));
+
+ gnt = &dm->gnt.band[RTW89_PHY_0];
+
+ p += scnprintf(p, end - p, ", phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d]",
+ gnt->gnt_wl_sw_en ? "SW" : "HW", gnt->gnt_wl,
+ gnt->gnt_bt_sw_en ? "SW" : "HW", gnt->gnt_bt);
+
+ if (rtwdev->dbcc_en) {
+ gnt = &dm->gnt.band[RTW89_PHY_1];
+ p += scnprintf(p, end - p,
+ ", phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]",
+ gnt->gnt_wl_sw_en ? "SW" : "HW", gnt->gnt_wl,
+ gnt->gnt_bt_sw_en ? "SW" : "HW", gnt->gnt_bt);
}
- gdbg = &pfwinfo->rpt_fbtc_gpio_dbg.finfo;
- if (!gdbg->en_map)
- return;
+ pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo;
+ if (!pcinfo->valid)
+ goto out;
- seq_printf(m, " %-15s : enable_map:0x%08x",
- "[gpio_dbg]", gdbg->en_map);
+ pmreg = &pfwinfo->rpt_fbtc_mregval.finfo.v7;
- for (i = 0; i < BTC_DBG_MAX1; i++) {
- if (!(gdbg->en_map & BIT(i)))
- continue;
- seq_printf(m, ", %d->GPIO%d", (u32)i, gdbg->gpio_map[i]);
+ for (i = 0; i < pmreg->reg_num; i++) {
+ type = (u8)le16_to_cpu(rtwdev->chip->mon_reg[i].type);
+ offset = le32_to_cpu(rtwdev->chip->mon_reg[i].offset);
+ val = le32_to_cpu(pmreg->mreg_val[i]);
+
+ if (cnt % 6 == 0)
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : %s_0x%x=0x%x", "[reg]",
+ id_to_regtype(type), offset, val);
+ else
+ p += scnprintf(p, end - p, ", %s_0x%x=0x%x",
+ id_to_regtype(type), offset, val);
+ cnt++;
}
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
+
+out:
+ return p - buf;
}
-static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_summary_v1(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
@@ -8452,56 +10449,59 @@ static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m)
struct rtw89_btc_wl_info *wl = &cx->wl;
struct rtw89_btc_bt_info *bt = &cx->bt;
u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify;
+ char *p = buf, *end = buf + bufsz;
u8 i;
if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY))
- return;
+ return 0;
- seq_puts(m, "========== [Statistics] ==========\n");
+ p += scnprintf(p, end - p, "========== [Statistics] ==========\n");
pcinfo = &pfwinfo->rpt_ctrl.cinfo;
if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) {
prptctrl = &pfwinfo->rpt_ctrl.finfo.v1;
- seq_printf(m,
- " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ",
- "[summary]", pfwinfo->cnt_h2c,
- pfwinfo->cnt_h2c_fail, prptctrl->h2c_cnt,
- pfwinfo->cnt_c2h, prptctrl->c2h_cnt);
+ p += scnprintf(p, end - p,
+ " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ",
+ "[summary]", pfwinfo->cnt_h2c,
+ pfwinfo->cnt_h2c_fail, prptctrl->h2c_cnt,
+ pfwinfo->cnt_c2h, prptctrl->c2h_cnt);
- seq_printf(m,
- "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x",
- pfwinfo->event[BTF_EVNT_RPT], prptctrl->rpt_cnt,
- prptctrl->rpt_enable, dm->error.val);
+ p += scnprintf(p, end - p,
+ "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x",
+ pfwinfo->event[BTF_EVNT_RPT],
+ prptctrl->rpt_cnt,
+ prptctrl->rpt_enable, dm->error.val);
if (dm->error.map.wl_fw_hang)
- seq_puts(m, " (WL FW Hang!!)");
- seq_puts(m, "\n");
- seq_printf(m,
- " %-15s : send_ok:%d, send_fail:%d, recv:%d",
- "[mailbox]", prptctrl->mb_send_ok_cnt,
- prptctrl->mb_send_fail_cnt, prptctrl->mb_recv_cnt);
-
- seq_printf(m,
- "(A2DP_empty:%d, A2DP_flowstop:%d, A2DP_full:%d)\n",
- prptctrl->mb_a2dp_empty_cnt,
- prptctrl->mb_a2dp_flct_cnt,
- prptctrl->mb_a2dp_full_cnt);
-
- seq_printf(m,
- " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]",
- "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
- cx->cnt_wl[BTC_WCNT_RFK_GO],
- cx->cnt_wl[BTC_WCNT_RFK_REJECT],
- cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
-
- seq_printf(m,
- ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n",
- prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REQ],
- prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_GO],
- prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REJECT],
- prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT],
- prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_FAIL]);
+ p += scnprintf(p, end - p, " (WL FW Hang!!)");
+ p += scnprintf(p, end - p, "\n");
+ p += scnprintf(p, end - p,
+ " %-15s : send_ok:%d, send_fail:%d, recv:%d",
+ "[mailbox]", prptctrl->mb_send_ok_cnt,
+ prptctrl->mb_send_fail_cnt,
+ prptctrl->mb_recv_cnt);
+
+ p += scnprintf(p, end - p,
+ "(A2DP_empty:%d, A2DP_flowstop:%d, A2DP_full:%d)\n",
+ prptctrl->mb_a2dp_empty_cnt,
+ prptctrl->mb_a2dp_flct_cnt,
+ prptctrl->mb_a2dp_full_cnt);
+
+ p += scnprintf(p, end - p,
+ " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]",
+ "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
+ cx->cnt_wl[BTC_WCNT_RFK_GO],
+ cx->cnt_wl[BTC_WCNT_RFK_REJECT],
+ cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
+
+ p += scnprintf(p, end - p,
+ ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n",
+ prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REQ],
+ prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_GO],
+ prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REJECT],
+ prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT],
+ prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_FAIL]);
if (prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT] > 0)
bt->rfk_info.map.timeout = 1;
@@ -8510,42 +10510,44 @@ static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m)
dm->error.map.wl_rfk_timeout = bt->rfk_info.map.timeout;
} else {
- seq_printf(m,
- " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x",
- "[summary]", pfwinfo->cnt_h2c,
- pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h,
- pfwinfo->event[BTF_EVNT_RPT],
- btc->fwinfo.rpt_en_map);
- seq_puts(m, " (WL FW report invalid!!)\n");
+ p += scnprintf(p, end - p,
+ " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x",
+ "[summary]", pfwinfo->cnt_h2c,
+ pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h,
+ pfwinfo->event[BTF_EVNT_RPT],
+ btc->fwinfo.rpt_en_map);
+ p += scnprintf(p, end - p, " (WL FW report invalid!!)\n");
}
for (i = 0; i < BTC_NCNT_NUM; i++)
cnt_sum += dm->cnt_notify[i];
- seq_printf(m,
- " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
- "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
- cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
+ p += scnprintf(p, end - p,
+ " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
+ "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
+ cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
+
+ p += scnprintf(p, end - p,
+ "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n",
+ cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
+ cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
+ cnt[BTC_NCNT_WL_STA]);
- seq_printf(m,
- "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n",
- cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
- cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
- cnt[BTC_NCNT_WL_STA]);
+ p += scnprintf(p, end - p,
+ " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ",
+ "[notify_cnt]", cnt[BTC_NCNT_SCAN_START],
+ cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND],
+ cnt[BTC_NCNT_SPECIAL_PACKET]);
- seq_printf(m,
- " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ",
- "[notify_cnt]", cnt[BTC_NCNT_SCAN_START],
- cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND],
- cnt[BTC_NCNT_SPECIAL_PACKET]);
+ p += scnprintf(p, end - p,
+ "timer=%d, control=%d, customerize=%d\n",
+ cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL],
+ cnt[BTC_NCNT_CUSTOMERIZE]);
- seq_printf(m,
- "timer=%d, control=%d, customerize=%d\n",
- cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL],
- cnt[BTC_NCNT_CUSTOMERIZE]);
+ return p - buf;
}
-static void _show_summary_v4(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_summary_v4(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
@@ -8556,64 +10558,65 @@ static void _show_summary_v4(struct rtw89_dev *rtwdev, struct seq_file *m)
struct rtw89_btc_wl_info *wl = &cx->wl;
struct rtw89_btc_bt_info *bt = &cx->bt;
u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify;
+ char *p = buf, *end = buf + bufsz;
u8 i;
if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY))
- return;
+ return 0;
- seq_puts(m, "========== [Statistics] ==========\n");
+ p += scnprintf(p, end - p, "========== [Statistics] ==========\n");
pcinfo = &pfwinfo->rpt_ctrl.cinfo;
if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) {
prptctrl = &pfwinfo->rpt_ctrl.finfo.v4;
- seq_printf(m,
- " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ",
- "[summary]", pfwinfo->cnt_h2c,
- pfwinfo->cnt_h2c_fail,
- le32_to_cpu(prptctrl->rpt_info.cnt_h2c),
- pfwinfo->cnt_c2h,
- le32_to_cpu(prptctrl->rpt_info.cnt_c2h));
-
- seq_printf(m,
- "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x",
- pfwinfo->event[BTF_EVNT_RPT],
- le32_to_cpu(prptctrl->rpt_info.cnt),
- le32_to_cpu(prptctrl->rpt_info.en),
- dm->error.val);
+ p += scnprintf(p, end - p,
+ " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ",
+ "[summary]", pfwinfo->cnt_h2c,
+ pfwinfo->cnt_h2c_fail,
+ le32_to_cpu(prptctrl->rpt_info.cnt_h2c),
+ pfwinfo->cnt_c2h,
+ le32_to_cpu(prptctrl->rpt_info.cnt_c2h));
+
+ p += scnprintf(p, end - p,
+ "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x",
+ pfwinfo->event[BTF_EVNT_RPT],
+ le32_to_cpu(prptctrl->rpt_info.cnt),
+ le32_to_cpu(prptctrl->rpt_info.en),
+ dm->error.val);
if (dm->error.map.wl_fw_hang)
- seq_puts(m, " (WL FW Hang!!)");
- seq_puts(m, "\n");
- seq_printf(m,
- " %-15s : send_ok:%d, send_fail:%d, recv:%d, ",
- "[mailbox]",
- le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok),
- le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail),
- le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv));
-
- seq_printf(m,
- "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n",
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty),
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl),
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx),
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack),
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack));
-
- seq_printf(m,
- " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]",
- "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
- cx->cnt_wl[BTC_WCNT_RFK_GO],
- cx->cnt_wl[BTC_WCNT_RFK_REJECT],
- cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
-
- seq_printf(m,
- ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n",
- le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]),
- le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_GO]),
- le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REJECT]),
- le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_TIMEOUT]),
- le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_FAIL]));
+ p += scnprintf(p, end - p, " (WL FW Hang!!)");
+ p += scnprintf(p, end - p, "\n");
+ p += scnprintf(p, end - p,
+ " %-15s : send_ok:%d, send_fail:%d, recv:%d, ",
+ "[mailbox]",
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok),
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail),
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv));
+
+ p += scnprintf(p, end - p,
+ "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n",
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack));
+
+ p += scnprintf(p, end - p,
+ " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]",
+ "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
+ cx->cnt_wl[BTC_WCNT_RFK_GO],
+ cx->cnt_wl[BTC_WCNT_RFK_REJECT],
+ cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
+
+ p += scnprintf(p, end - p,
+ ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n",
+ le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]),
+ le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_GO]),
+ le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REJECT]),
+ le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_TIMEOUT]),
+ le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_FAIL]));
if (le32_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0)
bt->rfk_info.map.timeout = 1;
@@ -8622,42 +10625,44 @@ static void _show_summary_v4(struct rtw89_dev *rtwdev, struct seq_file *m)
dm->error.map.wl_rfk_timeout = bt->rfk_info.map.timeout;
} else {
- seq_printf(m,
- " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x",
- "[summary]", pfwinfo->cnt_h2c,
- pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h,
- pfwinfo->event[BTF_EVNT_RPT],
- btc->fwinfo.rpt_en_map);
- seq_puts(m, " (WL FW report invalid!!)\n");
+ p += scnprintf(p, end - p,
+ " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x",
+ "[summary]", pfwinfo->cnt_h2c,
+ pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h,
+ pfwinfo->event[BTF_EVNT_RPT],
+ btc->fwinfo.rpt_en_map);
+ p += scnprintf(p, end - p, " (WL FW report invalid!!)\n");
}
for (i = 0; i < BTC_NCNT_NUM; i++)
cnt_sum += dm->cnt_notify[i];
- seq_printf(m,
- " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
- "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
- cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
+ p += scnprintf(p, end - p,
+ " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
+ "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
+ cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
- seq_printf(m,
- "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n",
- cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
- cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
- cnt[BTC_NCNT_WL_STA]);
+ p += scnprintf(p, end - p,
+ "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n",
+ cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
+ cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
+ cnt[BTC_NCNT_WL_STA]);
- seq_printf(m,
- " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ",
- "[notify_cnt]", cnt[BTC_NCNT_SCAN_START],
- cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND],
- cnt[BTC_NCNT_SPECIAL_PACKET]);
+ p += scnprintf(p, end - p,
+ " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ",
+ "[notify_cnt]", cnt[BTC_NCNT_SCAN_START],
+ cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND],
+ cnt[BTC_NCNT_SPECIAL_PACKET]);
- seq_printf(m,
- "timer=%d, control=%d, customerize=%d\n",
- cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL],
- cnt[BTC_NCNT_CUSTOMERIZE]);
+ p += scnprintf(p, end - p,
+ "timer=%d, control=%d, customerize=%d\n",
+ cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL],
+ cnt[BTC_NCNT_CUSTOMERIZE]);
+
+ return p - buf;
}
-static void _show_summary_v5(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_summary_v5(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
@@ -8667,112 +10672,118 @@ static void _show_summary_v5(struct rtw89_dev *rtwdev, struct seq_file *m)
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_wl_info *wl = &cx->wl;
u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify;
+ char *p = buf, *end = buf + bufsz;
u8 i;
if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY))
- return;
+ return 0;
- seq_puts(m, "========== [Statistics] ==========\n");
+ p += scnprintf(p, end - p, "========== [Statistics] ==========\n");
pcinfo = &pfwinfo->rpt_ctrl.cinfo;
if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) {
prptctrl = &pfwinfo->rpt_ctrl.finfo.v5;
- seq_printf(m,
- " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ",
- "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail,
- le16_to_cpu(prptctrl->rpt_info.cnt_h2c),
- pfwinfo->cnt_c2h,
- le16_to_cpu(prptctrl->rpt_info.cnt_c2h),
- le16_to_cpu(prptctrl->rpt_info.len_c2h));
-
- seq_printf(m,
- "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x",
- pfwinfo->event[BTF_EVNT_RPT],
- le16_to_cpu(prptctrl->rpt_info.cnt),
- le32_to_cpu(prptctrl->rpt_info.en));
+ p += scnprintf(p, end - p,
+ " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ",
+ "[summary]", pfwinfo->cnt_h2c,
+ pfwinfo->cnt_h2c_fail,
+ le16_to_cpu(prptctrl->rpt_info.cnt_h2c),
+ pfwinfo->cnt_c2h,
+ le16_to_cpu(prptctrl->rpt_info.cnt_c2h),
+ le16_to_cpu(prptctrl->rpt_info.len_c2h));
+
+ p += scnprintf(p, end - p,
+ "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x",
+ pfwinfo->event[BTF_EVNT_RPT],
+ le16_to_cpu(prptctrl->rpt_info.cnt),
+ le32_to_cpu(prptctrl->rpt_info.en));
if (dm->error.map.wl_fw_hang)
- seq_puts(m, " (WL FW Hang!!)");
- seq_puts(m, "\n");
- seq_printf(m,
- " %-15s : send_ok:%d, send_fail:%d, recv:%d, ",
- "[mailbox]",
- le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok),
- le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail),
- le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv));
-
- seq_printf(m,
- "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n",
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty),
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl),
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx),
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack),
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack));
-
- seq_printf(m,
- " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]",
- "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
- cx->cnt_wl[BTC_WCNT_RFK_GO],
- cx->cnt_wl[BTC_WCNT_RFK_REJECT],
- cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
-
- seq_printf(m,
- ", bt_rfk[req:%d]",
- le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]));
-
- seq_printf(m,
- ", AOAC[RF_on:%d/RF_off:%d]",
- le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on),
- le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off));
+ p += scnprintf(p, end - p, " (WL FW Hang!!)");
+ p += scnprintf(p, end - p, "\n");
+ p += scnprintf(p, end - p,
+ " %-15s : send_ok:%d, send_fail:%d, recv:%d, ",
+ "[mailbox]",
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok),
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail),
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv));
+
+ p += scnprintf(p, end - p,
+ "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n",
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack));
+
+ p += scnprintf(p, end - p,
+ " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]",
+ "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
+ cx->cnt_wl[BTC_WCNT_RFK_GO],
+ cx->cnt_wl[BTC_WCNT_RFK_REJECT],
+ cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
+
+ p += scnprintf(p, end - p,
+ ", bt_rfk[req:%d]",
+ le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]));
+
+ p += scnprintf(p, end - p,
+ ", AOAC[RF_on:%d/RF_off:%d]",
+ le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on),
+ le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off));
} else {
- seq_printf(m,
- " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d",
- "[summary]", pfwinfo->cnt_h2c,
- pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h);
+ p += scnprintf(p, end - p,
+ " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d",
+ "[summary]", pfwinfo->cnt_h2c,
+ pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h);
}
if (!pcinfo->valid || pfwinfo->len_mismch || pfwinfo->fver_mismch ||
pfwinfo->err[BTFRE_EXCEPTION]) {
- seq_puts(m, "\n");
- seq_printf(m,
- " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:"
- "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]",
- "[ERROR]", pcinfo->valid, pfwinfo->len_mismch,
- pfwinfo->fver_mismch, pfwinfo->err[BTFRE_EXCEPTION],
- wl->status.map.lps, wl->status.map.rf_off);
+ p += scnprintf(p, end - p, "\n");
+ p += scnprintf(p, end - p,
+ " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:"
+ "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]",
+ "[ERROR]", pcinfo->valid, pfwinfo->len_mismch,
+ pfwinfo->fver_mismch,
+ pfwinfo->err[BTFRE_EXCEPTION],
+ wl->status.map.lps, wl->status.map.rf_off);
}
for (i = 0; i < BTC_NCNT_NUM; i++)
cnt_sum += dm->cnt_notify[i];
- seq_puts(m, "\n");
- seq_printf(m,
- " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
- "[notify_cnt]",
- cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
- cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
+ p += scnprintf(p, end - p, "\n");
+ p += scnprintf(p, end - p,
+ " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
+ "[notify_cnt]",
+ cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
+ cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
- seq_printf(m,
- "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d",
- cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
- cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
- cnt[BTC_NCNT_WL_STA]);
+ p += scnprintf(p, end - p,
+ "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d",
+ cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
+ cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
+ cnt[BTC_NCNT_WL_STA]);
- seq_puts(m, "\n");
- seq_printf(m,
- " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ",
- "[notify_cnt]",
- cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH],
- cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SPECIAL_PACKET]);
+ p += scnprintf(p, end - p, "\n");
+ p += scnprintf(p, end - p,
+ " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ",
+ "[notify_cnt]",
+ cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH],
+ cnt[BTC_NCNT_SWITCH_BAND],
+ cnt[BTC_NCNT_SPECIAL_PACKET]);
- seq_printf(m,
- "timer=%d, control=%d, customerize=%d",
- cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL],
- cnt[BTC_NCNT_CUSTOMERIZE]);
+ p += scnprintf(p, end - p,
+ "timer=%d, control=%d, customerize=%d",
+ cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL],
+ cnt[BTC_NCNT_CUSTOMERIZE]);
+
+ return p - buf;
}
-static void _show_summary_v105(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_summary_v105(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
@@ -8782,157 +10793,406 @@ static void _show_summary_v105(struct rtw89_dev *rtwdev, struct seq_file *m)
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_wl_info *wl = &cx->wl;
u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify;
+ char *p = buf, *end = buf + bufsz;
u8 i;
if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY))
- return;
+ return 0;
- seq_puts(m, "========== [Statistics] ==========\n");
+ p += scnprintf(p, end - p, "========== [Statistics] ==========\n");
pcinfo = &pfwinfo->rpt_ctrl.cinfo;
if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) {
prptctrl = &pfwinfo->rpt_ctrl.finfo.v105;
- seq_printf(m,
- " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ",
- "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail,
- le16_to_cpu(prptctrl->rpt_info.cnt_h2c),
- pfwinfo->cnt_c2h,
- le16_to_cpu(prptctrl->rpt_info.cnt_c2h),
- le16_to_cpu(prptctrl->rpt_info.len_c2h));
-
- seq_printf(m,
- "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x",
- pfwinfo->event[BTF_EVNT_RPT],
- le16_to_cpu(prptctrl->rpt_info.cnt),
- le32_to_cpu(prptctrl->rpt_info.en));
+ p += scnprintf(p, end - p,
+ " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ",
+ "[summary]", pfwinfo->cnt_h2c,
+ pfwinfo->cnt_h2c_fail,
+ le16_to_cpu(prptctrl->rpt_info.cnt_h2c),
+ pfwinfo->cnt_c2h,
+ le16_to_cpu(prptctrl->rpt_info.cnt_c2h),
+ le16_to_cpu(prptctrl->rpt_info.len_c2h));
+
+ p += scnprintf(p, end - p,
+ "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x",
+ pfwinfo->event[BTF_EVNT_RPT],
+ le16_to_cpu(prptctrl->rpt_info.cnt),
+ le32_to_cpu(prptctrl->rpt_info.en));
if (dm->error.map.wl_fw_hang)
- seq_puts(m, " (WL FW Hang!!)");
- seq_puts(m, "\n");
- seq_printf(m,
- " %-15s : send_ok:%d, send_fail:%d, recv:%d, ",
- "[mailbox]",
- le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok),
- le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail),
- le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv));
-
- seq_printf(m,
- "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n",
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty),
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl),
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx),
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack),
- le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack));
-
- seq_printf(m,
- " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]",
- "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
- cx->cnt_wl[BTC_WCNT_RFK_GO],
- cx->cnt_wl[BTC_WCNT_RFK_REJECT],
- cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
-
- seq_printf(m,
- ", bt_rfk[req:%d]",
- le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]));
-
- seq_printf(m,
- ", AOAC[RF_on:%d/RF_off:%d]",
- le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on),
- le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off));
+ p += scnprintf(p, end - p, " (WL FW Hang!!)");
+ p += scnprintf(p, end - p, "\n");
+ p += scnprintf(p, end - p,
+ " %-15s : send_ok:%d, send_fail:%d, recv:%d, ",
+ "[mailbox]",
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok),
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail),
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv));
+
+ p += scnprintf(p, end - p,
+ "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n",
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack));
+
+ p += scnprintf(p, end - p,
+ " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]",
+ "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
+ cx->cnt_wl[BTC_WCNT_RFK_GO],
+ cx->cnt_wl[BTC_WCNT_RFK_REJECT],
+ cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]);
+
+ p += scnprintf(p, end - p,
+ ", bt_rfk[req:%d]",
+ le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]));
+
+ p += scnprintf(p, end - p,
+ ", AOAC[RF_on:%d/RF_off:%d]",
+ le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on),
+ le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off));
} else {
- seq_printf(m,
- " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d",
- "[summary]", pfwinfo->cnt_h2c,
- pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h);
+ p += scnprintf(p, end - p,
+ " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d",
+ "[summary]", pfwinfo->cnt_h2c,
+ pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h);
}
if (!pcinfo->valid || pfwinfo->len_mismch || pfwinfo->fver_mismch ||
pfwinfo->err[BTFRE_EXCEPTION]) {
- seq_puts(m, "\n");
- seq_printf(m,
- " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:"
- "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]",
- "[ERROR]", pcinfo->valid, pfwinfo->len_mismch,
- pfwinfo->fver_mismch, pfwinfo->err[BTFRE_EXCEPTION],
- wl->status.map.lps, wl->status.map.rf_off);
+ p += scnprintf(p, end - p, "\n");
+ p += scnprintf(p, end - p,
+ " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:"
+ "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]",
+ "[ERROR]", pcinfo->valid, pfwinfo->len_mismch,
+ pfwinfo->fver_mismch,
+ pfwinfo->err[BTFRE_EXCEPTION],
+ wl->status.map.lps, wl->status.map.rf_off);
}
for (i = 0; i < BTC_NCNT_NUM; i++)
cnt_sum += dm->cnt_notify[i];
- seq_puts(m, "\n");
- seq_printf(m,
- " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
- "[notify_cnt]",
- cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
- cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
+ p += scnprintf(p, end - p, "\n");
+ p += scnprintf(p, end - p,
+ " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
+ "[notify_cnt]",
+ cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
+ cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
- seq_printf(m,
- "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d",
- cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
- cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
- cnt[BTC_NCNT_WL_STA]);
+ p += scnprintf(p, end - p,
+ "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d",
+ cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
+ cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
+ cnt[BTC_NCNT_WL_STA]);
- seq_puts(m, "\n");
- seq_printf(m,
- " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ",
- "[notify_cnt]",
- cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH],
- cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SPECIAL_PACKET]);
+ p += scnprintf(p, end - p, "\n");
+ p += scnprintf(p, end - p,
+ " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ",
+ "[notify_cnt]",
+ cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH],
+ cnt[BTC_NCNT_SWITCH_BAND],
+ cnt[BTC_NCNT_SPECIAL_PACKET]);
- seq_printf(m,
- "timer=%d, control=%d, customerize=%d",
- cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL],
- cnt[BTC_NCNT_CUSTOMERIZE]);
+ p += scnprintf(p, end - p,
+ "timer=%d, control=%d, customerize=%d",
+ cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL],
+ cnt[BTC_NCNT_CUSTOMERIZE]);
+
+ return p - buf;
}
-void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m)
+static int _show_summary_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
- struct rtw89_fw_suit *fw_suit = &rtwdev->fw.normal;
- struct rtw89_btc *btc = &rtwdev->btc;
- const struct rtw89_btc_ver *ver = btc->ver;
- struct rtw89_btc_cx *cx = &btc->cx;
- struct rtw89_btc_bt_info *bt = &cx->bt;
+ struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo;
+ struct rtw89_btc_fbtc_rpt_ctrl_v7 *prptctrl = NULL;
+ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
+ struct rtw89_btc_cx *cx = &rtwdev->btc.cx;
+ struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
+ struct rtw89_btc_wl_info *wl = &cx->wl;
+ u32 *cnt = rtwdev->btc.dm.cnt_notify;
+ char *p = buf, *end = buf + bufsz;
+ u32 cnt_sum = 0;
+ u8 i;
+
+ if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY))
+ return 0;
+
+ p += scnprintf(p, end - p, "%s",
+ "\n\r========== [Statistics] ==========");
+
+ pcinfo = &pfwinfo->rpt_ctrl.cinfo;
+ if (pcinfo->valid && wl->status.map.lps != BTC_LPS_RF_OFF &&
+ !wl->status.map.rf_off) {
+ prptctrl = &pfwinfo->rpt_ctrl.finfo.v7;
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d),"
+ "c2h_cnt=%d(fw_send:%d, len:%d, max:%d), ",
+ "[summary]", pfwinfo->cnt_h2c,
+ pfwinfo->cnt_h2c_fail,
+ le16_to_cpu(prptctrl->rpt_info.cnt_h2c),
+ pfwinfo->cnt_c2h,
+ le16_to_cpu(prptctrl->rpt_info.cnt_c2h),
+ le16_to_cpu(prptctrl->rpt_info.len_c2h),
+ rtwdev->btc.ver->info_buf);
+
+ p += scnprintf(p, end - p,
+ "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x",
+ pfwinfo->event[BTF_EVNT_RPT],
+ le16_to_cpu(prptctrl->rpt_info.cnt),
+ le32_to_cpu(prptctrl->rpt_info.en));
+
+ if (dm->error.map.wl_fw_hang)
+ p += scnprintf(p, end - p, " (WL FW Hang!!)");
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : send_ok:%d, send_fail:%d, recv:%d, ",
+ "[mailbox]",
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok),
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail),
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv));
+
+ p += scnprintf(p, end - p,
+ "A2DP_empty:%d(stop:%d/tx:%d/ack:%d/nack:%d)",
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack));
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]",
+ "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
+ cx->cnt_wl[BTC_WCNT_RFK_GO],
+ cx->cnt_wl[BTC_WCNT_RFK_REJECT],
+ cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT],
+ wl->rfk_info.proc_time);
+
+ p += scnprintf(p, end - p, ", bt_rfk[req:%d]",
+ le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]));
+
+ p += scnprintf(p, end - p, ", AOAC[RF_on:%d/RF_off:%d]",
+ le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on),
+ le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off));
+ } else {
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d (lps=%d/rf_off=%d)",
+ "[summary]",
+ pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail,
+ pfwinfo->cnt_c2h,
+ wl->status.map.lps, wl->status.map.rf_off);
+ }
+
+ for (i = 0; i < BTC_NCNT_NUM; i++)
+ cnt_sum += dm->cnt_notify[i];
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
+ "[notify_cnt]",
+ cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
+ cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
+
+ p += scnprintf(p, end - p,
+ "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d",
+ cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
+ cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
+ cnt[BTC_NCNT_WL_STA]);
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, switch_chbw=%d, special_pkt=%d, ",
+ "[notify_cnt]",
+ cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH],
+ cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SWITCH_CHBW],
+ cnt[BTC_NCNT_SPECIAL_PACKET]);
+
+ p += scnprintf(p, end - p,
+ "timer=%d, customerize=%d, hub_msg=%d, chg_fw=%d, send_cc=%d",
+ cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CUSTOMERIZE],
+ rtwdev->btc.hubmsg_cnt, cnt[BTC_NCNT_RESUME_DL_FW],
+ cnt[BTC_NCNT_COUNTRYCODE]);
+
+ return p - buf;
+}
+
+static int _show_summary_v8(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
+{
+ struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo;
+ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
+ struct rtw89_btc_fbtc_rpt_ctrl_v8 *prptctrl = NULL;
+ struct rtw89_btc_cx *cx = &rtwdev->btc.cx;
+ struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
+ struct rtw89_btc_wl_info *wl = &cx->wl;
+ u32 *cnt = rtwdev->btc.dm.cnt_notify;
+ char *p = buf, *end = buf + bufsz;
+ u32 cnt_sum = 0;
+ u8 i;
+
+ if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY))
+ return 0;
- seq_puts(m, "=========================================\n");
- seq_printf(m, "WL FW / BT FW %d.%d.%d.%d / NA\n",
- fw_suit->major_ver, fw_suit->minor_ver,
- fw_suit->sub_ver, fw_suit->sub_idex);
- seq_printf(m, "manual %d\n", btc->manual_ctrl);
+ p += scnprintf(p, end - p, "%s",
+ "\n\r========== [Statistics] ==========");
- seq_puts(m, "=========================================\n");
+ pcinfo = &pfwinfo->rpt_ctrl.cinfo;
+ if (pcinfo->valid && wl->status.map.lps != BTC_LPS_RF_OFF &&
+ !wl->status.map.rf_off) {
+ prptctrl = &pfwinfo->rpt_ctrl.finfo.v8;
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d, max:fw-%d/drv-%d), ",
+ "[summary]", pfwinfo->cnt_h2c,
+ pfwinfo->cnt_h2c_fail,
+ le16_to_cpu(prptctrl->rpt_info.cnt_h2c),
+ pfwinfo->cnt_c2h,
+ le16_to_cpu(prptctrl->rpt_info.cnt_c2h),
+ le16_to_cpu(prptctrl->rpt_info.len_c2h),
+ (prptctrl->rpt_len_max_h << 8) + prptctrl->rpt_len_max_l,
+ rtwdev->btc.ver->info_buf);
+
+ p += scnprintf(p, end - p,
+ "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x",
+ pfwinfo->event[BTF_EVNT_RPT],
+ le16_to_cpu(prptctrl->rpt_info.cnt),
+ le32_to_cpu(prptctrl->rpt_info.en));
- seq_printf(m, "\n\r %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)",
- "[bt_info]",
- bt->raw_info[2], bt->raw_info[3],
- bt->raw_info[4], bt->raw_info[5],
- bt->raw_info[6], bt->raw_info[7],
- bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply",
- cx->cnt_bt[BTC_BCNT_INFOUPDATE],
- cx->cnt_bt[BTC_BCNT_INFOSAME]);
+ if (dm->error.map.wl_fw_hang)
+ p += scnprintf(p, end - p, " (WL FW Hang!!)");
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : send_ok:%d, send_fail:%d, recv:%d, ",
+ "[mailbox]",
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok),
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail),
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv));
+
+ p += scnprintf(p, end - p,
+ "A2DP_empty:%d(stop:%d/tx:%d/ack:%d/nack:%d)",
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack));
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]",
+ "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ],
+ cx->cnt_wl[BTC_WCNT_RFK_GO],
+ cx->cnt_wl[BTC_WCNT_RFK_REJECT],
+ cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT],
+ wl->rfk_info.proc_time);
+
+ p += scnprintf(p, end - p, ", bt_rfk[req:%d]",
+ le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ]));
+
+ p += scnprintf(p, end - p, ", AOAC[RF_on:%d/RF_off:%d]",
+ le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on),
+ le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off));
+ } else {
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d (lps=%d/rf_off=%d)",
+ "[summary]",
+ pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail,
+ pfwinfo->cnt_c2h,
+ wl->status.map.lps, wl->status.map.rf_off);
+ }
+
+ for (i = 0; i < BTC_NCNT_NUM; i++)
+ cnt_sum += dm->cnt_notify[i];
- seq_puts(m, "\n=========================================\n");
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
+ "[notify_cnt]",
+ cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
+ cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
- _show_cx_info(rtwdev, m);
- _show_wl_info(rtwdev, m);
- _show_bt_info(rtwdev, m);
- _show_dm_info(rtwdev, m);
- _show_fw_dm_msg(rtwdev, m);
+ p += scnprintf(p, end - p,
+ "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d",
+ cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
+ cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
+ cnt[BTC_NCNT_WL_STA]);
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, switch_chbw=%d, special_pkt=%d, ",
+ "[notify_cnt]",
+ cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH],
+ cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SWITCH_CHBW],
+ cnt[BTC_NCNT_SPECIAL_PACKET]);
+
+ p += scnprintf(p, end - p,
+ "timer=%d, customerize=%d, hub_msg=%d, chg_fw=%d, send_cc=%d",
+ cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CUSTOMERIZE],
+ rtwdev->btc.hubmsg_cnt, cnt[BTC_NCNT_RESUME_DL_FW],
+ cnt[BTC_NCNT_COUNTRYCODE]);
+
+ return p - buf;
+}
+
+ssize_t rtw89_btc_dump_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
+{
+ struct rtw89_fw_suit *fw_suit = &rtwdev->fw.normal;
+ struct rtw89_btc *btc = &rtwdev->btc;
+ const struct rtw89_btc_ver *ver = btc->ver;
+ struct rtw89_btc_cx *cx = &btc->cx;
+ struct rtw89_btc_bt_info *bt = &cx->bt;
+ char *p = buf, *end = buf + bufsz;
+
+ p += scnprintf(p, end - p,
+ "=========================================\n");
+ p += scnprintf(p, end - p,
+ "WL FW / BT FW %d.%d.%d.%d / NA\n",
+ fw_suit->major_ver, fw_suit->minor_ver,
+ fw_suit->sub_ver, fw_suit->sub_idex);
+ p += scnprintf(p, end - p, "manual %d\n",
+ btc->manual_ctrl);
+
+ p += scnprintf(p, end - p,
+ "=========================================\n");
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)",
+ "[bt_info]",
+ bt->raw_info[2], bt->raw_info[3],
+ bt->raw_info[4], bt->raw_info[5],
+ bt->raw_info[6], bt->raw_info[7],
+ bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply",
+ cx->cnt_bt[BTC_BCNT_INFOUPDATE],
+ cx->cnt_bt[BTC_BCNT_INFOSAME]);
+
+ p += scnprintf(p, end - p,
+ "\n=========================================\n");
+
+ p += _show_cx_info(rtwdev, p, end - p);
+ p += _show_wl_info(rtwdev, p, end - p);
+ p += _show_bt_info(rtwdev, p, end - p);
+ p += _show_dm_info(rtwdev, p, end - p);
+ p += _show_fw_dm_msg(rtwdev, p, end - p);
if (ver->fcxmreg == 1)
- _show_mreg_v1(rtwdev, m);
+ p += _show_mreg_v1(rtwdev, p, end - p);
else if (ver->fcxmreg == 2)
- _show_mreg_v2(rtwdev, m);
+ p += _show_mreg_v2(rtwdev, p, end - p);
+ else if (ver->fcxmreg == 7)
+ p += _show_mreg_v7(rtwdev, p, end - p);
+
+ p += _show_gpio_dbg(rtwdev, p, end - p);
if (ver->fcxbtcrpt == 1)
- _show_summary_v1(rtwdev, m);
+ p += _show_summary_v1(rtwdev, p, end - p);
else if (ver->fcxbtcrpt == 4)
- _show_summary_v4(rtwdev, m);
+ p += _show_summary_v4(rtwdev, p, end - p);
else if (ver->fcxbtcrpt == 5)
- _show_summary_v5(rtwdev, m);
+ p += _show_summary_v5(rtwdev, p, end - p);
else if (ver->fcxbtcrpt == 105)
- _show_summary_v105(rtwdev, m);
+ p += _show_summary_v105(rtwdev, p, end - p);
+ else if (ver->fcxbtcrpt == 7)
+ p += _show_summary_v7(rtwdev, p, end - p);
+ else if (ver->fcxbtcrpt == 8)
+ p += _show_summary_v8(rtwdev, p, end - p);
+
+ return p - buf;
}
void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev)
@@ -8965,3 +11225,24 @@ out:
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] use version def[%d] = 0x%08x\n",
(int)(btc->ver - rtw89_btc_ver_defs), btc->ver->fw_ver_code);
}
+
+void rtw89_btc_ntfy_preserve_bt_time(struct rtw89_dev *rtwdev, u32 ms)
+{
+ struct rtw89_btc_bt_link_info *bt_linfo = &rtwdev->btc.cx.bt.link_info;
+ struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
+
+ if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags))
+ return;
+
+ if (!a2dp.exist)
+ return;
+
+ fsleep(ms * 1000);
+}
+EXPORT_SYMBOL(rtw89_btc_ntfy_preserve_bt_time);
+
+void rtw89_btc_ntfy_conn_rfk(struct rtw89_dev *rtwdev, bool state)
+{
+ rtwdev->btc.cx.wl.rfk_info.con_rfk = state;
+}
+EXPORT_SYMBOL(rtw89_btc_ntfy_conn_rfk);
diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h
index 13303830684e..e3a1fcd79620 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.h
+++ b/drivers/net/wireless/realtek/rtw89/coex.h
@@ -8,6 +8,8 @@
#include "core.h"
#define BTC_H2C_MAXLEN 2020
+#define BTC_TLV_SLOT_ID_LEN_V7 1
+#define BTC_SLOT_REQ_TH 2
enum btc_mode {
BTC_MODE_NORMAL,
@@ -191,6 +193,8 @@ enum btc_wa_type {
BTC_WA_5G_HI_CH_RX = BIT(0),
BTC_WA_NULL_AP = BIT(1),
BTC_WA_HFP_ZB = BIT(2), /* HFP PTA req bit4 define issue */
+ BTC_WA_HFP_LAG = BIT(3), /* 52BT WL break BT Rx lag issue */
+ BTC_WA_INIT_SCAN = BIT(4) /* 52A/C/D init scan move to wl slot WA */
};
enum btc_3cx_type {
@@ -201,6 +205,60 @@ enum btc_3cx_type {
BTC_3CX_MAX,
};
+enum btc_chip_feature {
+ BTC_FEAT_PTA_ONOFF_CTRL = BIT(0), /* on/off ctrl by HW (not 0x73[2]) */
+ BTC_FEAT_NONBTG_GWL_THRU = BIT(1), /* non-BTG GNT_WL!=0 if GNT_BT = 1 */
+ BTC_FEAT_WLAN_ACT_MUX = BIT(2), /* separate wlan_act/gnt mux */
+ BTC_FEAT_NEW_BBAPI_FLOW = BIT(3), /* new btg_ctrl/pre_agc_ctrl */
+ BTC_FEAT_MLO_SUPPORT = BIT(4),
+ BTC_FEAT_H2C_MACRO = BIT(5),
+};
+
+enum btc_wl_mode {
+ BTC_WL_MODE_11B = 0,
+ BTC_WL_MODE_11A = 1,
+ BTC_WL_MODE_11G = 2,
+ BTC_WL_MODE_HT = 3,
+ BTC_WL_MODE_VHT = 4,
+ BTC_WL_MODE_HE = 5,
+ BTC_WL_MODE_NUM,
+};
+
+enum btc_wl_gpio_debug {
+ BTC_DBG_GNT_BT = 0,
+ BTC_DBG_GNT_WL = 1,
+ BTC_DBG_BCN_EARLY = 2,
+ BTC_DBG_WL_NULL0 = 3,
+ BTC_DBG_WL_NULL1 = 4,
+ BTC_DBG_WL_RXISR = 5,
+ BTC_DBG_TDMA_ENTRY = 6,
+ BTC_DBG_A2DP_EMPTY = 7,
+ BTC_DBG_BT_RETRY = 8,
+ BTC_DBG_BT_RELINK = 9,
+ BTC_DBG_SLOT_WL = 10,
+ BTC_DBG_SLOT_BT = 11,
+ BTC_DBG_WL_ERR = 12,
+ BTC_DBG_WL_OK = 13,
+ BTC_DBG_SLOT_B2W = 14,
+ BTC_DBG_SLOT_W1 = 15,
+ BTC_DBG_SLOT_W2 = 16,
+ BTC_DBG_SLOT_W2B = 17,
+ BTC_DBG_SLOT_B1 = 18,
+ BTC_DBG_SLOT_B2 = 19,
+ BTC_DBG_SLOT_B3 = 20,
+ BTC_DBG_SLOT_B4 = 21,
+ BTC_DBG_SLOT_LK = 22,
+ BTC_DBG_SLOT_E2G = 23,
+ BTC_DBG_SLOT_E5G = 24,
+ BTC_DBG_SLOT_EBT = 25,
+ BTC_DBG_SLOT_WLK = 26,
+ BTC_DBG_SLOT_B1FDD = 27,
+ BTC_DBG_BT_CHANGE = 28,
+ BTC_DBG_WL_CCA = 29,
+ BTC_DBG_BT_LEAUDIO = 30,
+ BTC_DBG_USER_DEF = 31,
+};
+
void rtw89_btc_ntfy_poweron(struct rtw89_dev *rtwdev);
void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev);
void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode);
@@ -209,12 +267,14 @@ void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx);
void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band);
void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev,
enum btc_pkt_type pkt_type);
-void rtw89_btc_ntfy_eapol_packet_work(struct work_struct *work);
-void rtw89_btc_ntfy_arp_packet_work(struct work_struct *work);
-void rtw89_btc_ntfy_dhcp_packet_work(struct work_struct *work);
-void rtw89_btc_ntfy_icmp_packet_work(struct work_struct *work);
-void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta, enum btc_role_state state);
+void rtw89_btc_ntfy_eapol_packet_work(struct wiphy *wiphy, struct wiphy_work *work);
+void rtw89_btc_ntfy_arp_packet_work(struct wiphy *wiphy, struct wiphy_work *work);
+void rtw89_btc_ntfy_dhcp_packet_work(struct wiphy *wiphy, struct wiphy_work *work);
+void rtw89_btc_ntfy_icmp_packet_work(struct wiphy *wiphy, struct wiphy_work *work);
+void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ enum btc_role_state state);
void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_state);
void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map,
enum btc_wl_rfk_type type,
@@ -222,20 +282,23 @@ void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map,
void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev);
void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u32 len, u8 class, u8 func);
-void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m);
-void rtw89_coex_act1_work(struct work_struct *work);
-void rtw89_coex_bt_devinfo_work(struct work_struct *work);
-void rtw89_coex_rfk_chk_work(struct work_struct *work);
+ssize_t rtw89_btc_dump_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz);
+void rtw89_coex_act1_work(struct wiphy *wiphy, struct wiphy_work *work);
+void rtw89_coex_bt_devinfo_work(struct wiphy *wiphy, struct wiphy_work *work);
+void rtw89_coex_rfk_chk_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_coex_power_on(struct rtw89_dev *rtwdev);
void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type);
void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type);
void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev);
+void rtw89_btc_ntfy_preserve_bt_time(struct rtw89_dev *rtwdev, u32 ms);
+void rtw89_btc_ntfy_conn_rfk(struct rtw89_dev *rtwdev, bool state);
static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
- enum rtw89_rf_path_bit paths)
+ enum rtw89_rf_path_bit paths,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
u8 phy_map;
phy_map = FIELD_PREP(BTC_RFK_PATH_MAP, paths) |
@@ -247,9 +310,10 @@ static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev,
static inline u8 rtw89_btc_path_phymap(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- return rtw89_btc_phymap(rtwdev, phy_idx, BIT(path));
+ return rtw89_btc_phymap(rtwdev, phy_idx, BIT(path), chanctx_idx);
}
/* return bt req len in TU */
@@ -261,4 +325,56 @@ static inline u16 rtw89_coex_query_bt_req_len(struct rtw89_dev *rtwdev,
return btc->bt_req_len;
}
+static inline u32 rtw89_get_antpath_type(u8 phy_map, u8 type)
+{
+ return ((phy_map << 8) + type);
+}
+
+static inline
+void _slot_set_le(struct rtw89_btc *btc, u8 sid, __le16 dura, __le32 tbl, __le16 type)
+{
+ if (btc->ver->fcxslots == 1) {
+ btc->dm.slot.v1[sid].dur = dura;
+ btc->dm.slot.v1[sid].cxtbl = tbl;
+ btc->dm.slot.v1[sid].cxtype = type;
+ } else if (btc->ver->fcxslots == 7) {
+ btc->dm.slot.v7[sid].dur = dura;
+ btc->dm.slot.v7[sid].cxtype = type;
+ btc->dm.slot.v7[sid].cxtbl = tbl;
+ }
+}
+
+static inline
+void _slot_set(struct rtw89_btc *btc, u8 sid, u16 dura, u32 tbl, u16 type)
+{
+ _slot_set_le(btc, sid, cpu_to_le16(dura), cpu_to_le32(tbl), cpu_to_le16(type));
+}
+
+static inline
+void _slot_set_dur(struct rtw89_btc *btc, u8 sid, u16 dura)
+{
+ if (btc->ver->fcxslots == 1)
+ btc->dm.slot.v1[sid].dur = cpu_to_le16(dura);
+ else if (btc->ver->fcxslots == 7)
+ btc->dm.slot.v7[sid].dur = cpu_to_le16(dura);
+}
+
+static inline
+void _slot_set_type(struct rtw89_btc *btc, u8 sid, u16 type)
+{
+ if (btc->ver->fcxslots == 1)
+ btc->dm.slot.v1[sid].cxtype = cpu_to_le16(type);
+ else if (btc->ver->fcxslots == 7)
+ btc->dm.slot.v7[sid].cxtype = cpu_to_le16(type);
+}
+
+static inline
+void _slot_set_tbl(struct rtw89_btc *btc, u8 sid, u32 tbl)
+{
+ if (btc->ver->fcxslots == 1)
+ btc->dm.slot.v1[sid].cxtbl = cpu_to_le32(tbl);
+ else if (btc->ver->fcxslots == 7)
+ btc->dm.slot.v7[sid].cxtbl = cpu_to_le32(tbl);
+}
+
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index d474b8d5df3d..49447668cbf3 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -18,6 +18,7 @@
#include "ser.h"
#include "txrx.h"
#include "util.h"
+#include "wow.h"
static bool rtw89_disable_ps_mode;
module_param_named(disable_ps_mode, rtw89_disable_ps_mode, bool, 0644);
@@ -82,6 +83,9 @@ static struct ieee80211_channel rtw89_channels_5ghz[] = {
RTW89_DEF_CHAN_5G(5885, 177),
};
+static_assert(RTW89_5GHZ_UNII4_START_INDEX + RTW89_5GHZ_UNII4_CHANNEL_NUM ==
+ ARRAY_SIZE(rtw89_channels_5ghz));
+
static struct ieee80211_channel rtw89_channels_6ghz[] = {
RTW89_DEF_CHAN_6G(5955, 1),
RTW89_DEF_CHAN_6G(5975, 5),
@@ -188,17 +192,85 @@ static const struct ieee80211_iface_combination rtw89_iface_combs[] = {
{
.limits = rtw89_iface_limits,
.n_limits = ARRAY_SIZE(rtw89_iface_limits),
- .max_interfaces = 2,
+ .max_interfaces = RTW89_MAX_INTERFACE_NUM,
.num_different_channels = 1,
},
{
.limits = rtw89_iface_limits_mcc,
.n_limits = ARRAY_SIZE(rtw89_iface_limits_mcc),
- .max_interfaces = 2,
+ .max_interfaces = RTW89_MAX_INTERFACE_NUM,
.num_different_channels = 2,
},
};
+static const u8 rtw89_ext_capa_sta[] = {
+ [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
+ [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
+};
+
+static const struct wiphy_iftype_ext_capab rtw89_iftypes_ext_capa[] = {
+ {
+ .iftype = NL80211_IFTYPE_STATION,
+ .extended_capabilities = rtw89_ext_capa_sta,
+ .extended_capabilities_mask = rtw89_ext_capa_sta,
+ .extended_capabilities_len = sizeof(rtw89_ext_capa_sta),
+ /* relevant only if EHT is supported */
+ .eml_capabilities = 0,
+ .mld_capa_and_ops = 0,
+ },
+};
+
+#define RTW89_6GHZ_SPAN_HEAD 6145
+#define RTW89_6GHZ_SPAN_IDX(center_freq) \
+ ((((int)(center_freq) - RTW89_6GHZ_SPAN_HEAD) / 5) / 2)
+
+#define RTW89_DECL_6GHZ_SPAN(center_freq, subband_l, subband_h) \
+ [RTW89_6GHZ_SPAN_IDX(center_freq)] = { \
+ .sar_subband_low = RTW89_SAR_6GHZ_ ## subband_l, \
+ .sar_subband_high = RTW89_SAR_6GHZ_ ## subband_h, \
+ .acpi_sar_subband_low = RTW89_ACPI_SAR_6GHZ_ ## subband_l, \
+ .acpi_sar_subband_high = RTW89_ACPI_SAR_6GHZ_ ## subband_h, \
+ .ant_gain_subband_low = RTW89_ANT_GAIN_6GHZ_ ## subband_l, \
+ .ant_gain_subband_high = RTW89_ANT_GAIN_6GHZ_ ## subband_h, \
+ }
+
+/* Since 6GHz subbands are not edge aligned, some cases span two subbands.
+ * In the following, we describe each of them with rtw89_6ghz_span.
+ */
+static const struct rtw89_6ghz_span rtw89_overlapping_6ghz[] = {
+ RTW89_DECL_6GHZ_SPAN(6145, SUBBAND_5_L, SUBBAND_5_H),
+ RTW89_DECL_6GHZ_SPAN(6165, SUBBAND_5_L, SUBBAND_5_H),
+ RTW89_DECL_6GHZ_SPAN(6185, SUBBAND_5_L, SUBBAND_5_H),
+ RTW89_DECL_6GHZ_SPAN(6505, SUBBAND_6, SUBBAND_7_L),
+ RTW89_DECL_6GHZ_SPAN(6525, SUBBAND_6, SUBBAND_7_L),
+ RTW89_DECL_6GHZ_SPAN(6545, SUBBAND_6, SUBBAND_7_L),
+ RTW89_DECL_6GHZ_SPAN(6665, SUBBAND_7_L, SUBBAND_7_H),
+ RTW89_DECL_6GHZ_SPAN(6705, SUBBAND_7_L, SUBBAND_7_H),
+ RTW89_DECL_6GHZ_SPAN(6825, SUBBAND_7_H, SUBBAND_8),
+ RTW89_DECL_6GHZ_SPAN(6865, SUBBAND_7_H, SUBBAND_8),
+ RTW89_DECL_6GHZ_SPAN(6875, SUBBAND_7_H, SUBBAND_8),
+ RTW89_DECL_6GHZ_SPAN(6885, SUBBAND_7_H, SUBBAND_8),
+};
+
+const struct rtw89_6ghz_span *
+rtw89_get_6ghz_span(struct rtw89_dev *rtwdev, u32 center_freq)
+{
+ int idx;
+
+ if (center_freq >= RTW89_6GHZ_SPAN_HEAD) {
+ idx = RTW89_6GHZ_SPAN_IDX(center_freq);
+ /* To decrease size of rtw89_overlapping_6ghz[],
+ * RTW89_6GHZ_SPAN_IDX() truncates the leading NULLs
+ * to make first span as index 0 of the table. So, if center
+ * frequency is less than the first one, it will get netative.
+ */
+ if (idx >= 0 && idx < ARRAY_SIZE(rtw89_overlapping_6ghz))
+ return &rtw89_overlapping_6ghz[idx];
+ }
+
+ return NULL;
+}
+
bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 *bitrate)
{
struct ieee80211_rate rate;
@@ -252,6 +324,9 @@ static void rtw89_traffic_stats_accu(struct rtw89_dev *rtwdev,
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ if (tx && ieee80211_is_assoc_req(hdr->frame_control))
+ rtw89_wow_parse_akm(rtwdev, skb);
+
if (!ieee80211_is_data(hdr->frame_control))
return;
@@ -334,83 +409,47 @@ void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
rtw89_chan_create(chan, center_chan, channel->hw_value, band, bandwidth);
}
-void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
+static void __rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
{
- struct rtw89_hal *hal = &rtwdev->hal;
const struct rtw89_chip_info *chip = rtwdev->chip;
- const struct rtw89_chan *chan;
- enum rtw89_sub_entity_idx sub_entity_idx;
- enum rtw89_sub_entity_idx roc_idx;
- enum rtw89_phy_idx phy_idx;
- enum rtw89_entity_mode mode;
bool entity_active;
- entity_active = rtw89_get_entity_state(rtwdev);
+ entity_active = rtw89_get_entity_state(rtwdev, phy_idx);
if (!entity_active)
return;
- mode = rtw89_get_entity_mode(rtwdev);
- switch (mode) {
- case RTW89_ENTITY_MODE_SCC:
- case RTW89_ENTITY_MODE_MCC:
- sub_entity_idx = RTW89_SUB_ENTITY_0;
- break;
- case RTW89_ENTITY_MODE_MCC_PREPARE:
- sub_entity_idx = RTW89_SUB_ENTITY_1;
- break;
- default:
- WARN(1, "Invalid ent mode: %d\n", mode);
- return;
- }
+ chip->ops->set_txpwr(rtwdev, chan, phy_idx);
+}
- roc_idx = atomic_read(&hal->roc_entity_idx);
- if (roc_idx != RTW89_SUB_ENTITY_IDLE)
- sub_entity_idx = roc_idx;
+void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_chan *chan;
- phy_idx = RTW89_PHY_0;
- chan = rtw89_chan_get(rtwdev, sub_entity_idx);
- chip->ops->set_txpwr(rtwdev, chan, phy_idx);
+ chan = rtw89_mgnt_chan_get(rtwdev, 0);
+ __rtw89_core_set_chip_txpwr(rtwdev, chan, RTW89_PHY_0);
+
+ if (!rtwdev->support_mlo)
+ return;
+
+ chan = rtw89_mgnt_chan_get(rtwdev, 1);
+ __rtw89_core_set_chip_txpwr(rtwdev, chan, RTW89_PHY_1);
}
-int rtw89_set_channel(struct rtw89_dev *rtwdev)
+static void __rtw89_set_channel(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_mac_idx mac_idx,
+ enum rtw89_phy_idx phy_idx)
{
- struct rtw89_hal *hal = &rtwdev->hal;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_chan_rcd *chan_rcd;
- const struct rtw89_chan *chan;
- enum rtw89_sub_entity_idx sub_entity_idx;
- enum rtw89_sub_entity_idx roc_idx;
- enum rtw89_mac_idx mac_idx;
- enum rtw89_phy_idx phy_idx;
struct rtw89_channel_help_params bak;
- enum rtw89_entity_mode mode;
bool entity_active;
- entity_active = rtw89_get_entity_state(rtwdev);
+ entity_active = rtw89_get_entity_state(rtwdev, phy_idx);
- mode = rtw89_entity_recalc(rtwdev);
- switch (mode) {
- case RTW89_ENTITY_MODE_SCC:
- case RTW89_ENTITY_MODE_MCC:
- sub_entity_idx = RTW89_SUB_ENTITY_0;
- break;
- case RTW89_ENTITY_MODE_MCC_PREPARE:
- sub_entity_idx = RTW89_SUB_ENTITY_1;
- break;
- default:
- WARN(1, "Invalid ent mode: %d\n", mode);
- return -EINVAL;
- }
-
- roc_idx = atomic_read(&hal->roc_entity_idx);
- if (roc_idx != RTW89_SUB_ENTITY_IDLE)
- sub_entity_idx = roc_idx;
-
- mac_idx = RTW89_MAC_0;
- phy_idx = RTW89_PHY_0;
-
- chan = rtw89_chan_get(rtwdev, sub_entity_idx);
- chan_rcd = rtw89_chan_rcd_get(rtwdev, sub_entity_idx);
+ chan_rcd = rtw89_chan_rcd_get_by_chan(chan);
rtw89_chip_set_channel_prepare(rtwdev, &bak, chan, mac_idx, phy_idx);
@@ -422,20 +461,33 @@ int rtw89_set_channel(struct rtw89_dev *rtwdev)
if (!entity_active || chan_rcd->band_changed) {
rtw89_btc_ntfy_switch_band(rtwdev, phy_idx, chan->band_type);
- rtw89_chip_rfk_band_changed(rtwdev, phy_idx);
+ rtw89_chip_rfk_band_changed(rtwdev, phy_idx, chan);
}
- rtw89_set_entity_state(rtwdev, true);
- return 0;
+ rtw89_set_entity_state(rtwdev, phy_idx, true);
}
-void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_chan *chan)
+int rtw89_set_channel(struct rtw89_dev *rtwdev)
{
- const struct cfg80211_chan_def *chandef;
+ const struct rtw89_chan *chan;
+ enum rtw89_entity_mode mode;
+
+ mode = rtw89_entity_recalc(rtwdev);
+ if (mode < 0 || mode >= NUM_OF_RTW89_ENTITY_MODE) {
+ WARN(1, "Invalid ent mode: %d\n", mode);
+ return -EINVAL;
+ }
+
+ chan = rtw89_mgnt_chan_get(rtwdev, 0);
+ __rtw89_set_channel(rtwdev, chan, RTW89_MAC_0, RTW89_PHY_0);
+
+ if (!rtwdev->support_mlo)
+ return 0;
- chandef = rtw89_chandef_get(rtwdev, rtwvif->sub_entity_idx);
- rtw89_get_channel_params(chandef, chan);
+ chan = rtw89_mgnt_chan_get(rtwdev, 1);
+ __rtw89_set_channel(rtwdev, chan, RTW89_MAC_1, RTW89_PHY_1);
+
+ return 0;
}
static enum rtw89_core_tx_type
@@ -456,8 +508,9 @@ rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req,
enum btc_pkt_type pkt_type)
{
- struct ieee80211_sta *sta = tx_req->sta;
+ struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
+ struct ieee80211_link_sta *link_sta;
struct sk_buff *skb = tx_req->skb;
struct rtw89_sta *rtwsta;
u8 ampdu_num;
@@ -471,52 +524,47 @@ rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev,
if (!(IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_AMPDU))
return;
- if (!sta) {
+ if (!rtwsta_link) {
rtw89_warn(rtwdev, "cannot set ampdu info without sta\n");
return;
}
tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
- rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ rtwsta = rtwsta_link->rtwsta;
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
ampdu_num = (u8)((rtwsta->ampdu_params[tid].agg_num ?
rtwsta->ampdu_params[tid].agg_num :
- 4 << sta->deflink.ht_cap.ampdu_factor) - 1);
+ 4 << link_sta->ht_cap.ampdu_factor) - 1);
desc_info->agg_en = true;
- desc_info->ampdu_density = sta->deflink.ht_cap.ampdu_density;
+ desc_info->ampdu_density = link_sta->ht_cap.ampdu_density;
desc_info->ampdu_num = ampdu_num;
+
+ rcu_read_unlock();
}
static void
rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
+ struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
const struct rtw89_chip_info *chip = rtwdev->chip;
- struct ieee80211_vif *vif = tx_req->vif;
- struct ieee80211_sta *sta = tx_req->sta;
+ const struct rtw89_sec_cam_entry *sec_cam;
struct ieee80211_tx_info *info;
struct ieee80211_key_conf *key;
- struct rtw89_vif *rtwvif;
- struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
- struct rtw89_addr_cam_entry *addr_cam;
- struct rtw89_sec_cam_entry *sec_cam;
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
struct sk_buff *skb = tx_req->skb;
u8 sec_type = RTW89_SEC_KEY_TYPE_NONE;
+ u8 sec_cam_idx;
u64 pn64;
- if (!vif) {
- rtw89_warn(rtwdev, "cannot set sec key without vif\n");
- return;
- }
-
- rtwvif = (struct rtw89_vif *)vif->drv_priv;
- addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
-
info = IEEE80211_SKB_CB(skb);
key = info->control.hw_key;
- sec_cam = addr_cam->sec_entries[key->hw_key_idx];
+ sec_cam_idx = key->hw_key_idx;
+ sec_cam = cam_info->sec_entries[sec_cam_idx];
if (!sec_cam) {
rtw89_warn(rtwdev, "sec cam entry is empty\n");
return;
@@ -572,9 +620,13 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan)
{
struct sk_buff *skb = tx_req->skb;
+ struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_vif *vif = tx_info->control.vif;
+ struct ieee80211_bss_conf *bss_conf;
u16 lowest_rate;
+ u16 rate;
if (tx_info->flags & IEEE80211_TX_CTL_NO_CCK_RATE ||
(vif && vif->p2p))
@@ -584,44 +636,74 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev,
else
lowest_rate = RTW89_HW_RATE_OFDM6;
- if (!vif || !vif->bss_conf.basic_rates || !tx_req->sta)
+ if (!rtwvif_link)
return lowest_rate;
- return __ffs(vif->bss_conf.basic_rates) + lowest_rate;
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+ if (!bss_conf->basic_rates || !rtwsta_link) {
+ rate = lowest_rate;
+ goto out;
+ }
+
+ rate = __ffs(bss_conf->basic_rates) + lowest_rate;
+
+out:
+ rcu_read_unlock();
+
+ return rate;
}
static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
- struct ieee80211_vif *vif = tx_req->vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct ieee80211_sta *sta = tx_req->sta;
- struct rtw89_sta *rtwsta;
+ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
+ struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
- if (!sta)
- return rtwvif->mac_id;
+ if (desc_info->mlo && !desc_info->sw_mld) {
+ if (rtwsta_link)
+ return rtw89_sta_get_main_macid(rtwsta_link->rtwsta);
+ else
+ return rtw89_vif_get_main_macid(rtwvif_link->rtwvif);
+ }
+
+ if (!rtwsta_link)
+ return rtwvif_link->mac_id;
+
+ return rtwsta_link->mac_id;
+}
+
+static void rtw89_core_tx_update_llc_hdr(struct rtw89_dev *rtwdev,
+ struct rtw89_tx_desc_info *desc_info,
+ struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr = (void *)skb->data;
+ __le16 fc = hdr->frame_control;
- rtwsta = (struct rtw89_sta *)sta->drv_priv;
- return rtwsta->mac_id;
+ desc_info->hdr_llc_len = ieee80211_hdrlen(fc);
+ desc_info->hdr_llc_len >>= 1; /* in unit of 2 bytes */
}
static void
rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
- struct ieee80211_vif *vif = tx_req->vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link;
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->sub_entity_idx);
+ rtwvif_link->chanctx_idx);
+ struct sk_buff *skb = tx_req->skb;
u8 qsel, ch_dma;
- qsel = desc_info->hiq ? RTW89_TX_QSEL_B0_HI : RTW89_TX_QSEL_B0_MGMT;
+ qsel = rtw89_core_get_qsel_mgmt(rtwdev, tx_req);
ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel);
desc_info->qsel = qsel;
desc_info->ch_dma = ch_dma;
- desc_info->port = desc_info->hiq ? rtwvif->port : 0;
+ desc_info->port = desc_info->hiq ? rtwvif_link->port : 0;
desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req);
desc_info->hw_ssn_sel = RTW89_MGMT_HW_SSN_SEL;
desc_info->hw_seq_mode = RTW89_MGMT_HW_SEQ_MODE;
@@ -632,6 +714,11 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
desc_info->dis_data_fb = true;
desc_info->data_rate = rtw89_core_get_mgmt_rate(rtwdev, tx_req, chan);
+ if (chip->hw_mgmt_tx_encrypt && IEEE80211_SKB_CB(skb)->control.hw_key) {
+ rtw89_core_tx_update_sec_key(rtwdev, tx_req);
+ rtw89_core_tx_update_llc_hdr(rtwdev, desc_info, skb);
+ }
+
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
"tx mgmt frame with rate 0x%x on channel %d (band %d, bw %d)\n",
desc_info->data_rate, chan->channel, chan->band_type,
@@ -686,26 +773,36 @@ __rtw89_core_tx_check_he_qos_htc(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req,
enum btc_pkt_type pkt_type)
{
- struct ieee80211_sta *sta = tx_req->sta;
- struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
+ struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
struct sk_buff *skb = tx_req->skb;
struct ieee80211_hdr *hdr = (void *)skb->data;
+ struct ieee80211_link_sta *link_sta;
__le16 fc = hdr->frame_control;
/* AP IOT issue with EAPoL, ARP and DHCP */
if (pkt_type < PACKET_MAX)
return false;
- if (!sta || !sta->deflink.he_cap.has_he)
+ if (!rtwsta_link)
return false;
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
+ if (!link_sta->he_cap.has_he) {
+ rcu_read_unlock();
+ return false;
+ }
+
+ rcu_read_unlock();
+
if (!ieee80211_is_data_qos(fc))
return false;
if (skb_headroom(skb) < IEEE80211_HT_CTL_LEN)
return false;
- if (rtwsta && rtwsta->ra_report.might_fallback_legacy)
+ if (rtwsta_link && rtwsta_link->ra_report.might_fallback_legacy)
return false;
return true;
@@ -715,8 +812,7 @@ static void
__rtw89_core_tx_adjust_he_qos_htc(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
- struct ieee80211_sta *sta = tx_req->sta;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
struct sk_buff *skb = tx_req->skb;
struct ieee80211_hdr *hdr = (void *)skb->data;
__le16 fc = hdr->frame_control;
@@ -732,7 +828,7 @@ __rtw89_core_tx_adjust_he_qos_htc(struct rtw89_dev *rtwdev,
hdr = data;
htc = data + hdr_len;
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_ORDER);
- *htc = rtwsta->htc_template ? rtwsta->htc_template :
+ *htc = rtwsta_link->htc_template ? rtwsta_link->htc_template :
le32_encode_bits(RTW89_HTC_VARIANT_HE, RTW89_HTC_MASK_VARIANT) |
le32_encode_bits(RTW89_HTC_VARIANT_HE_CID_CAS, RTW89_HTC_MASK_CTL_ID);
@@ -746,8 +842,7 @@ rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev,
enum btc_pkt_type pkt_type)
{
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
- struct ieee80211_vif *vif = tx_req->vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link;
if (!__rtw89_core_tx_check_he_qos_htc(rtwdev, tx_req, pkt_type))
goto desc_bk;
@@ -758,23 +853,25 @@ rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev,
desc_info->a_ctrl_bsr = true;
desc_bk:
- if (!rtwvif || rtwvif->last_a_ctrl == desc_info->a_ctrl_bsr)
+ if (!rtwvif_link || rtwvif_link->last_a_ctrl == desc_info->a_ctrl_bsr)
return;
- rtwvif->last_a_ctrl = desc_info->a_ctrl_bsr;
+ rtwvif_link->last_a_ctrl = desc_info->a_ctrl_bsr;
desc_info->bk = true;
}
static u16 rtw89_core_get_data_rate(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
- struct ieee80211_vif *vif = tx_req->vif;
- struct ieee80211_sta *sta = tx_req->sta;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern;
- enum rtw89_sub_entity_idx idx = rtwvif->sub_entity_idx;
+ struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif_link->rate_pattern;
+ enum rtw89_chanctx_idx idx = rtwvif_link->chanctx_idx;
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx);
+ struct ieee80211_link_sta *link_sta;
u16 lowest_rate;
+ u16 rate;
if (rate_pattern->enable)
return rate_pattern->rate;
@@ -786,20 +883,31 @@ static u16 rtw89_core_get_data_rate(struct rtw89_dev *rtwdev,
else
lowest_rate = RTW89_HW_RATE_OFDM6;
- if (!sta || !sta->deflink.supp_rates[chan->band_type])
+ if (!rtwsta_link)
return lowest_rate;
- return __ffs(sta->deflink.supp_rates[chan->band_type]) + lowest_rate;
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
+ if (!link_sta->supp_rates[chan->band_type]) {
+ rate = lowest_rate;
+ goto out;
+ }
+
+ rate = __ffs(link_sta->supp_rates[chan->band_type]) + lowest_rate;
+
+out:
+ rcu_read_unlock();
+
+ return rate;
}
static void
rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
- struct ieee80211_vif *vif = tx_req->vif;
- struct ieee80211_sta *sta = tx_req->sta;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
+ struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link = tx_req->rtwsta_link;
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
struct sk_buff *skb = tx_req->skb;
u8 tid, tid_indicate;
@@ -814,8 +922,10 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev,
desc_info->tid_indicate = tid_indicate;
desc_info->qsel = qsel;
desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req);
- desc_info->port = desc_info->hiq ? rtwvif->port : 0;
- desc_info->er_cap = rtwsta ? rtwsta->er_cap : false;
+ desc_info->port = desc_info->hiq ? rtwvif_link->port : 0;
+ desc_info->er_cap = rtwsta_link ? rtwsta_link->er_cap : false;
+ desc_info->stbc = rtwsta_link ? rtwsta_link->ra.stbc_cap : false;
+ desc_info->ldpc = rtwsta_link ? rtwsta_link->ra.ldpc_cap : false;
/* enable wd_info for AMPDU */
desc_info->en_wd_info = true;
@@ -830,16 +940,17 @@ static enum btc_pkt_type
rtw89_core_tx_btc_spec_pkt_notify(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
+ struct wiphy *wiphy = rtwdev->hw->wiphy;
struct sk_buff *skb = tx_req->skb;
struct udphdr *udphdr;
if (IEEE80211_SKB_CB(skb)->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {
- ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.eapol_notify_work);
+ wiphy_work_queue(wiphy, &rtwdev->btc.eapol_notify_work);
return PACKET_EAPOL;
}
if (skb->protocol == htons(ETH_P_ARP)) {
- ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.arp_notify_work);
+ wiphy_work_queue(wiphy, &rtwdev->btc.arp_notify_work);
return PACKET_ARP;
}
@@ -849,31 +960,20 @@ rtw89_core_tx_btc_spec_pkt_notify(struct rtw89_dev *rtwdev,
if (((udphdr->source == htons(67) && udphdr->dest == htons(68)) ||
(udphdr->source == htons(68) && udphdr->dest == htons(67))) &&
skb->len > 282) {
- ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.dhcp_notify_work);
+ wiphy_work_queue(wiphy, &rtwdev->btc.dhcp_notify_work);
return PACKET_DHCP;
}
}
if (skb->protocol == htons(ETH_P_IP) &&
ip_hdr(skb)->protocol == IPPROTO_ICMP) {
- ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.icmp_notify_work);
+ wiphy_work_queue(wiphy, &rtwdev->btc.icmp_notify_work);
return PACKET_ICMP;
}
return PACKET_MAX;
}
-static void rtw89_core_tx_update_llc_hdr(struct rtw89_dev *rtwdev,
- struct rtw89_tx_desc_info *desc_info,
- struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr = (void *)skb->data;
- __le16 fc = hdr->frame_control;
-
- desc_info->hdr_llc_len = ieee80211_hdrlen(fc);
- desc_info->hdr_llc_len >>= 1; /* in unit of 2 bytes */
-}
-
static void
rtw89_core_tx_wake(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
@@ -901,15 +1001,27 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev,
struct sk_buff *skb = tx_req->skb;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (void *)skb->data;
+ struct rtw89_addr_cam_entry *addr_cam;
enum rtw89_core_tx_type tx_type;
enum btc_pkt_type pkt_type;
+ bool upd_wlan_hdr = false;
bool is_bmc;
u16 seq;
+ if (tx_req->sta)
+ desc_info->mlo = tx_req->sta->mlo;
+ else if (tx_req->vif)
+ desc_info->mlo = ieee80211_vif_is_mld(tx_req->vif);
+
seq = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
if (tx_req->tx_type != RTW89_CORE_TX_TYPE_FWCMD) {
tx_type = rtw89_core_get_tx_type(rtwdev, skb);
tx_req->tx_type = tx_type;
+
+ addr_cam = rtw89_get_addr_cam_of(tx_req->rtwvif_link,
+ tx_req->rtwsta_link);
+ if (addr_cam->valid && desc_info->mlo)
+ upd_wlan_hdr = true;
}
is_bmc = (is_broadcast_ether_addr(hdr->addr1) ||
is_multicast_ether_addr(hdr->addr1));
@@ -919,6 +1031,7 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev,
desc_info->is_bmc = is_bmc;
desc_info->wd_page = true;
desc_info->hiq = info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM;
+ desc_info->upd_wlan_hdr = upd_wlan_hdr;
switch (tx_req->tx_type) {
case RTW89_CORE_TX_TYPE_MGMT:
@@ -1018,16 +1131,23 @@ int rtw89_h2c_tx(struct rtw89_dev *rtwdev,
return 0;
}
-int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel)
+static int rtw89_core_tx_write_link(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ struct sk_buff *skb, int *qsel, bool sw_mld)
{
- struct rtw89_core_tx_request tx_req = {0};
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ struct rtw89_core_tx_request tx_req = {};
int ret;
tx_req.skb = skb;
- tx_req.sta = sta;
tx_req.vif = vif;
+ tx_req.sta = sta;
+ tx_req.rtwvif_link = rtwvif_link;
+ tx_req.rtwsta_link = rtwsta_link;
+ tx_req.desc_info.sw_mld = sw_mld;
rtw89_traffic_stats_accu(rtwdev, &rtwdev->stats, skb, true);
rtw89_traffic_stats_accu(rtwdev, &rtwvif->stats, skb, true);
@@ -1046,6 +1166,33 @@ int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
return 0;
}
+int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_sta_link *rtwsta_link = NULL;
+ struct rtw89_vif_link *rtwvif_link;
+
+ if (rtwsta) {
+ rtwsta_link = rtw89_get_designated_link(rtwsta);
+ if (unlikely(!rtwsta_link)) {
+ rtw89_err(rtwdev, "tx: find no sta designated link\n");
+ return -ENOLINK;
+ }
+
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ } else {
+ rtwvif_link = rtw89_get_designated_link(rtwvif);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "tx: find no vif designated link\n");
+ return -ENOLINK;
+ }
+ }
+
+ return rtw89_core_tx_write_link(rtwdev, rtwvif_link, rtwsta_link, skb, qsel, false);
+}
+
static __le32 rtw89_build_txwd_body0(struct rtw89_tx_desc_info *desc_info)
{
u32 dword = FIELD_PREP(RTW89_TXWD_BODY0_WP_OFFSET, desc_info->wp_offset) |
@@ -1130,6 +1277,8 @@ static __le32 rtw89_build_txwd_info0(struct rtw89_tx_desc_info *desc_info)
{
u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_USE_RATE, desc_info->use_rate) |
FIELD_PREP(RTW89_TXWD_INFO0_DATA_RATE, desc_info->data_rate) |
+ FIELD_PREP(RTW89_TXWD_INFO0_DATA_STBC, desc_info->stbc) |
+ FIELD_PREP(RTW89_TXWD_INFO0_DATA_LDPC, desc_info->ldpc) |
FIELD_PREP(RTW89_TXWD_INFO0_DISDATAFB, desc_info->dis_data_fb) |
FIELD_PREP(RTW89_TXWD_INFO0_MULTIPORT_ID, desc_info->port);
@@ -1138,7 +1287,9 @@ static __le32 rtw89_build_txwd_info0(struct rtw89_tx_desc_info *desc_info)
static __le32 rtw89_build_txwd_info0_v1(struct rtw89_tx_desc_info *desc_info)
{
- u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_DISDATAFB, desc_info->dis_data_fb) |
+ u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_DATA_STBC, desc_info->stbc) |
+ FIELD_PREP(RTW89_TXWD_INFO0_DATA_LDPC, desc_info->ldpc) |
+ FIELD_PREP(RTW89_TXWD_INFO0_DISDATAFB, desc_info->dis_data_fb) |
FIELD_PREP(RTW89_TXWD_INFO0_MULTIPORT_ID, desc_info->port) |
FIELD_PREP(RTW89_TXWD_INFO0_DATA_ER, desc_info->er_cap) |
FIELD_PREP(RTW89_TXWD_INFO0_DATA_BW_ER, 0);
@@ -1269,7 +1420,9 @@ static __le32 rtw89_build_txwd_body2_v2(struct rtw89_tx_desc_info *desc_info)
static __le32 rtw89_build_txwd_body3_v2(struct rtw89_tx_desc_info *desc_info)
{
- u32 dword = FIELD_PREP(BE_TXD_BODY3_WIFI_SEQ, desc_info->seq);
+ u32 dword = FIELD_PREP(BE_TXD_BODY3_WIFI_SEQ, desc_info->seq) |
+ FIELD_PREP(BE_TXD_BODY3_MLO_FLAG, desc_info->mlo) |
+ FIELD_PREP(BE_TXD_BODY3_IS_MLD_SW_EN, desc_info->sw_mld);
return cpu_to_le32(dword);
}
@@ -1292,6 +1445,13 @@ static __le32 rtw89_build_txwd_body5_v2(struct rtw89_tx_desc_info *desc_info)
return cpu_to_le32(dword);
}
+static __le32 rtw89_build_txwd_body6_v2(struct rtw89_tx_desc_info *desc_info)
+{
+ u32 dword = FIELD_PREP(BE_TXD_BODY6_UPD_WLAN_HDR, desc_info->upd_wlan_hdr);
+
+ return cpu_to_le32(dword);
+}
+
static __le32 rtw89_build_txwd_body7_v2(struct rtw89_tx_desc_info *desc_info)
{
u32 dword = FIELD_PREP(BE_TXD_BODY7_USERATE_SEL, desc_info->use_rate) |
@@ -1304,7 +1464,9 @@ static __le32 rtw89_build_txwd_body7_v2(struct rtw89_tx_desc_info *desc_info)
static __le32 rtw89_build_txwd_info0_v2(struct rtw89_tx_desc_info *desc_info)
{
- u32 dword = FIELD_PREP(BE_TXD_INFO0_DISDATAFB, desc_info->dis_data_fb) |
+ u32 dword = FIELD_PREP(BE_TXD_INFO0_DATA_STBC, desc_info->stbc) |
+ FIELD_PREP(BE_TXD_INFO0_DATA_LDPC, desc_info->ldpc) |
+ FIELD_PREP(BE_TXD_INFO0_DISDATAFB, desc_info->dis_data_fb) |
FIELD_PREP(BE_TXD_INFO0_MULTIPORT_ID, desc_info->port);
return cpu_to_le32(dword);
@@ -1353,6 +1515,7 @@ void rtw89_core_fill_txdesc_v2(struct rtw89_dev *rtwdev,
txwd_body->dword4 = rtw89_build_txwd_body4_v2(desc_info);
txwd_body->dword5 = rtw89_build_txwd_body5_v2(desc_info);
}
+ txwd_body->dword6 = rtw89_build_txwd_body6_v2(desc_info);
txwd_body->dword7 = rtw89_build_txwd_body7_v2(desc_info);
if (!desc_info->en_wd_info)
@@ -1444,16 +1607,20 @@ static int rtw89_core_rx_process_mac_ppdu(struct rtw89_dev *rtwdev,
return -EINVAL;
}
- /* For WiFi 7 chips, RXWD.mac_id of PPDU status is not set by hardware,
- * so update mac_id by rxinfo_user[].mac_id.
- */
- for (i = 0; i < usr_num && chip_gen == RTW89_CHIP_BE; i++) {
+ for (i = 0; i < usr_num; i++) {
user = &rxinfo->user[i];
if (!le32_get_bits(user->w0, RTW89_RXINFO_USER_MAC_ID_VALID))
continue;
-
- phy_ppdu->mac_id =
- le32_get_bits(user->w0, RTW89_RXINFO_USER_MACID);
+ /* For WiFi 7 chips, RXWD.mac_id of PPDU status is not set
+ * by hardware, so update mac_id by rxinfo_user[].mac_id.
+ */
+ if (chip_gen == RTW89_CHIP_BE)
+ phy_ppdu->mac_id =
+ le32_get_bits(user->w0, RTW89_RXINFO_USER_MACID);
+ phy_ppdu->has_data =
+ le32_get_bits(user->w0, RTW89_RXINFO_USER_DATA);
+ phy_ppdu->has_bcn =
+ le32_get_bits(user->w0, RTW89_RXINFO_USER_BCN);
break;
}
@@ -1475,19 +1642,44 @@ static int rtw89_core_rx_process_mac_ppdu(struct rtw89_dev *rtwdev,
return 0;
}
+static u8 rtw89_get_data_rate_nss(struct rtw89_dev *rtwdev, u16 data_rate)
+{
+ u8 data_rate_mode;
+
+ data_rate_mode = rtw89_get_data_rate_mode(rtwdev, data_rate);
+ switch (data_rate_mode) {
+ case DATA_RATE_MODE_NON_HT:
+ return 1;
+ case DATA_RATE_MODE_HT:
+ return rtw89_get_data_ht_nss(rtwdev, data_rate) + 1;
+ case DATA_RATE_MODE_VHT:
+ case DATA_RATE_MODE_HE:
+ case DATA_RATE_MODE_EHT:
+ return rtw89_get_data_nss(rtwdev, data_rate) + 1;
+ default:
+ rtw89_warn(rtwdev, "invalid RX rate mode %d\n", data_rate_mode);
+ return 0;
+ }
+}
+
static void rtw89_core_rx_process_phy_ppdu_iter(void *data,
struct ieee80211_sta *sta)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_rx_phy_ppdu *phy_ppdu = (struct rtw89_rx_phy_ppdu *)data;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_dev *rtwdev = rtwsta->rtwdev;
struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_sta_link *rtwsta_link;
u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num;
u8 ant_pos = U8_MAX;
u8 evm_pos = 0;
int i;
- if (rtwsta->mac_id != phy_ppdu->mac_id || !phy_ppdu->to_self)
+ rtwsta_link = rtw89_sta_get_link_inst(rtwsta, phy_ppdu->phy_idx);
+ if (unlikely(!rtwsta_link))
+ return;
+
+ if (rtwsta_link->mac_id != phy_ppdu->mac_id || !phy_ppdu->to_self)
return;
if (hal->ant_diversity && hal->antenna_rx) {
@@ -1495,19 +1687,25 @@ static void rtw89_core_rx_process_phy_ppdu_iter(void *data,
evm_pos = ant_pos;
}
- ewma_rssi_add(&rtwsta->avg_rssi, phy_ppdu->rssi_avg);
+ ewma_rssi_add(&rtwsta_link->avg_rssi, phy_ppdu->rssi_avg);
if (ant_pos < ant_num) {
- ewma_rssi_add(&rtwsta->rssi[ant_pos], phy_ppdu->rssi[0]);
+ ewma_rssi_add(&rtwsta_link->rssi[ant_pos], phy_ppdu->rssi[0]);
} else {
for (i = 0; i < rtwdev->chip->rf_path_num; i++)
- ewma_rssi_add(&rtwsta->rssi[i], phy_ppdu->rssi[i]);
+ ewma_rssi_add(&rtwsta_link->rssi[i], phy_ppdu->rssi[i]);
}
- if (phy_ppdu->ofdm.has) {
- ewma_snr_add(&rtwsta->avg_snr, phy_ppdu->ofdm.avg_snr);
- ewma_evm_add(&rtwsta->evm_min[evm_pos], phy_ppdu->ofdm.evm_min);
- ewma_evm_add(&rtwsta->evm_max[evm_pos], phy_ppdu->ofdm.evm_max);
+ if (phy_ppdu->ofdm.has && (phy_ppdu->has_data || phy_ppdu->has_bcn)) {
+ ewma_snr_add(&rtwsta_link->avg_snr, phy_ppdu->ofdm.avg_snr);
+ if (rtw89_get_data_rate_nss(rtwdev, phy_ppdu->rate) == 1) {
+ ewma_evm_add(&rtwsta_link->evm_1ss, phy_ppdu->ofdm.evm_min);
+ } else {
+ ewma_evm_add(&rtwsta_link->evm_min[evm_pos],
+ phy_ppdu->ofdm.evm_min);
+ ewma_evm_add(&rtwsta_link->evm_max[evm_pos],
+ phy_ppdu->ofdm.evm_max);
+ }
}
}
@@ -1543,21 +1741,48 @@ static u16 rtw89_core_get_phy_status_ie_len(struct rtw89_dev *rtwdev,
return ie_len;
}
+static void rtw89_core_parse_phy_status_ie01_v2(struct rtw89_dev *rtwdev,
+ const struct rtw89_phy_sts_iehdr *iehdr,
+ struct rtw89_rx_phy_ppdu *phy_ppdu)
+{
+ const struct rtw89_phy_sts_ie01_v2 *ie;
+ u8 *rpl_fd = phy_ppdu->rpl_fd;
+
+ ie = (const struct rtw89_phy_sts_ie01_v2 *)iehdr;
+ rpl_fd[RF_PATH_A] = le32_get_bits(ie->w8, RTW89_PHY_STS_IE01_V2_W8_RPL_FD_A);
+ rpl_fd[RF_PATH_B] = le32_get_bits(ie->w8, RTW89_PHY_STS_IE01_V2_W8_RPL_FD_B);
+ rpl_fd[RF_PATH_C] = le32_get_bits(ie->w9, RTW89_PHY_STS_IE01_V2_W9_RPL_FD_C);
+ rpl_fd[RF_PATH_D] = le32_get_bits(ie->w9, RTW89_PHY_STS_IE01_V2_W9_RPL_FD_D);
+
+ phy_ppdu->bw_idx = le32_get_bits(ie->w5, RTW89_PHY_STS_IE01_V2_W5_BW_IDX);
+}
+
static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev,
const struct rtw89_phy_sts_iehdr *iehdr,
struct rtw89_rx_phy_ppdu *phy_ppdu)
{
- const struct rtw89_phy_sts_ie0 *ie = (const struct rtw89_phy_sts_ie0 *)iehdr;
+ const struct rtw89_phy_sts_ie01 *ie = (const struct rtw89_phy_sts_ie01 *)iehdr;
s16 cfo;
u32 t;
phy_ppdu->chan_idx = le32_get_bits(ie->w0, RTW89_PHY_STS_IE01_W0_CH_IDX);
+
+ if (rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR) {
+ phy_ppdu->ldpc = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_LDPC);
+ phy_ppdu->stbc = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_STBC);
+ }
+
+ if (!phy_ppdu->hdr_2_en)
+ phy_ppdu->rx_path_en =
+ le32_get_bits(ie->w0, RTW89_PHY_STS_IE01_W0_RX_PATH_EN);
+
if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6)
return;
if (!phy_ppdu->to_self)
return;
+ phy_ppdu->rpl_avg = le32_get_bits(ie->w0, RTW89_PHY_STS_IE01_W0_RSSI_AVG_FD);
phy_ppdu->ofdm.avg_snr = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_AVG_SNR);
phy_ppdu->ofdm.evm_max = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_EVM_MAX);
phy_ppdu->ofdm.evm_min = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_EVM_MIN);
@@ -1573,6 +1798,39 @@ static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev,
}
rtw89_phy_cfo_parse(rtwdev, cfo, phy_ppdu);
+
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
+ rtw89_core_parse_phy_status_ie01_v2(rtwdev, iehdr, phy_ppdu);
+}
+
+static void rtw89_core_parse_phy_status_ie00(struct rtw89_dev *rtwdev,
+ const struct rtw89_phy_sts_iehdr *iehdr,
+ struct rtw89_rx_phy_ppdu *phy_ppdu)
+{
+ const struct rtw89_phy_sts_ie00 *ie = (const struct rtw89_phy_sts_ie00 *)iehdr;
+ u16 tmp_rpl;
+
+ tmp_rpl = le32_get_bits(ie->w0, RTW89_PHY_STS_IE00_W0_RPL);
+ phy_ppdu->rpl_avg = tmp_rpl >> 1;
+}
+
+static void rtw89_core_parse_phy_status_ie00_v2(struct rtw89_dev *rtwdev,
+ const struct rtw89_phy_sts_iehdr *iehdr,
+ struct rtw89_rx_phy_ppdu *phy_ppdu)
+{
+ const struct rtw89_phy_sts_ie00_v2 *ie;
+ u8 *rpl_path = phy_ppdu->rpl_path;
+ u16 tmp_rpl[RF_PATH_MAX];
+ u8 i;
+
+ ie = (const struct rtw89_phy_sts_ie00_v2 *)iehdr;
+ tmp_rpl[RF_PATH_A] = le32_get_bits(ie->w4, RTW89_PHY_STS_IE00_V2_W4_RPL_TD_A);
+ tmp_rpl[RF_PATH_B] = le32_get_bits(ie->w4, RTW89_PHY_STS_IE00_V2_W4_RPL_TD_B);
+ tmp_rpl[RF_PATH_C] = le32_get_bits(ie->w4, RTW89_PHY_STS_IE00_V2_W4_RPL_TD_C);
+ tmp_rpl[RF_PATH_D] = le32_get_bits(ie->w5, RTW89_PHY_STS_IE00_V2_W5_RPL_TD_D);
+
+ for (i = 0; i < RF_PATH_MAX; i++)
+ rpl_path[i] = tmp_rpl[i] >> 1;
}
static int rtw89_core_process_phy_status_ie(struct rtw89_dev *rtwdev,
@@ -1584,6 +1842,11 @@ static int rtw89_core_process_phy_status_ie(struct rtw89_dev *rtwdev,
ie = le32_get_bits(iehdr->w0, RTW89_PHY_STS_IEHDR_TYPE);
switch (ie) {
+ case RTW89_PHYSTS_IE00_CMN_CCK:
+ rtw89_core_parse_phy_status_ie00(rtwdev, iehdr, phy_ppdu);
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
+ rtw89_core_parse_phy_status_ie00_v2(rtwdev, iehdr, phy_ppdu);
+ break;
case RTW89_PHYSTS_IE01_CMN_OFDM:
rtw89_core_parse_phy_status_ie01(rtwdev, iehdr, phy_ppdu);
break;
@@ -1594,6 +1857,13 @@ static int rtw89_core_process_phy_status_ie(struct rtw89_dev *rtwdev,
return 0;
}
+static void rtw89_core_update_phy_ppdu_hdr_v2(struct rtw89_rx_phy_ppdu *phy_ppdu)
+{
+ const struct rtw89_phy_sts_hdr_v2 *hdr = phy_ppdu->buf + PHY_STS_HDR_LEN;
+
+ phy_ppdu->rx_path_en = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_V2_W0_PATH_EN);
+}
+
static void rtw89_core_update_phy_ppdu(struct rtw89_rx_phy_ppdu *phy_ppdu)
{
const struct rtw89_phy_sts_hdr *hdr = phy_ppdu->buf;
@@ -1605,6 +1875,10 @@ static void rtw89_core_update_phy_ppdu(struct rtw89_rx_phy_ppdu *phy_ppdu)
rssi[RF_PATH_B] = le32_get_bits(hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_B);
rssi[RF_PATH_C] = le32_get_bits(hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_C);
rssi[RF_PATH_D] = le32_get_bits(hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_D);
+
+ phy_ppdu->hdr_2_en = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_W0_HDR_2_EN);
+ if (phy_ppdu->hdr_2_en)
+ rtw89_core_update_phy_ppdu_hdr_v2(phy_ppdu);
}
static int rtw89_core_rx_process_phy_ppdu(struct rtw89_dev *rtwdev,
@@ -1657,6 +1931,7 @@ static int rtw89_core_rx_parse_phy_sts(struct rtw89_dev *rtwdev,
}
}
+ rtw89_chip_convert_rpl_to_rssi(rtwdev, phy_ppdu);
rtw89_phy_antdiv_parse(rtwdev, phy_ppdu);
return 0;
@@ -1678,32 +1953,58 @@ static void rtw89_core_rx_process_phy_sts(struct rtw89_dev *rtwdev,
phy_ppdu);
}
-static u8 rtw89_rxdesc_to_nl_he_eht_gi(struct rtw89_dev *rtwdev,
- u8 desc_info_gi,
- bool rx_status, bool eht)
+static u8 rtw89_rxdesc_to_nl_he_gi(struct rtw89_dev *rtwdev,
+ u8 desc_info_gi,
+ bool rx_status)
+{
+ switch (desc_info_gi) {
+ case RTW89_GILTF_SGI_4XHE08:
+ case RTW89_GILTF_2XHE08:
+ case RTW89_GILTF_1XHE08:
+ return NL80211_RATE_INFO_HE_GI_0_8;
+ case RTW89_GILTF_2XHE16:
+ case RTW89_GILTF_1XHE16:
+ return NL80211_RATE_INFO_HE_GI_1_6;
+ case RTW89_GILTF_LGI_4XHE32:
+ return NL80211_RATE_INFO_HE_GI_3_2;
+ default:
+ rtw89_warn(rtwdev, "invalid gi_ltf=%d", desc_info_gi);
+ if (rx_status)
+ return NL80211_RATE_INFO_HE_GI_3_2;
+ return U8_MAX;
+ }
+}
+
+static u8 rtw89_rxdesc_to_nl_eht_gi(struct rtw89_dev *rtwdev,
+ u8 desc_info_gi,
+ bool rx_status)
{
switch (desc_info_gi) {
case RTW89_GILTF_SGI_4XHE08:
case RTW89_GILTF_2XHE08:
case RTW89_GILTF_1XHE08:
- return eht ? NL80211_RATE_INFO_EHT_GI_0_8 :
- NL80211_RATE_INFO_HE_GI_0_8;
+ return NL80211_RATE_INFO_EHT_GI_0_8;
case RTW89_GILTF_2XHE16:
case RTW89_GILTF_1XHE16:
- return eht ? NL80211_RATE_INFO_EHT_GI_1_6 :
- NL80211_RATE_INFO_HE_GI_1_6;
+ return NL80211_RATE_INFO_EHT_GI_1_6;
case RTW89_GILTF_LGI_4XHE32:
- return eht ? NL80211_RATE_INFO_EHT_GI_3_2 :
- NL80211_RATE_INFO_HE_GI_3_2;
+ return NL80211_RATE_INFO_EHT_GI_3_2;
default:
rtw89_warn(rtwdev, "invalid gi_ltf=%d", desc_info_gi);
if (rx_status)
- return eht ? NL80211_RATE_INFO_EHT_GI_3_2 :
- NL80211_RATE_INFO_HE_GI_3_2;
+ return NL80211_RATE_INFO_EHT_GI_3_2;
return U8_MAX;
}
}
+static u8 rtw89_rxdesc_to_nl_he_eht_gi(struct rtw89_dev *rtwdev,
+ u8 desc_info_gi,
+ bool rx_status, bool eht)
+{
+ return eht ? rtw89_rxdesc_to_nl_eht_gi(rtwdev, desc_info_gi, rx_status) :
+ rtw89_rxdesc_to_nl_he_gi(rtwdev, desc_info_gi, rx_status);
+}
+
static
bool rtw89_check_rx_statu_gi_match(struct ieee80211_rx_status *status, u8 gi_ltf,
bool eht)
@@ -1759,17 +2060,19 @@ struct rtw89_vif_rx_stats_iter_data {
};
static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf,
struct sk_buff *skb)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct ieee80211_trigger *tf = (struct ieee80211_trigger *)skb->data;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
u8 *pos, *end, type, tf_bw;
u16 aid, tf_rua;
- if (!ether_addr_equal(vif->bss_conf.bssid, tf->ta) ||
- rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION ||
- rtwvif->net_type == RTW89_NET_TYPE_NO_LINK)
+ if (!ether_addr_equal(bss_conf->bssid, tf->ta) ||
+ rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION ||
+ rtwvif_link->net_type == RTW89_NET_TYPE_NO_LINK)
return;
type = le64_get_bits(tf->common_info, IEEE80211_TRIGGER_TYPE_MASK);
@@ -1792,13 +2095,24 @@ static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev,
break;
if (aid == vif->cfg.aid) {
- enum nl80211_he_ru_alloc rua = rtw89_he_rua_to_ru_alloc(tf_rua >> 1);
+ enum nl80211_he_ru_alloc rua;
rtwvif->stats.rx_tf_acc++;
rtwdev->stats.rx_tf_acc++;
+
+ /* The following only required for HE trigger frame, but we
+ * cannot use UL HE-SIG-A2 reserved subfield to identify it
+ * since some 11ax APs will fill it with all 0s, which will
+ * be misunderstood as EHT trigger frame.
+ */
+ if (bss_conf->eht_support)
+ break;
+
+ rua = rtw89_he_rua_to_ru_alloc(tf_rua >> 1);
+
if (tf_bw == IEEE80211_TRIGGER_ULBW_160_80P80MHZ &&
rua <= NL80211_RATE_INFO_HE_RU_ALLOC_106)
- rtwvif->pwr_diff_en = true;
+ rtwvif_link->pwr_diff_en = true;
break;
}
@@ -1806,17 +2120,17 @@ static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev,
}
}
-static void rtw89_cancel_6ghz_probe_work(struct work_struct *work)
+static void rtw89_cancel_6ghz_probe_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
cancel_6ghz_probe_work);
struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
struct rtw89_pktofld_info *info;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(wiphy);
if (!rtwdev->scanning)
- goto out;
+ return;
list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) {
if (!info->cancel || !test_bit(info->id, rtwdev->pkt_offload))
@@ -1829,9 +2143,6 @@ static void rtw89_cancel_6ghz_probe_work(struct work_struct *work)
* since if during scanning, pkt_list is accessed in bottom half.
*/
}
-
-out:
- mutex_unlock(&rtwdev->mutex);
}
static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev,
@@ -1866,10 +2177,10 @@ static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev,
}
if (queue_work)
- ieee80211_queue_work(rtwdev->hw, &rtwdev->cancel_6ghz_probe_work);
+ wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->cancel_6ghz_probe_work);
}
-static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif *rtwvif,
+static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif_link *rtwvif_link,
struct ieee80211_hdr *hdr, size_t len)
{
struct ieee80211_mgmt *mgmt = (typeof(mgmt))hdr;
@@ -1877,20 +2188,24 @@ static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif *rtwvif,
if (len < offsetof(typeof(*mgmt), u.beacon.variable))
return;
- WRITE_ONCE(rtwvif->sync_bcn_tsf, le64_to_cpu(mgmt->u.beacon.timestamp));
+ WRITE_ONCE(rtwvif_link->sync_bcn_tsf, le64_to_cpu(mgmt->u.beacon.timestamp));
}
static void rtw89_vif_rx_stats_iter(void *data, u8 *mac,
struct ieee80211_vif *vif)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_vif_rx_stats_iter_data *iter_data = data;
struct rtw89_dev *rtwdev = iter_data->rtwdev;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.cur_pkt_stat;
struct rtw89_rx_desc_info *desc_info = iter_data->desc_info;
struct sk_buff *skb = iter_data->skb;
+ struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct rtw89_rx_phy_ppdu *phy_ppdu = iter_data->phy_ppdu;
+ bool is_mld = ieee80211_vif_is_mld(vif);
+ struct ieee80211_bss_conf *bss_conf;
+ struct rtw89_vif_link *rtwvif_link;
const u8 *bssid = iter_data->bssid;
if (rtwdev->scanning &&
@@ -1898,32 +2213,56 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac,
ieee80211_is_probe_resp(hdr->frame_control)))
rtw89_core_cancel_6ghz_probe_tx(rtwdev, skb);
- if (!vif->bss_conf.bssid)
- return;
+ rcu_read_lock();
+
+ rtwvif_link = rtw89_vif_get_link_inst(rtwvif, desc_info->bb_sel);
+ if (unlikely(!rtwvif_link))
+ goto out;
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+ if (!bss_conf->bssid)
+ goto out;
if (ieee80211_is_trigger(hdr->frame_control)) {
- rtw89_stats_trigger_frame(rtwdev, vif, skb);
- return;
+ rtw89_stats_trigger_frame(rtwdev, rtwvif_link, bss_conf, skb);
+ goto out;
}
- if (!ether_addr_equal(vif->bss_conf.bssid, bssid))
- return;
+ if (!ether_addr_equal(bss_conf->bssid, bssid))
+ goto out;
+
+ if (is_mld) {
+ rx_status->link_valid = true;
+ rx_status->link_id = rtwvif_link->link_id;
+ }
if (ieee80211_is_beacon(hdr->frame_control)) {
- if (vif->type == NL80211_IFTYPE_STATION) {
- rtw89_vif_sync_bcn_tsf(rtwvif, hdr, skb->len);
+ if (vif->type == NL80211_IFTYPE_STATION &&
+ !test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags)) {
+ rtw89_vif_sync_bcn_tsf(rtwvif_link, hdr, skb->len);
rtw89_fw_h2c_rssi_offload(rtwdev, phy_ppdu);
}
pkt_stat->beacon_nr++;
+
+ if (phy_ppdu) {
+ ewma_rssi_add(&rtwdev->phystat.bcn_rssi, phy_ppdu->rssi_avg);
+ if (!test_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags))
+ rtwvif_link->bcn_bw_idx = phy_ppdu->bw_idx;
+ }
+
+ pkt_stat->beacon_rate = desc_info->data_rate;
}
- if (!ether_addr_equal(vif->addr, hdr->addr1))
- return;
+ if (!ether_addr_equal(bss_conf->addr, hdr->addr1))
+ goto out;
if (desc_info->data_rate < RTW89_HW_RATE_NR)
pkt_stat->rx_rate_cnt[desc_info->data_rate]++;
rtw89_traffic_stats_accu(rtwdev, &rtwvif->stats, skb, false);
+
+out:
+ rcu_read_unlock();
}
static void rtw89_core_rx_stats(struct rtw89_dev *rtwdev,
@@ -1947,7 +2286,7 @@ static void rtw89_correct_cck_chan(struct rtw89_dev *rtwdev,
struct ieee80211_rx_status *status)
{
const struct rtw89_chan_rcd *rcd =
- rtw89_chan_rcd_get(rtwdev, RTW89_SUB_ENTITY_0);
+ rtw89_chan_rcd_get(rtwdev, RTW89_CHANCTX_0);
u16 chan = rcd->prev_primary_channel;
u8 band = rtw89_hw_to_nl80211_band(rcd->prev_band_type);
@@ -1977,6 +2316,23 @@ static void rtw89_core_hw_to_sband_rate(struct ieee80211_rx_status *rx_status)
rx_status->rate_idx -= 4;
}
+static
+void rtw89_core_update_rx_status_by_ppdu(struct rtw89_dev *rtwdev,
+ struct ieee80211_rx_status *rx_status,
+ struct rtw89_rx_phy_ppdu *phy_ppdu)
+{
+ if (!(rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR))
+ return;
+
+ if (!phy_ppdu)
+ return;
+
+ if (phy_ppdu->ldpc)
+ rx_status->enc_flags |= RX_ENC_FLAG_LDPC;
+ if (phy_ppdu->stbc)
+ rx_status->enc_flags |= u8_encode_bits(1, RX_ENC_FLAG_STBC_MASK);
+}
+
static const u8 rx_status_bw_to_radiotap_eht_usig[] = {
[RATE_INFO_BW_20] = IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_20MHZ,
[RATE_INFO_BW_5] = U8_MAX,
@@ -2020,10 +2376,14 @@ static void rtw89_core_update_radiotap_eht(struct rtw89_dev *rtwdev,
eht->user_info[0] =
cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN |
- IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O);
+ IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O |
+ IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN);
eht->user_info[0] |=
le32_encode_bits(rx_status->rate_idx, IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) |
le32_encode_bits(rx_status->nss, IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O);
+ if (rx_status->enc_flags & RX_ENC_FLAG_LDPC)
+ eht->user_info[0] |=
+ cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_CODING);
/* U-SIG */
tlv = (void *)tlv + sizeof(*tlv) + ALIGN(eht_len, 4);
@@ -2049,6 +2409,8 @@ static void rtw89_core_update_radiotap(struct rtw89_dev *rtwdev,
{
static const struct ieee80211_radiotap_he known_he = {
.data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
+ IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN |
+ IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN |
IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN),
.data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN),
};
@@ -2066,6 +2428,55 @@ static void rtw89_core_update_radiotap(struct rtw89_dev *rtwdev,
}
}
+static void rtw89_core_validate_rx_signal(struct ieee80211_rx_status *rx_status)
+{
+ if (!rx_status->signal)
+ rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
+}
+
+static void rtw89_core_update_rx_freq_from_ie(struct rtw89_dev *rtwdev,
+ struct sk_buff *skb,
+ struct ieee80211_rx_status *rx_status)
+{
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+ size_t hdr_len, ielen;
+ u8 *variable;
+ int chan;
+
+ if (!rtwdev->chip->rx_freq_frome_ie)
+ return;
+
+ if (!rtwdev->scanning)
+ return;
+
+ if (ieee80211_is_beacon(mgmt->frame_control)) {
+ variable = mgmt->u.beacon.variable;
+ hdr_len = offsetof(struct ieee80211_mgmt,
+ u.beacon.variable);
+ } else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
+ variable = mgmt->u.probe_resp.variable;
+ hdr_len = offsetof(struct ieee80211_mgmt,
+ u.probe_resp.variable);
+ } else {
+ return;
+ }
+
+ if (skb->len > hdr_len)
+ ielen = skb->len - hdr_len;
+ else
+ return;
+
+ /* The parsing code for both 2GHz and 5GHz bands is the same in this
+ * function.
+ */
+ chan = cfg80211_get_ies_channel_number(variable, ielen, NL80211_BAND_2GHZ);
+ if (chan == -1)
+ return;
+
+ rx_status->band = chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G;
+ rx_status->freq = ieee80211_channel_to_frequency(chan, rx_status->band);
+}
+
static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu,
struct rtw89_rx_desc_info *desc_info,
@@ -2080,7 +2491,11 @@ static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev,
rtw89_core_hw_to_sband_rate(rx_status);
rtw89_core_rx_stats(rtwdev, phy_ppdu, desc_info, skb_ppdu);
+ rtw89_core_update_rx_status_by_ppdu(rtwdev, rx_status, phy_ppdu);
rtw89_core_update_radiotap(rtwdev, skb_ppdu, rx_status);
+ rtw89_core_validate_rx_signal(rx_status);
+ rtw89_core_update_rx_freq_from_ie(rtwdev, skb_ppdu, rx_status);
+
/* In low power mode, it does RX in thread context. */
local_bh_disable();
ieee80211_rx_napi(rtwdev->hw, NULL, skb_ppdu, napi);
@@ -2119,7 +2534,8 @@ static void rtw89_core_rx_process_ppdu_sts(struct rtw89_dev *rtwdev,
.len = skb->len,
.to_self = desc_info->addr1_match,
.rate = desc_info->data_rate,
- .mac_id = desc_info->mac_id};
+ .mac_id = desc_info->mac_id,
+ .phy_idx = desc_info->bb_sel};
int ret;
if (desc_info->mac_info_valid) {
@@ -2216,6 +2632,7 @@ void rtw89_core_query_rxdesc_v2(struct rtw89_dev *rtwdev,
struct rtw89_rx_desc_info *desc_info,
u8 *data, u32 data_offset)
{
+ struct rtw89_rxdesc_phy_rpt_v2 *rxd_rpt;
struct rtw89_rxdesc_short_v2 *rxd_s;
struct rtw89_rxdesc_long_v2 *rxd_l;
u16 shift_len, drv_info_len, phy_rtp_len, hdr_cnv_len;
@@ -2229,6 +2646,7 @@ void rtw89_core_query_rxdesc_v2(struct rtw89_dev *rtwdev,
desc_info->shift = le32_get_bits(rxd_s->dword0, BE_RXD_SHIFT_MASK);
desc_info->long_rxdesc = le32_get_bits(rxd_s->dword0, BE_RXD_LONG_RXD);
desc_info->pkt_type = le32_get_bits(rxd_s->dword0, BE_RXD_RPKT_TYPE_MASK);
+ desc_info->bb_sel = le32_get_bits(rxd_s->dword0, BE_RXD_BB_SEL);
if (desc_info->pkt_type == RTW89_CORE_RX_TYPE_PPDU_STAT)
desc_info->mac_info_valid = true;
@@ -2263,6 +2681,12 @@ void rtw89_core_query_rxdesc_v2(struct rtw89_dev *rtwdev,
desc_info->rxd_len = sizeof(struct rtw89_rxdesc_short_v2);
desc_info->ready = true;
+ if (phy_rtp_len == sizeof(*rxd_rpt)) {
+ rxd_rpt = (struct rtw89_rxdesc_phy_rpt_v2 *)(data + data_offset +
+ desc_info->rxd_len);
+ desc_info->rssi = le32_get_bits(rxd_rpt->dword0, BE_RXD_PHY_RSSI);
+ }
+
if (!desc_info->long_rxdesc)
return;
@@ -2290,15 +2714,20 @@ void rtw89_core_stats_sta_rx_status_iter(void *data, struct ieee80211_sta *sta)
struct rtw89_core_iter_rx_status *iter_data =
(struct rtw89_core_iter_rx_status *)data;
struct ieee80211_rx_status *rx_status = iter_data->rx_status;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_rx_desc_info *desc_info = iter_data->desc_info;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_sta_link *rtwsta_link;
u8 mac_id = iter_data->mac_id;
- if (mac_id != rtwsta->mac_id)
+ rtwsta_link = rtw89_sta_get_link_inst(rtwsta, desc_info->bb_sel);
+ if (unlikely(!rtwsta_link))
+ return;
+
+ if (mac_id != rtwsta_link->mac_id)
return;
- rtwsta->rx_status = *rx_status;
- rtwsta->rx_hw_rate = desc_info->data_rate;
+ rtwsta_link->rx_status = *rx_status;
+ rtwsta_link->rx_hw_rate = desc_info->data_rate;
}
static void rtw89_core_stats_sta_rx_status(struct rtw89_dev *rtwdev,
@@ -2327,7 +2756,7 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev,
struct ieee80211_rx_status *rx_status)
{
const struct cfg80211_chan_def *chandef =
- rtw89_chandef_get(rtwdev, RTW89_SUB_ENTITY_0);
+ rtw89_chandef_get(rtwdev, RTW89_CHANCTX_0);
u16 data_rate;
u8 data_rate_mode;
bool eht = false;
@@ -2397,6 +2826,7 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev,
rx_status->flag |= RX_FLAG_MACTIME_START;
rx_status->mactime = desc_info->free_run_cnt;
+ rtw89_chip_phy_rpt_to_rssi(rtwdev, desc_info, rx_status);
rtw89_core_stats_sta_rx_status(rtwdev, desc_info, rx_status);
}
@@ -2436,6 +2866,41 @@ static void rtw89_core_flush_ppdu_rx_queue(struct rtw89_dev *rtwdev,
}
}
+static
+void rtw89_core_rx_pkt_hdl(struct rtw89_dev *rtwdev, const struct sk_buff *skb,
+ const struct rtw89_rx_desc_info *desc)
+{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct rtw89_sta_link *rtwsta_link;
+ struct ieee80211_sta *sta;
+ struct rtw89_sta *rtwsta;
+ u8 macid = desc->mac_id;
+
+ if (!refcount_read(&rtwdev->refcount_ap_info))
+ return;
+
+ rcu_read_lock();
+
+ rtwsta_link = rtw89_assoc_link_rcu_dereference(rtwdev, macid);
+ if (!rtwsta_link)
+ goto out;
+
+ rtwsta = rtwsta_link->rtwsta;
+ if (!test_bit(RTW89_REMOTE_STA_IN_PS, rtwsta->flags))
+ goto out;
+
+ sta = rtwsta_to_sta(rtwsta);
+ if (ieee80211_is_pspoll(hdr->frame_control))
+ ieee80211_sta_pspoll(sta);
+ else if (ieee80211_has_pm(hdr->frame_control) &&
+ (ieee80211_is_data_qos(hdr->frame_control) ||
+ ieee80211_is_qos_nullfunc(hdr->frame_control)))
+ ieee80211_sta_uapsd_trigger(sta, ieee80211_get_tid(hdr));
+
+out:
+ rcu_read_unlock();
+}
+
void rtw89_core_rx(struct rtw89_dev *rtwdev,
struct rtw89_rx_desc_info *desc_info,
struct sk_buff *skb)
@@ -2458,6 +2923,7 @@ void rtw89_core_rx(struct rtw89_dev *rtwdev,
rx_status = IEEE80211_SKB_RXCB(skb);
memset(rx_status, 0, sizeof(*rx_status));
rtw89_core_update_rx_status(rtwdev, desc_info, rx_status);
+ rtw89_core_rx_pkt_hdl(rtwdev, skb, desc_info);
if (desc_info->long_rxdesc &&
BIT(desc_info->frame_type) & PPDU_FILTER_BITMAP)
skb_queue_tail(&ppdu_sts->rx_queue[band], skb);
@@ -2485,11 +2951,15 @@ void rtw89_core_napi_stop(struct rtw89_dev *rtwdev)
}
EXPORT_SYMBOL(rtw89_core_napi_stop);
-void rtw89_core_napi_init(struct rtw89_dev *rtwdev)
+int rtw89_core_napi_init(struct rtw89_dev *rtwdev)
{
- init_dummy_netdev(&rtwdev->netdev);
- netif_napi_add(&rtwdev->netdev, &rtwdev->napi,
+ rtwdev->netdev = alloc_netdev_dummy(0);
+ if (!rtwdev->netdev)
+ return -ENOMEM;
+
+ netif_napi_add(rtwdev->netdev, &rtwdev->napi,
rtwdev->hci.ops->napi_poll);
+ return 0;
}
EXPORT_SYMBOL(rtw89_core_napi_init);
@@ -2497,6 +2967,7 @@ void rtw89_core_napi_deinit(struct rtw89_dev *rtwdev)
{
rtw89_core_napi_stop(rtwdev);
netif_napi_del(&rtwdev->napi);
+ free_netdev(rtwdev->netdev);
}
EXPORT_SYMBOL(rtw89_core_napi_deinit);
@@ -2511,7 +2982,7 @@ static void rtw89_core_ba_work(struct work_struct *work)
list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->ba_list, list) {
struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq);
struct ieee80211_sta *sta = txq->sta;
- struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
u8 tid = txq->tid;
if (!sta) {
@@ -2539,8 +3010,8 @@ skip_ba_work:
spin_unlock_bh(&rtwdev->ba_lock);
}
-static void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta)
+void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev,
+ struct ieee80211_sta *sta)
{
struct rtw89_txq *rtwtxq, *tmp;
@@ -2554,8 +3025,8 @@ static void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev,
spin_unlock_bh(&rtwdev->ba_lock);
}
-static void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta)
+void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev,
+ struct ieee80211_sta *sta)
{
struct rtw89_txq *rtwtxq, *tmp;
@@ -2571,10 +3042,10 @@ static void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev,
spin_unlock_bh(&rtwdev->ba_lock);
}
-static void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta)
+void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev,
+ struct ieee80211_sta *sta)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct sk_buff *skb, *tmp;
skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) {
@@ -2615,7 +3086,7 @@ static void rtw89_core_txq_check_agg(struct rtw89_dev *rtwdev,
struct ieee80211_hw *hw = rtwdev->hw;
struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq);
struct ieee80211_sta *sta = txq->sta;
- struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
if (test_bit(RTW89_TXQ_F_FORBID_BA, &rtwtxq->flags))
return;
@@ -2691,10 +3162,19 @@ static bool rtw89_core_txq_agg_wait(struct rtw89_dev *rtwdev,
bool *sched_txq, bool *reinvoke)
{
struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv;
- struct ieee80211_sta *sta = txq->sta;
- struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(txq->sta);
+ struct rtw89_sta_link *rtwsta_link;
+
+ if (!rtwsta)
+ return false;
+
+ rtwsta_link = rtw89_get_designated_link(rtwsta);
+ if (unlikely(!rtwsta_link)) {
+ rtw89_err(rtwdev, "agg wait: find no designated link\n");
+ return false;
+ }
- if (!sta || rtwsta->max_agg_wait <= 0)
+ if (rtwsta_link->max_agg_wait <= 0)
return false;
if (rtwdev->stats.tx_tfc_lv <= RTW89_TFC_MID)
@@ -2708,7 +3188,7 @@ static bool rtw89_core_txq_agg_wait(struct rtw89_dev *rtwdev,
return false;
}
- if (*frame_cnt == 1 && rtwtxq->wait_cnt < rtwsta->max_agg_wait) {
+ if (*frame_cnt == 1 && rtwtxq->wait_cnt < rtwsta_link->max_agg_wait) {
*reinvoke = true;
rtwtxq->wait_cnt++;
return true;
@@ -2732,7 +3212,7 @@ static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinv
ieee80211_txq_schedule_start(hw, ac);
while ((txq = ieee80211_next_txq(hw, ac))) {
rtwtxq = (struct rtw89_txq *)txq->drv_priv;
- rtwvif = (struct rtw89_vif *)txq->vif->drv_priv;
+ rtwvif = vif_to_rtwvif(txq->vif);
if (rtwvif->offchan) {
ieee80211_return_txq(hw, txq, true);
@@ -2759,13 +3239,14 @@ static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinv
ieee80211_txq_schedule_end(hw, ac);
}
-static void rtw89_ips_work(struct work_struct *work)
+static void rtw89_ips_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
ips_work);
- mutex_lock(&rtwdev->mutex);
+
+ lockdep_assert_wiphy(wiphy);
+
rtw89_enter_ips_by_hwflags(rtwdev);
- mutex_unlock(&rtwdev->mutex);
}
static void rtw89_core_txq_work(struct work_struct *w)
@@ -2808,16 +3289,23 @@ static void rtw89_forbid_ba_work(struct work_struct *w)
static void rtw89_core_sta_pending_tx_iter(void *data,
struct ieee80211_sta *sta)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_vif *rtwvif_target = data, *rtwvif = rtwsta->rtwvif;
- struct rtw89_dev *rtwdev = rtwvif->rtwdev;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+ struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct rtw89_vif_link *target = data;
+ struct rtw89_vif_link *rtwvif_link;
struct sk_buff *skb, *tmp;
+ unsigned int link_id;
int qsel, ret;
- if (rtwvif->sub_entity_idx != rtwvif_target->sub_entity_idx)
- return;
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ if (rtwvif_link->chanctx_idx == target->chanctx_idx)
+ goto bottom;
+
+ return;
+bottom:
if (skb_queue_len(&rtwsta->roc_queue) == 0)
return;
@@ -2835,19 +3323,22 @@ static void rtw89_core_sta_pending_tx_iter(void *data,
}
static void rtw89_core_handle_sta_pending_tx(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
ieee80211_iterate_stations_atomic(rtwdev->hw,
rtw89_core_sta_pending_tx_iter,
- rtwvif);
+ rtwvif_link);
}
static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool qos, bool ps)
+ struct rtw89_vif_link *rtwvif_link, bool qos, bool ps)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ int link_id = ieee80211_vif_is_mld(vif) ? rtwvif_link->link_id : -1;
+ struct rtw89_sta_link *rtwsta_link;
struct ieee80211_sta *sta;
struct ieee80211_hdr *hdr;
+ struct rtw89_sta *rtwsta;
struct sk_buff *skb;
int ret, qsel;
@@ -2855,13 +3346,14 @@ static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev,
return 0;
rcu_read_lock();
- sta = ieee80211_find_sta(vif, vif->bss_conf.bssid);
+ sta = ieee80211_find_sta(vif, vif->cfg.ap_addr);
if (!sta) {
ret = -EINVAL;
goto out;
}
+ rtwsta = sta_to_rtwsta(sta);
- skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, qos);
+ skb = ieee80211_nullfunc_get(rtwdev->hw, vif, link_id, qos);
if (!skb) {
ret = -ENOMEM;
goto out;
@@ -2871,7 +3363,13 @@ static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev,
if (ps)
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
- ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel);
+ rtwsta_link = rtwsta->links[rtwvif_link->link_id];
+ if (unlikely(!rtwsta_link)) {
+ ret = -ENOLINK;
+ goto out;
+ }
+
+ ret = rtw89_core_tx_write_link(rtwdev, rtwvif_link, rtwsta_link, skb, &qsel, true);
if (ret) {
rtw89_warn(rtwdev, "nullfunc transmit failed: %d\n", ret);
dev_kfree_skb_any(skb);
@@ -2891,38 +3389,61 @@ out:
void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ struct rtw89_chanctx_pause_parm pause_parm = {
+ .rsn = RTW89_CHANCTX_PAUSE_REASON_ROC,
+ };
struct ieee80211_hw *hw = rtwdev->hw;
struct rtw89_roc *roc = &rtwvif->roc;
+ struct rtw89_vif_link *rtwvif_link;
struct cfg80211_chan_def roc_chan;
- struct rtw89_vif *tmp;
+ struct rtw89_vif *tmp_vif;
+ u32 reg;
int ret;
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
rtw89_leave_ips_by_hwflags(rtwdev);
rtw89_leave_lps(rtwdev);
- rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_ROC);
- ret = rtw89_core_send_nullfunc(rtwdev, rtwvif, true, true);
+ rtwvif_link = rtw89_get_designated_link(rtwvif);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "roc start: find no designated link\n");
+ return;
+ }
+
+ roc->link_id = rtwvif_link->link_id;
+
+ pause_parm.trigger = rtwvif_link;
+ rtw89_chanctx_pause(rtwdev, &pause_parm);
+
+ ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, true);
if (ret)
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
"roc send null-1 failed: %d\n", ret);
- rtw89_for_each_rtwvif(rtwdev, tmp)
- if (tmp->sub_entity_idx == rtwvif->sub_entity_idx)
- tmp->offchan = true;
+ rtw89_for_each_rtwvif(rtwdev, tmp_vif) {
+ struct rtw89_vif_link *tmp_link;
+ unsigned int link_id;
+
+ rtw89_vif_for_each_link(tmp_vif, tmp_link, link_id) {
+ if (tmp_link->chanctx_idx == rtwvif_link->chanctx_idx) {
+ tmp_vif->offchan = true;
+ break;
+ }
+ }
+ }
cfg80211_chandef_create(&roc_chan, &roc->chan, NL80211_CHAN_NO_HT);
- rtw89_config_roc_chandef(rtwdev, rtwvif->sub_entity_idx, &roc_chan);
+ rtw89_config_roc_chandef(rtwdev, rtwvif_link, &roc_chan);
rtw89_set_channel(rtwdev);
- rtw89_write32_clr(rtwdev,
- rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
- B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH);
+
+ reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
+ rtw89_write32_clr(rtwdev, reg, B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH);
ieee80211_ready_on_channel(hw);
- cancel_delayed_work(&rtwvif->roc.roc_work);
- ieee80211_queue_delayed_work(hw, &rtwvif->roc.roc_work,
- msecs_to_jiffies(rtwvif->roc.duration));
+ wiphy_delayed_work_cancel(hw->wiphy, &rtwvif->roc.roc_work);
+ wiphy_delayed_work_queue(hw->wiphy, &rtwvif->roc.roc_work,
+ msecs_to_jiffies(rtwvif->roc.duration));
}
void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
@@ -2930,49 +3451,55 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct ieee80211_hw *hw = rtwdev->hw;
struct rtw89_roc *roc = &rtwvif->roc;
- struct rtw89_vif *tmp;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_vif *tmp_vif;
+ u32 reg;
int ret;
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
ieee80211_remain_on_channel_expired(hw);
rtw89_leave_ips_by_hwflags(rtwdev);
rtw89_leave_lps(rtwdev);
- rtw89_write32_mask(rtwdev,
- rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
- B_AX_RX_FLTR_CFG_MASK,
- rtwdev->hal.rx_fltr);
+ rtwvif_link = rtwvif->links[roc->link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "roc end: find no link (link id %u)\n",
+ roc->link_id);
+ return;
+ }
+
+ reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
+ rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rtwdev->hal.rx_fltr);
roc->state = RTW89_ROC_IDLE;
- rtw89_config_roc_chandef(rtwdev, rtwvif->sub_entity_idx, NULL);
- rtw89_chanctx_proceed(rtwdev);
- ret = rtw89_core_send_nullfunc(rtwdev, rtwvif, true, false);
+ rtw89_config_roc_chandef(rtwdev, rtwvif_link, NULL);
+ rtw89_chanctx_proceed(rtwdev, NULL);
+ ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, false);
if (ret)
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
"roc send null-0 failed: %d\n", ret);
- rtw89_for_each_rtwvif(rtwdev, tmp)
- if (tmp->sub_entity_idx == rtwvif->sub_entity_idx)
- tmp->offchan = false;
+ rtw89_for_each_rtwvif(rtwdev, tmp_vif)
+ tmp_vif->offchan = false;
- rtw89_core_handle_sta_pending_tx(rtwdev, rtwvif);
+ rtw89_core_handle_sta_pending_tx(rtwdev, rtwvif_link);
queue_work(rtwdev->txq_wq, &rtwdev->txq_work);
if (hw->conf.flags & IEEE80211_CONF_IDLE)
- ieee80211_queue_delayed_work(hw, &roc->roc_work,
- msecs_to_jiffies(RTW89_ROC_IDLE_TIMEOUT));
+ wiphy_delayed_work_queue(hw->wiphy, &roc->roc_work,
+ msecs_to_jiffies(RTW89_ROC_IDLE_TIMEOUT));
}
-void rtw89_roc_work(struct work_struct *work)
+void rtw89_roc_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif,
roc.roc_work.work);
struct rtw89_dev *rtwdev = rtwvif->rtwdev;
struct rtw89_roc *roc = &rtwvif->roc;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(wiphy);
switch (roc->state) {
case RTW89_ROC_IDLE:
@@ -2985,8 +3512,6 @@ void rtw89_roc_work(struct work_struct *work)
default:
break;
}
-
- mutex_unlock(&rtwdev->mutex);
}
static enum rtw89_tfc_lv rtw89_get_traffic_level(struct rtw89_dev *rtwdev,
@@ -3041,39 +3566,46 @@ static bool rtw89_traffic_stats_calc(struct rtw89_dev *rtwdev,
static bool rtw89_traffic_stats_track(struct rtw89_dev *rtwdev)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
bool tfc_changed;
tfc_changed = rtw89_traffic_stats_calc(rtwdev, &rtwdev->stats);
+
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
rtw89_traffic_stats_calc(rtwdev, &rtwvif->stats);
- rtw89_fw_h2c_tp_offload(rtwdev, rtwvif);
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_fw_h2c_tp_offload(rtwdev, rtwvif_link);
}
return tfc_changed;
}
-static void rtw89_vif_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev)
{
- if ((rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION &&
- rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) ||
- rtwvif->tdls_peer)
- return;
+ struct ieee80211_vif *vif;
+ struct rtw89_vif *rtwvif;
- if (rtwvif->offchan)
- return;
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+ if (rtwvif->tdls_peer)
+ continue;
+ if (rtwvif->offchan)
+ continue;
- if (rtwvif->stats.tx_tfc_lv == RTW89_TFC_IDLE &&
- rtwvif->stats.rx_tfc_lv == RTW89_TFC_IDLE)
- rtw89_enter_lps(rtwdev, rtwvif, true);
-}
+ if (rtwvif->stats.tx_tfc_lv != RTW89_TFC_IDLE ||
+ rtwvif->stats.rx_tfc_lv != RTW89_TFC_IDLE)
+ continue;
-static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev)
-{
- struct rtw89_vif *rtwvif;
+ vif = rtwvif_to_vif(rtwvif);
+
+ if (!(vif->type == NL80211_IFTYPE_STATION ||
+ vif->type == NL80211_IFTYPE_P2P_CLIENT))
+ continue;
- rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_vif_enter_lps(rtwdev, rtwvif);
+ rtw89_enter_lps(rtwdev, rtwvif, true);
+ }
}
static void rtw89_core_rfk_track(struct rtw89_dev *rtwdev)
@@ -3087,14 +3619,16 @@ static void rtw89_core_rfk_track(struct rtw89_dev *rtwdev)
rtw89_chip_rfk_track(rtwdev);
}
-void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
+void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf)
{
enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev);
if (mode == RTW89_ENTITY_MODE_MCC)
rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_P2P_PS_CHANGE);
else
- rtw89_process_p2p_ps(rtwdev, vif);
+ rtw89_process_p2p_ps(rtwdev, rtwvif_link, bss_conf);
}
void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev,
@@ -3108,26 +3642,118 @@ void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev,
ewma_tp_init(&stats->rx_ewma_tp);
}
-static void rtw89_track_work(struct work_struct *work)
+#define RTW89_MLSR_GOTO_2GHZ_THRESHOLD -53
+#define RTW89_MLSR_EXIT_2GHZ_THRESHOLD -38
+static void rtw89_core_mlsr_link_decision(struct rtw89_dev *rtwdev,
+ struct rtw89_vif *rtwvif)
+{
+ unsigned int sel_link_id = IEEE80211_MLD_MAX_NUM_LINKS;
+ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct rtw89_vif_link *rtwvif_link;
+ const struct rtw89_chan *chan;
+ unsigned long usable_links;
+ unsigned int link_id;
+ u8 decided_bands;
+ u8 rssi;
+
+ rssi = ewma_rssi_read(&rtwdev->phystat.bcn_rssi);
+ if (unlikely(!rssi))
+ return;
+
+ if (RTW89_RSSI_RAW_TO_DBM(rssi) >= RTW89_MLSR_EXIT_2GHZ_THRESHOLD)
+ decided_bands = BIT(RTW89_BAND_5G) | BIT(RTW89_BAND_6G);
+ else if (RTW89_RSSI_RAW_TO_DBM(rssi) <= RTW89_MLSR_GOTO_2GHZ_THRESHOLD)
+ decided_bands = BIT(RTW89_BAND_2G);
+ else
+ return;
+
+ usable_links = ieee80211_vif_usable_links(vif);
+
+ rtwvif_link = rtw89_get_designated_link(rtwvif);
+ if (unlikely(!rtwvif_link))
+ goto select;
+
+ chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
+ if (decided_bands & BIT(chan->band_type))
+ return;
+
+ usable_links &= ~BIT(rtwvif_link->link_id);
+
+select:
+ rcu_read_lock();
+
+ for_each_set_bit(link_id, &usable_links, IEEE80211_MLD_MAX_NUM_LINKS) {
+ struct ieee80211_bss_conf *link_conf;
+ struct ieee80211_channel *channel;
+ enum rtw89_band band;
+
+ link_conf = rcu_dereference(vif->link_conf[link_id]);
+ if (unlikely(!link_conf))
+ continue;
+
+ channel = link_conf->chanreq.oper.chan;
+ if (unlikely(!channel))
+ continue;
+
+ band = rtw89_nl80211_to_hw_band(channel->band);
+ if (decided_bands & BIT(band)) {
+ sel_link_id = link_id;
+ break;
+ }
+ }
+
+ rcu_read_unlock();
+
+ if (sel_link_id == IEEE80211_MLD_MAX_NUM_LINKS)
+ return;
+
+ rtw89_core_mlsr_switch(rtwdev, rtwvif, sel_link_id);
+}
+
+static void rtw89_core_mlo_track(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ struct ieee80211_vif *vif;
+ struct rtw89_vif *rtwvif;
+
+ if (hal->disabled_dm_bitmap & BIT(RTW89_DM_MLO))
+ return;
+
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+ vif = rtwvif_to_vif(rtwvif);
+ if (!vif->cfg.assoc || !ieee80211_vif_is_mld(vif))
+ continue;
+
+ switch (rtwvif->mlo_mode) {
+ case RTW89_MLO_MODE_MLSR:
+ rtw89_core_mlsr_link_decision(rtwdev, rtwvif);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void rtw89_track_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
track_work.work);
bool tfc_changed;
+ lockdep_assert_wiphy(wiphy);
+
if (test_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags))
return;
- mutex_lock(&rtwdev->mutex);
-
if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
- goto out;
+ return;
- ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work,
- RTW89_TRACK_WORK_PERIOD);
+ wiphy_delayed_work_queue(wiphy, &rtwdev->track_work,
+ RTW89_TRACK_WORK_PERIOD);
tfc_changed = rtw89_traffic_stats_track(rtwdev);
if (rtwdev->scanning)
- goto out;
+ return;
rtw89_leave_lps(rtwdev);
@@ -3146,14 +3772,13 @@ static void rtw89_track_work(struct work_struct *work)
rtw89_phy_antdiv_track(rtwdev);
rtw89_phy_ul_tb_ctrl_track(rtwdev);
rtw89_phy_edcca_track(rtwdev);
- rtw89_tas_track(rtwdev);
+ rtw89_sar_track(rtwdev);
rtw89_chanctx_track(rtwdev);
+ rtw89_core_rfkill_poll(rtwdev, false);
+ rtw89_core_mlo_track(rtwdev);
if (rtwdev->lps_enabled && !rtwdev->btc.lps)
rtw89_enter_lps_track(rtwdev);
-
-out:
- mutex_unlock(&rtwdev->mutex);
}
u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size)
@@ -3178,7 +3803,8 @@ void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits)
}
int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx)
+ struct rtw89_sta_link *rtwsta_link, u8 tid,
+ u8 *cam_idx)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
@@ -3186,7 +3812,7 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
u8 idx;
int i;
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
idx = rtw89_core_acquire_bit_map(cam_info->ba_cam_map, chip->bacam_num);
if (idx == chip->bacam_num) {
@@ -3215,7 +3841,7 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
}
entry->tid = tid;
- list_add_tail(&entry->list, &rtwsta->ba_cam_list);
+ list_add_tail(&entry->list, &rtwsta_link->ba_cam_list);
*cam_idx = idx;
@@ -3223,15 +3849,16 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
}
int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx)
+ struct rtw89_sta_link *rtwsta_link, u8 tid,
+ u8 *cam_idx)
{
struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
struct rtw89_ba_cam_entry *entry = NULL, *tmp;
u8 idx;
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
- list_for_each_entry_safe(entry, tmp, &rtwsta->ba_cam_list, list) {
+ list_for_each_entry_safe(entry, tmp, &rtwsta_link->ba_cam_list, list) {
if (entry->tid != tid)
continue;
@@ -3248,24 +3875,25 @@ int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
#define RTW89_TYPE_MAPPING(_type) \
case NL80211_IFTYPE_ ## _type: \
- rtwvif->wifi_role = RTW89_WIFI_ROLE_ ## _type; \
+ rtwvif_link->wifi_role = RTW89_WIFI_ROLE_ ## _type; \
break
-void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc)
+void rtw89_vif_type_mapping(struct rtw89_vif_link *rtwvif_link, bool assoc)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct ieee80211_bss_conf *bss_conf;
switch (vif->type) {
case NL80211_IFTYPE_STATION:
if (vif->p2p)
- rtwvif->wifi_role = RTW89_WIFI_ROLE_P2P_CLIENT;
+ rtwvif_link->wifi_role = RTW89_WIFI_ROLE_P2P_CLIENT;
else
- rtwvif->wifi_role = RTW89_WIFI_ROLE_STATION;
+ rtwvif_link->wifi_role = RTW89_WIFI_ROLE_STATION;
break;
case NL80211_IFTYPE_AP:
if (vif->p2p)
- rtwvif->wifi_role = RTW89_WIFI_ROLE_P2P_GO;
+ rtwvif_link->wifi_role = RTW89_WIFI_ROLE_P2P_GO;
else
- rtwvif->wifi_role = RTW89_WIFI_ROLE_AP;
+ rtwvif_link->wifi_role = RTW89_WIFI_ROLE_AP;
break;
RTW89_TYPE_MAPPING(ADHOC);
RTW89_TYPE_MAPPING(MONITOR);
@@ -3278,23 +3906,27 @@ void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc)
switch (vif->type) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_MESH_POINT:
- rtwvif->net_type = RTW89_NET_TYPE_AP_MODE;
- rtwvif->self_role = RTW89_SELF_ROLE_AP;
+ rtwvif_link->net_type = RTW89_NET_TYPE_AP_MODE;
+ rtwvif_link->self_role = RTW89_SELF_ROLE_AP;
break;
case NL80211_IFTYPE_ADHOC:
- rtwvif->net_type = RTW89_NET_TYPE_AD_HOC;
- rtwvif->self_role = RTW89_SELF_ROLE_CLIENT;
+ rtwvif_link->net_type = RTW89_NET_TYPE_AD_HOC;
+ rtwvif_link->self_role = RTW89_SELF_ROLE_CLIENT;
break;
case NL80211_IFTYPE_STATION:
if (assoc) {
- rtwvif->net_type = RTW89_NET_TYPE_INFRA;
- rtwvif->trigger = vif->bss_conf.he_support;
+ rtwvif_link->net_type = RTW89_NET_TYPE_INFRA;
+
+ rcu_read_lock();
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+ rtwvif_link->trigger = bss_conf->he_support;
+ rcu_read_unlock();
} else {
- rtwvif->net_type = RTW89_NET_TYPE_NO_LINK;
- rtwvif->trigger = false;
+ rtwvif_link->net_type = RTW89_NET_TYPE_NO_LINK;
+ rtwvif_link->trigger = false;
}
- rtwvif->self_role = RTW89_SELF_ROLE_CLIENT;
- rtwvif->addr_cam.sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL;
+ rtwvif_link->self_role = RTW89_SELF_ROLE_CLIENT;
+ rtwvif_link->addr_cam.sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL;
break;
case NL80211_IFTYPE_MONITOR:
break;
@@ -3304,133 +3936,115 @@ void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc)
}
}
-int rtw89_core_sta_add(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+int rtw89_core_sta_link_add(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
struct rtw89_hal *hal = &rtwdev->hal;
u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num;
int i;
int ret;
- rtwsta->rtwdev = rtwdev;
- rtwsta->rtwvif = rtwvif;
- rtwsta->prev_rssi = 0;
- INIT_LIST_HEAD(&rtwsta->ba_cam_list);
- skb_queue_head_init(&rtwsta->roc_queue);
-
- for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
- rtw89_core_txq_init(rtwdev, sta->txq[i]);
-
- ewma_rssi_init(&rtwsta->avg_rssi);
- ewma_snr_init(&rtwsta->avg_snr);
+ rtwsta_link->prev_rssi = 0;
+ INIT_LIST_HEAD(&rtwsta_link->ba_cam_list);
+ ewma_rssi_init(&rtwsta_link->avg_rssi);
+ ewma_snr_init(&rtwsta_link->avg_snr);
+ ewma_evm_init(&rtwsta_link->evm_1ss);
for (i = 0; i < ant_num; i++) {
- ewma_rssi_init(&rtwsta->rssi[i]);
- ewma_evm_init(&rtwsta->evm_min[i]);
- ewma_evm_init(&rtwsta->evm_max[i]);
+ ewma_rssi_init(&rtwsta_link->rssi[i]);
+ ewma_evm_init(&rtwsta_link->evm_min[i]);
+ ewma_evm_init(&rtwsta_link->evm_max[i]);
}
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
- /* for station mode, assign the mac_id from itself */
- rtwsta->mac_id = rtwvif->mac_id;
- /* must do rtw89_reg_6ghz_power_recalc() before rfk channel */
- rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif, true);
- rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta,
+ /* must do rtw89_reg_6ghz_recalc() before rfk channel */
+ ret = rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true);
+ if (ret)
+ return ret;
+
+ rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link,
BTC_ROLE_MSTS_STA_CONN_START);
- rtw89_chip_rfk_channel(rtwdev);
+ rtw89_chip_rfk_channel(rtwdev, rtwvif_link);
} else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
- rtwsta->mac_id = rtw89_core_acquire_bit_map(rtwdev->mac_id_map,
- RTW89_MAX_MAC_ID_NUM);
- if (rtwsta->mac_id == RTW89_MAX_MAC_ID_NUM)
- return -ENOSPC;
-
- ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta->mac_id, false);
+ ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta_link->mac_id, false);
if (ret) {
- rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwsta->mac_id);
rtw89_warn(rtwdev, "failed to send h2c macid pause\n");
return ret;
}
- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta,
+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link,
RTW89_ROLE_CREATE);
if (ret) {
- rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwsta->mac_id);
rtw89_warn(rtwdev, "failed to send h2c role info\n");
return ret;
}
- ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif, rtwsta);
+ ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
if (ret)
return ret;
- ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif, rtwsta);
+ ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
if (ret)
return ret;
-
- rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE);
}
return 0;
}
-int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+int rtw89_core_sta_link_disassoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+
+ rtw89_assoc_link_clr(rtwsta_link);
if (vif->type == NL80211_IFTYPE_STATION)
- rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, false);
+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, false);
- rtwdev->total_sta_assoc--;
- if (sta->tdls)
- rtwvif->tdls_peer--;
- rtwsta->disassoc = true;
+ if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)
+ rtw89_p2p_noa_once_deinit(rtwvif_link);
return 0;
}
-int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+int rtw89_core_sta_link_disconnect(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
int ret;
- rtw89_mac_bf_monitor_calc(rtwdev, sta, true);
- rtw89_mac_bf_disassoc(rtwdev, vif, sta);
- rtw89_core_free_sta_pending_ba(rtwdev, sta);
- rtw89_core_free_sta_pending_forbid_ba(rtwdev, sta);
- rtw89_core_free_sta_pending_roc_tx(rtwdev, sta);
+ rtw89_mac_bf_monitor_calc(rtwdev, rtwsta_link, true);
+ rtw89_mac_bf_disassoc(rtwdev, rtwvif_link, rtwsta_link);
if (vif->type == NL80211_IFTYPE_AP || sta->tdls)
- rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam);
+ rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta_link->addr_cam);
if (sta->tdls)
- rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta->bssid_cam);
+ rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta_link->bssid_cam);
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
- rtw89_vif_type_mapping(vif, false);
- rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, true);
+ rtw89_vif_type_mapping(rtwvif_link, false);
+ rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link, true);
}
- ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, sta);
+ ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cmac table\n");
return ret;
}
- ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, true);
+ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta_link, true);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c join info\n");
return ret;
}
/* update cam aid mac_id net_type */
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cam\n");
return ret;
@@ -3439,106 +4053,129 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
return ret;
}
-int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+static bool rtw89_sta_link_can_er(struct rtw89_dev *rtwdev,
+ struct ieee80211_bss_conf *bss_conf,
+ struct ieee80211_link_sta *link_sta)
+{
+ if (!bss_conf->he_support ||
+ bss_conf->he_oper.params & IEEE80211_HE_OPERATION_ER_SU_DISABLE)
+ return false;
+
+ if (rtwdev->chip->chip_id == RTL8852C &&
+ rtw89_sta_link_has_su_mu_4xhe08(link_sta) &&
+ !rtw89_sta_link_has_er_su_4xhe08(link_sta))
+ return false;
+
+ return true;
+}
+
+int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif, rtwsta);
+ const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
+ struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link,
+ rtwsta_link);
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->sub_entity_idx);
+ rtwvif_link->chanctx_idx);
+ struct ieee80211_link_sta *link_sta;
int ret;
if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
if (sta->tdls) {
- ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif, bssid_cam, sta->addr);
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif_link, bssid_cam,
+ link_sta->addr);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c init bssid cam for TDLS\n");
+ rcu_read_unlock();
return ret;
}
+
+ rcu_read_unlock();
}
- ret = rtw89_cam_init_addr_cam(rtwdev, &rtwsta->addr_cam, bssid_cam);
+ ret = rtw89_cam_init_addr_cam(rtwdev, &rtwsta_link->addr_cam, bssid_cam);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c init addr cam\n");
return ret;
}
}
- ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, sta);
+ ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cmac table\n");
return ret;
}
- ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, false);
+ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta_link, false);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c join info\n");
return ret;
}
/* update cam aid mac_id net_type */
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cam\n");
return ret;
}
- rtwdev->total_sta_assoc++;
- if (sta->tdls)
- rtwvif->tdls_peer++;
- rtw89_phy_ra_assoc(rtwdev, sta);
- rtw89_mac_bf_assoc(rtwdev, vif, sta);
- rtw89_mac_bf_monitor_calc(rtwdev, sta, false);
+ rtw89_phy_ra_assoc(rtwdev, rtwsta_link);
+ rtw89_mac_bf_assoc(rtwdev, rtwvif_link, rtwsta_link);
+ rtw89_mac_bf_monitor_calc(rtwdev, rtwsta_link, false);
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+ struct ieee80211_bss_conf *bss_conf;
+
+ rcu_read_lock();
- if (bss_conf->he_support &&
- !(bss_conf->he_oper.params & IEEE80211_HE_OPERATION_ER_SU_DISABLE))
- rtwsta->er_cap = true;
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ rtwsta_link->er_cap = rtw89_sta_link_can_er(rtwdev, bss_conf, link_sta);
- rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta,
+ rcu_read_unlock();
+
+ rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link,
BTC_ROLE_MSTS_STA_CONN_END);
- rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template, chan);
- rtw89_phy_ul_tb_assoc(rtwdev, rtwvif);
+ rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta_link->htc_template, chan);
+ rtw89_phy_ul_tb_assoc(rtwdev, rtwvif_link);
- ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id);
+ ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta_link->mac_id);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c general packet\n");
return ret;
}
- rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true);
+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
}
+ rtw89_assoc_link_set(rtwsta_link);
return ret;
}
-int rtw89_core_sta_remove(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+int rtw89_core_sta_link_remove(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ const struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
int ret;
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
- rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif, false);
- rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta,
+ rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, false);
+ rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link,
BTC_ROLE_MSTS_STA_DIS_CONN);
} else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
- rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwsta->mac_id);
-
- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta,
+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link,
RTW89_ROLE_REMOVE);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c role info\n");
return ret;
}
-
- rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE);
}
return 0;
@@ -3800,13 +4437,17 @@ static void rtw89_init_eht_cap(struct rtw89_dev *rtwdev,
struct ieee80211_eht_mcs_nss_supp *eht_nss;
struct ieee80211_sta_eht_cap *eht_cap;
struct rtw89_hal *hal = &rtwdev->hal;
+ bool support_mcs_12_13 = true;
bool support_320mhz = false;
+ u8 val, val_mcs13;
int sts = 8;
- u8 val;
if (chip->chip_gen == RTW89_CHIP_AX)
return;
+ if (hal->no_mcs_12_13)
+ support_mcs_12_13 = false;
+
if (band == NL80211_BAND_6GHZ &&
chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_320))
support_320mhz = true;
@@ -3864,32 +4505,35 @@ static void rtw89_init_eht_cap(struct rtw89_dev *rtwdev,
val = u8_encode_bits(hal->rx_nss, IEEE80211_EHT_MCS_NSS_RX) |
u8_encode_bits(hal->tx_nss, IEEE80211_EHT_MCS_NSS_TX);
+ val_mcs13 = support_mcs_12_13 ? val : 0;
+
eht_nss->bw._80.rx_tx_mcs9_max_nss = val;
eht_nss->bw._80.rx_tx_mcs11_max_nss = val;
- eht_nss->bw._80.rx_tx_mcs13_max_nss = val;
+ eht_nss->bw._80.rx_tx_mcs13_max_nss = val_mcs13;
eht_nss->bw._160.rx_tx_mcs9_max_nss = val;
eht_nss->bw._160.rx_tx_mcs11_max_nss = val;
- eht_nss->bw._160.rx_tx_mcs13_max_nss = val;
+ eht_nss->bw._160.rx_tx_mcs13_max_nss = val_mcs13;
if (support_320mhz) {
eht_nss->bw._320.rx_tx_mcs9_max_nss = val;
eht_nss->bw._320.rx_tx_mcs11_max_nss = val;
- eht_nss->bw._320.rx_tx_mcs13_max_nss = val;
+ eht_nss->bw._320.rx_tx_mcs13_max_nss = val_mcs13;
}
}
#define RTW89_SBAND_IFTYPES_NR 2
-static void rtw89_init_he_eht_cap(struct rtw89_dev *rtwdev,
- enum nl80211_band band,
- struct ieee80211_supported_band *sband)
+static int rtw89_init_he_eht_cap(struct rtw89_dev *rtwdev,
+ enum nl80211_band band,
+ struct ieee80211_supported_band *sband)
{
struct ieee80211_sband_iftype_data *iftype_data;
enum nl80211_iftype iftype;
int idx = 0;
- iftype_data = kcalloc(RTW89_SBAND_IFTYPES_NR, sizeof(*iftype_data), GFP_KERNEL);
+ iftype_data = devm_kcalloc(rtwdev->dev, RTW89_SBAND_IFTYPES_NR,
+ sizeof(*iftype_data), GFP_KERNEL);
if (!iftype_data)
- return;
+ return -ENOMEM;
for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) {
switch (iftype) {
@@ -3914,116 +4558,115 @@ static void rtw89_init_he_eht_cap(struct rtw89_dev *rtwdev,
}
_ieee80211_set_sband_iftype_data(sband, iftype_data, idx);
+ return 0;
+}
+
+static struct ieee80211_supported_band *
+rtw89_core_sband_dup(struct rtw89_dev *rtwdev,
+ const struct ieee80211_supported_band *sband)
+{
+ struct ieee80211_supported_band *dup;
+
+ dup = devm_kmemdup(rtwdev->dev, sband, sizeof(*sband), GFP_KERNEL);
+ if (!dup)
+ return NULL;
+
+ dup->channels = devm_kmemdup(rtwdev->dev, sband->channels,
+ sizeof(*sband->channels) * sband->n_channels,
+ GFP_KERNEL);
+ if (!dup->channels)
+ return NULL;
+
+ dup->bitrates = devm_kmemdup(rtwdev->dev, sband->bitrates,
+ sizeof(*sband->bitrates) * sband->n_bitrates,
+ GFP_KERNEL);
+ if (!dup->bitrates)
+ return NULL;
+
+ return dup;
}
static int rtw89_core_set_supported_band(struct rtw89_dev *rtwdev)
{
struct ieee80211_hw *hw = rtwdev->hw;
- struct ieee80211_supported_band *sband_2ghz = NULL, *sband_5ghz = NULL;
- struct ieee80211_supported_band *sband_6ghz = NULL;
- u32 size = sizeof(struct ieee80211_supported_band);
+ struct ieee80211_supported_band *sband;
u8 support_bands = rtwdev->chip->support_bands;
+ int ret;
if (support_bands & BIT(NL80211_BAND_2GHZ)) {
- sband_2ghz = kmemdup(&rtw89_sband_2ghz, size, GFP_KERNEL);
- if (!sband_2ghz)
- goto err;
- rtw89_init_ht_cap(rtwdev, &sband_2ghz->ht_cap);
- rtw89_init_he_eht_cap(rtwdev, NL80211_BAND_2GHZ, sband_2ghz);
- hw->wiphy->bands[NL80211_BAND_2GHZ] = sband_2ghz;
+ sband = rtw89_core_sband_dup(rtwdev, &rtw89_sband_2ghz);
+ if (!sband)
+ return -ENOMEM;
+ rtw89_init_ht_cap(rtwdev, &sband->ht_cap);
+ ret = rtw89_init_he_eht_cap(rtwdev, NL80211_BAND_2GHZ, sband);
+ if (ret)
+ return ret;
+ hw->wiphy->bands[NL80211_BAND_2GHZ] = sband;
}
if (support_bands & BIT(NL80211_BAND_5GHZ)) {
- sband_5ghz = kmemdup(&rtw89_sband_5ghz, size, GFP_KERNEL);
- if (!sband_5ghz)
- goto err;
- rtw89_init_ht_cap(rtwdev, &sband_5ghz->ht_cap);
- rtw89_init_vht_cap(rtwdev, &sband_5ghz->vht_cap);
- rtw89_init_he_eht_cap(rtwdev, NL80211_BAND_5GHZ, sband_5ghz);
- hw->wiphy->bands[NL80211_BAND_5GHZ] = sband_5ghz;
+ sband = rtw89_core_sband_dup(rtwdev, &rtw89_sband_5ghz);
+ if (!sband)
+ return -ENOMEM;
+ rtw89_init_ht_cap(rtwdev, &sband->ht_cap);
+ rtw89_init_vht_cap(rtwdev, &sband->vht_cap);
+ ret = rtw89_init_he_eht_cap(rtwdev, NL80211_BAND_5GHZ, sband);
+ if (ret)
+ return ret;
+ hw->wiphy->bands[NL80211_BAND_5GHZ] = sband;
}
if (support_bands & BIT(NL80211_BAND_6GHZ)) {
- sband_6ghz = kmemdup(&rtw89_sband_6ghz, size, GFP_KERNEL);
- if (!sband_6ghz)
- goto err;
- rtw89_init_he_eht_cap(rtwdev, NL80211_BAND_6GHZ, sband_6ghz);
- hw->wiphy->bands[NL80211_BAND_6GHZ] = sband_6ghz;
+ sband = rtw89_core_sband_dup(rtwdev, &rtw89_sband_6ghz);
+ if (!sband)
+ return -ENOMEM;
+ ret = rtw89_init_he_eht_cap(rtwdev, NL80211_BAND_6GHZ, sband);
+ if (ret)
+ return ret;
+ hw->wiphy->bands[NL80211_BAND_6GHZ] = sband;
}
return 0;
-
-err:
- hw->wiphy->bands[NL80211_BAND_2GHZ] = NULL;
- hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL;
- hw->wiphy->bands[NL80211_BAND_6GHZ] = NULL;
- if (sband_2ghz)
- kfree((__force void *)sband_2ghz->iftype_data);
- if (sband_5ghz)
- kfree((__force void *)sband_5ghz->iftype_data);
- if (sband_6ghz)
- kfree((__force void *)sband_6ghz->iftype_data);
- kfree(sband_2ghz);
- kfree(sband_5ghz);
- kfree(sband_6ghz);
- return -ENOMEM;
-}
-
-static void rtw89_core_clr_supported_band(struct rtw89_dev *rtwdev)
-{
- struct ieee80211_hw *hw = rtwdev->hw;
-
- if (hw->wiphy->bands[NL80211_BAND_2GHZ])
- kfree((__force void *)hw->wiphy->bands[NL80211_BAND_2GHZ]->iftype_data);
- if (hw->wiphy->bands[NL80211_BAND_5GHZ])
- kfree((__force void *)hw->wiphy->bands[NL80211_BAND_5GHZ]->iftype_data);
- if (hw->wiphy->bands[NL80211_BAND_6GHZ])
- kfree((__force void *)hw->wiphy->bands[NL80211_BAND_6GHZ]->iftype_data);
- kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]);
- kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]);
- kfree(hw->wiphy->bands[NL80211_BAND_6GHZ]);
- hw->wiphy->bands[NL80211_BAND_2GHZ] = NULL;
- hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL;
- hw->wiphy->bands[NL80211_BAND_6GHZ] = NULL;
}
static void rtw89_core_ppdu_sts_init(struct rtw89_dev *rtwdev)
{
int i;
- for (i = 0; i < RTW89_PHY_MAX; i++)
+ for (i = 0; i < RTW89_PHY_NUM; i++)
skb_queue_head_init(&rtwdev->ppdu_sts.rx_queue[i]);
- for (i = 0; i < RTW89_PHY_MAX; i++)
+ for (i = 0; i < RTW89_PHY_NUM; i++)
rtwdev->ppdu_sts.curr_rx_ppdu_cnt[i] = U8_MAX;
}
-void rtw89_core_update_beacon_work(struct work_struct *work)
+void rtw89_core_update_beacon_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev;
- struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif,
- update_beacon_work);
+ struct rtw89_vif_link *rtwvif_link = container_of(work, struct rtw89_vif_link,
+ update_beacon_work);
+
+ lockdep_assert_wiphy(wiphy);
- if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE)
+ if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE)
return;
- rtwdev = rtwvif->rtwdev;
- mutex_lock(&rtwdev->mutex);
- rtw89_chip_h2c_update_beacon(rtwdev, rtwvif);
- mutex_unlock(&rtwdev->mutex);
+ rtwdev = rtwvif_link->rtwvif->rtwdev;
+
+ rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link);
}
int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond)
{
struct completion *cmpl = &wait->completion;
- unsigned long timeout;
+ unsigned long time_left;
unsigned int cur;
cur = atomic_cmpxchg(&wait->cond, RTW89_WAIT_COND_IDLE, cond);
if (cur != RTW89_WAIT_COND_IDLE)
return -EBUSY;
- timeout = wait_for_completion_timeout(cmpl, RTW89_WAIT_FOR_COND_TIMEOUT);
- if (timeout == 0) {
+ time_left = wait_for_completion_timeout(cmpl, RTW89_WAIT_FOR_COND_TIMEOUT);
+ if (time_left == 0) {
atomic_set(&wait->cond, RTW89_WAIT_COND_IDLE);
return -ETIMEDOUT;
}
@@ -4069,6 +4712,24 @@ void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, enum rtw89_btc_hmsg eve
}
}
+void rtw89_check_quirks(struct rtw89_dev *rtwdev, const struct dmi_system_id *quirks)
+{
+ const struct dmi_system_id *match;
+ enum rtw89_quirks quirk;
+
+ if (!quirks)
+ return;
+
+ for (match = dmi_first_match(quirks); match; match = dmi_first_match(match + 1)) {
+ quirk = (uintptr_t)match->driver_data;
+ if (quirk >= NUM_OF_RTW89_QUIRKS)
+ continue;
+
+ set_bit(quirk, rtwdev->quirks);
+ }
+}
+EXPORT_SYMBOL(rtw89_check_quirks);
+
int rtw89_core_start(struct rtw89_dev *rtwdev)
{
int ret;
@@ -4096,10 +4757,9 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
rtw89_phy_dm_init(rtwdev);
- rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true);
- rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0);
-
- rtw89_tas_reset(rtwdev);
+ rtw89_mac_cfg_ppdu_status_bands(rtwdev, true);
+ rtw89_mac_cfg_phy_rpt_bands(rtwdev, true);
+ rtw89_mac_update_rts_threshold(rtwdev);
ret = rtw89_hci_start(rtwdev);
if (ret) {
@@ -4107,8 +4767,8 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
return ret;
}
- ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work,
- RTW89_TRACK_WORK_PERIOD);
+ wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->track_work,
+ RTW89_TRACK_WORK_PERIOD);
set_bit(RTW89_FLAG_RUNNING, rtwdev->flags);
@@ -4122,8 +4782,11 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
void rtw89_core_stop(struct rtw89_dev *rtwdev)
{
+ struct wiphy *wiphy = rtwdev->hw->wiphy;
struct rtw89_btc *btc = &rtwdev->btc;
+ lockdep_assert_wiphy(wiphy);
+
/* Prvent to stop twice; enter_ips and ops_stop */
if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
return;
@@ -4132,25 +4795,21 @@ void rtw89_core_stop(struct rtw89_dev *rtwdev)
clear_bit(RTW89_FLAG_RUNNING, rtwdev->flags);
- mutex_unlock(&rtwdev->mutex);
-
- cancel_work_sync(&rtwdev->c2h_work);
- cancel_work_sync(&rtwdev->cancel_6ghz_probe_work);
- cancel_work_sync(&btc->eapol_notify_work);
- cancel_work_sync(&btc->arp_notify_work);
- cancel_work_sync(&btc->dhcp_notify_work);
- cancel_work_sync(&btc->icmp_notify_work);
+ wiphy_work_cancel(wiphy, &rtwdev->c2h_work);
+ wiphy_work_cancel(wiphy, &rtwdev->cancel_6ghz_probe_work);
+ wiphy_work_cancel(wiphy, &btc->eapol_notify_work);
+ wiphy_work_cancel(wiphy, &btc->arp_notify_work);
+ wiphy_work_cancel(wiphy, &btc->dhcp_notify_work);
+ wiphy_work_cancel(wiphy, &btc->icmp_notify_work);
cancel_delayed_work_sync(&rtwdev->txq_reinvoke_work);
- cancel_delayed_work_sync(&rtwdev->track_work);
- cancel_delayed_work_sync(&rtwdev->chanctx_work);
- cancel_delayed_work_sync(&rtwdev->coex_act1_work);
- cancel_delayed_work_sync(&rtwdev->coex_bt_devinfo_work);
- cancel_delayed_work_sync(&rtwdev->coex_rfk_chk_work);
- cancel_delayed_work_sync(&rtwdev->cfo_track_work);
+ wiphy_delayed_work_cancel(wiphy, &rtwdev->track_work);
+ wiphy_delayed_work_cancel(wiphy, &rtwdev->chanctx_work);
+ wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_act1_work);
+ wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_bt_devinfo_work);
+ wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_rfk_chk_work);
+ wiphy_delayed_work_cancel(wiphy, &rtwdev->cfo_track_work);
cancel_delayed_work_sync(&rtwdev->forbid_ba_work);
- cancel_delayed_work_sync(&rtwdev->antdiv_work);
-
- mutex_lock(&rtwdev->mutex);
+ wiphy_delayed_work_cancel(wiphy, &rtwdev->antdiv_work);
rtw89_btc_ntfy_poweroff(rtwdev);
rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1, true);
@@ -4161,6 +4820,196 @@ void rtw89_core_stop(struct rtw89_dev *rtwdev)
rtw89_hci_reset(rtwdev);
}
+u8 rtw89_acquire_mac_id(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ u8 mac_id_num;
+ u8 mac_id;
+
+ if (rtwdev->support_mlo)
+ mac_id_num = chip->support_macid_num / chip->support_link_num;
+ else
+ mac_id_num = chip->support_macid_num;
+
+ mac_id = find_first_zero_bit(rtwdev->mac_id_map, mac_id_num);
+ if (mac_id == mac_id_num)
+ return RTW89_MAX_MAC_ID_NUM;
+
+ set_bit(mac_id, rtwdev->mac_id_map);
+ return mac_id;
+}
+
+void rtw89_release_mac_id(struct rtw89_dev *rtwdev, u8 mac_id)
+{
+ clear_bit(mac_id, rtwdev->mac_id_map);
+}
+
+void rtw89_init_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ u8 mac_id, u8 port)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ u8 support_link_num = chip->support_link_num;
+ u8 support_mld_num = 0;
+ unsigned int link_id;
+ u8 index;
+
+ bitmap_zero(rtwvif->links_inst_map, __RTW89_MLD_MAX_LINK_NUM);
+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++)
+ rtwvif->links[link_id] = NULL;
+
+ rtwvif->rtwdev = rtwdev;
+
+ if (rtwdev->support_mlo) {
+ rtwvif->links_inst_valid_num = support_link_num;
+ support_mld_num = chip->support_macid_num / support_link_num;
+ } else {
+ rtwvif->links_inst_valid_num = 1;
+ }
+
+ for (index = 0; index < rtwvif->links_inst_valid_num; index++) {
+ struct rtw89_vif_link *inst = &rtwvif->links_inst[index];
+
+ inst->rtwvif = rtwvif;
+ inst->mac_id = mac_id + index * support_mld_num;
+ inst->mac_idx = RTW89_MAC_0 + index;
+ inst->phy_idx = RTW89_PHY_0 + index;
+
+ /* multi-link use the same port id on different HW bands */
+ inst->port = port;
+ }
+}
+
+void rtw89_init_sta(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ struct rtw89_sta *rtwsta, u8 mac_id)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ u8 support_link_num = chip->support_link_num;
+ u8 support_mld_num = 0;
+ unsigned int link_id;
+ u8 index;
+
+ bitmap_zero(rtwsta->links_inst_map, __RTW89_MLD_MAX_LINK_NUM);
+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++)
+ rtwsta->links[link_id] = NULL;
+
+ rtwsta->rtwdev = rtwdev;
+ rtwsta->rtwvif = rtwvif;
+
+ if (rtwdev->support_mlo) {
+ rtwsta->links_inst_valid_num = support_link_num;
+ support_mld_num = chip->support_macid_num / support_link_num;
+ } else {
+ rtwsta->links_inst_valid_num = 1;
+ }
+
+ for (index = 0; index < rtwsta->links_inst_valid_num; index++) {
+ struct rtw89_sta_link *inst = &rtwsta->links_inst[index];
+
+ inst->rtwvif_link = &rtwvif->links_inst[index];
+
+ inst->rtwsta = rtwsta;
+ inst->mac_id = mac_id + index * support_mld_num;
+ }
+}
+
+struct rtw89_vif_link *rtw89_vif_set_link(struct rtw89_vif *rtwvif,
+ unsigned int link_id)
+{
+ struct rtw89_vif_link *rtwvif_link = rtwvif->links[link_id];
+ u8 index;
+ int ret;
+
+ if (rtwvif_link)
+ return rtwvif_link;
+
+ index = find_first_zero_bit(rtwvif->links_inst_map,
+ rtwvif->links_inst_valid_num);
+ if (index == rtwvif->links_inst_valid_num) {
+ ret = -EBUSY;
+ goto err;
+ }
+
+ rtwvif_link = &rtwvif->links_inst[index];
+ rtwvif_link->link_id = link_id;
+
+ set_bit(index, rtwvif->links_inst_map);
+ rtwvif->links[link_id] = rtwvif_link;
+ list_add_tail(&rtwvif_link->dlink_schd, &rtwvif->dlink_pool);
+ return rtwvif_link;
+
+err:
+ rtw89_err(rtwvif->rtwdev, "vif (link_id %u) failed to set link: %d\n",
+ link_id, ret);
+ return NULL;
+}
+
+void rtw89_vif_unset_link(struct rtw89_vif *rtwvif, unsigned int link_id)
+{
+ struct rtw89_vif_link **container = &rtwvif->links[link_id];
+ struct rtw89_vif_link *link = *container;
+ u8 index;
+
+ if (!link)
+ return;
+
+ index = rtw89_vif_link_inst_get_index(link);
+ clear_bit(index, rtwvif->links_inst_map);
+ *container = NULL;
+ list_del(&link->dlink_schd);
+}
+
+struct rtw89_sta_link *rtw89_sta_set_link(struct rtw89_sta *rtwsta,
+ unsigned int link_id)
+{
+ struct rtw89_vif *rtwvif = rtwsta->rtwvif;
+ struct rtw89_vif_link *rtwvif_link = rtwvif->links[link_id];
+ struct rtw89_sta_link *rtwsta_link = rtwsta->links[link_id];
+ u8 index;
+ int ret;
+
+ if (rtwsta_link)
+ return rtwsta_link;
+
+ if (!rtwvif_link) {
+ ret = -ENOLINK;
+ goto err;
+ }
+
+ index = rtw89_vif_link_inst_get_index(rtwvif_link);
+ if (test_bit(index, rtwsta->links_inst_map)) {
+ ret = -EBUSY;
+ goto err;
+ }
+
+ rtwsta_link = &rtwsta->links_inst[index];
+ rtwsta_link->link_id = link_id;
+
+ set_bit(index, rtwsta->links_inst_map);
+ rtwsta->links[link_id] = rtwsta_link;
+ list_add_tail(&rtwsta_link->dlink_schd, &rtwsta->dlink_pool);
+ return rtwsta_link;
+
+err:
+ rtw89_err(rtwsta->rtwdev, "sta (link_id %u) failed to set link: %d\n",
+ link_id, ret);
+ return NULL;
+}
+
+void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id)
+{
+ struct rtw89_sta_link **container = &rtwsta->links[link_id];
+ struct rtw89_sta_link *link = *container;
+ u8 index;
+
+ if (!link)
+ return;
+
+ index = rtw89_sta_link_inst_get_index(link);
+ clear_bit(index, rtwsta->links_inst_map);
+ *container = NULL;
+ list_del(&link->dlink_schd);
+}
+
int rtw89_core_init(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
@@ -4175,33 +5024,36 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
continue;
INIT_LIST_HEAD(&rtwdev->scan_info.pkt_list[band]);
}
+ INIT_LIST_HEAD(&rtwdev->scan_info.chan_list);
INIT_WORK(&rtwdev->ba_work, rtw89_core_ba_work);
INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work);
INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work);
- INIT_DELAYED_WORK(&rtwdev->track_work, rtw89_track_work);
- INIT_DELAYED_WORK(&rtwdev->chanctx_work, rtw89_chanctx_work);
- INIT_DELAYED_WORK(&rtwdev->coex_act1_work, rtw89_coex_act1_work);
- INIT_DELAYED_WORK(&rtwdev->coex_bt_devinfo_work, rtw89_coex_bt_devinfo_work);
- INIT_DELAYED_WORK(&rtwdev->coex_rfk_chk_work, rtw89_coex_rfk_chk_work);
- INIT_DELAYED_WORK(&rtwdev->cfo_track_work, rtw89_phy_cfo_track_work);
+ wiphy_delayed_work_init(&rtwdev->track_work, rtw89_track_work);
+ wiphy_delayed_work_init(&rtwdev->chanctx_work, rtw89_chanctx_work);
+ wiphy_delayed_work_init(&rtwdev->coex_act1_work, rtw89_coex_act1_work);
+ wiphy_delayed_work_init(&rtwdev->coex_bt_devinfo_work, rtw89_coex_bt_devinfo_work);
+ wiphy_delayed_work_init(&rtwdev->coex_rfk_chk_work, rtw89_coex_rfk_chk_work);
+ wiphy_delayed_work_init(&rtwdev->cfo_track_work, rtw89_phy_cfo_track_work);
INIT_DELAYED_WORK(&rtwdev->forbid_ba_work, rtw89_forbid_ba_work);
- INIT_DELAYED_WORK(&rtwdev->antdiv_work, rtw89_phy_antdiv_work);
+ wiphy_delayed_work_init(&rtwdev->antdiv_work, rtw89_phy_antdiv_work);
rtwdev->txq_wq = alloc_workqueue("rtw89_tx_wq", WQ_UNBOUND | WQ_HIGHPRI, 0);
if (!rtwdev->txq_wq)
return -ENOMEM;
spin_lock_init(&rtwdev->ba_lock);
spin_lock_init(&rtwdev->rpwm_lock);
- mutex_init(&rtwdev->mutex);
mutex_init(&rtwdev->rf_mutex);
rtwdev->total_sta_assoc = 0;
rtw89_init_wait(&rtwdev->mcc.wait);
+ rtw89_init_wait(&rtwdev->mlo.wait);
rtw89_init_wait(&rtwdev->mac.fw_ofld_wait);
+ rtw89_init_wait(&rtwdev->wow.wait);
+ rtw89_init_wait(&rtwdev->mac.ps_wait);
- INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work);
- INIT_WORK(&rtwdev->ips_work, rtw89_ips_work);
+ wiphy_work_init(&rtwdev->c2h_work, rtw89_fw_c2h_work);
+ wiphy_work_init(&rtwdev->ips_work, rtw89_ips_work);
+ wiphy_work_init(&rtwdev->cancel_6ghz_probe_work, rtw89_cancel_6ghz_probe_work);
INIT_WORK(&rtwdev->load_firmware_work, rtw89_load_firmware_work);
- INIT_WORK(&rtwdev->cancel_6ghz_probe_work, rtw89_cancel_6ghz_probe_work);
skb_queue_head_init(&rtwdev->c2h_queue);
rtw89_core_ppdu_sts_init(rtwdev);
@@ -4215,13 +5067,16 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
rtwdev->dbcc_en = true;
rtwdev->mac.qta_mode = RTW89_QTA_DBCC;
- rtwdev->mlo_dbcc_mode = MLO_2_PLUS_0_1RF;
+ rtwdev->mlo_dbcc_mode = MLO_1_PLUS_1_1RF;
}
- INIT_WORK(&btc->eapol_notify_work, rtw89_btc_ntfy_eapol_packet_work);
- INIT_WORK(&btc->arp_notify_work, rtw89_btc_ntfy_arp_packet_work);
- INIT_WORK(&btc->dhcp_notify_work, rtw89_btc_ntfy_dhcp_packet_work);
- INIT_WORK(&btc->icmp_notify_work, rtw89_btc_ntfy_icmp_packet_work);
+ rtwdev->bbs[RTW89_PHY_0].phy_idx = RTW89_PHY_0;
+ rtwdev->bbs[RTW89_PHY_1].phy_idx = RTW89_PHY_1;
+
+ wiphy_work_init(&btc->eapol_notify_work, rtw89_btc_ntfy_eapol_packet_work);
+ wiphy_work_init(&btc->arp_notify_work, rtw89_btc_ntfy_arp_packet_work);
+ wiphy_work_init(&btc->dhcp_notify_work, rtw89_btc_ntfy_dhcp_packet_work);
+ wiphy_work_init(&btc->icmp_notify_work, rtw89_btc_ntfy_icmp_packet_work);
init_completion(&rtwdev->fw.req.completion);
init_completion(&rtwdev->rfk_wait.completion);
@@ -4230,7 +5085,8 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
rtw89_ser_init(rtwdev);
rtw89_entity_init(rtwdev);
- rtw89_tas_init(rtwdev);
+ rtw89_sar_init(rtwdev);
+ rtw89_phy_ant_gain_init(rtwdev);
return 0;
}
@@ -4240,53 +5096,61 @@ void rtw89_core_deinit(struct rtw89_dev *rtwdev)
{
rtw89_ser_deinit(rtwdev);
rtw89_unload_firmware(rtwdev);
- rtw89_fw_free_all_early_h2c(rtwdev);
+ __rtw89_fw_free_all_early_h2c(rtwdev);
destroy_workqueue(rtwdev->txq_wq);
mutex_destroy(&rtwdev->rf_mutex);
- mutex_destroy(&rtwdev->mutex);
}
EXPORT_SYMBOL(rtw89_core_deinit);
-void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
const u8 *mac_addr, bool hw_scan)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->sub_entity_idx);
+ rtwvif_link->chanctx_idx);
+ struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx);
rtwdev->scanning = true;
- rtw89_leave_lps(rtwdev);
- if (hw_scan)
- rtw89_leave_ips_by_hwflags(rtwdev);
- ether_addr_copy(rtwvif->mac_addr, mac_addr);
- rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, chan->band_type);
- rtw89_chip_rfk_scan(rtwdev, true);
+ ether_addr_copy(rtwvif_link->mac_addr, mac_addr);
+ rtw89_btc_ntfy_scan_start(rtwdev, rtwvif_link->phy_idx, chan->band_type);
+ rtw89_chip_rfk_scan(rtwdev, rtwvif_link, true);
rtw89_hci_recalc_int_mit(rtwdev);
- rtw89_phy_config_edcca(rtwdev, true);
+ rtw89_phy_config_edcca(rtwdev, bb, true);
+ rtw89_tas_scan(rtwdev, true);
- rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, mac_addr);
+ rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, mac_addr);
}
void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif, bool hw_scan)
+ struct rtw89_vif_link *rtwvif_link, bool hw_scan)
{
- struct rtw89_vif *rtwvif = vif ? (struct rtw89_vif *)vif->drv_priv : NULL;
+ struct ieee80211_bss_conf *bss_conf;
+ struct rtw89_bb_ctx *bb;
- if (!rtwvif)
+ if (!rtwvif_link)
return;
- ether_addr_copy(rtwvif->mac_addr, vif->addr);
- rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ ether_addr_copy(rtwvif_link->mac_addr, bss_conf->addr);
+
+ rcu_read_unlock();
- rtw89_chip_rfk_scan(rtwdev, false);
- rtw89_btc_ntfy_scan_finish(rtwdev, RTW89_PHY_0);
- rtw89_phy_config_edcca(rtwdev, false);
+ rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
+
+ rtw89_chip_rfk_scan(rtwdev, rtwvif_link, false);
+ rtw89_btc_ntfy_scan_finish(rtwdev, rtwvif_link->phy_idx);
+ bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx);
+ rtw89_phy_config_edcca(rtwdev, bb, false);
+ rtw89_tas_scan(rtwdev, false);
rtwdev->scanning = false;
- rtwdev->dig.bypass_dig = true;
+ rtw89_for_each_active_bb(rtwdev, bb)
+ bb->dig.bypass_dig = true;
if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE))
- ieee80211_queue_work(rtwdev->hw, &rtwdev->ips_work);
+ wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->ips_work);
}
static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev)
@@ -4306,7 +5170,7 @@ static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev)
rtwdev->hal.cv = cv;
- if (chip->chip_id == RTL8852B || chip->chip_id == RTL8851B) {
+ if (rtw89_is_rtl885xb(rtwdev)) {
ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_CV, &val);
if (ret)
return;
@@ -4317,11 +5181,20 @@ static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev)
static void rtw89_core_setup_phycap(struct rtw89_dev *rtwdev)
{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+
rtwdev->hal.support_cckpd =
!(rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv <= CHIP_CBV) &&
!(rtwdev->chip->chip_id == RTL8852B && rtwdev->hal.cv <= CHIP_CAV);
rtwdev->hal.support_igi =
rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv <= CHIP_CBV;
+
+ if (test_bit(RTW89_QUIRK_THERMAL_PROT_120C, rtwdev->quirks))
+ rtwdev->hal.thermal_prot_th = chip->thermal_th[1];
+ else if (test_bit(RTW89_QUIRK_THERMAL_PROT_110C, rtwdev->quirks))
+ rtwdev->hal.thermal_prot_th = chip->thermal_th[0];
+ else
+ rtwdev->hal.thermal_prot_th = 0;
}
static void rtw89_core_setup_rfe_parms(struct rtw89_dev *rtwdev)
@@ -4352,6 +5225,76 @@ out:
rtw89_load_txpwr_table(rtwdev, rtwdev->rfe_parms->byr_tbl);
}
+int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ unsigned int link_id)
+{
+ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ u16 usable_links = ieee80211_vif_usable_links(vif);
+ u16 active_links = vif->active_links;
+ struct rtw89_vif_link *target, *cur;
+ int ret;
+
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ if (unlikely(!ieee80211_vif_is_mld(vif)))
+ return -EOPNOTSUPP;
+
+ if (unlikely(!(usable_links & BIT(link_id)))) {
+ rtw89_warn(rtwdev, "%s: link id %u is not usable\n", __func__,
+ link_id);
+ return -ENOLINK;
+ }
+
+ if (active_links == BIT(link_id))
+ return 0;
+
+ rtw89_debug(rtwdev, RTW89_DBG_STATE, "%s: switch to link id %u MLSR\n",
+ __func__, link_id);
+
+ rtw89_leave_lps(rtwdev);
+
+ ieee80211_stop_queues(rtwdev->hw);
+ flush_work(&rtwdev->txq_work);
+
+ cur = rtw89_get_designated_link(rtwvif);
+
+ ret = ieee80211_set_active_links(vif, active_links | BIT(link_id));
+ if (ret) {
+ rtw89_err(rtwdev, "%s: failed to activate link id %u\n",
+ __func__, link_id);
+ goto wake_queue;
+ }
+
+ target = rtwvif->links[link_id];
+ if (unlikely(!target)) {
+ rtw89_err(rtwdev, "%s: failed to confirm link id %u\n",
+ __func__, link_id);
+
+ ieee80211_set_active_links(vif, active_links);
+ ret = -EFAULT;
+ goto wake_queue;
+ }
+
+ if (likely(cur))
+ rtw89_fw_h2c_mlo_link_cfg(rtwdev, cur, false);
+
+ rtw89_fw_h2c_mlo_link_cfg(rtwdev, target, true);
+
+ ret = ieee80211_set_active_links(vif, BIT(link_id));
+ if (ret)
+ rtw89_err(rtwdev, "%s: failed to inactivate links 0x%x\n",
+ __func__, active_links);
+
+ rtw89_chip_rfk_channel(rtwdev, target);
+
+ rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR;
+
+wake_queue:
+ ieee80211_wake_queues(rtwdev->hw);
+
+ return ret;
+}
+
static int rtw89_chip_efuse_info_setup(struct rtw89_dev *rtwdev)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
@@ -4377,8 +5320,6 @@ static int rtw89_chip_efuse_info_setup(struct rtw89_dev *rtwdev)
rtw89_hci_mac_pre_deinit(rtwdev);
- rtw89_mac_pwr_off(rtwdev);
-
return 0;
}
@@ -4389,56 +5330,151 @@ static int rtw89_chip_board_info_setup(struct rtw89_dev *rtwdev)
return 0;
}
+static bool rtw89_chip_has_rfkill(struct rtw89_dev *rtwdev)
+{
+ return !!rtwdev->chip->rfkill_init;
+}
+
+static void rtw89_core_rfkill_init(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_rfkill_regs *regs = rtwdev->chip->rfkill_init;
+
+ rtw89_write16_mask(rtwdev, regs->pinmux.addr,
+ regs->pinmux.mask, regs->pinmux.data);
+ rtw89_write16_mask(rtwdev, regs->mode.addr,
+ regs->mode.mask, regs->mode.data);
+}
+
+static bool rtw89_core_rfkill_get(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_reg_def *reg = &rtwdev->chip->rfkill_get;
+
+ return !rtw89_read8_mask(rtwdev, reg->addr, reg->mask);
+}
+
+static void rtw89_rfkill_polling_init(struct rtw89_dev *rtwdev)
+{
+ if (!rtw89_chip_has_rfkill(rtwdev))
+ return;
+
+ rtw89_core_rfkill_init(rtwdev);
+ rtw89_core_rfkill_poll(rtwdev, true);
+ wiphy_rfkill_start_polling(rtwdev->hw->wiphy);
+}
+
+static void rtw89_rfkill_polling_deinit(struct rtw89_dev *rtwdev)
+{
+ if (!rtw89_chip_has_rfkill(rtwdev))
+ return;
+
+ wiphy_rfkill_stop_polling(rtwdev->hw->wiphy);
+}
+
+void rtw89_core_rfkill_poll(struct rtw89_dev *rtwdev, bool force)
+{
+ bool prev, blocked;
+
+ if (!rtw89_chip_has_rfkill(rtwdev))
+ return;
+
+ prev = test_bit(RTW89_FLAG_HW_RFKILL_STATE, rtwdev->flags);
+ blocked = rtw89_core_rfkill_get(rtwdev);
+
+ if (!force && prev == blocked)
+ return;
+
+ rtw89_info(rtwdev, "rfkill hardware state changed to %s\n",
+ blocked ? "disable" : "enable");
+
+ if (blocked)
+ set_bit(RTW89_FLAG_HW_RFKILL_STATE, rtwdev->flags);
+ else
+ clear_bit(RTW89_FLAG_HW_RFKILL_STATE, rtwdev->flags);
+
+ wiphy_rfkill_set_hw_state(rtwdev->hw->wiphy, blocked);
+}
+
int rtw89_chip_info_setup(struct rtw89_dev *rtwdev)
{
int ret;
rtw89_read_chip_ver(rtwdev);
+ ret = rtw89_mac_pwr_on(rtwdev);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to power on\n");
+ return ret;
+ }
+
ret = rtw89_wait_firmware_completion(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to wait firmware completion\n");
- return ret;
+ goto out;
}
ret = rtw89_fw_recognize(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to recognize firmware\n");
- return ret;
+ goto out;
}
ret = rtw89_chip_efuse_info_setup(rtwdev);
if (ret)
- return ret;
+ goto out;
ret = rtw89_fw_recognize_elements(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to recognize firmware elements\n");
- return ret;
+ goto out;
}
ret = rtw89_chip_board_info_setup(rtwdev);
if (ret)
- return ret;
+ goto out;
rtw89_core_setup_rfe_parms(rtwdev);
rtwdev->ps_mode = rtw89_update_ps_mode(rtwdev);
- return 0;
+out:
+ rtw89_mac_pwr_off(rtwdev);
+
+ return ret;
}
EXPORT_SYMBOL(rtw89_chip_info_setup);
+void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct ieee80211_bss_conf *bss_conf;
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+ if (!bss_conf->he_support || !vif->cfg.assoc) {
+ rcu_read_unlock();
+ return;
+ }
+
+ rcu_read_unlock();
+
+ if (chip->ops->set_txpwr_ul_tb_offset)
+ chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif_link->mac_idx);
+}
+
static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
+ u8 n = rtwdev->support_mlo ? chip->support_link_num : 1;
struct ieee80211_hw *hw = rtwdev->hw;
struct rtw89_efuse *efuse = &rtwdev->efuse;
struct rtw89_hal *hal = &rtwdev->hal;
int ret;
int tx_headroom = IEEE80211_HT_CTL_LEN;
- hw->vif_data_size = sizeof(struct rtw89_vif);
- hw->sta_data_size = sizeof(struct rtw89_sta);
+ hw->vif_data_size = struct_size_t(struct rtw89_vif, links_inst, n);
+ hw->sta_data_size = struct_size_t(struct rtw89_sta, links_inst, n);
hw->txq_data_size = sizeof(struct rtw89_txq);
hw->chanctx_data_size = sizeof(struct rtw89_chanctx_cfg);
@@ -4450,6 +5486,10 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
hw->max_tx_aggregation_subframes = RTW89_MAX_TX_AGG_NUM;
hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL;
+ hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FEC |
+ IEEE80211_RADIOTAP_MCS_HAVE_STBC;
+ hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC;
+
ieee80211_hw_set(hw, SIGNAL_DBM);
ieee80211_hw_set(hw, HAS_RATE_CONTROL);
ieee80211_hw_set(hw, MFP_CAPABLE);
@@ -4471,6 +5511,9 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
if (RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw))
ieee80211_hw_set(hw, CONNECTION_MONITOR);
+ if (RTW89_CHK_FW_FEATURE(NOTIFY_AP_INFO, &rtwdev->fw))
+ ieee80211_hw_set(hw, AP_LINK_PS);
+
hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_P2P_CLIENT) |
@@ -4486,7 +5529,21 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
WIPHY_FLAG_TDLS_EXTERNAL_SETUP |
- WIPHY_FLAG_AP_UAPSD | WIPHY_FLAG_SPLIT_SCAN_6GHZ;
+ WIPHY_FLAG_AP_UAPSD |
+ WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK;
+
+ if (!chip->support_rnr)
+ hw->wiphy->flags |= WIPHY_FLAG_SPLIT_SCAN_6GHZ;
+
+ if (chip->chip_gen == RTW89_CHIP_BE)
+ hw->wiphy->flags |= WIPHY_FLAG_DISABLE_WEXT;
+
+ if (rtwdev->support_mlo) {
+ hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_MLO;
+ hw->wiphy->iftype_ext_capab = rtw89_iftypes_ext_capa;
+ hw->wiphy->num_iftype_ext_capab = ARRAY_SIZE(rtw89_iftypes_ext_capa);
+ }
+
hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
hw->wiphy->max_scan_ssids = RTW89_SCANOFLD_MAX_SSID;
@@ -4494,6 +5551,7 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
#ifdef CONFIG_PM
hw->wiphy->wowlan = rtwdev->chip->wowlan_stub;
+ hw->wiphy->max_sched_scan_ssids = RTW89_SCANOFLD_MAX_SSID;
#endif
hw->wiphy->tid_config_support.vif |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL);
@@ -4515,7 +5573,7 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
ret = rtw89_regd_setup(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to set up regd\n");
- goto err_free_supported_band;
+ return ret;
}
hw->wiphy->sar_capa = &rtw89_sar_capa;
@@ -4523,21 +5581,21 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
ret = ieee80211_register_hw(hw);
if (ret) {
rtw89_err(rtwdev, "failed to register hw\n");
- goto err_free_supported_band;
+ return ret;
}
- ret = rtw89_regd_init(rtwdev, rtw89_regd_notifier);
+ ret = rtw89_regd_init_hint(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to init regd\n");
goto err_unregister_hw;
}
+ rtw89_rfkill_polling_init(rtwdev);
+
return 0;
err_unregister_hw:
ieee80211_unregister_hw(hw);
-err_free_supported_band:
- rtw89_core_clr_supported_band(rtwdev);
return ret;
}
@@ -4546,8 +5604,8 @@ static void rtw89_core_unregister_hw(struct rtw89_dev *rtwdev)
{
struct ieee80211_hw *hw = rtwdev->hw;
+ rtw89_rfkill_polling_deinit(rtwdev);
ieee80211_unregister_hw(hw);
- rtw89_core_clr_supported_band(rtwdev);
}
int rtw89_core_register(struct rtw89_dev *rtwdev)
@@ -4569,12 +5627,15 @@ EXPORT_SYMBOL(rtw89_core_register);
void rtw89_core_unregister(struct rtw89_dev *rtwdev)
{
rtw89_core_unregister_hw(rtwdev);
+
+ rtw89_debugfs_deinit(rtwdev);
}
EXPORT_SYMBOL(rtw89_core_unregister);
struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
u32 bus_data_size,
- const struct rtw89_chip_info *chip)
+ const struct rtw89_chip_info *chip,
+ const struct rtw89_chip_variant *variant)
{
struct rtw89_fw_info early_fw = {};
const struct firmware *firmware;
@@ -4583,6 +5644,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
struct ieee80211_ops *ops;
u32 driver_data_size;
int fw_format = -1;
+ bool support_mlo;
bool no_chanctx;
firmware = rtw89_early_fw_feature_recognize(device, chip, &early_fw, &fw_format);
@@ -4611,6 +5673,14 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
if (!hw)
goto err;
+ /* Currently, our AP_LINK_PS handling only works for non-MLD softap
+ * or MLD-single-link softap. If RTW89_MLD_NON_STA_LINK_NUM enlarges,
+ * please tweak entire AP_LINKS_PS handling before supporting MLO.
+ */
+ support_mlo = !no_chanctx && chip->support_link_num &&
+ RTW89_CHK_FW_FEATURE(NOTIFY_AP_INFO, &early_fw) &&
+ RTW89_MLD_NON_STA_LINK_NUM == 1;
+
hw->wiphy->iface_combinations = rtw89_iface_combs;
if (no_chanctx || chip->support_chanctx_num == 1)
@@ -4623,11 +5693,15 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
rtwdev->dev = device;
rtwdev->ops = ops;
rtwdev->chip = chip;
+ rtwdev->variant = variant;
rtwdev->fw.req.firmware = firmware;
rtwdev->fw.fw_format = fw_format;
+ rtwdev->support_mlo = support_mlo;
- rtw89_debug(rtwdev, RTW89_DBG_FW, "probe driver %s chanctx\n",
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, "probe driver %s chanctx\n",
no_chanctx ? "without" : "with");
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, "probe driver %s MLO cap\n",
+ support_mlo ? "with" : "without");
return rtwdev;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 2e854c9af709..1c8f3b9b7c4c 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -7,6 +7,7 @@
#include <linux/average.h>
#include <linux/bitfield.h>
+#include <linux/dmi.h>
#include <linux/firmware.h>
#include <linux/iopoll.h>
#include <linux/workqueue.h>
@@ -16,10 +17,13 @@ struct rtw89_dev;
struct rtw89_pci_info;
struct rtw89_mac_gen_def;
struct rtw89_phy_gen_def;
+struct rtw89_fw_blacklist;
struct rtw89_efuse_block_cfg;
struct rtw89_h2c_rf_tssi;
struct rtw89_fw_txpwr_track_cfg;
struct rtw89_phy_rfk_log_fmt;
+struct rtw89_debugfs;
+struct rtw89_regd_data;
extern const struct ieee80211_ops rtw89_ops;
@@ -131,6 +135,7 @@ enum rtw89_hci_type {
enum rtw89_core_chip_id {
RTL8852A,
RTL8852B,
+ RTL8852BT,
RTL8852C,
RTL8851B,
RTL8922A,
@@ -715,6 +720,7 @@ enum rtw89_ofdma_type {
RTW89_OFDMA_NUM,
};
+/* neither insert new in the middle, nor change any given definition */
enum rtw89_regulation_type {
RTW89_WW = 0,
RTW89_ETSI = 1,
@@ -744,6 +750,14 @@ enum rtw89_reg_6ghz_power {
RTW89_REG_6GHZ_POWER_DFLT = RTW89_REG_6GHZ_POWER_VLP,
};
+#define RTW89_MIN_VALID_POWER_CONSTRAINT (-10) /* unit: dBm */
+
+/* calculate based on ieee80211 Transmit Power Envelope */
+struct rtw89_reg_6ghz_tpe {
+ bool valid;
+ s8 constraint; /* unit: dBm */
+};
+
enum rtw89_fw_pkt_ofld_type {
RTW89_PKT_OFLD_TYPE_PROBE_RSP = 0,
RTW89_PKT_OFLD_TYPE_PS_POLL = 1,
@@ -784,35 +798,50 @@ struct rtw89_rx_phy_ppdu {
u8 rssi[RF_PATH_MAX];
u8 mac_id;
u8 chan_idx;
+ u8 phy_idx;
u8 ie;
u16 rate;
+ u8 rpl_avg;
+ u8 rpl_path[RF_PATH_MAX];
+ u8 rpl_fd[RF_PATH_MAX];
+ u8 bw_idx;
+ u8 rx_path_en;
struct {
bool has;
u8 avg_snr;
u8 evm_max;
u8 evm_min;
} ofdm;
+ bool has_data;
+ bool has_bcn;
+ bool ldpc;
+ bool stbc;
bool to_self;
bool valid;
+ bool hdr_2_en;
};
enum rtw89_mac_idx {
RTW89_MAC_0 = 0,
RTW89_MAC_1 = 1,
+ RTW89_MAC_NUM,
};
enum rtw89_phy_idx {
RTW89_PHY_0 = 0,
RTW89_PHY_1 = 1,
- RTW89_PHY_MAX
+ RTW89_PHY_NUM,
};
-enum rtw89_sub_entity_idx {
- RTW89_SUB_ENTITY_0 = 0,
- RTW89_SUB_ENTITY_1 = 1,
+#define __RTW89_MLD_MAX_LINK_NUM 2
+#define RTW89_MLD_NON_STA_LINK_NUM 1
+
+enum rtw89_chanctx_idx {
+ RTW89_CHANCTX_0 = 0,
+ RTW89_CHANCTX_1 = 1,
- NUM_OF_RTW89_SUB_ENTITY,
- RTW89_SUB_ENTITY_IDLE = NUM_OF_RTW89_SUB_ENTITY,
+ NUM_OF_RTW89_CHANCTX,
+ RTW89_CHANCTX_IDLE = NUM_OF_RTW89_CHANCTX,
};
enum rtw89_rf_path {
@@ -882,6 +911,13 @@ enum rtw89_ps_mode {
#define RTW89_BYR_BW_NUM (RTW89_CHANNEL_WIDTH_320 + 1)
#define RTW89_PPE_BW_NUM (RTW89_CHANNEL_WIDTH_320 + 1)
+enum rtw89_pe_duration {
+ RTW89_PE_DURATION_0 = 0,
+ RTW89_PE_DURATION_8 = 1,
+ RTW89_PE_DURATION_16 = 2,
+ RTW89_PE_DURATION_16_20 = 3,
+};
+
enum rtw89_ru_bandwidth {
RTW89_RU26 = 0,
RTW89_RU52 = 1,
@@ -905,10 +941,12 @@ enum rtw89_sc_offset {
RTW89_SC_40_LOWER = 10,
};
+/* only mgd features can be added to the enum */
enum rtw89_wow_flags {
RTW89_WOW_FLAG_EN_MAGIC_PKT,
RTW89_WOW_FLAG_EN_REKEY_PKT,
RTW89_WOW_FLAG_EN_DISCONNECT,
+ RTW89_WOW_FLAG_EN_PATTERN,
RTW89_WOW_FLAG_NUM,
};
@@ -1050,6 +1088,7 @@ struct rtw89_rx_desc_info {
u16 offset;
u16 rxd_len;
bool ready;
+ u16 rssi;
};
struct rtw89_rxdesc_short {
@@ -1092,6 +1131,11 @@ struct rtw89_rxdesc_long_v2 {
__le32 dword9;
} __packed;
+struct rtw89_rxdesc_phy_rpt_v2 {
+ __le32 dword0;
+ __le32 dword1;
+} __packed;
+
struct rtw89_tx_desc_info {
u16 pkt_size;
u8 wp_offset;
@@ -1127,6 +1171,11 @@ struct rtw89_tx_desc_info {
bool hiq;
u8 port;
bool er_cap;
+ bool stbc;
+ bool ldpc;
+ bool upd_wlan_hdr;
+ bool mlo;
+ bool sw_mld;
};
struct rtw89_core_tx_request {
@@ -1135,6 +1184,8 @@ struct rtw89_core_tx_request {
struct sk_buff *skb;
struct ieee80211_vif *vif;
struct ieee80211_sta *sta;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
struct rtw89_tx_desc_info desc_info;
};
@@ -1178,9 +1229,13 @@ enum rtw89_btc_ncnt {
BTC_NCNT_CUSTOMERIZE,
BTC_NCNT_WL_RFK,
BTC_NCNT_WL_STA,
+ BTC_NCNT_WL_STA_LAST,
BTC_NCNT_FWINFO,
BTC_NCNT_TIMER,
- BTC_NCNT_NUM
+ BTC_NCNT_SWITCH_CHBW,
+ BTC_NCNT_RESUME_DL_FW,
+ BTC_NCNT_COUNTRYCODE,
+ BTC_NCNT_NUM,
};
enum rtw89_btc_btinfo {
@@ -1209,6 +1264,7 @@ enum rtw89_btc_dcnt {
BTC_DCNT_TDMA_NONSYNC,
BTC_DCNT_SLOT_NONSYNC,
BTC_DCNT_BTCNT_HANG,
+ BTC_DCNT_BTTX_HANG,
BTC_DCNT_WL_SLOT_DRIFT,
BTC_DCNT_WL_STA_LAST,
BTC_DCNT_BT_SLOT_DRIFT,
@@ -1216,7 +1272,10 @@ enum rtw89_btc_dcnt {
BTC_DCNT_FDDT_TRIG,
BTC_DCNT_E2G,
BTC_DCNT_E2G_HANG,
- BTC_DCNT_NUM
+ BTC_DCNT_WL_FW_VER_MATCH,
+ BTC_DCNT_NULL_TX_FAIL,
+ BTC_DCNT_WL_STA_NTFY,
+ BTC_DCNT_NUM,
};
enum rtw89_btc_wl_state_cnt {
@@ -1230,6 +1289,13 @@ enum rtw89_btc_wl_state_cnt {
BTC_WCNT_RFK_REJECT,
BTC_WCNT_RFK_TIMEOUT,
BTC_WCNT_CH_UPDATE,
+ BTC_WCNT_DBCC_ALL_2G,
+ BTC_WCNT_DBCC_CHG,
+ BTC_WCNT_RX_OK_LAST,
+ BTC_WCNT_RX_OK_LAST2S,
+ BTC_WCNT_RX_ERR_LAST,
+ BTC_WCNT_RX_ERR_LAST2S,
+ BTC_WCNT_RX_LAST,
BTC_WCNT_NUM
};
@@ -1253,8 +1319,10 @@ enum rtw89_btc_bt_state_cnt {
BTC_BCNT_LOPRI_TX,
BTC_BCNT_LOPRI_RX,
BTC_BCNT_POLUT,
+ BTC_BCNT_POLUT_NOW,
+ BTC_BCNT_POLUT_DIFF,
BTC_BCNT_RATECHG,
- BTC_BCNT_NUM
+ BTC_BCNT_NUM,
};
enum rtw89_btc_bt_profile {
@@ -1299,6 +1367,7 @@ struct rtw89_btc_wl_smap {
u32 scan: 1;
u32 connecting: 1;
u32 roaming: 1;
+ u32 dbccing: 1;
u32 _4way: 1;
u32 rf_off: 1;
u32 lps: 2;
@@ -1307,6 +1376,8 @@ struct rtw89_btc_wl_smap {
u32 traffic_dir : 2;
u32 rf_off_pre: 1;
u32 lps_pre: 2;
+ u32 lps_exiting: 1;
+ u32 emlsr: 1;
};
enum rtw89_tfc_lv {
@@ -1349,6 +1420,14 @@ struct rtw89_traffic_stats {
u16 rx_rate;
};
+struct rtw89_btc_chdef {
+ u8 center_ch;
+ u8 band;
+ u8 chan;
+ enum rtw89_sc_offset offset;
+ enum rtw89_bandwidth bw;
+};
+
struct rtw89_btc_statistic {
u8 rssi; /* 0%~110% (dBm = rssi -110) */
struct rtw89_traffic_stats traffic;
@@ -1357,6 +1436,7 @@ struct rtw89_btc_statistic {
#define BTC_WL_RSSI_THMAX 4
struct rtw89_btc_wl_link_info {
+ struct rtw89_btc_chdef chdef;
struct rtw89_btc_statistic stat;
enum rtw89_tfc_dir dir;
u8 rssi_state[BTC_WL_RSSI_THMAX];
@@ -1370,6 +1450,7 @@ struct rtw89_btc_wl_link_info {
u8 phy;
u8 dtim_period;
u8 mode;
+ u8 tx_1ss_limit;
u8 mac_id;
u8 tx_retry;
@@ -1379,6 +1460,7 @@ struct rtw89_btc_wl_link_info {
u32 tx_time;
u32 client_cnt;
u32 rx_rate_drop_cnt;
+ u32 noa_duration;
u32 active: 1;
u32 noa: 1;
@@ -1412,6 +1494,11 @@ struct rtw89_btc_bt_a2dp_desc {
u8 type: 3;
u8 active: 1;
u8 sink: 1;
+ u32 handle_update: 1;
+ u32 devinfo_query: 1;
+ u32 no_empty_streak_2s: 8;
+ u32 no_empty_streak_max: 8;
+ u32 rsvd: 6;
u8 bitpool;
u16 vendor_id;
@@ -1458,16 +1545,16 @@ struct rtw89_btc_u8_sta_chg {
};
struct rtw89_btc_wl_scan_info {
- u8 band[RTW89_PHY_MAX];
+ u8 band[RTW89_PHY_NUM];
u8 phy_map;
u8 rsvd;
};
struct rtw89_btc_wl_dbcc_info {
- u8 op_band[RTW89_PHY_MAX]; /* op band in each phy */
- u8 scan_band[RTW89_PHY_MAX]; /* scan band in each phy */
- u8 real_band[RTW89_PHY_MAX];
- u8 role[RTW89_PHY_MAX]; /* role in each phy */
+ u8 op_band[RTW89_PHY_NUM]; /* op band in each phy */
+ u8 scan_band[RTW89_PHY_NUM]; /* scan band in each phy */
+ u8 real_band[RTW89_PHY_NUM];
+ u8 role[RTW89_PHY_NUM]; /* role in each phy */
};
struct rtw89_btc_wl_active_role {
@@ -1526,6 +1613,23 @@ struct rtw89_btc_wl_active_role_v2 {
u32 noa_duration; /* ms */
};
+struct rtw89_btc_wl_active_role_v7 {
+ u8 connected;
+ u8 pid;
+ u8 phy;
+ u8 noa;
+
+ u8 band;
+ u8 client_ps;
+ u8 bw;
+ u8 role;
+
+ u8 ch;
+ u8 noa_dur;
+ u8 client_cnt;
+ u8 rsvd2;
+} __packed;
+
struct rtw89_btc_wl_role_info_bpos {
u16 none: 1;
u16 station: 1;
@@ -1589,6 +1693,58 @@ struct rtw89_btc_wl_role_info_v2 { /* struct size must be n*4 bytes */
u32 rsvd: 27;
};
+struct rtw89_btc_wl_rlink { /* H2C info, struct size must be n*4 bytes */
+ u8 connected;
+ u8 pid;
+ u8 phy;
+ u8 noa;
+
+ u8 rf_band; /* enum band_type RF band: 2.4G/5G/6G */
+ u8 active; /* 0:rlink is under doze */
+ u8 bw; /* enum channel_width */
+ u8 role; /*enum role_type */
+
+ u8 ch;
+ u8 noa_dur; /* ms */
+ u8 client_cnt; /* for Role = P2P-Go/AP */
+ u8 mode; /* wifi protocol */
+} __packed;
+
+#define RTW89_BE_BTC_WL_MAX_ROLE_NUMBER 6
+struct rtw89_btc_wl_role_info_v7 { /* struct size must be n*4 bytes */
+ u8 connect_cnt;
+ u8 link_mode;
+ u8 link_mode_chg;
+ u8 p2p_2g;
+
+ struct rtw89_btc_wl_active_role_v7 active_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER];
+
+ u32 role_map;
+ u32 mrole_type; /* btc_wl_mrole_type */
+ u32 mrole_noa_duration; /* ms */
+ u32 dbcc_en;
+ u32 dbcc_chg;
+ u32 dbcc_2g_phy; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */
+} __packed;
+
+struct rtw89_btc_wl_role_info_v8 { /* H2C info, struct size must be n*4 bytes */
+ u8 connect_cnt;
+ u8 link_mode;
+ u8 link_mode_chg;
+ u8 p2p_2g;
+
+ u8 pta_req_band;
+ u8 dbcc_en; /* 1+1 and 2.4G-included */
+ u8 dbcc_chg;
+ u8 dbcc_2g_phy; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */
+
+ struct rtw89_btc_wl_rlink rlink[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM];
+
+ u32 role_map;
+ u32 mrole_type; /* btc_wl_mrole_type */
+ u32 mrole_noa_duration; /* ms */
+} __packed;
+
struct rtw89_btc_wl_ver_info {
u32 fw_coex; /* match with which coex_ver */
u32 fw;
@@ -1610,7 +1766,11 @@ struct rtw89_btc_wl_rfk_info {
u32 phy_map: 2;
u32 band: 2;
u32 type: 8;
- u32 rsvd: 14;
+ u32 con_rfk: 1;
+ u32 rsvd: 13;
+
+ u32 start_time;
+ u32 proc_time;
};
struct rtw89_btc_bt_smap {
@@ -1724,12 +1884,15 @@ struct rtw89_btc_wl_nhm {
struct rtw89_btc_wl_info {
struct rtw89_btc_wl_link_info link_info[RTW89_PORT_NUM];
+ struct rtw89_btc_wl_link_info rlink_info[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM];
struct rtw89_btc_wl_rfk_info rfk_info;
struct rtw89_btc_wl_ver_info ver_info;
struct rtw89_btc_wl_afh_info afh_info;
struct rtw89_btc_wl_role_info role_info;
struct rtw89_btc_wl_role_info_v1 role_info_v1;
struct rtw89_btc_wl_role_info_v2 role_info_v2;
+ struct rtw89_btc_wl_role_info_v7 role_info_v7;
+ struct rtw89_btc_wl_role_info_v8 role_info_v8;
struct rtw89_btc_wl_scan_info scan_info;
struct rtw89_btc_wl_dbcc_info dbcc_info;
struct rtw89_btc_rf_para rf_para;
@@ -1740,9 +1903,16 @@ struct rtw89_btc_wl_info {
u8 rssi_level;
u8 cn_report;
u8 coex_mode;
+ u8 pta_req_mac;
+ u8 bt_polut_type[RTW89_PHY_NUM]; /* BT polluted WL-Tx type for phy0/1 */
+ bool is_5g_hi_channel;
+ bool pta_reg_mac_chg;
bool bg_mode;
+ bool he_mode;
bool scbd_change;
+ bool fw_ver_mismatch;
+ bool client_cnt_inc_2g;
u32 scbd;
};
@@ -1870,9 +2040,18 @@ struct rtw89_btc_fbtc_btscan_v2 {
struct rtw89_btc_bt_scan_info_v2 para[CXSCAN_MAX];
} __packed;
+struct rtw89_btc_fbtc_btscan_v7 {
+ u8 fver; /* btc_ver::fcxbtscan */
+ u8 type;
+ u8 rsvd0;
+ u8 rsvd1;
+ struct rtw89_btc_bt_scan_info_v2 para[CXSCAN_MAX];
+} __packed;
+
union rtw89_btc_fbtc_btscan {
struct rtw89_btc_fbtc_btscan_v1 v1;
struct rtw89_btc_fbtc_btscan_v2 v2;
+ struct rtw89_btc_fbtc_btscan_v7 v7;
};
struct rtw89_btc_bt_info {
@@ -2014,6 +2193,20 @@ struct rtw89_btc_fbtc_rpt_ctrl_info_v5 {
__le16 cnt_aoac_rf_off; /* rf-off counter for aoac switch notify */
} __packed;
+struct rtw89_btc_fbtc_rpt_ctrl_info_v8 {
+ __le16 cnt; /* fw report counter */
+ __le16 cnt_c2h; /* fw send c2h counter */
+ __le16 cnt_h2c; /* fw recv h2c counter */
+ __le16 len_c2h; /* The total length of the last C2H */
+
+ __le16 cnt_aoac_rf_on; /* rf-on counter for aoac switch notify */
+ __le16 cnt_aoac_rf_off; /* rf-off counter for aoac switch notify */
+
+ __le32 cx_ver; /* match which driver's coex version */
+ __le32 fw_ver;
+ __le32 en; /* report map */
+} __packed;
+
struct rtw89_btc_fbtc_rpt_ctrl_wl_fw_info {
__le32 cx_ver; /* match which driver's coex version */
__le32 cx_offload;
@@ -2043,7 +2236,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_v4 {
struct rtw89_btc_fbtc_rpt_ctrl_wl_fw_info wl_fw_info;
struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info;
__le32 bt_cnt[BTC_BCNT_STA_MAX];
- struct rtw89_mac_ax_gnt gnt_val[RTW89_PHY_MAX];
+ struct rtw89_mac_ax_gnt gnt_val[RTW89_PHY_NUM];
} __packed;
struct rtw89_btc_fbtc_rpt_ctrl_v5 {
@@ -2051,7 +2244,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_v5 {
u8 rsvd;
__le16 rsvd1;
- u8 gnt_val[RTW89_PHY_MAX][4];
+ u8 gnt_val[RTW89_PHY_NUM][4];
__le16 bt_cnt[BTC_BCNT_STA_MAX];
struct rtw89_btc_fbtc_rpt_ctrl_info_v5 rpt_info;
@@ -2063,18 +2256,46 @@ struct rtw89_btc_fbtc_rpt_ctrl_v105 {
u8 rsvd;
__le16 rsvd1;
- u8 gnt_val[RTW89_PHY_MAX][4];
+ u8 gnt_val[RTW89_PHY_NUM][4];
__le16 bt_cnt[BTC_BCNT_STA_MAX_V105];
struct rtw89_btc_fbtc_rpt_ctrl_info_v5 rpt_info;
struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info;
} __packed;
+struct rtw89_btc_fbtc_rpt_ctrl_v7 {
+ u8 fver;
+ u8 rsvd0;
+ u8 rsvd1;
+ u8 rsvd2;
+
+ u8 gnt_val[RTW89_PHY_NUM][4];
+ __le16 bt_cnt[BTC_BCNT_STA_MAX_V105];
+
+ struct rtw89_btc_fbtc_rpt_ctrl_info_v8 rpt_info;
+ struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info;
+} __packed;
+
+struct rtw89_btc_fbtc_rpt_ctrl_v8 {
+ u8 fver;
+ u8 rsvd0;
+ u8 rpt_len_max_l; /* BTC_RPT_MAX bit0~7 */
+ u8 rpt_len_max_h; /* BTC_RPT_MAX bit8~15 */
+
+ u8 gnt_val[RTW89_PHY_NUM][4];
+ __le16 bt_cnt[BTC_BCNT_STA_MAX_V105];
+
+ struct rtw89_btc_fbtc_rpt_ctrl_info_v8 rpt_info;
+ struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info;
+} __packed;
+
union rtw89_btc_fbtc_rpt_ctrl_ver_info {
struct rtw89_btc_fbtc_rpt_ctrl_v1 v1;
struct rtw89_btc_fbtc_rpt_ctrl_v4 v4;
struct rtw89_btc_fbtc_rpt_ctrl_v5 v5;
struct rtw89_btc_fbtc_rpt_ctrl_v105 v105;
+ struct rtw89_btc_fbtc_rpt_ctrl_v7 v7;
+ struct rtw89_btc_fbtc_rpt_ctrl_v8 v8;
};
enum rtw89_fbtc_ext_ctrl_type {
@@ -2181,15 +2402,32 @@ enum rtw89_btc_afh_map_type { /*AFH MAP TYPE */
};
#define BTC_DBG_MAX1 32
-struct rtw89_btc_fbtc_gpio_dbg {
+struct rtw89_btc_fbtc_gpio_dbg_v1 {
u8 fver; /* btc_ver::fcxgpiodbg */
u8 rsvd;
- u16 rsvd2;
- u32 en_map; /* which debug signal (see btc_wl_gpio_debug) is enable */
- u32 pre_state; /* the debug signal is 1 or 0 */
+ __le16 rsvd2;
+ __le32 en_map; /* which debug signal (see btc_wl_gpio_debug) is enable */
+ __le32 pre_state; /* the debug signal is 1 or 0 */
u8 gpio_map[BTC_DBG_MAX1]; /*the debug signals to GPIO-Position */
} __packed;
+struct rtw89_btc_fbtc_gpio_dbg_v7 {
+ u8 fver;
+ u8 rsvd0;
+ u8 rsvd1;
+ u8 rsvd2;
+
+ u8 gpio_map[BTC_DBG_MAX1];
+
+ __le32 en_map;
+ __le32 pre_state;
+} __packed;
+
+union rtw89_btc_fbtc_gpio_dbg {
+ struct rtw89_btc_fbtc_gpio_dbg_v1 v1;
+ struct rtw89_btc_fbtc_gpio_dbg_v7 v7;
+};
+
struct rtw89_btc_fbtc_mreg_val_v1 {
u8 fver; /* btc_ver::fcxmreg */
u8 reg_num;
@@ -2204,9 +2442,18 @@ struct rtw89_btc_fbtc_mreg_val_v2 {
__le32 mreg_val[CXMREG_MAX_V2];
} __packed;
+struct rtw89_btc_fbtc_mreg_val_v7 {
+ u8 fver;
+ u8 reg_num;
+ u8 rsvd0;
+ u8 rsvd1;
+ __le32 mreg_val[CXMREG_MAX_V2];
+} __packed;
+
union rtw89_btc_fbtc_mreg_val {
struct rtw89_btc_fbtc_mreg_val_v1 v1;
struct rtw89_btc_fbtc_mreg_val_v2 v2;
+ struct rtw89_btc_fbtc_mreg_val_v7 v7;
};
#define RTW89_DEF_FBTC_MREG(__type, __bytes, __offset) \
@@ -2233,6 +2480,40 @@ struct rtw89_btc_fbtc_slots {
struct rtw89_btc_fbtc_slot slot[CXST_MAX];
} __packed;
+struct rtw89_btc_fbtc_slot_v7 {
+ __le16 dur; /* slot duration */
+ __le16 cxtype;
+ __le32 cxtbl;
+} __packed;
+
+struct rtw89_btc_fbtc_slot_u16 {
+ __le16 dur; /* slot duration */
+ __le16 cxtype;
+ __le16 cxtbl_l16; /* coex table [15:0] */
+ __le16 cxtbl_h16; /* coex table [31:16] */
+} __packed;
+
+struct rtw89_btc_fbtc_1slot_v7 {
+ u8 fver;
+ u8 sid; /* slot id */
+ __le16 rsvd;
+ struct rtw89_btc_fbtc_slot_v7 slot;
+} __packed;
+
+struct rtw89_btc_fbtc_slots_v7 {
+ u8 fver;
+ u8 slot_cnt;
+ u8 rsvd0;
+ u8 rsvd1;
+ struct rtw89_btc_fbtc_slot_u16 slot[CXST_MAX];
+ __le32 update_map;
+} __packed;
+
+union rtw89_btc_fbtc_slots_info {
+ struct rtw89_btc_fbtc_slots v1;
+ struct rtw89_btc_fbtc_slots_v7 v7;
+} __packed;
+
struct rtw89_btc_fbtc_step {
u8 type;
u8 val;
@@ -2339,6 +2620,12 @@ struct rtw89_btc_fbtc_cycle_leak_info {
__le16 tmax; /* max leak-slot time */
} __packed;
+struct rtw89_btc_fbtc_cycle_leak_info_v7 {
+ __le16 tavg;
+ __le16 tamx;
+ __le32 cnt_rximr;
+} __packed;
+
#define RTW89_BTC_FDDT_PHASE_CYCLE GENMASK(9, 0)
#define RTW89_BTC_FDDT_TRAIN_STEP GENMASK(15, 10)
@@ -2451,11 +2738,36 @@ struct rtw89_btc_fbtc_cysta_v5 { /* statistics for cycles */
__le32 except_map;
} __packed;
+struct rtw89_btc_fbtc_cysta_v7 { /* statistics for cycles */
+ u8 fver;
+ u8 rsvd;
+ u8 collision_cnt; /* counter for event/timer occur at the same time */
+ u8 except_cnt;
+
+ u8 wl_rx_err_ratio[BTC_CYCLE_SLOT_MAX];
+
+ struct rtw89_btc_fbtc_a2dp_trx_stat_v4 a2dp_trx[BTC_CYCLE_SLOT_MAX];
+
+ __le16 skip_cnt;
+ __le16 cycles; /* total cycle number */
+
+ __le16 slot_step_time[BTC_CYCLE_SLOT_MAX]; /* record the wl/bt slot time */
+ __le16 slot_cnt[CXST_MAX]; /* slot count */
+ __le16 bcn_cnt[CXBCN_MAX];
+
+ struct rtw89_btc_fbtc_cycle_time_info_v5 cycle_time;
+ struct rtw89_btc_fbtc_cycle_a2dp_empty_info a2dp_ept;
+ struct rtw89_btc_fbtc_cycle_leak_info_v7 leak_slot;
+
+ __le32 except_map;
+} __packed;
+
union rtw89_btc_fbtc_cysta_info {
struct rtw89_btc_fbtc_cysta_v2 v2;
struct rtw89_btc_fbtc_cysta_v3 v3;
struct rtw89_btc_fbtc_cysta_v4 v4;
struct rtw89_btc_fbtc_cysta_v5 v5;
+ struct rtw89_btc_fbtc_cysta_v7 v7;
};
struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */
@@ -2476,12 +2788,24 @@ struct rtw89_btc_fbtc_cynullsta_v2 { /* cycle null statistics */
__le32 result[2][5]; /* 0:fail, 1:ok, 2:on_time, 3:retry, 4:tx */
} __packed;
+struct rtw89_btc_fbtc_cynullsta_v7 { /* cycle null statistics */
+ u8 fver;
+ u8 rsvd0;
+ u8 rsvd1;
+ u8 rsvd2;
+
+ __le32 tmax[2];
+ __le32 tavg[2];
+ __le32 result[2][5];
+} __packed;
+
union rtw89_btc_fbtc_cynullsta_info {
struct rtw89_btc_fbtc_cynullsta_v1 v1; /* info from fw */
struct rtw89_btc_fbtc_cynullsta_v2 v2;
+ struct rtw89_btc_fbtc_cynullsta_v7 v7;
};
-struct rtw89_btc_fbtc_btver {
+struct rtw89_btc_fbtc_btver_v1 {
u8 fver; /* btc_ver::fcxbtver */
u8 rsvd;
__le16 rsvd2;
@@ -2490,6 +2814,22 @@ struct rtw89_btc_fbtc_btver {
__le32 feature;
} __packed;
+struct rtw89_btc_fbtc_btver_v7 {
+ u8 fver;
+ u8 rsvd0;
+ u8 rsvd1;
+ u8 rsvd2;
+
+ __le32 coex_ver; /*bit[15:8]->shared, bit[7:0]->non-shared */
+ __le32 fw_ver;
+ __le32 feature;
+} __packed;
+
+union rtw89_btc_fbtc_btver {
+ struct rtw89_btc_fbtc_btver_v1 v1;
+ struct rtw89_btc_fbtc_btver_v7 v7;
+} __packed;
+
struct rtw89_btc_fbtc_btafh {
u8 fver; /* btc_ver::fcxbtafh */
u8 rsvd;
@@ -2511,6 +2851,18 @@ struct rtw89_btc_fbtc_btafh_v2 {
u8 afh_le_b[4];
} __packed;
+struct rtw89_btc_fbtc_btafh_v7 {
+ u8 fver;
+ u8 map_type;
+ u8 rsvd0;
+ u8 rsvd1;
+ u8 afh_l[4]; /*bit0:2402, bit1:2403.... bit31:2433 */
+ u8 afh_m[4]; /*bit0:2434, bit1:2435.... bit31:2465 */
+ u8 afh_h[4]; /*bit0:2466, bit1:2467.....bit14:2480 */
+ u8 afh_le_a[4];
+ u8 afh_le_b[4];
+} __packed;
+
struct rtw89_btc_fbtc_btdevinfo {
u8 fver; /* btc_ver::fcxbtdevinfo */
u8 rsvd;
@@ -2551,9 +2903,14 @@ struct rtw89_btc_trx_info {
u32 rx_err_ratio;
};
+union rtw89_btc_fbtc_slot_u {
+ struct rtw89_btc_fbtc_slot v1[CXST_MAX];
+ struct rtw89_btc_fbtc_slot_v7 v7[CXST_MAX];
+};
+
struct rtw89_btc_dm {
- struct rtw89_btc_fbtc_slot slot[CXST_MAX];
- struct rtw89_btc_fbtc_slot slot_now[CXST_MAX];
+ union rtw89_btc_fbtc_slot_u slot;
+ union rtw89_btc_fbtc_slot_u slot_now;
struct rtw89_btc_fbtc_tdma tdma;
struct rtw89_btc_fbtc_tdma tdma_now;
struct rtw89_mac_ax_coex_gnt gnt;
@@ -2569,6 +2926,8 @@ struct rtw89_btc_dm {
u32 update_slot_map;
u32 set_ant_path;
+ u32 e2g_slot_limit;
+ u32 e2g_slot_nulltx_time;
u32 wl_only: 1;
u32 wl_fw_cx_offload: 1;
@@ -2589,13 +2948,17 @@ struct rtw89_btc_dm {
u32 wl_btg_rx_rb: 2;
u16 slot_dur[CXST_MAX];
+ u16 bt_slot_flood;
u8 run_reason;
u8 run_action;
u8 wl_pre_agc: 2;
u8 wl_lna2: 1;
+ u8 freerun_chk: 1;
u8 wl_pre_agc_rb: 2;
+ u8 bt_select: 2; /* 0:s0, 1:s1, 2:s0 & s1, refer to enum btc_bt_index */
+ u8 slot_req_more: 1;
};
struct rtw89_btc_ctrl {
@@ -2631,6 +2994,8 @@ enum rtw89_btc_btf_fw_event {
BTF_EVNT_BT_REG = 3,
BTF_EVNT_CX_RUNINFO = 4,
BTF_EVNT_BT_PSD = 5,
+ BTF_EVNT_BT_DEV_INFO = 6, /* fwc2hfunc > 0 */
+ BTF_EVNT_BT_LEAUDIO_INFO = 7, /* fwc2hfunc > 1 */
BTF_EVNT_BUF_OVERFLOW,
BTF_EVNT_C2H_LOOPBACK,
BTF_EVNT_MAX,
@@ -2643,6 +3008,7 @@ enum btf_fw_event_report {
BTC_RPT_TYPE_CYSTA,
BTC_RPT_TYPE_STEP,
BTC_RPT_TYPE_NULLSTA,
+ BTC_RPT_TYPE_FDDT, /* added by ver->fwevntrptl == 1 */
BTC_RPT_TYPE_MREG,
BTC_RPT_TYPE_GPIO_DBG,
BTC_RPT_TYPE_BT_VER,
@@ -2650,7 +3016,10 @@ enum btf_fw_event_report {
BTC_RPT_TYPE_BT_AFH,
BTC_RPT_TYPE_BT_DEVICE,
BTC_RPT_TYPE_TEST,
- BTC_RPT_TYPE_MAX = 31
+ BTC_RPT_TYPE_MAX = 31,
+
+ __BTC_RPT_TYPE_V0_SAME = BTC_RPT_TYPE_NULLSTA,
+ __BTC_RPT_TYPE_V0_MAX = 12,
};
enum rtw_btc_btf_reg_type {
@@ -2677,6 +3046,7 @@ struct rtw89_btc_rpt_cmn_info {
union rtw89_btc_fbtc_btafh_info {
struct rtw89_btc_fbtc_btafh v1;
struct rtw89_btc_fbtc_btafh_v2 v2;
+ struct rtw89_btc_fbtc_btafh_v7 v7;
};
struct rtw89_btc_report_ctrl_state {
@@ -2691,7 +3061,7 @@ struct rtw89_btc_rpt_fbtc_tdma {
struct rtw89_btc_rpt_fbtc_slots {
struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */
- struct rtw89_btc_fbtc_slots finfo; /* info from fw */
+ union rtw89_btc_fbtc_slots_info finfo; /* info from fw */
};
struct rtw89_btc_rpt_fbtc_cysta {
@@ -2716,12 +3086,12 @@ struct rtw89_btc_rpt_fbtc_mreg {
struct rtw89_btc_rpt_fbtc_gpio_dbg {
struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */
- struct rtw89_btc_fbtc_gpio_dbg finfo; /* info from fw */
+ union rtw89_btc_fbtc_gpio_dbg finfo; /* info from fw */
};
struct rtw89_btc_rpt_fbtc_btver {
struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */
- struct rtw89_btc_fbtc_btver finfo; /* info from fw */
+ union rtw89_btc_fbtc_btver finfo; /* info from fw */
};
struct rtw89_btc_rpt_fbtc_btscan {
@@ -2792,6 +3162,8 @@ struct rtw89_btc_ver {
u8 fcxctrl;
u8 fcxinit;
+ u8 fwevntrptl;
+ u8 fwc2hfunc;
u8 drvinfo_type;
u16 info_buf;
u8 max_role_num;
@@ -2809,10 +3181,10 @@ struct rtw89_btc {
struct rtw89_btc_btf_fwinfo fwinfo;
struct rtw89_btc_dbg dbg;
- struct work_struct eapol_notify_work;
- struct work_struct arp_notify_work;
- struct work_struct dhcp_notify_work;
- struct work_struct icmp_notify_work;
+ struct wiphy_work eapol_notify_work;
+ struct wiphy_work arp_notify_work;
+ struct wiphy_work dhcp_notify_work;
+ struct wiphy_work icmp_notify_work;
u32 bt_req_len;
@@ -2821,6 +3193,7 @@ struct rtw89_btc {
u8 btg_pos;
u16 policy_len;
u16 policy_type;
+ u32 hubmsg_cnt;
bool bt_req_en;
bool update_policy_force;
bool lps;
@@ -2981,7 +3354,6 @@ struct rtw89_addr_cam_entry {
DECLARE_BITMAP(sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM);
u8 sec_ent_keyid[RTW89_SEC_CAM_IN_ADDR_CAM];
u8 sec_ent[RTW89_SEC_CAM_IN_ADDR_CAM];
- struct rtw89_sec_cam_entry *sec_entries[RTW89_SEC_CAM_IN_ADDR_CAM];
};
struct rtw89_bssid_cam_entry {
@@ -3003,14 +3375,18 @@ struct rtw89_sec_cam_entry {
u8 spp_mode : 1;
/* 256 bits */
u8 key[32];
+
+ struct ieee80211_key_conf *key_conf;
};
-struct rtw89_sta {
+struct rtw89_sta_link {
+ struct rtw89_sta *rtwsta;
+ struct list_head dlink_schd;
+ unsigned int link_id;
+
u8 mac_id;
- bool disassoc;
bool er_cap;
- struct rtw89_dev *rtwdev;
- struct rtw89_vif *rtwvif;
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_ra_info ra;
struct rtw89_ra_report ra_report;
int max_agg_wait;
@@ -3018,17 +3394,15 @@ struct rtw89_sta {
struct ewma_rssi avg_rssi;
struct ewma_rssi rssi[RF_PATH_MAX];
struct ewma_snr avg_snr;
+ struct ewma_evm evm_1ss;
struct ewma_evm evm_min[RF_PATH_MAX];
struct ewma_evm evm_max[RF_PATH_MAX];
- struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS];
- DECLARE_BITMAP(ampdu_map, IEEE80211_NUM_TIDS);
struct ieee80211_rx_status rx_status;
u16 rx_hw_rate;
__le32 htc_template;
struct rtw89_addr_cam_entry addr_cam; /* AP mode or TDLS peer only */
struct rtw89_bssid_cam_entry bssid_cam; /* TDLS peer only */
struct list_head ba_cam_list;
- struct sk_buff_head roc_queue;
bool use_cfg_mask;
struct cfg80211_bitrate_mask mask;
@@ -3076,10 +3450,11 @@ enum rtw89_roc_state {
struct rtw89_roc {
struct ieee80211_channel chan;
- struct delayed_work roc_work;
+ struct wiphy_delayed_work roc_work;
enum ieee80211_roc_type type;
enum rtw89_roc_state state;
int duration;
+ unsigned int link_id;
};
#define RTW89_P2P_MAX_NOA_NUM 2
@@ -3110,13 +3485,23 @@ struct rtw89_p2p_noa_setter {
u8 noa_index;
};
-struct rtw89_vif {
- struct list_head list;
- struct rtw89_dev *rtwdev;
- struct rtw89_roc roc;
+struct rtw89_ps_noa_once_handler {
+ bool in_duration;
+ u64 tsf_begin;
+ u64 tsf_end;
+ struct wiphy_delayed_work set_work;
+ struct wiphy_delayed_work clr_work;
+};
+
+struct rtw89_vif_link {
+ struct rtw89_vif *rtwvif;
+ struct list_head dlink_schd;
+ unsigned int link_id;
+
bool chanctx_assigned; /* only valid when running with chanctx_ops */
- enum rtw89_sub_entity_idx sub_entity_idx;
+ enum rtw89_chanctx_idx chanctx_idx;
enum rtw89_reg_6ghz_power reg_6ghz_power;
+ struct rtw89_reg_6ghz_tpe reg_6ghz_tpe;
u8 mac_id;
u8 port;
@@ -3129,10 +3514,11 @@ struct rtw89_vif {
u8 self_role;
u8 wmm;
u8 bcn_hit_cond;
+ u8 bcn_bw_idx;
u8 hit_rule;
u8 last_noa_nr;
u64 sync_bcn_tsf;
- bool offchan;
+ bool rand_tsf_done;
bool trigger;
bool lsig_txop;
u8 tgt_ind;
@@ -3146,17 +3532,14 @@ struct rtw89_vif {
bool pre_pwr_diff_en;
bool pwr_diff_en;
u8 def_tri_idx;
- u32 tdls_peer;
- struct work_struct update_beacon_work;
+ struct wiphy_work update_beacon_work;
struct rtw89_addr_cam_entry addr_cam;
struct rtw89_bssid_cam_entry bssid_cam;
struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS];
- struct rtw89_traffic_stats stats;
struct rtw89_phy_rate_pattern rate_pattern;
- struct cfg80211_scan_request *scan_req;
- struct ieee80211_scan_ies *scan_ies;
struct list_head general_pkt_list;
struct rtw89_p2p_noa_setter p2p_noa;
+ struct rtw89_ps_noa_once_handler noa_once;
};
enum rtw89_lv1_rcvy_step {
@@ -3247,10 +3630,12 @@ struct rtw89_chip_ops {
void (*rfk_hw_init)(struct rtw89_dev *rtwdev);
void (*rfk_init)(struct rtw89_dev *rtwdev);
void (*rfk_init_late)(struct rtw89_dev *rtwdev);
- void (*rfk_channel)(struct rtw89_dev *rtwdev);
+ void (*rfk_channel)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
void (*rfk_band_changed)(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx);
- void (*rfk_scan)(struct rtw89_dev *rtwdev, bool start);
+ enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan);
+ void (*rfk_scan)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ bool start);
void (*rfk_track)(struct rtw89_dev *rtwdev);
void (*power_trim)(struct rtw89_dev *rtwdev);
void (*set_txpwr)(struct rtw89_dev *rtwdev,
@@ -3265,11 +3650,18 @@ struct rtw89_chip_ops {
void (*query_ppdu)(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu,
struct ieee80211_rx_status *status);
+ void (*convert_rpl_to_rssi)(struct rtw89_dev *rtwdev,
+ struct rtw89_rx_phy_ppdu *phy_ppdu);
+ void (*phy_rpt_to_rssi)(struct rtw89_dev *rtwdev,
+ struct rtw89_rx_desc_info *desc_info,
+ struct ieee80211_rx_status *rx_status);
void (*ctrl_nbtg_bt_tx)(struct rtw89_dev *rtwdev, bool en,
enum rtw89_phy_idx phy_idx);
void (*cfg_txrx_path)(struct rtw89_dev *rtwdev);
void (*set_txpwr_ul_tb_offset)(struct rtw89_dev *rtwdev,
s8 pw_ofst, enum rtw89_mac_idx mac_idx);
+ void (*digital_pwr_comp)(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx);
int (*pwr_on_func)(struct rtw89_dev *rtwdev);
int (*pwr_off_func)(struct rtw89_dev *rtwdev);
void (*query_rxdesc)(struct rtw89_dev *rtwdev,
@@ -3288,23 +3680,27 @@ struct rtw89_chip_ops {
u32 *tx_en, enum rtw89_sch_tx_sel sel);
int (*resume_sch_tx)(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en);
int (*h2c_dctl_sec_cam)(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int (*h2c_default_cmac_tbl)(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int (*h2c_assoc_cmac_tbl)(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int (*h2c_ampdu_cmac_tbl)(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
+ int (*h2c_txtime_cmac_tbl)(struct rtw89_dev *rtwdev,
+ struct rtw89_sta_link *rtwsta_link);
int (*h2c_default_dmac_tbl)(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int (*h2c_update_beacon)(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif);
- int (*h2c_ba_cam)(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *rtwvif_link);
+ int (*h2c_ba_cam)(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
bool valid, struct ieee80211_ampdu_params *params);
void (*btc_set_rfe)(struct rtw89_dev *rtwdev);
@@ -3381,6 +3777,7 @@ struct rtw89_scan_option {
u16 slow_pd;
u16 norm_cy;
u8 opch_end;
+ u16 delay;
u64 prohib_chan;
enum rtw89_phy_idx band;
enum rtw89_scan_be_operation operation;
@@ -3602,7 +3999,11 @@ struct rtw89_rfe_parms {
struct rtw89_txpwr_rule_2ghz rule_2ghz;
struct rtw89_txpwr_rule_5ghz rule_5ghz;
struct rtw89_txpwr_rule_6ghz rule_6ghz;
+ struct rtw89_txpwr_rule_2ghz rule_da_2ghz;
+ struct rtw89_txpwr_rule_5ghz rule_da_5ghz;
+ struct rtw89_txpwr_rule_6ghz rule_da_6ghz;
struct rtw89_tx_shape tx_shape;
+ bool has_da;
};
struct rtw89_rfe_parms_conf {
@@ -3619,16 +4020,22 @@ struct rtw89_txpwr_conf {
const void *data;
};
+static inline bool rtw89_txpwr_entcpy(void *entry, const void *cursor, u8 size,
+ const struct rtw89_txpwr_conf *conf)
+{
+ u8 valid_size = min(size, conf->ent_sz);
+
+ memcpy(entry, cursor, valid_size);
+ return true;
+}
+
#define rtw89_txpwr_conf_valid(conf) (!!(conf)->data)
#define rtw89_for_each_in_txpwr_conf(entry, cursor, conf) \
- for (typecheck(const void *, cursor), (cursor) = (conf)->data, \
- memcpy(&(entry), cursor, \
- min_t(u8, sizeof(entry), (conf)->ent_sz)); \
+ for (typecheck(const void *, cursor), (cursor) = (conf)->data; \
(cursor) < (conf)->data + (conf)->num_ents * (conf)->ent_sz; \
- (cursor) += (conf)->ent_sz, \
- memcpy(&(entry), cursor, \
- min_t(u8, sizeof(entry), (conf)->ent_sz)))
+ (cursor) += (conf)->ent_sz) \
+ if (rtw89_txpwr_entcpy(&(entry), cursor, sizeof(entry), conf))
struct rtw89_txpwr_byrate_data {
struct rtw89_txpwr_conf conf;
@@ -3691,9 +4098,15 @@ struct rtw89_rfe_data {
struct rtw89_txpwr_lmt_2ghz_data lmt_2ghz;
struct rtw89_txpwr_lmt_5ghz_data lmt_5ghz;
struct rtw89_txpwr_lmt_6ghz_data lmt_6ghz;
+ struct rtw89_txpwr_lmt_2ghz_data da_lmt_2ghz;
+ struct rtw89_txpwr_lmt_5ghz_data da_lmt_5ghz;
+ struct rtw89_txpwr_lmt_6ghz_data da_lmt_6ghz;
struct rtw89_txpwr_lmt_ru_2ghz_data lmt_ru_2ghz;
struct rtw89_txpwr_lmt_ru_5ghz_data lmt_ru_5ghz;
struct rtw89_txpwr_lmt_ru_6ghz_data lmt_ru_6ghz;
+ struct rtw89_txpwr_lmt_ru_2ghz_data da_lmt_ru_2ghz;
+ struct rtw89_txpwr_lmt_ru_5ghz_data da_lmt_ru_5ghz;
+ struct rtw89_txpwr_lmt_ru_6ghz_data da_lmt_ru_6ghz;
struct rtw89_tx_shape_lmt_data tx_shape_lmt;
struct rtw89_tx_shape_lmt_ru_data tx_shape_lmt_ru;
struct rtw89_rfe_parms rfe_parms;
@@ -3776,6 +4189,11 @@ struct rtw89_rrsr_cfgs {
struct rtw89_reg3_def rsc;
};
+struct rtw89_rfkill_regs {
+ struct rtw89_reg3_def pinmux;
+ struct rtw89_reg3_def mode;
+};
+
struct rtw89_dig_regs {
u32 seg0_pd_reg;
u32 pd_lower_bound_mask;
@@ -3802,10 +4220,12 @@ struct rtw89_edcca_regs {
u32 edcca_p_mask;
u32 ppdu_level;
u32 ppdu_mask;
- u32 rpt_a;
- u32 rpt_b;
- u32 rpt_sel;
- u32 rpt_sel_mask;
+ struct rtw89_edcca_p_regs {
+ u32 rpt_a;
+ u32 rpt_b;
+ u32 rpt_sel;
+ u32 rpt_sel_mask;
+ } p[RTW89_PHY_NUM];
u32 rpt_sel_be;
u32 rpt_sel_be_mask;
u32 tx_collision_t2r_st;
@@ -3844,6 +4264,7 @@ enum rtw89_chanctx_state {
enum rtw89_chanctx_callbacks {
RTW89_CHANCTX_CALLBACK_PLACEHOLDER,
RTW89_CHANCTX_CALLBACK_RFK,
+ RTW89_CHANCTX_CALLBACK_TAS,
NUM_OF_RTW89_CHANCTX_CALLBACKS,
};
@@ -3864,6 +4285,7 @@ struct rtw89_chip_info {
bool try_ce_fw;
u8 bbmcu_nr;
u32 needed_fw_elms;
+ const struct rtw89_fw_blacklist *fw_blacklist;
u32 fifo_size;
bool small_fifo_size;
u32 dle_scc_rsvd_size;
@@ -3875,13 +4297,24 @@ struct rtw89_chip_info {
u8 wde_qempty_acq_grpnum;
u8 wde_qempty_mgq_grpsel;
u32 rf_base_addr[2];
+ u8 thermal_th[2];
+ u8 support_macid_num;
+ u8 support_link_num;
u8 support_chanctx_num;
u8 support_bands;
u16 support_bandwidths;
bool support_unii4;
+ bool support_rnr;
+ bool support_ant_gain;
+ bool support_tas;
+ bool support_sar_by_ant;
bool ul_tb_waveform_ctrl;
bool ul_tb_pwr_diff;
+ bool rx_freq_frome_ie;
bool hw_sec_hdr;
+ bool hw_mgmt_tx_encrypt;
+ bool hw_tkip_crypto;
+ bool hw_mlo_bmc_crypto;
u8 rf_path_num;
u8 tx_nss;
u8 rx_nss;
@@ -3919,6 +4352,7 @@ struct rtw89_chip_info {
const struct rtw89_rfe_parms *dflt_parms;
const struct rtw89_chanctx_listener *chanctx_listener;
+ u8 txpwr_factor_bb;
u8 txpwr_factor_rf;
u8 txpwr_factor_mac;
@@ -3954,7 +4388,7 @@ struct rtw89_chip_info {
const u32 *c2h_regs;
struct rtw89_reg_def c2h_counter_reg;
const struct rtw89_page_regs *page_regs;
- u32 wow_reason_reg;
+ const u32 *wow_reason_reg;
bool cfo_src_fd;
bool cfo_hw_comp;
const struct rtw89_reg_def *dcfo_comp;
@@ -3965,18 +4399,27 @@ struct rtw89_chip_info {
const struct rtw89_rrsr_cfgs *rrsr_cfgs;
struct rtw89_reg_def bss_clr_vld;
u32 bss_clr_map_reg;
+ const struct rtw89_rfkill_regs *rfkill_init;
+ struct rtw89_reg_def rfkill_get;
u32 dma_ch_mask;
const struct rtw89_edcca_regs *edcca_regs;
const struct wiphy_wowlan_support *wowlan_stub;
const struct rtw89_xtal_info *xtal_info;
};
+struct rtw89_chip_variant {
+ bool no_mcs_12_13: 1;
+ u32 fw_min_ver_code;
+};
+
union rtw89_bus_info {
const struct rtw89_pci_info *pci;
};
struct rtw89_driver_info {
const struct rtw89_chip_info *chip;
+ const struct rtw89_chip_variant *variant;
+ const struct dmi_system_id *quirks;
union rtw89_bus_info bus;
};
@@ -4034,6 +4477,8 @@ struct rtw89_mac_info {
/* see RTW89_FW_OFLD_WAIT_COND series for wait condition */
struct rtw89_wait_info fw_ofld_wait;
+ /* see RTW89_PS_WAIT_COND series for wait condition */
+ struct rtw89_wait_info ps_wait;
};
enum rtw89_fwdl_check_type {
@@ -4063,6 +4508,18 @@ enum rtw89_fw_feature {
RTW89_FW_FEATURE_NO_LPS_PG,
RTW89_FW_FEATURE_BEACON_FILTER,
RTW89_FW_FEATURE_MACID_PAUSE_SLEEP,
+ RTW89_FW_FEATURE_SCAN_OFFLOAD_BE_V0,
+ RTW89_FW_FEATURE_WOW_REASON_V1,
+ RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0,
+ RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V1,
+ RTW89_FW_FEATURE_RFK_RXDCK_V0,
+ RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX,
+ RTW89_FW_FEATURE_NOTIFY_AP_INFO,
+ RTW89_FW_FEATURE_CH_INFO_BE_V0,
+ RTW89_FW_FEATURE_LPS_CH_INFO,
+ RTW89_FW_FEATURE_NO_PHYCAP_P1,
+ RTW89_FW_FEATURE_NO_POWER_DIFFERENCE,
+ RTW89_FW_FEATURE_BEACON_LOSS_COUNT_V1,
};
struct rtw89_fw_suit {
@@ -4121,6 +4578,7 @@ struct rtw89_fw_elm_info {
struct rtw89_phy_table *rf_nctl;
struct rtw89_fw_txpwr_track_cfg *txpwr_trk;
struct rtw89_phy_rfk_log_fmt *rfk_log_fmt;
+ const struct rtw89_regd_data *regd;
};
enum rtw89_fw_mss_dev_type {
@@ -4129,11 +4587,14 @@ enum rtw89_fw_mss_dev_type {
};
struct rtw89_fw_secure {
- bool secure_boot;
+ bool secure_boot: 1;
+ bool can_mss_v1: 1;
+ bool can_mss_v0: 1;
u32 sb_sel_mgn;
u8 mss_dev_type;
u8 mss_cust_idx;
u8 mss_key_num;
+ u8 mss_idx; /* v0 */
};
struct rtw89_fw_info {
@@ -4165,11 +4626,13 @@ struct rtw89_cam_info {
DECLARE_BITMAP(sec_cam_map, RTW89_MAX_SEC_CAM_NUM);
DECLARE_BITMAP(ba_cam_map, RTW89_MAX_BA_CAM_NUM);
struct rtw89_ba_cam_entry ba_cam_entry[RTW89_MAX_BA_CAM_NUM];
+ const struct rtw89_sec_cam_entry *sec_entries[RTW89_MAX_SEC_CAM_NUM];
};
enum rtw89_sar_sources {
RTW89_SAR_SOURCE_NONE,
RTW89_SAR_SOURCE_COMMON,
+ RTW89_SAR_SOURCE_ACPI,
RTW89_SAR_SOURCE_NR,
};
@@ -4178,7 +4641,7 @@ enum rtw89_sar_subband {
RTW89_SAR_2GHZ_SUBBAND,
RTW89_SAR_5GHZ_SUBBAND_1_2, /* U-NII-1 and U-NII-2 */
RTW89_SAR_5GHZ_SUBBAND_2_E, /* U-NII-2-Extended */
- RTW89_SAR_5GHZ_SUBBAND_3, /* U-NII-3 */
+ RTW89_SAR_5GHZ_SUBBAND_3_4, /* U-NII-3 and U-NII-4 */
RTW89_SAR_6GHZ_SUBBAND_5_L, /* U-NII-5 lower part */
RTW89_SAR_6GHZ_SUBBAND_5_H, /* U-NII-5 higher part */
RTW89_SAR_6GHZ_SUBBAND_6, /* U-NII-6 */
@@ -4194,8 +4657,62 @@ struct rtw89_sar_cfg_common {
s32 cfg[RTW89_SAR_SUBBAND_NR];
};
+enum rtw89_acpi_sar_subband {
+ RTW89_ACPI_SAR_2GHZ_SUBBAND,
+ RTW89_ACPI_SAR_5GHZ_SUBBAND_1, /* U-NII-1 */
+ RTW89_ACPI_SAR_5GHZ_SUBBAND_2, /* U-NII-2 */
+ RTW89_ACPI_SAR_5GHZ_SUBBAND_2E, /* U-NII-2-Extended */
+ RTW89_ACPI_SAR_5GHZ_SUBBAND_3_4, /* U-NII-3 and U-NII-4 */
+ RTW89_ACPI_SAR_6GHZ_SUBBAND_5_L, /* U-NII-5 lower part */
+ RTW89_ACPI_SAR_6GHZ_SUBBAND_5_H, /* U-NII-5 higher part */
+ RTW89_ACPI_SAR_6GHZ_SUBBAND_6, /* U-NII-6 */
+ RTW89_ACPI_SAR_6GHZ_SUBBAND_7_L, /* U-NII-7 lower part */
+ RTW89_ACPI_SAR_6GHZ_SUBBAND_7_H, /* U-NII-7 higher part */
+ RTW89_ACPI_SAR_6GHZ_SUBBAND_8, /* U-NII-8 */
+
+ NUM_OF_RTW89_ACPI_SAR_SUBBAND,
+ RTW89_ACPI_SAR_SUBBAND_NR_LEGACY = RTW89_ACPI_SAR_5GHZ_SUBBAND_3_4 + 1,
+ RTW89_ACPI_SAR_SUBBAND_NR_HAS_6GHZ = RTW89_ACPI_SAR_6GHZ_SUBBAND_8 + 1,
+};
+
+#define TXPWR_FACTOR_OF_RTW89_ACPI_SAR 3 /* unit: 0.125 dBm */
+#define MAX_VAL_OF_RTW89_ACPI_SAR S16_MAX
+#define MIN_VAL_OF_RTW89_ACPI_SAR S16_MIN
+#define MAX_NUM_OF_RTW89_ACPI_SAR_TBL 6
+#define NUM_OF_RTW89_ACPI_SAR_RF_PATH (RF_PATH_B + 1)
+
+struct rtw89_sar_entry_from_acpi {
+ s16 v[NUM_OF_RTW89_ACPI_SAR_SUBBAND][NUM_OF_RTW89_ACPI_SAR_RF_PATH];
+};
+
+struct rtw89_sar_table_from_acpi {
+ /* If this table is active, must fill all fields according to either
+ * configuration in BIOS or some default values for SAR to work well.
+ */
+ struct rtw89_sar_entry_from_acpi entries[RTW89_REGD_NUM];
+};
+
+struct rtw89_sar_indicator_from_acpi {
+ bool enable_sync;
+ unsigned int fields;
+ u8 (*rfpath_to_antidx)(enum rtw89_rf_path rfpath);
+
+ /* Select among @tables of container, rtw89_sar_cfg_acpi, by path.
+ * Not design with pointers since addresses will be invalid after
+ * sync content with local container instance.
+ */
+ u8 tblsel[NUM_OF_RTW89_ACPI_SAR_RF_PATH];
+};
+
+struct rtw89_sar_cfg_acpi {
+ u8 downgrade_2tx;
+ unsigned int valid_num;
+ struct rtw89_sar_table_from_acpi tables[MAX_NUM_OF_RTW89_ACPI_SAR_TBL];
+ struct rtw89_sar_indicator_from_acpi indicator;
+};
+
struct rtw89_sar_info {
- /* used to decide how to acces SAR cfg union */
+ /* used to decide how to access SAR cfg union */
enum rtw89_sar_sources src;
/* reserved for different knids of SAR cfg struct.
@@ -4203,28 +4720,83 @@ struct rtw89_sar_info {
*/
union {
struct rtw89_sar_cfg_common cfg_common;
+ struct rtw89_sar_cfg_acpi cfg_acpi;
};
};
+enum rtw89_ant_gain_subband {
+ RTW89_ANT_GAIN_2GHZ_SUBBAND,
+ RTW89_ANT_GAIN_5GHZ_SUBBAND_1, /* U-NII-1 */
+ RTW89_ANT_GAIN_5GHZ_SUBBAND_2, /* U-NII-2 */
+ RTW89_ANT_GAIN_5GHZ_SUBBAND_2E, /* U-NII-2-Extended */
+ RTW89_ANT_GAIN_5GHZ_SUBBAND_3_4, /* U-NII-3 and U-NII-4 */
+ RTW89_ANT_GAIN_6GHZ_SUBBAND_5_L, /* U-NII-5 lower part */
+ RTW89_ANT_GAIN_6GHZ_SUBBAND_5_H, /* U-NII-5 higher part */
+ RTW89_ANT_GAIN_6GHZ_SUBBAND_6, /* U-NII-6 */
+ RTW89_ANT_GAIN_6GHZ_SUBBAND_7_L, /* U-NII-7 lower part */
+ RTW89_ANT_GAIN_6GHZ_SUBBAND_7_H, /* U-NII-7 higher part */
+ RTW89_ANT_GAIN_6GHZ_SUBBAND_8, /* U-NII-8 */
+
+ RTW89_ANT_GAIN_SUBBAND_NR,
+};
+
+enum rtw89_ant_gain_domain_type {
+ RTW89_ANT_GAIN_ETSI = 0,
+
+ RTW89_ANT_GAIN_DOMAIN_NUM,
+};
+
+#define RTW89_ANT_GAIN_CHAIN_NUM 2
+struct rtw89_ant_gain_info {
+ s8 offset[RTW89_ANT_GAIN_CHAIN_NUM][RTW89_ANT_GAIN_SUBBAND_NR];
+ u32 regd_enabled;
+ bool block_country;
+};
+
+struct rtw89_6ghz_span {
+ enum rtw89_sar_subband sar_subband_low;
+ enum rtw89_sar_subband sar_subband_high;
+ enum rtw89_acpi_sar_subband acpi_sar_subband_low;
+ enum rtw89_acpi_sar_subband acpi_sar_subband_high;
+ enum rtw89_ant_gain_subband ant_gain_subband_low;
+ enum rtw89_ant_gain_subband ant_gain_subband_high;
+};
+
+#define RTW89_SAR_SPAN_VALID(span) ((span)->sar_subband_high)
+#define RTW89_ACPI_SAR_SPAN_VALID(span) ((span)->acpi_sar_subband_high)
+#define RTW89_ANT_GAIN_SPAN_VALID(span) ((span)->ant_gain_subband_high)
+
enum rtw89_tas_state {
RTW89_TAS_STATE_DPR_OFF,
RTW89_TAS_STATE_DPR_ON,
- RTW89_TAS_STATE_DPR_FORBID,
+ RTW89_TAS_STATE_STATIC_SAR,
};
-#define RTW89_TAS_MAX_WINDOW 50
+#define RTW89_TAS_TX_RATIO_WINDOW 6
+#define RTW89_TAS_TXPWR_WINDOW 180
struct rtw89_tas_info {
- s16 txpwr_history[RTW89_TAS_MAX_WINDOW];
- s32 total_txpwr;
- u8 cur_idx;
- s8 dpr_gap;
- s8 delta;
+ u16 tx_ratio_history[RTW89_TAS_TX_RATIO_WINDOW];
+ u64 txpwr_history[RTW89_TAS_TXPWR_WINDOW];
+ u8 enabled_countries;
+ u8 txpwr_head_idx;
+ u8 txpwr_tail_idx;
+ u8 tx_ratio_idx;
+ u16 total_tx_ratio;
+ u64 total_txpwr;
+ u64 instant_txpwr;
+ u32 window_size;
+ s8 dpr_on_threshold;
+ s8 dpr_off_threshold;
+ enum rtw89_tas_state backup_state;
enum rtw89_tas_state state;
+ bool keep_history;
+ bool block_regd;
bool enable;
+ bool pause;
};
struct rtw89_chanctx_cfg {
- enum rtw89_sub_entity_idx idx;
+ enum rtw89_chanctx_idx idx;
int ref_count;
};
@@ -4240,7 +4812,7 @@ enum rtw89_chanctx_changes {
};
enum rtw89_entity_mode {
- RTW89_ENTITY_MODE_SCC,
+ RTW89_ENTITY_MODE_SCC_OR_SMLD,
RTW89_ENTITY_MODE_MCC_PREPARE,
RTW89_ENTITY_MODE_MCC,
@@ -4249,7 +4821,17 @@ enum rtw89_entity_mode {
RTW89_ENTITY_MODE_UNHANDLED = -ESRCH,
};
-struct rtw89_sub_entity {
+#define RTW89_MAX_INTERFACE_NUM 2
+
+/* only valid when running with chanctx_ops */
+struct rtw89_entity_mgnt {
+ struct list_head active_list;
+ struct rtw89_vif *active_roles[RTW89_MAX_INTERFACE_NUM];
+ enum rtw89_chanctx_idx chanctx_tbl[RTW89_MAX_INTERFACE_NUM]
+ [__RTW89_MLD_MAX_LINK_NUM];
+};
+
+struct rtw89_chanctx {
struct cfg80211_chan_def chandef;
struct rtw89_chan chan;
struct rtw89_chan_rcd rcd;
@@ -4267,8 +4849,14 @@ struct rtw89_edcca_bak {
enum rtw89_dm_type {
RTW89_DM_DYNAMIC_EDCCA,
+ RTW89_DM_THERMAL_PROTECT,
+ RTW89_DM_TAS,
+ RTW89_DM_MLO,
};
+#define RTW89_THERMAL_PROT_LV_MAX 5
+#define RTW89_THERMAL_PROT_STEP 5 /* -5% for each level */
+
struct rtw89_hal {
u32 rx_fltr;
u8 cv;
@@ -4282,19 +4870,25 @@ struct rtw89_hal {
bool ant_diversity_fixed;
bool support_cckpd;
bool support_igi;
- atomic_t roc_entity_idx;
+ bool no_mcs_12_13;
+
+ atomic_t roc_chanctx_idx;
+ u8 roc_link_index;
DECLARE_BITMAP(changes, NUM_OF_RTW89_CHANCTX_CHANGES);
- DECLARE_BITMAP(entity_map, NUM_OF_RTW89_SUB_ENTITY);
- struct rtw89_sub_entity sub[NUM_OF_RTW89_SUB_ENTITY];
+ DECLARE_BITMAP(entity_map, NUM_OF_RTW89_CHANCTX);
+ struct rtw89_chanctx chanctx[NUM_OF_RTW89_CHANCTX];
struct cfg80211_chan_def roc_chandef;
- bool entity_active;
+ bool entity_active[RTW89_PHY_NUM];
bool entity_pause;
enum rtw89_entity_mode entity_mode;
+ struct rtw89_entity_mgnt entity_mgnt;
- struct rtw89_edcca_bak edcca_bak;
u32 disabled_dm_bitmap; /* bitmap of enum rtw89_dm_type */
+
+ u8 thermal_prot_th;
+ u8 thermal_prot_lv; /* 0 ~ RTW89_THERMAL_PROT_LV_MAX */
};
#define RTW89_MAX_MAC_ID_NUM 128
@@ -4320,10 +4914,29 @@ enum rtw89_flags {
RTW89_FLAG_WOWLAN,
RTW89_FLAG_FORBIDDEN_TRACK_WROK,
RTW89_FLAG_CHANGING_INTERFACE,
+ RTW89_FLAG_HW_RFKILL_STATE,
NUM_OF_RTW89_FLAGS,
};
+enum rtw89_quirks {
+ RTW89_QUIRK_PCI_BER,
+ RTW89_QUIRK_THERMAL_PROT_120C,
+ RTW89_QUIRK_THERMAL_PROT_110C,
+
+ NUM_OF_RTW89_QUIRKS,
+};
+
+enum rtw89_custid {
+ RTW89_CUSTID_NONE,
+ RTW89_CUSTID_ACER,
+ RTW89_CUSTID_AMD,
+ RTW89_CUSTID_ASUS,
+ RTW89_CUSTID_DELL,
+ RTW89_CUSTID_HP,
+ RTW89_CUSTID_LENOVO,
+};
+
enum rtw89_pkt_drop_sel {
RTW89_PKT_DROP_SEL_MACID_BE_ONCE,
RTW89_PKT_DROP_SEL_MACID_BK_ONCE,
@@ -4353,6 +4966,7 @@ struct rtw89_pkt_drop_params {
struct rtw89_pkt_stat {
u16 beacon_nr;
+ u8 beacon_rate;
u32 rx_rate_cnt[RTW89_HW_RATE_NR];
};
@@ -4360,6 +4974,8 @@ DECLARE_EWMA(thermal, 4, 4);
struct rtw89_phy_stat {
struct ewma_thermal avg_thermal[RF_PATH_MAX];
+ u8 last_thermal_max;
+ struct ewma_rssi bcn_rssi;
struct rtw89_pkt_stat cur_pkt_stat;
struct rtw89_pkt_stat last_pkt_stat;
};
@@ -4394,15 +5010,24 @@ struct rtw89_dack_info {
bool msbk_timeout[RTW89_DACK_PATH_NR];
};
-#define RTW89_RFK_CHS_NR 3
+enum rtw89_rfk_chs_nrs {
+ __RTW89_RFK_CHS_NR_V0 = 2,
+ __RTW89_RFK_CHS_NR_V1 = 3,
-struct rtw89_rfk_mcc_info {
+ RTW89_RFK_CHS_NR = __RTW89_RFK_CHS_NR_V1,
+};
+
+struct rtw89_rfk_mcc_info_data {
u8 ch[RTW89_RFK_CHS_NR];
u8 band[RTW89_RFK_CHS_NR];
u8 bw[RTW89_RFK_CHS_NR];
u8 table_idx;
};
+struct rtw89_rfk_mcc_info {
+ struct rtw89_rfk_mcc_info_data data[2];
+};
+
#define RTW89_IQK_CHS_NR 2
#define RTW89_IQK_PATH_NR 4
@@ -4465,7 +5090,7 @@ struct rtw89_dpk_bkup_para {
struct rtw89_dpk_info {
bool is_dpk_enable;
bool is_dpk_reload_en;
- u8 dpk_gs[RTW89_PHY_MAX];
+ u8 dpk_gs[RTW89_PHY_NUM];
u16 dc_i[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM];
u16 dc_q[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM];
u8 corr_val[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM];
@@ -4473,6 +5098,8 @@ struct rtw89_dpk_info {
u8 cur_idx[RTW89_DPK_RF_PATH];
u8 cur_k_set;
struct rtw89_dpk_bkup_para bp[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM];
+ u8 max_dpk_txagc[RTW89_DPK_RF_PATH];
+ u32 dpk_order[RTW89_DPK_RF_PATH];
};
struct rtw89_fem_info {
@@ -4505,6 +5132,7 @@ struct rtw89_agc_gaincode_set {
#define IGI_RSSI_TH_NUM 5
#define FA_TH_NUM 4
+#define TIA_LNA_OP1DB_NUM 8
#define LNA_GAIN_NUM 7
#define TIA_GAIN_NUM 2
struct rtw89_dig_info {
@@ -4624,7 +5252,7 @@ struct rtw89_tssi_info {
u32 alignment_backup_by_ch[RF_PATH_MAX][TSSI_MAX_CH_NUM][TSSI_ALIMK_VALUE_NUM];
u32 alignment_value[RF_PATH_MAX][TSSI_ALIMK_MAX][TSSI_ALIMK_VALUE_NUM];
bool alignment_done[RF_PATH_MAX][TSSI_ALIMK_MAX];
- u32 tssi_alimk_time;
+ u64 tssi_alimk_time;
};
struct rtw89_power_trim_info {
@@ -4635,17 +5263,43 @@ struct rtw89_power_trim_info {
u8 pad_bias_trim[RF_PATH_MAX];
};
+enum rtw89_regd_func {
+ RTW89_REGD_FUNC_TAS = 0, /* TAS (Time Average SAR) */
+ RTW89_REGD_FUNC_DAG = 1, /* DAG (Dynamic Antenna Gain) */
+
+ NUM_OF_RTW89_REGD_FUNC,
+};
+
struct rtw89_regd {
char alpha2[3];
u8 txpwr_regd[RTW89_BAND_NUM];
+ DECLARE_BITMAP(func_bitmap, NUM_OF_RTW89_REGD_FUNC);
+};
+
+struct rtw89_regd_data {
+ unsigned int nr;
+ struct rtw89_regd map[] __counted_by(nr);
+};
+
+struct rtw89_regd_ctrl {
+ unsigned int nr;
+ const struct rtw89_regd *map;
};
#define RTW89_REGD_MAX_COUNTRY_NUM U8_MAX
+#define RTW89_5GHZ_UNII4_CHANNEL_NUM 3
+#define RTW89_5GHZ_UNII4_START_INDEX 25
struct rtw89_regulatory_info {
+ struct rtw89_regd_ctrl ctrl;
const struct rtw89_regd *regd;
enum rtw89_reg_6ghz_power reg_6ghz_power;
+ struct rtw89_reg_6ghz_tpe reg_6ghz_tpe;
+ bool txpwr_uk_follow_etsi;
+
+ DECLARE_BITMAP(block_unii4, RTW89_REGD_MAX_COUNTRY_NUM);
DECLARE_BITMAP(block_6ghz, RTW89_REGD_MAX_COUNTRY_NUM);
+ DECLARE_BITMAP(block_6ghz_sp, RTW89_REGD_MAX_COUNTRY_NUM);
};
enum rtw89_ifs_clm_application {
@@ -4783,8 +5437,8 @@ struct rtw89_lps_parm {
};
struct rtw89_ppdu_sts_info {
- struct sk_buff_head rx_queue[RTW89_PHY_MAX];
- u8 curr_rx_ppdu_cnt[RTW89_PHY_MAX];
+ struct sk_buff_head rx_queue[RTW89_PHY_NUM];
+ u8 curr_rx_ppdu_cnt[RTW89_PHY_NUM];
};
struct rtw89_early_h2c {
@@ -4794,11 +5448,12 @@ struct rtw89_early_h2c {
};
struct rtw89_hw_scan_info {
- struct ieee80211_vif *scanning_vif;
+ struct rtw89_vif_link *scanning_vif;
struct list_head pkt_list[NUM_NL80211_BANDS];
+ struct list_head chan_list;
struct rtw89_chan op_chan;
+ bool connected;
bool abort;
- u32 last_chan_idx;
};
enum rtw89_phy_bb_gain_band {
@@ -4903,8 +5558,8 @@ struct rtw89_phy_efuse_gain {
bool offset_valid;
bool comp_valid;
s8 offset[RF_PATH_MAX][RTW89_GAIN_OFFSET_NR]; /* S(8, 0) */
- s8 offset_base[RTW89_PHY_MAX]; /* S(8, 4) */
- s8 rssi_base[RTW89_PHY_MAX]; /* S(8, 4) */
+ s8 offset_base[RTW89_PHY_NUM]; /* S(8, 4) */
+ s8 rssi_base[RTW89_PHY_NUM]; /* S(8, 4) */
s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */
};
@@ -4925,11 +5580,68 @@ struct rtw89_wow_cam_info {
bool valid;
};
+struct rtw89_wow_key_info {
+ u8 ptk_tx_iv[8];
+ u8 valid_check;
+ u8 symbol_check_en;
+ u8 gtk_keyidx;
+ u8 rsvd[5];
+ u8 ptk_rx_iv[8];
+ u8 gtk_rx_iv[4][8];
+} __packed;
+
+struct rtw89_wow_gtk_info {
+ u8 kck[32];
+ u8 kek[32];
+ u8 tk1[16];
+ u8 txmickey[8];
+ u8 rxmickey[8];
+ __le32 igtk_keyid;
+ __le64 ipn;
+ u8 igtk[2][32];
+ u8 psk[32];
+} __packed;
+
+struct rtw89_wow_aoac_report {
+ u8 rpt_ver;
+ u8 sec_type;
+ u8 key_idx;
+ u8 pattern_idx;
+ u8 rekey_ok;
+ u8 ptk_tx_iv[8];
+ u8 eapol_key_replay_count[8];
+ u8 gtk[32];
+ u8 ptk_rx_iv[8];
+ u8 gtk_rx_iv[4][8];
+ u64 igtk_key_id;
+ u64 igtk_ipn;
+ u8 igtk[32];
+ u8 csa_pri_ch;
+ u8 csa_bw;
+ u8 csa_ch_offset;
+ u8 csa_chsw_failed;
+ u8 csa_ch_band;
+};
+
struct rtw89_wow_param {
- struct ieee80211_vif *wow_vif;
+ struct rtw89_vif_link *rtwvif_link;
DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM);
struct rtw89_wow_cam_info patterns[RTW89_MAX_PATTERN_NUM];
+ struct rtw89_wow_key_info key_info;
+ struct rtw89_wow_gtk_info gtk_info;
+ struct rtw89_wow_aoac_report aoac_rpt;
u8 pattern_cnt;
+ u8 ptk_alg;
+ u8 gtk_alg;
+ u8 ptk_keyidx;
+ u8 akm;
+
+ /* see RTW89_WOW_WAIT_COND series for wait condition */
+ struct rtw89_wait_info wait;
+
+ bool pno_inited;
+ struct list_head pno_pkt_list;
+ struct cfg80211_sched_scan_request *nd_config;
};
struct rtw89_mcc_limit {
@@ -4949,10 +5661,12 @@ struct rtw89_mcc_policy {
};
struct rtw89_mcc_role {
- struct rtw89_vif *rtwvif;
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_mcc_policy policy;
struct rtw89_mcc_limit limit;
+ const struct rtw89_mcc_courtesy_cfg *crtz;
+
/* only valid when running with FW MRC mechanism */
u8 slot_idx;
@@ -4970,13 +5684,16 @@ struct rtw89_mcc_bt_role {
u16 duration; /* TU */
};
-struct rtw89_mcc_courtesy {
- bool enable;
+struct rtw89_mcc_courtesy_cfg {
u8 slot_num;
- u8 macid_src;
u8 macid_tgt;
};
+struct rtw89_mcc_courtesy {
+ struct rtw89_mcc_courtesy_cfg ref;
+ struct rtw89_mcc_courtesy_cfg aux;
+};
+
enum rtw89_mcc_plan {
RTW89_MCC_PLAN_TAIL_BT,
RTW89_MCC_PLAN_MID_BT,
@@ -5010,6 +5727,7 @@ struct rtw89_mcc_config {
struct rtw89_mcc_pattern pattern;
struct rtw89_mcc_sync sync;
u64 start_tsf;
+ u64 start_tsf_in_aux_domain;
u16 mcc_interval; /* TU */
u16 beacon_offset; /* TU */
};
@@ -5030,28 +5748,43 @@ struct rtw89_mcc_info {
struct rtw89_mcc_config config;
};
+enum rtw89_mlo_mode {
+ RTW89_MLO_MODE_MLSR = 0,
+
+ NUM_OF_RTW89_MLO_MODE,
+};
+
+struct rtw89_mlo_info {
+ struct rtw89_wait_info wait;
+};
+
struct rtw89_dev {
struct ieee80211_hw *hw;
struct device *dev;
const struct ieee80211_ops *ops;
bool dbcc_en;
+ bool support_mlo;
enum rtw89_mlo_dbcc_mode mlo_dbcc_mode;
struct rtw89_hw_scan_info scan_info;
const struct rtw89_chip_info *chip;
+ const struct rtw89_chip_variant *variant;
const struct rtw89_pci_info *pci_info;
const struct rtw89_rfe_parms *rfe_parms;
struct rtw89_hal hal;
struct rtw89_mcc_info mcc;
+ struct rtw89_mlo_info mlo;
struct rtw89_mac_info mac;
struct rtw89_fw_info fw;
struct rtw89_hci_info hci;
struct rtw89_efuse efuse;
struct rtw89_traffic_stats stats;
struct rtw89_rfe_data *rfe_data;
+ enum rtw89_custid custid;
+
+ struct rtw89_sta_link __rcu *assoc_link_on_macid[RTW89_MAX_MAC_ID_NUM];
+ refcount_t refcount_ap_info;
- /* ensures exclusive access from mac80211 callbacks */
- struct mutex mutex;
struct list_head rtwvifs_list;
/* used to protect rf read write */
struct mutex rf_mutex;
@@ -5071,10 +5804,10 @@ struct rtw89_dev {
struct rtw89_cam_info cam_info;
struct sk_buff_head c2h_queue;
- struct work_struct c2h_work;
- struct work_struct ips_work;
+ struct wiphy_work c2h_work;
+ struct wiphy_work ips_work;
+ struct wiphy_work cancel_6ghz_probe_work;
struct work_struct load_firmware_work;
- struct work_struct cancel_6ghz_probe_work;
struct list_head early_h2c_list;
@@ -5084,6 +5817,7 @@ struct rtw89_dev {
DECLARE_BITMAP(mac_id_map, RTW89_MAX_MAC_ID_NUM);
DECLARE_BITMAP(flags, NUM_OF_RTW89_FLAGS);
DECLARE_BITMAP(pkt_offload, RTW89_MAX_PKT_OFLD_NUM);
+ DECLARE_BITMAP(quirks, NUM_OF_RTW89_QUIRKS);
struct rtw89_phy_stat phystat;
struct rtw89_rfk_wait_info rfk_wait;
@@ -5102,9 +5836,6 @@ struct rtw89_dev {
struct rtw89_power_trim_info pwr_trim;
struct rtw89_cfo_tracking_info cfo_tracking;
- struct rtw89_env_monitor_info env_monitor;
- struct rtw89_dig_info dig;
- struct rtw89_phy_ch_info ch_info;
union {
struct rtw89_phy_bb_gain_info ax;
struct rtw89_phy_bb_gain_info_be be;
@@ -5113,15 +5844,22 @@ struct rtw89_dev {
struct rtw89_phy_ul_tb_info ul_tb_info;
struct rtw89_antdiv_info antdiv;
- struct delayed_work track_work;
- struct delayed_work chanctx_work;
- struct delayed_work coex_act1_work;
- struct delayed_work coex_bt_devinfo_work;
- struct delayed_work coex_rfk_chk_work;
- struct delayed_work cfo_track_work;
+ struct rtw89_bb_ctx {
+ enum rtw89_phy_idx phy_idx;
+ struct rtw89_env_monitor_info env_monitor;
+ struct rtw89_dig_info dig;
+ struct rtw89_phy_ch_info ch_info;
+ struct rtw89_edcca_bak edcca_bak;
+ } bbs[RTW89_PHY_NUM];
+
+ struct wiphy_delayed_work track_work;
+ struct wiphy_delayed_work chanctx_work;
+ struct wiphy_delayed_work coex_act1_work;
+ struct wiphy_delayed_work coex_bt_devinfo_work;
+ struct wiphy_delayed_work coex_rfk_chk_work;
+ struct wiphy_delayed_work cfo_track_work;
struct delayed_work forbid_ba_work;
- struct delayed_work roc_work;
- struct delayed_work antdiv_work;
+ struct wiphy_delayed_work antdiv_work;
struct rtw89_ppdu_sts_info ppdu_sts;
u8 total_sta_assoc;
bool scanning;
@@ -5129,6 +5867,7 @@ struct rtw89_dev {
struct rtw89_regulatory_info regulatory;
struct rtw89_sar_info sar;
struct rtw89_tas_info tas;
+ struct rtw89_ant_gain_info ant_gain;
struct rtw89_btc btc;
enum rtw89_ps_mode ps_mode;
@@ -5137,14 +5876,184 @@ struct rtw89_dev {
struct rtw89_wow_param wow;
/* napi structure */
- struct net_device netdev;
+ struct net_device *netdev;
struct napi_struct napi;
int napi_budget_countdown;
+ struct rtw89_debugfs *debugfs;
+
/* HCI related data, keep last */
u8 priv[] __aligned(sizeof(void *));
};
+struct rtw89_link_conf_container {
+ struct ieee80211_bss_conf *link_conf[IEEE80211_MLD_MAX_NUM_LINKS];
+};
+
+#define RTW89_VIF_IDLE_LINK_ID 0
+
+struct rtw89_vif {
+ struct rtw89_dev *rtwdev;
+ struct list_head list;
+ struct list_head mgnt_entry;
+ struct rtw89_link_conf_container __rcu *snap_link_confs;
+
+ u8 mac_addr[ETH_ALEN];
+ __be32 ip_addr;
+
+ struct rtw89_traffic_stats stats;
+ u32 tdls_peer;
+
+ struct ieee80211_scan_ies *scan_ies;
+ struct cfg80211_scan_request *scan_req;
+
+ struct rtw89_roc roc;
+ bool offchan;
+
+ enum rtw89_mlo_mode mlo_mode;
+
+ struct list_head dlink_pool;
+ u8 links_inst_valid_num;
+ DECLARE_BITMAP(links_inst_map, __RTW89_MLD_MAX_LINK_NUM);
+ struct rtw89_vif_link *links[IEEE80211_MLD_MAX_NUM_LINKS];
+ struct rtw89_vif_link links_inst[] __counted_by(links_inst_valid_num);
+};
+
+static inline bool rtw89_vif_assign_link_is_valid(struct rtw89_vif_link **rtwvif_link,
+ const struct rtw89_vif *rtwvif,
+ unsigned int link_id)
+{
+ *rtwvif_link = rtwvif->links[link_id];
+ return !!*rtwvif_link;
+}
+
+#define rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) \
+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) \
+ if (rtw89_vif_assign_link_is_valid(&(rtwvif_link), rtwvif, link_id))
+
+enum rtw89_sta_flags {
+ RTW89_REMOTE_STA_IN_PS,
+
+ NUM_OF_RTW89_STA_FLAGS,
+};
+
+struct rtw89_sta {
+ struct rtw89_dev *rtwdev;
+ struct rtw89_vif *rtwvif;
+
+ DECLARE_BITMAP(flags, NUM_OF_RTW89_STA_FLAGS);
+
+ bool disassoc;
+
+ struct sk_buff_head roc_queue;
+
+ struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS];
+ DECLARE_BITMAP(ampdu_map, IEEE80211_NUM_TIDS);
+
+ DECLARE_BITMAP(pairwise_sec_cam_map, RTW89_MAX_SEC_CAM_NUM);
+
+ struct list_head dlink_pool;
+ u8 links_inst_valid_num;
+ DECLARE_BITMAP(links_inst_map, __RTW89_MLD_MAX_LINK_NUM);
+ struct rtw89_sta_link *links[IEEE80211_MLD_MAX_NUM_LINKS];
+ struct rtw89_sta_link links_inst[] __counted_by(links_inst_valid_num);
+};
+
+static inline bool rtw89_sta_assign_link_is_valid(struct rtw89_sta_link **rtwsta_link,
+ const struct rtw89_sta *rtwsta,
+ unsigned int link_id)
+{
+ *rtwsta_link = rtwsta->links[link_id];
+ return !!*rtwsta_link;
+}
+
+#define rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) \
+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) \
+ if (rtw89_sta_assign_link_is_valid(&(rtwsta_link), rtwsta, link_id))
+
+static inline u8 rtw89_vif_get_main_macid(struct rtw89_vif *rtwvif)
+{
+ /* const after init, so no need to check if active first */
+ return rtwvif->links_inst[0].mac_id;
+}
+
+static inline u8 rtw89_vif_get_main_port(struct rtw89_vif *rtwvif)
+{
+ /* const after init, so no need to check if active first */
+ return rtwvif->links_inst[0].port;
+}
+
+static inline struct rtw89_vif_link *
+rtw89_vif_get_link_inst(struct rtw89_vif *rtwvif, u8 index)
+{
+ if (index >= rtwvif->links_inst_valid_num ||
+ !test_bit(index, rtwvif->links_inst_map))
+ return NULL;
+ return &rtwvif->links_inst[index];
+}
+
+static inline
+u8 rtw89_vif_link_inst_get_index(struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+
+ return rtwvif_link - rtwvif->links_inst;
+}
+
+static inline u8 rtw89_sta_get_main_macid(struct rtw89_sta *rtwsta)
+{
+ /* const after init, so no need to check if active first */
+ return rtwsta->links_inst[0].mac_id;
+}
+
+static inline struct rtw89_sta_link *
+rtw89_sta_get_link_inst(struct rtw89_sta *rtwsta, u8 index)
+{
+ if (index >= rtwsta->links_inst_valid_num ||
+ !test_bit(index, rtwsta->links_inst_map))
+ return NULL;
+ return &rtwsta->links_inst[index];
+}
+
+static inline
+u8 rtw89_sta_link_inst_get_index(struct rtw89_sta_link *rtwsta_link)
+{
+ struct rtw89_sta *rtwsta = rtwsta_link->rtwsta;
+
+ return rtwsta_link - rtwsta->links_inst;
+}
+
+static inline void rtw89_assoc_link_set(struct rtw89_sta_link *rtwsta_link)
+{
+ struct rtw89_sta *rtwsta = rtwsta_link->rtwsta;
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+
+ rcu_assign_pointer(rtwdev->assoc_link_on_macid[rtwsta_link->mac_id],
+ rtwsta_link);
+}
+
+static inline void rtw89_assoc_link_clr(struct rtw89_sta_link *rtwsta_link)
+{
+ struct rtw89_sta *rtwsta = rtwsta_link->rtwsta;
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+
+ rcu_assign_pointer(rtwdev->assoc_link_on_macid[rtwsta_link->mac_id],
+ NULL);
+ synchronize_rcu();
+}
+
+static inline struct rtw89_sta_link *
+rtw89_assoc_link_rcu_dereference(struct rtw89_dev *rtwdev, u8 macid)
+{
+ return rcu_dereference(rtwdev->assoc_link_on_macid[macid]);
+}
+
+#define rtw89_get_designated_link(links_holder) \
+({ \
+ typeof(links_holder) p = links_holder; \
+ list_first_entry_or_null(&p->dlink_pool, typeof(*p->links_inst), dlink_schd); \
+})
+
static inline int rtw89_hci_tx_write(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
@@ -5509,9 +6418,26 @@ static inline struct ieee80211_vif *rtwvif_to_vif_safe(struct rtw89_vif *rtwvif)
return rtwvif ? rtwvif_to_vif(rtwvif) : NULL;
}
+static inline
+struct ieee80211_vif *rtwvif_link_to_vif(struct rtw89_vif_link *rtwvif_link)
+{
+ return rtwvif_to_vif(rtwvif_link->rtwvif);
+}
+
+static inline
+struct ieee80211_vif *rtwvif_link_to_vif_safe(struct rtw89_vif_link *rtwvif_link)
+{
+ return rtwvif_link ? rtwvif_link_to_vif(rtwvif_link) : NULL;
+}
+
+static inline struct rtw89_vif *vif_to_rtwvif(struct ieee80211_vif *vif)
+{
+ return (struct rtw89_vif *)vif->drv_priv;
+}
+
static inline struct rtw89_vif *vif_to_rtwvif_safe(struct ieee80211_vif *vif)
{
- return vif ? (struct rtw89_vif *)vif->drv_priv : NULL;
+ return vif ? vif_to_rtwvif(vif) : NULL;
}
static inline struct ieee80211_sta *rtwsta_to_sta(struct rtw89_sta *rtwsta)
@@ -5526,11 +6452,98 @@ static inline struct ieee80211_sta *rtwsta_to_sta_safe(struct rtw89_sta *rtwsta)
return rtwsta ? rtwsta_to_sta(rtwsta) : NULL;
}
+static inline
+struct ieee80211_sta *rtwsta_link_to_sta(struct rtw89_sta_link *rtwsta_link)
+{
+ return rtwsta_to_sta(rtwsta_link->rtwsta);
+}
+
+static inline
+struct ieee80211_sta *rtwsta_link_to_sta_safe(struct rtw89_sta_link *rtwsta_link)
+{
+ return rtwsta_link ? rtwsta_link_to_sta(rtwsta_link) : NULL;
+}
+
+static inline struct rtw89_sta *sta_to_rtwsta(struct ieee80211_sta *sta)
+{
+ return (struct rtw89_sta *)sta->drv_priv;
+}
+
static inline struct rtw89_sta *sta_to_rtwsta_safe(struct ieee80211_sta *sta)
{
- return sta ? (struct rtw89_sta *)sta->drv_priv : NULL;
+ return sta ? sta_to_rtwsta(sta) : NULL;
}
+static inline struct ieee80211_bss_conf *
+__rtw89_vif_rcu_dereference_link(struct rtw89_vif_link *rtwvif_link, bool *nolink)
+{
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ struct rtw89_link_conf_container *snap;
+ struct ieee80211_bss_conf *bss_conf;
+
+ snap = rcu_dereference(rtwvif->snap_link_confs);
+ if (snap) {
+ bss_conf = snap->link_conf[rtwvif_link->link_id];
+ goto out;
+ }
+
+ bss_conf = rcu_dereference(vif->link_conf[rtwvif_link->link_id]);
+
+out:
+ if (unlikely(!bss_conf)) {
+ *nolink = true;
+ return &vif->bss_conf;
+ }
+
+ *nolink = false;
+ return bss_conf;
+}
+
+#define rtw89_vif_rcu_dereference_link(rtwvif_link, assert) \
+({ \
+ typeof(rtwvif_link) p = rtwvif_link; \
+ struct ieee80211_bss_conf *bss_conf; \
+ bool nolink; \
+ \
+ bss_conf = __rtw89_vif_rcu_dereference_link(p, &nolink); \
+ if (unlikely(nolink) && (assert)) \
+ rtw89_err(p->rtwvif->rtwdev, \
+ "%s: cannot find exact bss_conf for link_id %u\n",\
+ __func__, p->link_id); \
+ bss_conf; \
+})
+
+static inline struct ieee80211_link_sta *
+__rtw89_sta_rcu_dereference_link(struct rtw89_sta_link *rtwsta_link, bool *nolink)
+{
+ struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
+ struct ieee80211_link_sta *link_sta;
+
+ link_sta = rcu_dereference(sta->link[rtwsta_link->link_id]);
+ if (unlikely(!link_sta)) {
+ *nolink = true;
+ return &sta->deflink;
+ }
+
+ *nolink = false;
+ return link_sta;
+}
+
+#define rtw89_sta_rcu_dereference_link(rtwsta_link, assert) \
+({ \
+ typeof(rtwsta_link) p = rtwsta_link; \
+ struct ieee80211_link_sta *link_sta; \
+ bool nolink; \
+ \
+ link_sta = __rtw89_sta_rcu_dereference_link(p, &nolink); \
+ if (unlikely(nolink) && (assert)) \
+ rtw89_err(p->rtwsta->rtwdev, \
+ "%s: cannot find exact link_sta for link_id %u\n",\
+ __func__, p->link_id); \
+ link_sta; \
+})
+
static inline u8 rtw89_hw_to_rate_info_bw(enum rtw89_bandwidth hw_bw)
{
if (hw_bw == RTW89_CHANNEL_WIDTH_160)
@@ -5615,29 +6628,29 @@ enum nl80211_he_ru_alloc rtw89_he_rua_to_ru_alloc(u16 rua)
}
static inline
-struct rtw89_addr_cam_entry *rtw89_get_addr_cam_of(struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+struct rtw89_addr_cam_entry *rtw89_get_addr_cam_of(struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- if (rtwsta) {
- struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
+ if (rtwsta_link) {
+ struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
- return &rtwsta->addr_cam;
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
+ return &rtwsta_link->addr_cam;
}
- return &rtwvif->addr_cam;
+ return &rtwvif_link->addr_cam;
}
static inline
-struct rtw89_bssid_cam_entry *rtw89_get_bssid_cam_of(struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+struct rtw89_bssid_cam_entry *rtw89_get_bssid_cam_of(struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- if (rtwsta) {
- struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
+ if (rtwsta_link) {
+ struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
if (sta->tdls)
- return &rtwsta->bssid_cam;
+ return &rtwsta_link->bssid_cam;
}
- return &rtwvif->bssid_cam;
+ return &rtwvif_link->bssid_cam;
}
static inline
@@ -5664,45 +6677,53 @@ void rtw89_chip_set_channel_done(struct rtw89_dev *rtwdev,
static inline
const struct cfg80211_chan_def *rtw89_chandef_get(struct rtw89_dev *rtwdev,
- enum rtw89_sub_entity_idx idx)
+ enum rtw89_chanctx_idx idx)
{
struct rtw89_hal *hal = &rtwdev->hal;
- enum rtw89_sub_entity_idx roc_idx = atomic_read(&hal->roc_entity_idx);
+ enum rtw89_chanctx_idx roc_idx = atomic_read(&hal->roc_chanctx_idx);
if (roc_idx == idx)
return &hal->roc_chandef;
- return &hal->sub[idx].chandef;
+ return &hal->chanctx[idx].chandef;
}
static inline
const struct rtw89_chan *rtw89_chan_get(struct rtw89_dev *rtwdev,
- enum rtw89_sub_entity_idx idx)
+ enum rtw89_chanctx_idx idx)
{
struct rtw89_hal *hal = &rtwdev->hal;
- return &hal->sub[idx].chan;
+ return &hal->chanctx[idx].chan;
}
static inline
const struct rtw89_chan_rcd *rtw89_chan_rcd_get(struct rtw89_dev *rtwdev,
- enum rtw89_sub_entity_idx idx)
+ enum rtw89_chanctx_idx idx)
{
struct rtw89_hal *hal = &rtwdev->hal;
- return &hal->sub[idx].rcd;
+ return &hal->chanctx[idx].rcd;
+}
+
+static inline
+const struct rtw89_chan_rcd *rtw89_chan_rcd_get_by_chan(const struct rtw89_chan *chan)
+{
+ const struct rtw89_chanctx *chanctx =
+ container_of_const(chan, struct rtw89_chanctx, chan);
+
+ return &chanctx->rcd;
}
static inline
const struct rtw89_chan *rtw89_scan_chan_get(struct rtw89_dev *rtwdev)
{
- struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
- struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
+ struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
- if (rtwvif)
- return rtw89_chan_get(rtwdev, rtwvif->sub_entity_idx);
+ if (rtwvif_link)
+ return rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
else
- return rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ return rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
}
static inline void rtw89_chip_fem_setup(struct rtw89_dev *rtwdev)
@@ -5776,29 +6797,32 @@ static inline void rtw89_chip_rfk_init_late(struct rtw89_dev *rtwdev)
chip->ops->rfk_init_late(rtwdev);
}
-static inline void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev)
+static inline void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (chip->ops->rfk_channel)
- chip->ops->rfk_channel(rtwdev);
+ chip->ops->rfk_channel(rtwdev, rtwvif_link);
}
static inline void rtw89_chip_rfk_band_changed(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx)
+ enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (chip->ops->rfk_band_changed)
- chip->ops->rfk_band_changed(rtwdev, phy_idx);
+ chip->ops->rfk_band_changed(rtwdev, phy_idx, chan);
}
-static inline void rtw89_chip_rfk_scan(struct rtw89_dev *rtwdev, bool start)
+static inline void rtw89_chip_rfk_scan(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link, bool start)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (chip->ops->rfk_scan)
- chip->ops->rfk_scan(rtwdev, start);
+ chip->ops->rfk_scan(rtwdev, rtwvif_link, start);
}
static inline void rtw89_chip_rfk_track(struct rtw89_dev *rtwdev)
@@ -5813,8 +6837,12 @@ static inline void rtw89_chip_set_txpwr_ctrl(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- if (chip->ops->set_txpwr_ctrl)
- chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_0);
+ if (!chip->ops->set_txpwr_ctrl)
+ return;
+
+ chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_0);
+ if (rtwdev->dbcc_en)
+ chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_1);
}
static inline void rtw89_chip_power_trim(struct rtw89_dev *rtwdev)
@@ -5825,8 +6853,8 @@ static inline void rtw89_chip_power_trim(struct rtw89_dev *rtwdev)
chip->ops->power_trim(rtwdev);
}
-static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx)
+static inline void __rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
@@ -5834,6 +6862,13 @@ static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev,
chip->ops->init_txpwr_unit(rtwdev, phy_idx);
}
+static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev)
+{
+ __rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_0);
+ if (rtwdev->dbcc_en)
+ __rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_1);
+}
+
static inline u8 rtw89_chip_get_thermal(struct rtw89_dev *rtwdev,
enum rtw89_rf_path rf_path)
{
@@ -5855,6 +6890,25 @@ static inline void rtw89_chip_query_ppdu(struct rtw89_dev *rtwdev,
chip->ops->query_ppdu(rtwdev, phy_ppdu, status);
}
+static inline void rtw89_chip_convert_rpl_to_rssi(struct rtw89_dev *rtwdev,
+ struct rtw89_rx_phy_ppdu *phy_ppdu)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+
+ if (chip->ops->convert_rpl_to_rssi)
+ chip->ops->convert_rpl_to_rssi(rtwdev, phy_ppdu);
+}
+
+static inline void rtw89_chip_phy_rpt_to_rssi(struct rtw89_dev *rtwdev,
+ struct rtw89_rx_desc_info *desc_info,
+ struct ieee80211_rx_status *rx_status)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+
+ if (chip->ops->phy_rpt_to_rssi)
+ chip->ops->phy_rpt_to_rssi(rtwdev, desc_info, rx_status);
+}
+
static inline void rtw89_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en,
enum rtw89_phy_idx phy_idx)
{
@@ -5872,18 +6926,13 @@ static inline void rtw89_chip_cfg_txrx_path(struct rtw89_dev *rtwdev)
chip->ops->cfg_txrx_path(rtwdev);
}
-static inline
-void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif)
+static inline void rtw89_chip_digital_pwr_comp(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
const struct rtw89_chip_info *chip = rtwdev->chip;
- if (!vif->bss_conf.he_support || !vif->cfg.assoc)
- return;
-
- if (chip->ops->set_txpwr_ul_tb_offset)
- chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif->mac_idx);
+ if (chip->ops->digital_pwr_comp)
+ chip->ops->digital_pwr_comp(rtwdev, phy_idx);
}
static inline void rtw89_load_txpwr_table(struct rtw89_dev *rtwdev,
@@ -5894,9 +6943,14 @@ static inline void rtw89_load_txpwr_table(struct rtw89_dev *rtwdev,
static inline u8 rtw89_regd_get(struct rtw89_dev *rtwdev, u8 band)
{
- const struct rtw89_regd *regd = rtwdev->regulatory.regd;
+ const struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ const struct rtw89_regd *regd = regulatory->regd;
+ u8 txpwr_regd = regd->txpwr_regd[band];
+
+ if (regulatory->txpwr_uk_follow_etsi && txpwr_regd == RTW89_UK)
+ return RTW89_ETSI;
- return regd->txpwr_regd[band];
+ return txpwr_regd;
}
static inline void rtw89_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en,
@@ -5973,14 +7027,14 @@ int rtw89_chip_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en)
static inline
int rtw89_chip_h2c_dctl_sec_cam(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (!chip->ops->h2c_dctl_sec_cam)
return 0;
- return chip->ops->h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
+ return chip->ops->h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link);
}
static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr)
@@ -5995,18 +7049,39 @@ static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr)
return hdr->addr3;
}
-static inline bool rtw89_sta_has_beamformer_cap(struct ieee80211_sta *sta)
+static inline
+bool rtw89_sta_has_beamformer_cap(struct ieee80211_link_sta *link_sta)
{
- if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
- (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) ||
- (sta->deflink.he_cap.he_cap_elem.phy_cap_info[3] &
+ if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
+ (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) ||
+ (link_sta->he_cap.he_cap_elem.phy_cap_info[3] &
IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) ||
- (sta->deflink.he_cap.he_cap_elem.phy_cap_info[4] &
+ (link_sta->he_cap.he_cap_elem.phy_cap_info[4] &
IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER))
return true;
return false;
}
+static inline
+bool rtw89_sta_link_has_su_mu_4xhe08(struct ieee80211_link_sta *link_sta)
+{
+ if (link_sta->he_cap.he_cap_elem.phy_cap_info[7] &
+ IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI)
+ return true;
+
+ return false;
+}
+
+static inline
+bool rtw89_sta_link_has_er_su_4xhe08(struct ieee80211_link_sta *link_sta)
+{
+ if (link_sta->he_cap.he_cap_elem.phy_cap_info[8] &
+ IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI)
+ return true;
+
+ return false;
+}
+
static inline struct rtw89_fw_suit *rtw89_fw_suit_get(struct rtw89_dev *rtwdev,
enum rtw89_fw_type type)
{
@@ -6076,6 +7151,58 @@ static inline bool rtw89_is_mlo_1_1(struct rtw89_dev *rtwdev)
}
}
+static inline u8 rtw89_get_active_phy_bitmap(struct rtw89_dev *rtwdev)
+{
+ if (!rtwdev->dbcc_en)
+ return BIT(RTW89_PHY_0);
+
+ switch (rtwdev->mlo_dbcc_mode) {
+ case MLO_0_PLUS_2_1RF:
+ case MLO_0_PLUS_2_2RF:
+ return BIT(RTW89_PHY_1);
+ case MLO_1_PLUS_1_1RF:
+ case MLO_1_PLUS_1_2RF:
+ case MLO_2_PLUS_2_2RF:
+ case DBCC_LEGACY:
+ return BIT(RTW89_PHY_0) | BIT(RTW89_PHY_1);
+ case MLO_2_PLUS_0_1RF:
+ case MLO_2_PLUS_0_2RF:
+ default:
+ return BIT(RTW89_PHY_0);
+ }
+}
+
+#define rtw89_for_each_active_bb(rtwdev, bb) \
+ for (u8 __active_bb_bitmap = rtw89_get_active_phy_bitmap(rtwdev), \
+ __phy_idx = 0; __phy_idx < RTW89_PHY_NUM; __phy_idx++) \
+ if (__active_bb_bitmap & BIT(__phy_idx) && \
+ (bb = &rtwdev->bbs[__phy_idx]))
+
+#define rtw89_for_each_capab_bb(rtwdev, bb) \
+ for (u8 __phy_idx_max = rtwdev->dbcc_en ? RTW89_PHY_1 : RTW89_PHY_0, \
+ __phy_idx = 0; __phy_idx <= __phy_idx_max; __phy_idx++) \
+ if ((bb = &rtwdev->bbs[__phy_idx]))
+
+static inline
+struct rtw89_bb_ctx *rtw89_get_bb_ctx(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
+{
+ if (phy_idx >= RTW89_PHY_NUM)
+ return &rtwdev->bbs[RTW89_PHY_0];
+
+ return &rtwdev->bbs[phy_idx];
+}
+
+static inline bool rtw89_is_rtl885xb(struct rtw89_dev *rtwdev)
+{
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
+
+ if (chip_id == RTL8852B || chip_id == RTL8851B || chip_id == RTL8852BT)
+ return true;
+
+ return false;
+}
+
int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel);
int rtw89_h2c_tx(struct rtw89_dev *rtwdev,
@@ -6109,55 +7236,79 @@ void rtw89_core_query_rxdesc_v2(struct rtw89_dev *rtwdev,
u8 *data, u32 data_offset);
void rtw89_core_napi_start(struct rtw89_dev *rtwdev);
void rtw89_core_napi_stop(struct rtw89_dev *rtwdev);
-void rtw89_core_napi_init(struct rtw89_dev *rtwdev);
+int rtw89_core_napi_init(struct rtw89_dev *rtwdev);
void rtw89_core_napi_deinit(struct rtw89_dev *rtwdev);
-int rtw89_core_sta_add(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
-int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
-int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
-int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
-int rtw89_core_sta_remove(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+int rtw89_core_sta_link_add(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
+int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
+int rtw89_core_sta_link_disassoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
+int rtw89_core_sta_link_disconnect(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
+int rtw89_core_sta_link_remove(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
void rtw89_core_set_tid_config(struct rtw89_dev *rtwdev,
struct ieee80211_sta *sta,
struct cfg80211_tid_config *tid_config);
+void rtw89_core_rfkill_poll(struct rtw89_dev *rtwdev, bool force);
+void rtw89_check_quirks(struct rtw89_dev *rtwdev, const struct dmi_system_id *quirks);
int rtw89_core_init(struct rtw89_dev *rtwdev);
void rtw89_core_deinit(struct rtw89_dev *rtwdev);
int rtw89_core_register(struct rtw89_dev *rtwdev);
void rtw89_core_unregister(struct rtw89_dev *rtwdev);
struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
u32 bus_data_size,
- const struct rtw89_chip_info *chip);
+ const struct rtw89_chip_info *chip,
+ const struct rtw89_chip_variant *variant);
void rtw89_free_ieee80211_hw(struct rtw89_dev *rtwdev);
+u8 rtw89_acquire_mac_id(struct rtw89_dev *rtwdev);
+void rtw89_release_mac_id(struct rtw89_dev *rtwdev, u8 mac_id);
+void rtw89_init_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ u8 mac_id, u8 port);
+void rtw89_init_sta(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ struct rtw89_sta *rtwsta, u8 mac_id);
+struct rtw89_vif_link *rtw89_vif_set_link(struct rtw89_vif *rtwvif,
+ unsigned int link_id);
+void rtw89_vif_unset_link(struct rtw89_vif *rtwvif, unsigned int link_id);
+struct rtw89_sta_link *rtw89_sta_set_link(struct rtw89_sta *rtwsta,
+ unsigned int link_id);
+void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id);
void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev);
+const struct rtw89_6ghz_span *
+rtw89_get_6ghz_span(struct rtw89_dev *rtwdev, u32 center_freq);
void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef);
void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
struct rtw89_chan *chan);
int rtw89_set_channel(struct rtw89_dev *rtwdev);
-void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_chan *chan);
u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size);
void rtw89_core_release_bit_map(unsigned long *addr, u8 bit);
void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits);
int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx);
+ struct rtw89_sta_link *rtwsta_link, u8 tid,
+ u8 *cam_idx);
int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx);
-void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc);
+ struct rtw89_sta_link *rtwsta_link, u8 tid,
+ u8 *cam_idx);
+void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev,
+ struct ieee80211_sta *sta);
+void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev,
+ struct ieee80211_sta *sta);
+void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev,
+ struct ieee80211_sta *sta);
+void rtw89_vif_type_mapping(struct rtw89_vif_link *rtwvif_link, bool assoc);
int rtw89_chip_info_setup(struct rtw89_dev *rtwdev);
+void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 *bitrate);
int rtw89_regd_setup(struct rtw89_dev *rtwdev);
-int rtw89_regd_init(struct rtw89_dev *rtwdev,
- void (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request *request));
-void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+int rtw89_regd_init_hint(struct rtw89_dev *rtwdev);
+const char *rtw89_regd_get_string(enum rtw89_regulation_type regd);
void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev,
struct rtw89_traffic_stats *stats);
int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond);
@@ -6165,17 +7316,21 @@ void rtw89_complete_cond(struct rtw89_wait_info *wait, unsigned int cond,
const struct rtw89_completion_data *data);
int rtw89_core_start(struct rtw89_dev *rtwdev);
void rtw89_core_stop(struct rtw89_dev *rtwdev);
-void rtw89_core_update_beacon_work(struct work_struct *work);
-void rtw89_roc_work(struct work_struct *work);
+void rtw89_core_update_beacon_work(struct wiphy *wiphy, struct wiphy_work *work);
+void rtw89_roc_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
-void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
const u8 *mac_addr, bool hw_scan);
void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif, bool hw_scan);
-void rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool active);
-void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
+ struct rtw89_vif_link *rtwvif_link, bool hw_scan);
+int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ bool active);
+void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf);
void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, enum rtw89_btc_hmsg event);
+int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ unsigned int link_id);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
index affffc4092ba..d6016fa107fb 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.c
+++ b/drivers/net/wireless/realtek/rtw89/debug.c
@@ -9,9 +9,11 @@
#include "fw.h"
#include "mac.h"
#include "pci.h"
+#include "phy.h"
#include "ps.h"
#include "reg.h"
#include "sar.h"
+#include "util.h"
#ifdef CONFIG_RTW89_DEBUGMSG
unsigned int rtw89_debug_mask;
@@ -21,11 +23,21 @@ MODULE_PARM_DESC(debug_mask, "Debugging mask");
#endif
#ifdef CONFIG_RTW89_DEBUGFS
+struct rtw89_debugfs_priv_opt {
+ bool rlock:1;
+ bool wlock:1;
+ size_t rsize;
+};
+
struct rtw89_debugfs_priv {
struct rtw89_dev *rtwdev;
- int (*cb_read)(struct seq_file *m, void *v);
- ssize_t (*cb_write)(struct file *filp, const char __user *buffer,
- size_t count, loff_t *loff);
+ ssize_t (*cb_read)(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz);
+ ssize_t (*cb_write)(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count);
+ struct rtw89_debugfs_priv_opt opt;
union {
u32 cb_data;
struct {
@@ -50,8 +62,54 @@ struct rtw89_debugfs_priv {
u8 sel;
} mac_mem;
};
+ ssize_t rused;
+ char *rbuf;
+};
+
+struct rtw89_debugfs {
+ struct rtw89_debugfs_priv read_reg;
+ struct rtw89_debugfs_priv write_reg;
+ struct rtw89_debugfs_priv read_rf;
+ struct rtw89_debugfs_priv write_rf;
+ struct rtw89_debugfs_priv rf_reg_dump;
+ struct rtw89_debugfs_priv txpwr_table;
+ struct rtw89_debugfs_priv mac_reg_dump;
+ struct rtw89_debugfs_priv mac_mem_dump;
+ struct rtw89_debugfs_priv mac_dbg_port_dump;
+ struct rtw89_debugfs_priv send_h2c;
+ struct rtw89_debugfs_priv early_h2c;
+ struct rtw89_debugfs_priv fw_crash;
+ struct rtw89_debugfs_priv btc_info;
+ struct rtw89_debugfs_priv btc_manual;
+ struct rtw89_debugfs_priv fw_log_manual;
+ struct rtw89_debugfs_priv phy_info;
+ struct rtw89_debugfs_priv stations;
+ struct rtw89_debugfs_priv disable_dm;
+ struct rtw89_debugfs_priv mlo_mode;
+};
+
+struct rtw89_debugfs_iter_data {
+ char *buf;
+ size_t bufsz;
+ int written_sz;
};
+static void rtw89_debugfs_iter_data_setup(struct rtw89_debugfs_iter_data *iter_data,
+ char *buf, size_t bufsz)
+{
+ iter_data->buf = buf;
+ iter_data->bufsz = bufsz;
+ iter_data->written_sz = 0;
+}
+
+static void rtw89_debugfs_iter_data_next(struct rtw89_debugfs_iter_data *iter_data,
+ char *buf, size_t bufsz, int written_sz)
+{
+ iter_data->buf = buf;
+ iter_data->bufsz = bufsz;
+ iter_data->written_sz += written_sz;
+}
+
static const u16 rtw89_rate_info_bw_to_mhz_map[] = {
[RATE_INFO_BW_20] = 20,
[RATE_INFO_BW_40] = 40,
@@ -68,84 +126,122 @@ static u16 rtw89_rate_info_bw_to_mhz(enum rate_info_bw bw)
return 0;
}
-static int rtw89_debugfs_single_show(struct seq_file *m, void *v)
+static ssize_t rtw89_debugfs_file_read_helper(struct wiphy *wiphy, struct file *file,
+ char *buf, size_t bufsz, void *data)
{
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
+ struct rtw89_debugfs_priv *debugfs_priv = data;
+ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
+ ssize_t n;
+
+ n = debugfs_priv->cb_read(rtwdev, debugfs_priv, buf, bufsz);
+ rtw89_might_trailing_ellipsis(buf, bufsz, n);
- return debugfs_priv->cb_read(m, v);
+ return n;
}
-static ssize_t rtw89_debugfs_single_write(struct file *filp,
- const char __user *buffer,
- size_t count, loff_t *loff)
+static ssize_t rtw89_debugfs_file_read(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
{
- struct rtw89_debugfs_priv *debugfs_priv = filp->private_data;
+ struct rtw89_debugfs_priv *debugfs_priv = file->private_data;
+ struct rtw89_debugfs_priv_opt *opt = &debugfs_priv->opt;
+ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
+ size_t bufsz = opt->rsize ? opt->rsize : PAGE_SIZE;
+ char *buf;
+ ssize_t n;
- return debugfs_priv->cb_write(filp, buffer, count, loff);
-}
+ if (!debugfs_priv->rbuf)
+ debugfs_priv->rbuf = devm_kzalloc(rtwdev->dev, bufsz, GFP_KERNEL);
-static ssize_t rtw89_debugfs_seq_file_write(struct file *filp,
- const char __user *buffer,
- size_t count, loff_t *loff)
-{
- struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
- struct rtw89_debugfs_priv *debugfs_priv = seqpriv->private;
+ buf = debugfs_priv->rbuf;
+ if (!buf)
+ return -ENOMEM;
+
+ if (*ppos) {
+ n = debugfs_priv->rused;
+ goto out;
+ }
+
+ if (opt->rlock) {
+ n = wiphy_locked_debugfs_read(rtwdev->hw->wiphy, file, buf, bufsz,
+ userbuf, count, ppos,
+ rtw89_debugfs_file_read_helper,
+ debugfs_priv);
+ debugfs_priv->rused = n;
- return debugfs_priv->cb_write(filp, buffer, count, loff);
+ return n;
+ }
+
+ n = rtw89_debugfs_file_read_helper(rtwdev->hw->wiphy, file, buf, bufsz,
+ debugfs_priv);
+ debugfs_priv->rused = n;
+
+out:
+ return simple_read_from_buffer(userbuf, count, ppos, buf, n);
}
-static int rtw89_debugfs_single_open(struct inode *inode, struct file *filp)
+static ssize_t rtw89_debugfs_file_write_helper(struct wiphy *wiphy, struct file *file,
+ char *buf, size_t count, void *data)
{
- return single_open(filp, rtw89_debugfs_single_show, inode->i_private);
+ struct rtw89_debugfs_priv *debugfs_priv = data;
+ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
+
+ return debugfs_priv->cb_write(rtwdev, debugfs_priv, buf, count);
}
-static int rtw89_debugfs_close(struct inode *inode, struct file *filp)
+static ssize_t rtw89_debugfs_file_write(struct file *file,
+ const char __user *userbuf,
+ size_t count, loff_t *loff)
{
- return 0;
+ struct rtw89_debugfs_priv *debugfs_priv = file->private_data;
+ struct rtw89_debugfs_priv_opt *opt = &debugfs_priv->opt;
+ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
+ char *buf __free(kfree) = kmalloc(count + 1, GFP_KERNEL);
+ ssize_t n;
+
+ if (!buf)
+ return -ENOMEM;
+
+ if (opt->wlock) {
+ n = wiphy_locked_debugfs_write(rtwdev->hw->wiphy,
+ file, buf, count + 1,
+ userbuf, count,
+ rtw89_debugfs_file_write_helper,
+ debugfs_priv);
+ return n;
+ }
+
+ if (copy_from_user(buf, userbuf, count))
+ return -EFAULT;
+
+ buf[count] = '\0';
+
+ return debugfs_priv->cb_write(rtwdev, debugfs_priv, buf, count);
}
-static const struct file_operations file_ops_single_r = {
- .owner = THIS_MODULE,
- .open = rtw89_debugfs_single_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+static const struct debugfs_short_fops file_ops_single_r = {
+ .read = rtw89_debugfs_file_read,
+ .llseek = generic_file_llseek,
};
-static const struct file_operations file_ops_common_rw = {
- .owner = THIS_MODULE,
- .open = rtw89_debugfs_single_open,
- .release = single_release,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = rtw89_debugfs_seq_file_write,
+static const struct debugfs_short_fops file_ops_common_rw = {
+ .read = rtw89_debugfs_file_read,
+ .write = rtw89_debugfs_file_write,
+ .llseek = generic_file_llseek,
};
-static const struct file_operations file_ops_single_w = {
- .owner = THIS_MODULE,
- .write = rtw89_debugfs_single_write,
- .open = simple_open,
- .release = rtw89_debugfs_close,
+static const struct debugfs_short_fops file_ops_single_w = {
+ .write = rtw89_debugfs_file_write,
+ .llseek = generic_file_llseek,
};
static ssize_t
-rtw89_debug_priv_read_reg_select(struct file *filp,
- const char __user *user_buf,
- size_t count, loff_t *loff)
+rtw89_debug_priv_read_reg_select(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
{
- struct seq_file *m = (struct seq_file *)filp->private_data;
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
- char buf[32];
- size_t buf_size;
u32 addr, len;
int num;
- buf_size = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, buf_size))
- return -EFAULT;
-
- buf[buf_size] = '\0';
num = sscanf(buf, "%x %x", &addr, &len);
if (num != 2) {
rtw89_info(rtwdev, "invalid format: <addr> <len>\n");
@@ -160,11 +256,13 @@ rtw89_debug_priv_read_reg_select(struct file *filp,
return count;
}
-static int rtw89_debug_priv_read_reg_get(struct seq_file *m, void *v)
+static
+ssize_t rtw89_debug_priv_read_reg_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
{
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
- u32 addr, end, data, k;
+ char *p = buf, *end = buf + bufsz;
+ u32 addr, addr_end, data, k;
u32 len;
len = debugfs_priv->read_reg.len;
@@ -188,41 +286,34 @@ static int rtw89_debug_priv_read_reg_get(struct seq_file *m, void *v)
return -EINVAL;
}
- seq_printf(m, "get %d bytes at 0x%08x=0x%08x\n", len, addr, data);
+ p += scnprintf(p, end - p, "get %d bytes at 0x%08x=0x%08x\n", len,
+ addr, data);
- return 0;
+ return p - buf;
ndata:
- end = addr + len;
+ addr_end = addr + len;
- for (; addr < end; addr += 16) {
- seq_printf(m, "%08xh : ", 0x18600000 + addr);
+ for (; addr < addr_end; addr += 16) {
+ p += scnprintf(p, end - p, "%08xh : ", 0x18600000 + addr);
for (k = 0; k < 16; k += 4) {
data = rtw89_read32(rtwdev, addr + k);
- seq_printf(m, "%08x ", data);
+ p += scnprintf(p, end - p, "%08x ", data);
}
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
- return 0;
+ return p - buf;
}
-static ssize_t rtw89_debug_priv_write_reg_set(struct file *filp,
- const char __user *user_buf,
- size_t count, loff_t *loff)
+static
+ssize_t rtw89_debug_priv_write_reg_set(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
{
- struct rtw89_debugfs_priv *debugfs_priv = filp->private_data;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
- char buf[32];
- size_t buf_size;
u32 addr, val, len;
int num;
- buf_size = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, buf_size))
- return -EFAULT;
-
- buf[buf_size] = '\0';
num = sscanf(buf, "%x %x %x", &addr, &val, &len);
if (num != 3) {
rtw89_info(rtwdev, "invalid format: <addr> <val> <len>\n");
@@ -251,24 +342,14 @@ static ssize_t rtw89_debug_priv_write_reg_set(struct file *filp,
}
static ssize_t
-rtw89_debug_priv_read_rf_select(struct file *filp,
- const char __user *user_buf,
- size_t count, loff_t *loff)
+rtw89_debug_priv_read_rf_select(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
{
- struct seq_file *m = (struct seq_file *)filp->private_data;
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
- char buf[32];
- size_t buf_size;
u32 addr, mask;
u8 path;
int num;
- buf_size = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, buf_size))
- return -EFAULT;
-
- buf[buf_size] = '\0';
num = sscanf(buf, "%hhd %x %x", &path, &addr, &mask);
if (num != 3) {
rtw89_info(rtwdev, "invalid format: <path> <addr> <mask>\n");
@@ -288,10 +369,12 @@ rtw89_debug_priv_read_rf_select(struct file *filp,
return count;
}
-static int rtw89_debug_priv_read_rf_get(struct seq_file *m, void *v)
+static
+ssize_t rtw89_debug_priv_read_rf_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
{
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
+ char *p = buf, *end = buf + bufsz;
u32 addr, data, mask;
u8 path;
@@ -301,28 +384,21 @@ static int rtw89_debug_priv_read_rf_get(struct seq_file *m, void *v)
data = rtw89_read_rf(rtwdev, path, addr, mask);
- seq_printf(m, "path %d, rf register 0x%08x=0x%08x\n", path, addr, data);
+ p += scnprintf(p, end - p, "path %d, rf register 0x%08x=0x%08x\n",
+ path, addr, data);
- return 0;
+ return p - buf;
}
-static ssize_t rtw89_debug_priv_write_rf_set(struct file *filp,
- const char __user *user_buf,
- size_t count, loff_t *loff)
+static
+ssize_t rtw89_debug_priv_write_rf_set(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
{
- struct rtw89_debugfs_priv *debugfs_priv = filp->private_data;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
- char buf[32];
- size_t buf_size;
u32 addr, val, mask;
u8 path;
int num;
- buf_size = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, buf_size))
- return -EFAULT;
-
- buf[buf_size] = '\0';
num = sscanf(buf, "%hhd %x %x %x", &path, &addr, &mask, &val);
if (num != 4) {
rtw89_info(rtwdev, "invalid format: <path> <addr> <mask> <val>\n");
@@ -341,29 +417,31 @@ static ssize_t rtw89_debug_priv_write_rf_set(struct file *filp,
return count;
}
-static int rtw89_debug_priv_rf_reg_dump_get(struct seq_file *m, void *v)
+static
+ssize_t rtw89_debug_priv_rf_reg_dump_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
{
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
const struct rtw89_chip_info *chip = rtwdev->chip;
+ char *p = buf, *end = buf + bufsz;
u32 addr, offset, data;
u8 path;
for (path = 0; path < chip->rf_path_num; path++) {
- seq_printf(m, "RF path %d:\n\n", path);
+ p += scnprintf(p, end - p, "RF path %d:\n\n", path);
for (addr = 0; addr < 0x100; addr += 4) {
- seq_printf(m, "0x%08x: ", addr);
+ p += scnprintf(p, end - p, "0x%08x: ", addr);
for (offset = 0; offset < 4; offset++) {
data = rtw89_read_rf(rtwdev, path,
addr + offset, RFREG_MASK);
- seq_printf(m, "0x%05x ", data);
+ p += scnprintf(p, end - p, "0x%05x ", data);
}
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
- return 0;
+ return p - buf;
}
struct txpwr_ent {
@@ -682,56 +760,71 @@ static const struct txpwr_map __txpwr_map_lmt_ru_be = {
};
static unsigned int
-__print_txpwr_ent(struct seq_file *m, const struct txpwr_ent *ent,
- const s8 *buf, const unsigned int cur)
+__print_txpwr_ent(char *buf, size_t bufsz, const struct txpwr_ent *ent,
+ const s8 *bufp, const unsigned int cur, unsigned int *ate)
{
+ char *p = buf, *end = buf + bufsz;
unsigned int cnt, i;
+ unsigned int eaten;
char *fmt;
if (ent->nested) {
- for (cnt = 0, i = 0; i < ent->len; i++)
- cnt += __print_txpwr_ent(m, ent->ptr + i, buf,
- cur + cnt);
- return cnt;
+ for (cnt = 0, i = 0; i < ent->len; i++, cnt += eaten)
+ p += __print_txpwr_ent(p, end - p, ent->ptr + i, bufp,
+ cur + cnt, &eaten);
+ *ate = cnt;
+ goto out;
}
switch (ent->len) {
case 0:
- seq_printf(m, "\t<< %s >>\n", ent->txt);
- return 0;
+ p += scnprintf(p, end - p, "\t<< %s >>\n", ent->txt);
+ *ate = 0;
+ goto out;
case 2:
fmt = "%s\t| %3d, %3d,\t\tdBm\n";
- seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1]);
- return 2;
+ p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur],
+ bufp[cur + 1]);
+ *ate = 2;
+ goto out;
case 4:
fmt = "%s\t| %3d, %3d, %3d, %3d,\tdBm\n";
- seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1],
- buf[cur + 2], buf[cur + 3]);
- return 4;
+ p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur],
+ bufp[cur + 1],
+ bufp[cur + 2], bufp[cur + 3]);
+ *ate = 4;
+ goto out;
case 8:
fmt = "%s\t| %3d, %3d, %3d, %3d, %3d, %3d, %3d, %3d,\tdBm\n";
- seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1],
- buf[cur + 2], buf[cur + 3], buf[cur + 4],
- buf[cur + 5], buf[cur + 6], buf[cur + 7]);
- return 8;
+ p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur],
+ bufp[cur + 1],
+ bufp[cur + 2], bufp[cur + 3], bufp[cur + 4],
+ bufp[cur + 5], bufp[cur + 6], bufp[cur + 7]);
+ *ate = 8;
+ goto out;
default:
return 0;
}
+
+out:
+ return p - buf;
}
-static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev,
- const struct txpwr_map *map)
+static ssize_t __print_txpwr_map(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
+ const struct txpwr_map *map)
{
u8 fct = rtwdev->chip->txpwr_factor_mac;
u8 path_num = rtwdev->chip->rf_path_num;
+ char *p = buf, *end = buf + bufsz;
unsigned int cur, i;
+ unsigned int eaten;
u32 max_valid_addr;
u32 val, addr;
- s8 *buf, tmp;
+ s8 *bufp, tmp;
int ret;
- buf = vzalloc(map->addr_to - map->addr_from + 4);
- if (!buf)
+ bufp = vzalloc(map->addr_to - map->addr_from + 4);
+ if (!bufp)
return -ENOMEM;
if (path_num == 1)
@@ -751,49 +844,31 @@ static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev,
for (i = 0; i < 4; i++, val >>= 8) {
/* signed 7 bits, and reserved BIT(7) */
tmp = sign_extend32(val, 6);
- buf[cur + i] = tmp >> fct;
+ bufp[cur + i] = tmp >> fct;
}
}
- for (cur = 0, i = 0; i < map->size; i++)
- cur += __print_txpwr_ent(m, &map->ent[i], buf, cur);
+ for (cur = 0, i = 0; i < map->size; i++, cur += eaten)
+ p += __print_txpwr_ent(p, end - p, &map->ent[i], bufp, cur, &eaten);
- vfree(buf);
- return 0;
+ vfree(bufp);
+ return p - buf;
}
-#define case_REGD(_regd) \
- case RTW89_ ## _regd: \
- seq_puts(m, #_regd "\n"); \
- break
-
-static void __print_regd(struct seq_file *m, struct rtw89_dev *rtwdev,
- const struct rtw89_chan *chan)
+static int __print_regd(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
+ const struct rtw89_chan *chan)
{
+ const struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ char *p = buf, *end = buf + bufsz;
u8 band = chan->band_type;
u8 regd = rtw89_regd_get(rtwdev, band);
- switch (regd) {
- default:
- seq_printf(m, "UNKNOWN: %d\n", regd);
- break;
- case_REGD(WW);
- case_REGD(ETSI);
- case_REGD(FCC);
- case_REGD(MKK);
- case_REGD(NA);
- case_REGD(IC);
- case_REGD(KCC);
- case_REGD(NCC);
- case_REGD(CHILE);
- case_REGD(ACMA);
- case_REGD(MEXICO);
- case_REGD(UKRAINE);
- case_REGD(CN);
- }
-}
+ p += scnprintf(p, end - p, "%s\n", rtw89_regd_get_string(regd));
+ p += scnprintf(p, end - p, "\t(txpwr UK follow ETSI: %s)\n",
+ str_yes_no(regulatory->txpwr_uk_follow_etsi));
-#undef case_REGD
+ return p - buf;
+}
struct dbgfs_txpwr_table {
const struct txpwr_map *byr;
@@ -818,73 +893,96 @@ static const struct dbgfs_txpwr_table *dbgfs_txpwr_tables[RTW89_CHIP_GEN_NUM] =
[RTW89_CHIP_BE] = &dbgfs_txpwr_table_be,
};
-static int rtw89_debug_priv_txpwr_table_get(struct seq_file *m, void *v)
+static
+int rtw89_debug_priv_txpwr_table_get_regd(struct rtw89_dev *rtwdev,
+ char *buf, size_t bufsz,
+ const struct rtw89_chan *chan)
+{
+ const struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ const struct rtw89_reg_6ghz_tpe *tpe6 = &regulatory->reg_6ghz_tpe;
+ char *p = buf, *end = buf + bufsz;
+
+ p += scnprintf(p, end - p, "[Chanctx] band %u, ch %u, bw %u\n",
+ chan->band_type, chan->channel, chan->band_width);
+
+ p += scnprintf(p, end - p, "[Regulatory] ");
+ p += __print_regd(rtwdev, p, end - p, chan);
+
+ if (chan->band_type == RTW89_BAND_6G) {
+ p += scnprintf(p, end - p, "[reg6_pwr_type] %u\n",
+ regulatory->reg_6ghz_power);
+
+ if (tpe6->valid)
+ p += scnprintf(p, end - p, "[TPE] %d dBm\n",
+ tpe6->constraint);
+ }
+
+ return p - buf;
+}
+
+static
+ssize_t rtw89_debug_priv_txpwr_table_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
{
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
+ struct rtw89_sar_parm sar_parm = {};
const struct dbgfs_txpwr_table *tbl;
const struct rtw89_chan *chan;
- int ret = 0;
+ char *p = buf, *end = buf + bufsz;
+ ssize_t n;
+
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
- mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
- chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
+ sar_parm.center_freq = chan->freq;
- seq_puts(m, "[Regulatory] ");
- __print_regd(m, rtwdev, chan);
+ p += rtw89_debug_priv_txpwr_table_get_regd(rtwdev, p, end - p, chan);
- seq_puts(m, "[SAR]\n");
- rtw89_print_sar(m, rtwdev, chan->freq);
+ p += scnprintf(p, end - p, "[SAR]\n");
+ p += rtw89_print_sar(rtwdev, p, end - p, &sar_parm);
- seq_puts(m, "[TAS]\n");
- rtw89_print_tas(m, rtwdev);
+ p += scnprintf(p, end - p, "[TAS]\n");
+ p += rtw89_print_tas(rtwdev, p, end - p);
- tbl = dbgfs_txpwr_tables[chip_gen];
- if (!tbl) {
- ret = -EOPNOTSUPP;
- goto err;
- }
+ p += scnprintf(p, end - p, "[DAG]\n");
+ p += rtw89_print_ant_gain(rtwdev, p, end - p, chan);
- seq_puts(m, "\n[TX power byrate]\n");
- ret = __print_txpwr_map(m, rtwdev, tbl->byr);
- if (ret)
- goto err;
-
- seq_puts(m, "\n[TX power limit]\n");
- ret = __print_txpwr_map(m, rtwdev, tbl->lmt);
- if (ret)
- goto err;
-
- seq_puts(m, "\n[TX power limit_ru]\n");
- ret = __print_txpwr_map(m, rtwdev, tbl->lmt_ru);
- if (ret)
- goto err;
+ tbl = dbgfs_txpwr_tables[chip_gen];
+ if (!tbl)
+ return -EOPNOTSUPP;
-err:
- mutex_unlock(&rtwdev->mutex);
- return ret;
+ p += scnprintf(p, end - p, "\n[TX power byrate]\n");
+ n = __print_txpwr_map(rtwdev, p, end - p, tbl->byr);
+ if (n < 0)
+ return n;
+ p += n;
+
+ p += scnprintf(p, end - p, "\n[TX power limit]\n");
+ n = __print_txpwr_map(rtwdev, p, end - p, tbl->lmt);
+ if (n < 0)
+ return n;
+ p += n;
+
+ p += scnprintf(p, end - p, "\n[TX power limit_ru]\n");
+ n = __print_txpwr_map(rtwdev, p, end - p, tbl->lmt_ru);
+ if (n < 0)
+ return n;
+ p += n;
+
+ return p - buf;
}
static ssize_t
-rtw89_debug_priv_mac_reg_dump_select(struct file *filp,
- const char __user *user_buf,
- size_t count, loff_t *loff)
+rtw89_debug_priv_mac_reg_dump_select(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
{
- struct seq_file *m = (struct seq_file *)filp->private_data;
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
const struct rtw89_chip_info *chip = rtwdev->chip;
- char buf[32];
- size_t buf_size;
int sel;
int ret;
- buf_size = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, buf_size))
- return -EFAULT;
-
- buf[buf_size] = '\0';
ret = kstrtoint(buf, 0, &sel);
if (ret)
return ret;
@@ -908,99 +1006,91 @@ rtw89_debug_priv_mac_reg_dump_select(struct file *filp,
#define RTW89_MAC_PAGE_SIZE 0x100
-static int rtw89_debug_priv_mac_reg_dump_get(struct seq_file *m, void *v)
+static
+ssize_t rtw89_debug_priv_mac_reg_dump_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
{
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
enum rtw89_debug_mac_reg_sel reg_sel = debugfs_priv->cb_data;
- u32 start, end;
+ char *p = buf, *end = buf + bufsz;
+ u32 start, end_addr;
u32 i, j, k, page;
u32 val;
switch (reg_sel) {
case RTW89_DBG_SEL_MAC_00:
- seq_puts(m, "Debug selected MAC page 0x00\n");
+ p += scnprintf(p, end - p, "Debug selected MAC page 0x00\n");
start = 0x000;
- end = 0x014;
+ end_addr = 0x014;
break;
case RTW89_DBG_SEL_MAC_30:
- seq_puts(m, "Debug selected MAC page 0x30\n");
+ p += scnprintf(p, end - p, "Debug selected MAC page 0x30\n");
start = 0x030;
- end = 0x033;
+ end_addr = 0x033;
break;
case RTW89_DBG_SEL_MAC_40:
- seq_puts(m, "Debug selected MAC page 0x40\n");
+ p += scnprintf(p, end - p, "Debug selected MAC page 0x40\n");
start = 0x040;
- end = 0x07f;
+ end_addr = 0x07f;
break;
case RTW89_DBG_SEL_MAC_80:
- seq_puts(m, "Debug selected MAC page 0x80\n");
+ p += scnprintf(p, end - p, "Debug selected MAC page 0x80\n");
start = 0x080;
- end = 0x09f;
+ end_addr = 0x09f;
break;
case RTW89_DBG_SEL_MAC_C0:
- seq_puts(m, "Debug selected MAC page 0xc0\n");
+ p += scnprintf(p, end - p, "Debug selected MAC page 0xc0\n");
start = 0x0c0;
- end = 0x0df;
+ end_addr = 0x0df;
break;
case RTW89_DBG_SEL_MAC_E0:
- seq_puts(m, "Debug selected MAC page 0xe0\n");
+ p += scnprintf(p, end - p, "Debug selected MAC page 0xe0\n");
start = 0x0e0;
- end = 0x0ff;
+ end_addr = 0x0ff;
break;
case RTW89_DBG_SEL_BB:
- seq_puts(m, "Debug selected BB register\n");
+ p += scnprintf(p, end - p, "Debug selected BB register\n");
start = 0x100;
- end = 0x17f;
+ end_addr = 0x17f;
break;
case RTW89_DBG_SEL_IQK:
- seq_puts(m, "Debug selected IQK register\n");
+ p += scnprintf(p, end - p, "Debug selected IQK register\n");
start = 0x180;
- end = 0x1bf;
+ end_addr = 0x1bf;
break;
case RTW89_DBG_SEL_RFC:
- seq_puts(m, "Debug selected RFC register\n");
+ p += scnprintf(p, end - p, "Debug selected RFC register\n");
start = 0x1c0;
- end = 0x1ff;
+ end_addr = 0x1ff;
break;
default:
- seq_puts(m, "Selected invalid register page\n");
+ p += scnprintf(p, end - p, "Selected invalid register page\n");
return -EINVAL;
}
- for (i = start; i <= end; i++) {
+ for (i = start; i <= end_addr; i++) {
page = i << 8;
for (j = page; j < page + RTW89_MAC_PAGE_SIZE; j += 16) {
- seq_printf(m, "%08xh : ", 0x18600000 + j);
+ p += scnprintf(p, end - p, "%08xh : ", 0x18600000 + j);
for (k = 0; k < 4; k++) {
val = rtw89_read32(rtwdev, j + (k << 2));
- seq_printf(m, "%08x ", val);
+ p += scnprintf(p, end - p, "%08x ", val);
}
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
}
- return 0;
+ return p - buf;
}
static ssize_t
-rtw89_debug_priv_mac_mem_dump_select(struct file *filp,
- const char __user *user_buf,
- size_t count, loff_t *loff)
+rtw89_debug_priv_mac_mem_dump_select(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
{
- struct seq_file *m = (struct seq_file *)filp->private_data;
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
- char buf[32];
- size_t buf_size;
u32 sel, start_addr, len;
int num;
- buf_size = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, buf_size))
- return -EFAULT;
-
- buf[buf_size] = '\0';
num = sscanf(buf, "%x %x %x", &sel, &start_addr, &len);
if (num != 3) {
rtw89_info(rtwdev, "invalid format: <sel> <start> <len>\n");
@@ -1017,15 +1107,16 @@ rtw89_debug_priv_mac_mem_dump_select(struct file *filp,
return count;
}
-static void rtw89_debug_dump_mac_mem(struct seq_file *m,
- struct rtw89_dev *rtwdev,
- u8 sel, u32 start_addr, u32 len)
+static int rtw89_debug_dump_mac_mem(struct rtw89_dev *rtwdev,
+ char *buf, size_t bufsz,
+ u8 sel, u32 start_addr, u32 len)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u32 filter_model_addr = mac->filter_model_addr;
u32 indir_access_addr = mac->indir_access_addr;
u32 base_addr, start_page, residue;
- u32 i, j, p, pages;
+ char *p = buf, *end = buf + bufsz;
+ u32 i, j, pp, pages;
u32 dump_len, remain;
u32 val;
@@ -1036,32 +1127,37 @@ static void rtw89_debug_dump_mac_mem(struct seq_file *m,
base_addr = mac->mem_base_addrs[sel];
base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE;
- for (p = 0; p < pages; p++) {
+ for (pp = 0; pp < pages; pp++) {
dump_len = min_t(u32, remain, MAC_MEM_DUMP_PAGE_SIZE);
rtw89_write32(rtwdev, filter_model_addr, base_addr);
for (i = indir_access_addr + residue;
i < indir_access_addr + dump_len;) {
- seq_printf(m, "%08xh:", i);
+ p += scnprintf(p, end - p, "%08xh:", i);
for (j = 0;
j < 4 && i < indir_access_addr + dump_len;
j++, i += 4) {
val = rtw89_read32(rtwdev, i);
- seq_printf(m, " %08x", val);
+ p += scnprintf(p, end - p, " %08x", val);
remain -= 4;
}
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
}
base_addr += MAC_MEM_DUMP_PAGE_SIZE;
}
+
+ return p - buf;
}
-static int
-rtw89_debug_priv_mac_mem_dump_get(struct seq_file *m, void *v)
+static ssize_t
+rtw89_debug_priv_mac_mem_dump_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
{
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
+ char *p = buf, *end = buf + bufsz;
bool grant_read = false;
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
if (debugfs_priv->mac_mem.sel >= RTW89_MAC_MEM_NUM)
return -ENOENT;
@@ -1078,40 +1174,28 @@ rtw89_debug_priv_mac_mem_dump_get(struct seq_file *m, void *v)
}
}
- mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
if (grant_read)
rtw89_write32_set(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO);
- rtw89_debug_dump_mac_mem(m, rtwdev,
- debugfs_priv->mac_mem.sel,
- debugfs_priv->mac_mem.start,
- debugfs_priv->mac_mem.len);
+ p += rtw89_debug_dump_mac_mem(rtwdev, p, end - p,
+ debugfs_priv->mac_mem.sel,
+ debugfs_priv->mac_mem.start,
+ debugfs_priv->mac_mem.len);
if (grant_read)
rtw89_write32_clr(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO);
- mutex_unlock(&rtwdev->mutex);
- return 0;
+ return p - buf;
}
static ssize_t
-rtw89_debug_priv_mac_dbg_port_dump_select(struct file *filp,
- const char __user *user_buf,
- size_t count, loff_t *loff)
+rtw89_debug_priv_mac_dbg_port_dump_select(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
{
- struct seq_file *m = (struct seq_file *)filp->private_data;
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
- char buf[32];
- size_t buf_size;
int sel, set;
int num;
bool enable;
- buf_size = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, buf_size))
- return -EFAULT;
-
- buf[buf_size] = '\0';
num = sscanf(buf, "%d %d", &sel, &set);
if (num != 2) {
rtw89_info(rtwdev, "invalid format: <sel> <set>\n");
@@ -1147,13 +1231,13 @@ rtw89_debug_priv_mac_dbg_port_dump_select(struct file *filp,
}
static int rtw89_debug_mac_dump_ss_dbg(struct rtw89_dev *rtwdev,
- struct seq_file *m)
+ char *buf, size_t bufsz)
{
return 0;
}
static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev,
- struct seq_file *m)
+ char *buf, size_t bufsz)
{
#define DLE_DFI_DUMP(__type, __target, __sel) \
({ \
@@ -1182,7 +1266,7 @@ static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev,
__data; \
})
-#define DLE_DFI_FREE_PAGE_DUMP(__m, __type) \
+#define DLE_DFI_FREE_PAGE_DUMP(__p, __end, __type) \
({ \
u32 __freepg, __pubpg; \
u32 __freepg_head, __freepg_tail, __pubpg_num; \
@@ -1192,24 +1276,25 @@ static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev,
__freepg_head = FIELD_GET(B_AX_DLE_FREE_HEADPG, __freepg); \
__freepg_tail = FIELD_GET(B_AX_DLE_FREE_TAILPG, __freepg); \
__pubpg_num = FIELD_GET(B_AX_DLE_PUB_PGNUM, __pubpg); \
- seq_printf(__m, "[%s] freepg head: %d\n", \
- #__type, __freepg_head); \
- seq_printf(__m, "[%s] freepg tail: %d\n", \
- #__type, __freepg_tail); \
- seq_printf(__m, "[%s] pubpg num : %d\n", \
- #__type, __pubpg_num); \
+ __p += scnprintf(__p, __end - __p, "[%s] freepg head: %d\n", \
+ #__type, __freepg_head); \
+ __p += scnprintf(__p, __end - __p, "[%s] freepg tail: %d\n", \
+ #__type, __freepg_tail); \
+ __p += scnprintf(__p, __end - __p, "[%s] pubpg num : %d\n", \
+ #__type, __pubpg_num); \
})
-#define case_QUOTA(__m, __type, __id) \
+#define case_QUOTA(__p, __end, __type, __id) \
case __type##_QTAID_##__id: \
- val32 = DLE_DFI_DUMP(__type, QUOTA, __type##_QTAID_##__id); \
+ val32 = DLE_DFI_DUMP(__type, QUOTA, __type##_QTAID_##__id); \
rsv_pgnum = FIELD_GET(B_AX_DLE_RSV_PGNUM, val32); \
use_pgnum = FIELD_GET(B_AX_DLE_USE_PGNUM, val32); \
- seq_printf(__m, "[%s][%s] rsv_pgnum: %d\n", \
- #__type, #__id, rsv_pgnum); \
- seq_printf(__m, "[%s][%s] use_pgnum: %d\n", \
- #__type, #__id, use_pgnum); \
+ __p += scnprintf(__p, __end - __p, "[%s][%s] rsv_pgnum: %d\n", \
+ #__type, #__id, rsv_pgnum); \
+ __p += scnprintf(__p, __end - __p, "[%s][%s] use_pgnum: %d\n", \
+ #__type, #__id, use_pgnum); \
break
+ char *p = buf, *end = buf + bufsz;
u32 quota_id;
u32 val32;
u16 rsv_pgnum, use_pgnum;
@@ -1217,38 +1302,39 @@ static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev,
ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL);
if (ret) {
- seq_puts(m, "[DLE] : DMAC not enabled\n");
- return ret;
+ p += scnprintf(p, end - p, "[DLE] : DMAC not enabled\n");
+ goto out;
}
- DLE_DFI_FREE_PAGE_DUMP(m, WDE);
- DLE_DFI_FREE_PAGE_DUMP(m, PLE);
+ DLE_DFI_FREE_PAGE_DUMP(p, end, WDE);
+ DLE_DFI_FREE_PAGE_DUMP(p, end, PLE);
for (quota_id = 0; quota_id <= WDE_QTAID_CPUIO; quota_id++) {
switch (quota_id) {
- case_QUOTA(m, WDE, HOST_IF);
- case_QUOTA(m, WDE, WLAN_CPU);
- case_QUOTA(m, WDE, DATA_CPU);
- case_QUOTA(m, WDE, PKTIN);
- case_QUOTA(m, WDE, CPUIO);
+ case_QUOTA(p, end, WDE, HOST_IF);
+ case_QUOTA(p, end, WDE, WLAN_CPU);
+ case_QUOTA(p, end, WDE, DATA_CPU);
+ case_QUOTA(p, end, WDE, PKTIN);
+ case_QUOTA(p, end, WDE, CPUIO);
}
}
for (quota_id = 0; quota_id <= PLE_QTAID_CPUIO; quota_id++) {
switch (quota_id) {
- case_QUOTA(m, PLE, B0_TXPL);
- case_QUOTA(m, PLE, B1_TXPL);
- case_QUOTA(m, PLE, C2H);
- case_QUOTA(m, PLE, H2C);
- case_QUOTA(m, PLE, WLAN_CPU);
- case_QUOTA(m, PLE, MPDU);
- case_QUOTA(m, PLE, CMAC0_RX);
- case_QUOTA(m, PLE, CMAC1_RX);
- case_QUOTA(m, PLE, CMAC1_BBRPT);
- case_QUOTA(m, PLE, WDRLS);
- case_QUOTA(m, PLE, CPUIO);
+ case_QUOTA(p, end, PLE, B0_TXPL);
+ case_QUOTA(p, end, PLE, B1_TXPL);
+ case_QUOTA(p, end, PLE, C2H);
+ case_QUOTA(p, end, PLE, H2C);
+ case_QUOTA(p, end, PLE, WLAN_CPU);
+ case_QUOTA(p, end, PLE, MPDU);
+ case_QUOTA(p, end, PLE, CMAC0_RX);
+ case_QUOTA(p, end, PLE, CMAC1_RX);
+ case_QUOTA(p, end, PLE, CMAC1_BBRPT);
+ case_QUOTA(p, end, PLE, WDRLS);
+ case_QUOTA(p, end, PLE, CPUIO);
}
}
- return 0;
+out:
+ return p - buf;
#undef case_QUOTA
#undef DLE_DFI_DUMP
@@ -1256,73 +1342,88 @@ static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev,
}
static int rtw89_debug_mac_dump_dmac_dbg(struct rtw89_dev *rtwdev,
- struct seq_file *m)
+ char *buf, size_t bufsz)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
+ char *p = buf, *end = buf + bufsz;
u32 dmac_err;
int i, ret;
ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL);
if (ret) {
- seq_puts(m, "[DMAC] : DMAC not enabled\n");
- return ret;
+ p += scnprintf(p, end - p, "[DMAC] : DMAC not enabled\n");
+ goto out;
}
dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR);
- seq_printf(m, "R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err);
- seq_printf(m, "R_AX_DMAC_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR));
+ p += scnprintf(p, end - p, "R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err);
+ p += scnprintf(p, end - p, "R_AX_DMAC_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR));
if (dmac_err) {
- seq_printf(m, "R_AX_WDE_ERR_FLAG_CFG=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1));
- seq_printf(m, "R_AX_PLE_ERR_FLAG_CFG=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1));
+ p += scnprintf(p, end - p, "R_AX_WDE_ERR_FLAG_CFG=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1));
+ p += scnprintf(p, end - p, "R_AX_PLE_ERR_FLAG_CFG=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1));
if (chip->chip_id == RTL8852C) {
- seq_printf(m, "R_AX_PLE_ERRFLAG_MSG=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG));
- seq_printf(m, "R_AX_WDE_ERRFLAG_MSG=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG));
- seq_printf(m, "R_AX_PLE_DBGERR_LOCKEN=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN));
- seq_printf(m, "R_AX_PLE_DBGERR_STS=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS));
+ p += scnprintf(p, end - p,
+ "R_AX_PLE_ERRFLAG_MSG=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG));
+ p += scnprintf(p, end - p,
+ "R_AX_WDE_ERRFLAG_MSG=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG));
+ p += scnprintf(p, end - p,
+ "R_AX_PLE_DBGERR_LOCKEN=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN));
+ p += scnprintf(p, end - p,
+ "R_AX_PLE_DBGERR_STS=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS));
}
}
if (dmac_err & B_AX_WDRLS_ERR_FLAG) {
- seq_printf(m, "R_AX_WDRLS_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR));
- seq_printf(m, "R_AX_WDRLS_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR));
+ p += scnprintf(p, end - p, "R_AX_WDRLS_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR));
+ p += scnprintf(p, end - p, "R_AX_WDRLS_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR));
if (chip->chip_id == RTL8852C)
- seq_printf(m, "R_AX_RPQ_RXBD_IDX=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1));
+ p += scnprintf(p, end - p,
+ "R_AX_RPQ_RXBD_IDX=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1));
else
- seq_printf(m, "R_AX_RPQ_RXBD_IDX=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX));
+ p += scnprintf(p, end - p,
+ "R_AX_RPQ_RXBD_IDX=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX));
}
if (dmac_err & B_AX_WSEC_ERR_FLAG) {
if (chip->chip_id == RTL8852C) {
- seq_printf(m, "R_AX_SEC_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR));
- seq_printf(m, "R_AX_SEC_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG));
- seq_printf(m, "R_AX_SEC_ENG_CTRL=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL));
- seq_printf(m, "R_AX_SEC_MPDU_PROC=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC));
- seq_printf(m, "R_AX_SEC_CAM_ACCESS=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS));
- seq_printf(m, "R_AX_SEC_CAM_RDATA=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA));
- seq_printf(m, "R_AX_SEC_DEBUG1=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_DEBUG1));
- seq_printf(m, "R_AX_SEC_TX_DEBUG=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG));
- seq_printf(m, "R_AX_SEC_RX_DEBUG=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_ENG_CTRL=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_MPDU_PROC=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_CAM_ACCESS=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_CAM_RDATA=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA));
+ p += scnprintf(p, end - p, "R_AX_SEC_DEBUG1=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_DEBUG1));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_TX_DEBUG=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_RX_DEBUG=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG));
rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL,
B_AX_DBG_SEL0, 0x8B);
@@ -1333,187 +1434,229 @@ static int rtw89_debug_mac_dump_dmac_dbg(struct rtw89_dev *rtwdev,
for (i = 0; i < 0x10; i++) {
rtw89_write32_mask(rtwdev, R_AX_SEC_ENG_CTRL,
B_AX_SEC_DBG_PORT_FIELD_MASK, i);
- seq_printf(m, "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n",
- i, rtw89_read32(rtwdev, R_AX_SEC_DEBUG2));
+ p += scnprintf(p, end - p,
+ "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n",
+ i,
+ rtw89_read32(rtwdev, R_AX_SEC_DEBUG2));
}
} else {
- seq_printf(m, "R_AX_SEC_ERR_IMR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_DEBUG));
- seq_printf(m, "R_AX_SEC_ENG_CTRL=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL));
- seq_printf(m, "R_AX_SEC_MPDU_PROC=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC));
- seq_printf(m, "R_AX_SEC_CAM_ACCESS=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS));
- seq_printf(m, "R_AX_SEC_CAM_RDATA=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA));
- seq_printf(m, "R_AX_SEC_CAM_WDATA=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA));
- seq_printf(m, "R_AX_SEC_TX_DEBUG=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG));
- seq_printf(m, "R_AX_SEC_RX_DEBUG=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG));
- seq_printf(m, "R_AX_SEC_TRX_PKT_CNT=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT));
- seq_printf(m, "R_AX_SEC_TRX_BLK_CNT=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_ERR_IMR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_DEBUG));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_ENG_CTRL=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_MPDU_PROC=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_CAM_ACCESS=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_CAM_RDATA=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_CAM_WDATA=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_TX_DEBUG=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_RX_DEBUG=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_TRX_PKT_CNT=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT));
+ p += scnprintf(p, end - p,
+ "R_AX_SEC_TRX_BLK_CNT=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT));
}
}
if (dmac_err & B_AX_MPDU_ERR_FLAG) {
- seq_printf(m, "R_AX_MPDU_TX_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR));
- seq_printf(m, "R_AX_MPDU_TX_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR));
- seq_printf(m, "R_AX_MPDU_RX_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR));
- seq_printf(m, "R_AX_MPDU_RX_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR));
+ p += scnprintf(p, end - p, "R_AX_MPDU_TX_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR));
+ p += scnprintf(p, end - p, "R_AX_MPDU_TX_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR));
+ p += scnprintf(p, end - p, "R_AX_MPDU_RX_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR));
+ p += scnprintf(p, end - p, "R_AX_MPDU_RX_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR));
}
if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) {
- seq_printf(m, "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR));
- seq_printf(m, "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR));
+ p += scnprintf(p, end - p,
+ "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR));
+ p += scnprintf(p, end - p,
+ "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR));
}
if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) {
- seq_printf(m, "R_AX_WDE_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR));
- seq_printf(m, "R_AX_WDE_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR));
- seq_printf(m, "R_AX_PLE_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR));
- seq_printf(m, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR));
+ p += scnprintf(p, end - p, "R_AX_WDE_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR));
+ p += scnprintf(p, end - p, "R_AX_WDE_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR));
+ p += scnprintf(p, end - p, "R_AX_PLE_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR));
+ p += scnprintf(p, end - p, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR));
}
if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) {
if (chip->chip_id == RTL8852C) {
- seq_printf(m, "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR));
- seq_printf(m, "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR));
- seq_printf(m, "R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR));
- seq_printf(m, "R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR));
+ p += scnprintf(p, end - p,
+ "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR));
+ p += scnprintf(p, end - p,
+ "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR));
+ p += scnprintf(p, end - p,
+ "R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR));
+ p += scnprintf(p, end - p,
+ "R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR));
} else {
- seq_printf(m, "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR));
- seq_printf(m, "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1));
+ p += scnprintf(p, end - p,
+ "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR));
+ p += scnprintf(p, end - p,
+ "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1));
}
}
if (dmac_err & B_AX_PLE_DLE_ERR_FLAG) {
- seq_printf(m, "R_AX_WDE_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR));
- seq_printf(m, "R_AX_WDE_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR));
- seq_printf(m, "R_AX_PLE_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR));
- seq_printf(m, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR));
- seq_printf(m, "R_AX_WD_CPUQ_OP_0=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0));
- seq_printf(m, "R_AX_WD_CPUQ_OP_1=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1));
- seq_printf(m, "R_AX_WD_CPUQ_OP_2=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2));
- seq_printf(m, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS));
- seq_printf(m, "R_AX_PL_CPUQ_OP_0=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0));
- seq_printf(m, "R_AX_PL_CPUQ_OP_1=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1));
- seq_printf(m, "R_AX_PL_CPUQ_OP_2=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2));
- seq_printf(m, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS));
+ p += scnprintf(p, end - p, "R_AX_WDE_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR));
+ p += scnprintf(p, end - p, "R_AX_WDE_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR));
+ p += scnprintf(p, end - p, "R_AX_PLE_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR));
+ p += scnprintf(p, end - p, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR));
+ p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_0=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0));
+ p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_1=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1));
+ p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_2=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2));
+ p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS));
+ p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_0=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0));
+ p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_1=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1));
+ p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_2=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2));
+ p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS));
if (chip->chip_id == RTL8852C) {
- seq_printf(m, "R_AX_RX_CTRL0=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RX_CTRL0));
- seq_printf(m, "R_AX_RX_CTRL1=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RX_CTRL1));
- seq_printf(m, "R_AX_RX_CTRL2=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RX_CTRL2));
+ p += scnprintf(p, end - p, "R_AX_RX_CTRL0=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RX_CTRL0));
+ p += scnprintf(p, end - p, "R_AX_RX_CTRL1=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RX_CTRL1));
+ p += scnprintf(p, end - p, "R_AX_RX_CTRL2=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RX_CTRL2));
} else {
- seq_printf(m, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0));
- seq_printf(m, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1));
- seq_printf(m, "R_AX_RXDMA_PKT_INFO_2=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2));
+ p += scnprintf(p, end - p,
+ "R_AX_RXDMA_PKT_INFO_0=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0));
+ p += scnprintf(p, end - p,
+ "R_AX_RXDMA_PKT_INFO_1=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1));
+ p += scnprintf(p, end - p,
+ "R_AX_RXDMA_PKT_INFO_2=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2));
}
}
if (dmac_err & B_AX_PKTIN_ERR_FLAG) {
- seq_printf(m, "R_AX_PKTIN_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR));
- seq_printf(m, "R_AX_PKTIN_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR));
+ p += scnprintf(p, end - p, "R_AX_PKTIN_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR));
+ p += scnprintf(p, end - p, "R_AX_PKTIN_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR));
}
if (dmac_err & B_AX_DISPATCH_ERR_FLAG) {
- seq_printf(m, "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR));
- seq_printf(m, "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR));
- seq_printf(m, "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR));
- seq_printf(m, "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR));
- seq_printf(m, "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR));
- seq_printf(m, "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR));
+ p += scnprintf(p, end - p,
+ "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR));
+ p += scnprintf(p, end - p,
+ "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR));
+ p += scnprintf(p, end - p,
+ "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR));
+ p += scnprintf(p, end - p,
+ "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR));
+ p += scnprintf(p, end - p,
+ "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR));
+ p += scnprintf(p, end - p,
+ "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR));
}
if (dmac_err & B_AX_BBRPT_ERR_FLAG) {
if (chip->chip_id == RTL8852C) {
- seq_printf(m, "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR));
- seq_printf(m, "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR));
- seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR));
- seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR));
- seq_printf(m, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR));
- seq_printf(m, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));
+ p += scnprintf(p, end - p,
+ "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR));
+ p += scnprintf(p, end - p,
+ "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR));
+ p += scnprintf(p, end - p,
+ "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR));
+ p += scnprintf(p, end - p,
+ "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR));
+ p += scnprintf(p, end - p,
+ "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR));
+ p += scnprintf(p, end - p,
+ "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));
} else {
- seq_printf(m, "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR));
- seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR));
- seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR));
- seq_printf(m, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR));
- seq_printf(m, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));
+ p += scnprintf(p, end - p,
+ "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR));
+ p += scnprintf(p, end - p,
+ "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR));
+ p += scnprintf(p, end - p,
+ "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR));
+ p += scnprintf(p, end - p,
+ "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR));
+ p += scnprintf(p, end - p,
+ "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));
}
}
if (dmac_err & B_AX_HAXIDMA_ERR_FLAG && chip->chip_id == RTL8852C) {
- seq_printf(m, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK));
- seq_printf(m, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n",
- rtw89_read32(rtwdev, R_AX_HAXI_IDCT));
+ p += scnprintf(p, end - p, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK));
+ p += scnprintf(p, end - p, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n",
+ rtw89_read32(rtwdev, R_AX_HAXI_IDCT));
}
- return 0;
+out:
+ return p - buf;
}
static int rtw89_debug_mac_dump_cmac_err(struct rtw89_dev *rtwdev,
- struct seq_file *m,
+ char *buf, size_t bufsz,
enum rtw89_mac_idx band)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
+ char *p = buf, *end = buf + bufsz;
u32 offset = 0;
u32 cmac_err;
int ret;
@@ -1521,96 +1664,127 @@ static int rtw89_debug_mac_dump_cmac_err(struct rtw89_dev *rtwdev,
ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL);
if (ret) {
if (band)
- seq_puts(m, "[CMAC] : CMAC1 not enabled\n");
+ p += scnprintf(p, end - p,
+ "[CMAC] : CMAC1 not enabled\n");
else
- seq_puts(m, "[CMAC] : CMAC0 not enabled\n");
- return ret;
+ p += scnprintf(p, end - p,
+ "[CMAC] : CMAC0 not enabled\n");
+ goto out;
}
if (band)
offset = RTW89_MAC_AX_BAND_REG_OFFSET;
cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset);
- seq_printf(m, "R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset));
- seq_printf(m, "R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset));
- seq_printf(m, "R_AX_CK_EN [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_CK_EN + offset));
+ p += scnprintf(p, end - p, "R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset));
+ p += scnprintf(p, end - p, "R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset));
+ p += scnprintf(p, end - p, "R_AX_CK_EN [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_AX_CK_EN + offset));
if (cmac_err & B_AX_SCHEDULE_TOP_ERR_IND) {
- seq_printf(m, "R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset));
- seq_printf(m, "R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset));
+ p += scnprintf(p, end - p,
+ "R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset));
+ p += scnprintf(p, end - p,
+ "R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset));
}
if (cmac_err & B_AX_PTCL_TOP_ERR_IND) {
- seq_printf(m, "R_AX_PTCL_IMR0 [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset));
- seq_printf(m, "R_AX_PTCL_ISR0 [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_PTCL_ISR0 + offset));
+ p += scnprintf(p, end - p, "R_AX_PTCL_IMR0 [%d]=0x%08x\n",
+ band,
+ rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset));
+ p += scnprintf(p, end - p, "R_AX_PTCL_ISR0 [%d]=0x%08x\n",
+ band,
+ rtw89_read32(rtwdev, R_AX_PTCL_ISR0 + offset));
}
if (cmac_err & B_AX_DMA_TOP_ERR_IND) {
if (chip->chip_id == RTL8852C) {
- seq_printf(m, "R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset));
- seq_printf(m, "R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset));
+ p += scnprintf(p, end - p,
+ "R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset));
+ p += scnprintf(p, end - p,
+ "R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n",
+ band,
+ rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset));
} else {
- seq_printf(m, "R_AX_DLE_CTRL [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_DLE_CTRL + offset));
+ p += scnprintf(p, end - p,
+ "R_AX_DLE_CTRL [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_AX_DLE_CTRL + offset));
}
}
if (cmac_err & B_AX_DMA_TOP_ERR_IND || cmac_err & B_AX_WMAC_RX_ERR_IND) {
if (chip->chip_id == RTL8852C) {
- seq_printf(m, "R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset));
- seq_printf(m, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset));
+ p += scnprintf(p, end - p,
+ "R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n",
+ band,
+ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset));
+ p += scnprintf(p, end - p,
+ "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n",
+ band,
+ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset));
} else {
- seq_printf(m, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset));
+ p += scnprintf(p, end - p,
+ "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n",
+ band,
+ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset));
}
}
if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) {
- seq_printf(m, "R_AX_TXPWR_IMR [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset));
- seq_printf(m, "R_AX_TXPWR_ISR [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_TXPWR_ISR + offset));
+ p += scnprintf(p, end - p, "R_AX_TXPWR_IMR [%d]=0x%08x\n",
+ band,
+ rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset));
+ p += scnprintf(p, end - p, "R_AX_TXPWR_ISR [%d]=0x%08x\n",
+ band,
+ rtw89_read32(rtwdev, R_AX_TXPWR_ISR + offset));
}
if (cmac_err & B_AX_WMAC_TX_ERR_IND) {
if (chip->chip_id == RTL8852C) {
- seq_printf(m, "R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA + offset));
- seq_printf(m, "R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA_MASK + offset));
+ p += scnprintf(p, end - p,
+ "R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n",
+ band,
+ rtw89_read32(rtwdev,
+ R_AX_TRXPTCL_ERROR_INDICA + offset));
+ p += scnprintf(p, end - p,
+ "R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n",
+ band,
+ rtw89_read32(rtwdev,
+ R_AX_TRXPTCL_ERROR_INDICA_MASK + offset));
} else {
- seq_printf(m, "R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR + offset));
+ p += scnprintf(p, end - p,
+ "R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n",
+ band,
+ rtw89_read32(rtwdev,
+ R_AX_TMAC_ERR_IMR_ISR + offset));
}
- seq_printf(m, "R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset));
+ p += scnprintf(p, end - p,
+ "R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset));
}
- seq_printf(m, "R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band,
- rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset));
+ p += scnprintf(p, end - p, "R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band,
+ rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset));
- return 0;
+out:
+ return p - buf;
}
static int rtw89_debug_mac_dump_cmac_dbg(struct rtw89_dev *rtwdev,
- struct seq_file *m)
+ char *buf, size_t bufsz)
{
- rtw89_debug_mac_dump_cmac_err(rtwdev, m, RTW89_MAC_0);
+ char *p = buf, *end = buf + bufsz;
+
+ p += rtw89_debug_mac_dump_cmac_err(rtwdev, p, end - p, RTW89_MAC_0);
if (rtwdev->dbcc_en)
- rtw89_debug_mac_dump_cmac_err(rtwdev, m, RTW89_MAC_1);
+ p += rtw89_debug_mac_dump_cmac_err(rtwdev, p, end - p, RTW89_MAC_1);
- return 0;
+ return p - buf;
}
static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c0 = {
@@ -2416,11 +2590,12 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_misc2 = {
.rd_msk = B_AX_DEBUG_ST_MASK
};
-static const struct rtw89_mac_dbg_port_info *
-rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
- struct rtw89_dev *rtwdev, u32 sel)
+static int
+rtw89_debug_mac_dbg_port_sel(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
+ u32 sel, const struct rtw89_mac_dbg_port_info **ppinfo)
{
- const struct rtw89_mac_dbg_port_info *info;
+ const struct rtw89_mac_dbg_port_info *info = NULL;
+ char *p = buf, *end = buf + bufsz;
u32 index;
u32 val32;
u16 val16;
@@ -2432,28 +2607,28 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
val16 = rtw89_read16(rtwdev, R_AX_PTCL_DBG);
val16 |= B_AX_PTCL_DBG_EN;
rtw89_write16(rtwdev, R_AX_PTCL_DBG, val16);
- seq_puts(m, "Enable PTCL C0 dbgport.\n");
+ p += scnprintf(p, end - p, "Enable PTCL C0 dbgport.\n");
break;
case RTW89_DBG_PORT_SEL_PTCL_C1:
info = &dbg_port_ptcl_c1;
val16 = rtw89_read16(rtwdev, R_AX_PTCL_DBG_C1);
val16 |= B_AX_PTCL_DBG_EN;
rtw89_write16(rtwdev, R_AX_PTCL_DBG_C1, val16);
- seq_puts(m, "Enable PTCL C1 dbgport.\n");
+ p += scnprintf(p, end - p, "Enable PTCL C1 dbgport.\n");
break;
case RTW89_DBG_PORT_SEL_SCH_C0:
info = &dbg_port_sch_c0;
val32 = rtw89_read32(rtwdev, R_AX_SCH_DBG_SEL);
val32 |= B_AX_SCH_DBG_EN;
rtw89_write32(rtwdev, R_AX_SCH_DBG_SEL, val32);
- seq_puts(m, "Enable SCH C0 dbgport.\n");
+ p += scnprintf(p, end - p, "Enable SCH C0 dbgport.\n");
break;
case RTW89_DBG_PORT_SEL_SCH_C1:
info = &dbg_port_sch_c1;
val32 = rtw89_read32(rtwdev, R_AX_SCH_DBG_SEL_C1);
val32 |= B_AX_SCH_DBG_EN;
rtw89_write32(rtwdev, R_AX_SCH_DBG_SEL_C1, val32);
- seq_puts(m, "Enable SCH C1 dbgport.\n");
+ p += scnprintf(p, end - p, "Enable SCH C1 dbgport.\n");
break;
case RTW89_DBG_PORT_SEL_TMAC_C0:
info = &dbg_port_tmac_c0;
@@ -2470,7 +2645,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1);
val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK);
rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32);
- seq_puts(m, "Enable TMAC C0 dbgport.\n");
+ p += scnprintf(p, end - p, "Enable TMAC C0 dbgport.\n");
break;
case RTW89_DBG_PORT_SEL_TMAC_C1:
info = &dbg_port_tmac_c1;
@@ -2487,7 +2662,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1);
val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK);
rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32);
- seq_puts(m, "Enable TMAC C1 dbgport.\n");
+ p += scnprintf(p, end - p, "Enable TMAC C1 dbgport.\n");
break;
case RTW89_DBG_PORT_SEL_RMAC_C0:
info = &dbg_port_rmac_c0;
@@ -2509,7 +2684,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
val8 = u8_replace_bits(val8, RMAC_CMAC_DBG_SEL,
B_AX_DBGSEL_TRXPTCL_MASK);
rtw89_write8(rtwdev, R_AX_DBGSEL_TRXPTCL, val8);
- seq_puts(m, "Enable RMAC C0 dbgport.\n");
+ p += scnprintf(p, end - p, "Enable RMAC C0 dbgport.\n");
break;
case RTW89_DBG_PORT_SEL_RMAC_C1:
info = &dbg_port_rmac_c1;
@@ -2531,23 +2706,23 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
val8 = u8_replace_bits(val8, RMAC_CMAC_DBG_SEL,
B_AX_DBGSEL_TRXPTCL_MASK);
rtw89_write8(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val8);
- seq_puts(m, "Enable RMAC C1 dbgport.\n");
+ p += scnprintf(p, end - p, "Enable RMAC C1 dbgport.\n");
break;
case RTW89_DBG_PORT_SEL_RMACST_C0:
info = &dbg_port_rmacst_c0;
- seq_puts(m, "Enable RMAC state C0 dbgport.\n");
+ p += scnprintf(p, end - p, "Enable RMAC state C0 dbgport.\n");
break;
case RTW89_DBG_PORT_SEL_RMACST_C1:
info = &dbg_port_rmacst_c1;
- seq_puts(m, "Enable RMAC state C1 dbgport.\n");
+ p += scnprintf(p, end - p, "Enable RMAC state C1 dbgport.\n");
break;
case RTW89_DBG_PORT_SEL_RMAC_PLCP_C0:
info = &dbg_port_rmac_plcp_c0;
- seq_puts(m, "Enable RMAC PLCP C0 dbgport.\n");
+ p += scnprintf(p, end - p, "Enable RMAC PLCP C0 dbgport.\n");
break;
case RTW89_DBG_PORT_SEL_RMAC_PLCP_C1:
info = &dbg_port_rmac_plcp_c1;
- seq_puts(m, "Enable RMAC PLCP C1 dbgport.\n");
+ p += scnprintf(p, end - p, "Enable RMAC PLCP C1 dbgport.\n");
break;
case RTW89_DBG_PORT_SEL_TRXPTCL_C0:
info = &dbg_port_trxptcl_c0;
@@ -2559,7 +2734,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1);
val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK);
rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32);
- seq_puts(m, "Enable TRXPTCL C0 dbgport.\n");
+ p += scnprintf(p, end - p, "Enable TRXPTCL C0 dbgport.\n");
break;
case RTW89_DBG_PORT_SEL_TRXPTCL_C1:
info = &dbg_port_trxptcl_c1;
@@ -2571,131 +2746,137 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1);
val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK);
rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32);
- seq_puts(m, "Enable TRXPTCL C1 dbgport.\n");
+ p += scnprintf(p, end - p, "Enable TRXPTCL C1 dbgport.\n");
break;
case RTW89_DBG_PORT_SEL_TX_INFOL_C0:
info = &dbg_port_tx_infol_c0;
val32 = rtw89_read32(rtwdev, R_AX_TCR1);
val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
rtw89_write32(rtwdev, R_AX_TCR1, val32);
- seq_puts(m, "Enable tx infol dump.\n");
+ p += scnprintf(p, end - p, "Enable tx infol dump.\n");
break;
case RTW89_DBG_PORT_SEL_TX_INFOH_C0:
info = &dbg_port_tx_infoh_c0;
val32 = rtw89_read32(rtwdev, R_AX_TCR1);
val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
rtw89_write32(rtwdev, R_AX_TCR1, val32);
- seq_puts(m, "Enable tx infoh dump.\n");
+ p += scnprintf(p, end - p, "Enable tx infoh dump.\n");
break;
case RTW89_DBG_PORT_SEL_TX_INFOL_C1:
info = &dbg_port_tx_infol_c1;
val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1);
val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
rtw89_write32(rtwdev, R_AX_TCR1_C1, val32);
- seq_puts(m, "Enable tx infol dump.\n");
+ p += scnprintf(p, end - p, "Enable tx infol dump.\n");
break;
case RTW89_DBG_PORT_SEL_TX_INFOH_C1:
info = &dbg_port_tx_infoh_c1;
val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1);
val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
rtw89_write32(rtwdev, R_AX_TCR1_C1, val32);
- seq_puts(m, "Enable tx infoh dump.\n");
+ p += scnprintf(p, end - p, "Enable tx infoh dump.\n");
break;
case RTW89_DBG_PORT_SEL_TXTF_INFOL_C0:
info = &dbg_port_txtf_infol_c0;
val32 = rtw89_read32(rtwdev, R_AX_TCR1);
val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
rtw89_write32(rtwdev, R_AX_TCR1, val32);
- seq_puts(m, "Enable tx tf infol dump.\n");
+ p += scnprintf(p, end - p, "Enable tx tf infol dump.\n");
break;
case RTW89_DBG_PORT_SEL_TXTF_INFOH_C0:
info = &dbg_port_txtf_infoh_c0;
val32 = rtw89_read32(rtwdev, R_AX_TCR1);
val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
rtw89_write32(rtwdev, R_AX_TCR1, val32);
- seq_puts(m, "Enable tx tf infoh dump.\n");
+ p += scnprintf(p, end - p, "Enable tx tf infoh dump.\n");
break;
case RTW89_DBG_PORT_SEL_TXTF_INFOL_C1:
info = &dbg_port_txtf_infol_c1;
val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1);
val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
rtw89_write32(rtwdev, R_AX_TCR1_C1, val32);
- seq_puts(m, "Enable tx tf infol dump.\n");
+ p += scnprintf(p, end - p, "Enable tx tf infol dump.\n");
break;
case RTW89_DBG_PORT_SEL_TXTF_INFOH_C1:
info = &dbg_port_txtf_infoh_c1;
val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1);
val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
rtw89_write32(rtwdev, R_AX_TCR1_C1, val32);
- seq_puts(m, "Enable tx tf infoh dump.\n");
+ p += scnprintf(p, end - p, "Enable tx tf infoh dump.\n");
break;
case RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG:
info = &dbg_port_wde_bufmgn_freepg;
- seq_puts(m, "Enable wde bufmgn freepg dump.\n");
+ p += scnprintf(p, end - p, "Enable wde bufmgn freepg dump.\n");
break;
case RTW89_DBG_PORT_SEL_WDE_BUFMGN_QUOTA:
info = &dbg_port_wde_bufmgn_quota;
- seq_puts(m, "Enable wde bufmgn quota dump.\n");
+ p += scnprintf(p, end - p, "Enable wde bufmgn quota dump.\n");
break;
case RTW89_DBG_PORT_SEL_WDE_BUFMGN_PAGELLT:
info = &dbg_port_wde_bufmgn_pagellt;
- seq_puts(m, "Enable wde bufmgn pagellt dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable wde bufmgn pagellt dump.\n");
break;
case RTW89_DBG_PORT_SEL_WDE_BUFMGN_PKTINFO:
info = &dbg_port_wde_bufmgn_pktinfo;
- seq_puts(m, "Enable wde bufmgn pktinfo dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable wde bufmgn pktinfo dump.\n");
break;
case RTW89_DBG_PORT_SEL_WDE_QUEMGN_PREPKT:
info = &dbg_port_wde_quemgn_prepkt;
- seq_puts(m, "Enable wde quemgn prepkt dump.\n");
+ p += scnprintf(p, end - p, "Enable wde quemgn prepkt dump.\n");
break;
case RTW89_DBG_PORT_SEL_WDE_QUEMGN_NXTPKT:
info = &dbg_port_wde_quemgn_nxtpkt;
- seq_puts(m, "Enable wde quemgn nxtpkt dump.\n");
+ p += scnprintf(p, end - p, "Enable wde quemgn nxtpkt dump.\n");
break;
case RTW89_DBG_PORT_SEL_WDE_QUEMGN_QLNKTBL:
info = &dbg_port_wde_quemgn_qlnktbl;
- seq_puts(m, "Enable wde quemgn qlnktbl dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable wde quemgn qlnktbl dump.\n");
break;
case RTW89_DBG_PORT_SEL_WDE_QUEMGN_QEMPTY:
info = &dbg_port_wde_quemgn_qempty;
- seq_puts(m, "Enable wde quemgn qempty dump.\n");
+ p += scnprintf(p, end - p, "Enable wde quemgn qempty dump.\n");
break;
case RTW89_DBG_PORT_SEL_PLE_BUFMGN_FREEPG:
info = &dbg_port_ple_bufmgn_freepg;
- seq_puts(m, "Enable ple bufmgn freepg dump.\n");
+ p += scnprintf(p, end - p, "Enable ple bufmgn freepg dump.\n");
break;
case RTW89_DBG_PORT_SEL_PLE_BUFMGN_QUOTA:
info = &dbg_port_ple_bufmgn_quota;
- seq_puts(m, "Enable ple bufmgn quota dump.\n");
+ p += scnprintf(p, end - p, "Enable ple bufmgn quota dump.\n");
break;
case RTW89_DBG_PORT_SEL_PLE_BUFMGN_PAGELLT:
info = &dbg_port_ple_bufmgn_pagellt;
- seq_puts(m, "Enable ple bufmgn pagellt dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable ple bufmgn pagellt dump.\n");
break;
case RTW89_DBG_PORT_SEL_PLE_BUFMGN_PKTINFO:
info = &dbg_port_ple_bufmgn_pktinfo;
- seq_puts(m, "Enable ple bufmgn pktinfo dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable ple bufmgn pktinfo dump.\n");
break;
case RTW89_DBG_PORT_SEL_PLE_QUEMGN_PREPKT:
info = &dbg_port_ple_quemgn_prepkt;
- seq_puts(m, "Enable ple quemgn prepkt dump.\n");
+ p += scnprintf(p, end - p, "Enable ple quemgn prepkt dump.\n");
break;
case RTW89_DBG_PORT_SEL_PLE_QUEMGN_NXTPKT:
info = &dbg_port_ple_quemgn_nxtpkt;
- seq_puts(m, "Enable ple quemgn nxtpkt dump.\n");
+ p += scnprintf(p, end - p, "Enable ple quemgn nxtpkt dump.\n");
break;
case RTW89_DBG_PORT_SEL_PLE_QUEMGN_QLNKTBL:
info = &dbg_port_ple_quemgn_qlnktbl;
- seq_puts(m, "Enable ple quemgn qlnktbl dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable ple quemgn qlnktbl dump.\n");
break;
case RTW89_DBG_PORT_SEL_PLE_QUEMGN_QEMPTY:
info = &dbg_port_ple_quemgn_qempty;
- seq_puts(m, "Enable ple quemgn qempty dump.\n");
+ p += scnprintf(p, end - p, "Enable ple quemgn qempty dump.\n");
break;
case RTW89_DBG_PORT_SEL_PKTINFO:
info = &dbg_port_pktinfo;
- seq_puts(m, "Enable pktinfo dump.\n");
+ p += scnprintf(p, end - p, "Enable pktinfo dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_HDT_TX0:
rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL,
@@ -2714,7 +2895,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 0);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, index);
- seq_printf(m, "Enable Dispatcher hdt tx%x dump.\n", index);
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher hdt tx%x dump.\n", index);
break;
case RTW89_DBG_PORT_SEL_DSPT_HDT_TX6:
info = &dbg_port_dspt_hdt_tx6;
@@ -2722,7 +2904,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 0);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 6);
- seq_puts(m, "Enable Dispatcher hdt tx6 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher hdt tx6 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_HDT_TX7:
info = &dbg_port_dspt_hdt_tx7;
@@ -2730,7 +2913,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 0);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 7);
- seq_puts(m, "Enable Dispatcher hdt tx7 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher hdt tx7 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_HDT_TX8:
info = &dbg_port_dspt_hdt_tx8;
@@ -2738,7 +2922,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 0);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 8);
- seq_puts(m, "Enable Dispatcher hdt tx8 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher hdt tx8 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_HDT_TX9:
case RTW89_DBG_PORT_SEL_DSPT_HDT_TXA:
@@ -2750,7 +2935,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 0);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, index);
- seq_printf(m, "Enable Dispatcher hdt tx%x dump.\n", index);
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher hdt tx%x dump.\n", index);
break;
case RTW89_DBG_PORT_SEL_DSPT_HDT_TXD:
info = &dbg_port_dspt_hdt_txD;
@@ -2758,7 +2944,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 0);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 0xD);
- seq_puts(m, "Enable Dispatcher hdt txD dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher hdt txD dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_CDT_TX0:
info = &dbg_port_dspt_cdt_tx0;
@@ -2766,7 +2953,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 1);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 0);
- seq_puts(m, "Enable Dispatcher cdt tx0 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher cdt tx0 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_CDT_TX1:
info = &dbg_port_dspt_cdt_tx1;
@@ -2774,7 +2962,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 1);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 1);
- seq_puts(m, "Enable Dispatcher cdt tx1 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher cdt tx1 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_CDT_TX3:
info = &dbg_port_dspt_cdt_tx3;
@@ -2782,7 +2971,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 1);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 3);
- seq_puts(m, "Enable Dispatcher cdt tx3 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher cdt tx3 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_CDT_TX4:
info = &dbg_port_dspt_cdt_tx4;
@@ -2790,7 +2980,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 1);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 4);
- seq_puts(m, "Enable Dispatcher cdt tx4 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher cdt tx4 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_CDT_TX5:
case RTW89_DBG_PORT_SEL_DSPT_CDT_TX6:
@@ -2802,7 +2993,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 1);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, index);
- seq_printf(m, "Enable Dispatcher cdt tx%x dump.\n", index);
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher cdt tx%x dump.\n", index);
break;
case RTW89_DBG_PORT_SEL_DSPT_CDT_TX9:
info = &dbg_port_dspt_cdt_tx9;
@@ -2810,7 +3002,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 1);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 9);
- seq_puts(m, "Enable Dispatcher cdt tx9 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher cdt tx9 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_CDT_TXA:
case RTW89_DBG_PORT_SEL_DSPT_CDT_TXB:
@@ -2821,7 +3014,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 1);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, index);
- seq_printf(m, "Enable Dispatcher cdt tx%x dump.\n", index);
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher cdt tx%x dump.\n", index);
break;
case RTW89_DBG_PORT_SEL_DSPT_HDT_RX0:
info = &dbg_port_dspt_hdt_rx0;
@@ -2829,7 +3023,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 2);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 0);
- seq_puts(m, "Enable Dispatcher hdt rx0 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher hdt rx0 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_HDT_RX1:
case RTW89_DBG_PORT_SEL_DSPT_HDT_RX2:
@@ -2839,7 +3034,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 2);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, index);
- seq_printf(m, "Enable Dispatcher hdt rx%x dump.\n", index);
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher hdt rx%x dump.\n", index);
break;
case RTW89_DBG_PORT_SEL_DSPT_HDT_RX3:
info = &dbg_port_dspt_hdt_rx3;
@@ -2847,7 +3043,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 2);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 3);
- seq_puts(m, "Enable Dispatcher hdt rx3 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher hdt rx3 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_HDT_RX4:
info = &dbg_port_dspt_hdt_rx4;
@@ -2855,7 +3052,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 2);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 4);
- seq_puts(m, "Enable Dispatcher hdt rx4 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher hdt rx4 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_HDT_RX5:
info = &dbg_port_dspt_hdt_rx5;
@@ -2863,7 +3061,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 2);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 5);
- seq_puts(m, "Enable Dispatcher hdt rx5 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher hdt rx5 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_0:
info = &dbg_port_dspt_cdt_rx_p0_0;
@@ -2871,7 +3070,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 3);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 0);
- seq_puts(m, "Enable Dispatcher cdt rx part0 0 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher cdt rx part0 0 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0:
case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_1:
@@ -2880,7 +3080,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 3);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 1);
- seq_puts(m, "Enable Dispatcher cdt rx part0 1 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher cdt rx part0 1 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_2:
info = &dbg_port_dspt_cdt_rx_p0_2;
@@ -2888,43 +3089,50 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
B_AX_DISPATCHER_INTN_SEL_MASK, 3);
rtw89_write16_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_CH_SEL_MASK, 2);
- seq_puts(m, "Enable Dispatcher cdt rx part0 2 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher cdt rx part0 2 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P1:
info = &dbg_port_dspt_cdt_rx_p1;
rtw89_write8_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_INTN_SEL_MASK, 3);
- seq_puts(m, "Enable Dispatcher cdt rx part1 dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher cdt rx part1 dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_STF_CTRL:
info = &dbg_port_dspt_stf_ctrl;
rtw89_write8_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_INTN_SEL_MASK, 4);
- seq_puts(m, "Enable Dispatcher stf control dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher stf control dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_ADDR_CTRL:
info = &dbg_port_dspt_addr_ctrl;
rtw89_write8_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_INTN_SEL_MASK, 5);
- seq_puts(m, "Enable Dispatcher addr control dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher addr control dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_WDE_INTF:
info = &dbg_port_dspt_wde_intf;
rtw89_write8_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_INTN_SEL_MASK, 6);
- seq_puts(m, "Enable Dispatcher wde interface dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher wde interface dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_PLE_INTF:
info = &dbg_port_dspt_ple_intf;
rtw89_write8_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_INTN_SEL_MASK, 7);
- seq_puts(m, "Enable Dispatcher ple interface dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher ple interface dump.\n");
break;
case RTW89_DBG_PORT_SEL_DSPT_FLOW_CTRL:
info = &dbg_port_dspt_flow_ctrl;
rtw89_write8_mask(rtwdev, info->sel_addr,
B_AX_DISPATCHER_INTN_SEL_MASK, 8);
- seq_puts(m, "Enable Dispatcher flow control dump.\n");
+ p += scnprintf(p, end - p,
+ "Enable Dispatcher flow control dump.\n");
break;
case RTW89_DBG_PORT_SEL_PCIE_TXDMA:
info = &dbg_port_pcie_txdma;
@@ -2932,7 +3140,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
val32 = u32_replace_bits(val32, PCIE_TXDMA_DBG_SEL, B_AX_DBG_SEL0);
val32 = u32_replace_bits(val32, PCIE_TXDMA_DBG_SEL, B_AX_DBG_SEL1);
rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
- seq_puts(m, "Enable pcie txdma dump.\n");
+ p += scnprintf(p, end - p, "Enable pcie txdma dump.\n");
break;
case RTW89_DBG_PORT_SEL_PCIE_RXDMA:
info = &dbg_port_pcie_rxdma;
@@ -2940,7 +3148,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
val32 = u32_replace_bits(val32, PCIE_RXDMA_DBG_SEL, B_AX_DBG_SEL0);
val32 = u32_replace_bits(val32, PCIE_RXDMA_DBG_SEL, B_AX_DBG_SEL1);
rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
- seq_puts(m, "Enable pcie rxdma dump.\n");
+ p += scnprintf(p, end - p, "Enable pcie rxdma dump.\n");
break;
case RTW89_DBG_PORT_SEL_PCIE_CVT:
info = &dbg_port_pcie_cvt;
@@ -2948,7 +3156,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
val32 = u32_replace_bits(val32, PCIE_CVT_DBG_SEL, B_AX_DBG_SEL0);
val32 = u32_replace_bits(val32, PCIE_CVT_DBG_SEL, B_AX_DBG_SEL1);
rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
- seq_puts(m, "Enable pcie cvt dump.\n");
+ p += scnprintf(p, end - p, "Enable pcie cvt dump.\n");
break;
case RTW89_DBG_PORT_SEL_PCIE_CXPL:
info = &dbg_port_pcie_cxpl;
@@ -2956,7 +3164,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
val32 = u32_replace_bits(val32, PCIE_CXPL_DBG_SEL, B_AX_DBG_SEL0);
val32 = u32_replace_bits(val32, PCIE_CXPL_DBG_SEL, B_AX_DBG_SEL1);
rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
- seq_puts(m, "Enable pcie cxpl dump.\n");
+ p += scnprintf(p, end - p, "Enable pcie cxpl dump.\n");
break;
case RTW89_DBG_PORT_SEL_PCIE_IO:
info = &dbg_port_pcie_io;
@@ -2964,7 +3172,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
val32 = u32_replace_bits(val32, PCIE_IO_DBG_SEL, B_AX_DBG_SEL0);
val32 = u32_replace_bits(val32, PCIE_IO_DBG_SEL, B_AX_DBG_SEL1);
rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
- seq_puts(m, "Enable pcie io dump.\n");
+ p += scnprintf(p, end - p, "Enable pcie io dump.\n");
break;
case RTW89_DBG_PORT_SEL_PCIE_MISC:
info = &dbg_port_pcie_misc;
@@ -2972,7 +3180,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
val32 = u32_replace_bits(val32, PCIE_MISC_DBG_SEL, B_AX_DBG_SEL0);
val32 = u32_replace_bits(val32, PCIE_MISC_DBG_SEL, B_AX_DBG_SEL1);
rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
- seq_puts(m, "Enable pcie misc dump.\n");
+ p += scnprintf(p, end - p, "Enable pcie misc dump.\n");
break;
case RTW89_DBG_PORT_SEL_PCIE_MISC2:
info = &dbg_port_pcie_misc2;
@@ -2980,14 +3188,16 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
val16 = u16_replace_bits(val16, PCIE_MISC2_DBG_SEL,
B_AX_PCIE_DBG_SEL_MASK);
rtw89_write16(rtwdev, R_AX_PCIE_DBG_CTRL, val16);
- seq_puts(m, "Enable pcie misc2 dump.\n");
+ p += scnprintf(p, end - p, "Enable pcie misc2 dump.\n");
break;
default:
- seq_puts(m, "Dbg port select err\n");
- return NULL;
+ p += scnprintf(p, end - p, "Dbg port select err\n");
+ break;
}
- return info;
+ *ppinfo = info;
+
+ return p - buf;
}
static bool is_dbg_port_valid(struct rtw89_dev *rtwdev, u32 sel)
@@ -2996,7 +3206,7 @@ static bool is_dbg_port_valid(struct rtw89_dev *rtwdev, u32 sel)
sel >= RTW89_DBG_PORT_SEL_PCIE_TXDMA &&
sel <= RTW89_DBG_PORT_SEL_PCIE_MISC2)
return false;
- if (rtwdev->chip->chip_id == RTL8852B &&
+ if (rtw89_is_rtl885xb(rtwdev) &&
sel >= RTW89_DBG_PORT_SEL_PTCL_C1 &&
sel <= RTW89_DBG_PORT_SEL_TXTF_INFOH_C1)
return false;
@@ -3021,23 +3231,25 @@ static bool is_dbg_port_valid(struct rtw89_dev *rtwdev, u32 sel)
}
static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev,
- struct seq_file *m, u32 sel)
+ char *buf, size_t bufsz, u32 sel)
{
- const struct rtw89_mac_dbg_port_info *info;
- u8 val8;
- u16 val16;
+ const struct rtw89_mac_dbg_port_info *info = NULL;
+ char *p = buf, *end = buf + bufsz;
u32 val32;
+ u16 val16;
+ u8 val8;
u32 i;
- info = rtw89_debug_mac_dbg_port_sel(m, rtwdev, sel);
+ p += rtw89_debug_mac_dbg_port_sel(rtwdev, p, end - p, sel, &info);
+
if (!info) {
rtw89_err(rtwdev, "failed to select debug port %d\n", sel);
- return -EINVAL;
+ goto out;
}
#define case_DBG_SEL(__sel) \
case RTW89_DBG_PORT_SEL_##__sel: \
- seq_puts(m, "Dump debug port " #__sel ":\n"); \
+ p += scnprintf(p, end - p, "Dump debug port " #__sel ":\n"); \
break
switch (sel) {
@@ -3133,8 +3345,8 @@ static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev,
#undef case_DBG_SEL
- seq_printf(m, "Sel addr = 0x%X\n", info->sel_addr);
- seq_printf(m, "Read addr = 0x%X\n", info->rd_addr);
+ p += scnprintf(p, end - p, "Sel addr = 0x%X\n", info->sel_addr);
+ p += scnprintf(p, end - p, "Read addr = 0x%X\n", info->rd_addr);
for (i = info->srt; i <= info->end; i++) {
switch (info->sel_byte) {
@@ -3142,17 +3354,17 @@ static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev,
default:
rtw89_write8_mask(rtwdev, info->sel_addr,
info->sel_msk, i);
- seq_printf(m, "0x%02X: ", i);
+ p += scnprintf(p, end - p, "0x%02X: ", i);
break;
case 2:
rtw89_write16_mask(rtwdev, info->sel_addr,
info->sel_msk, i);
- seq_printf(m, "0x%04X: ", i);
+ p += scnprintf(p, end - p, "0x%04X: ", i);
break;
case 4:
rtw89_write32_mask(rtwdev, info->sel_addr,
info->sel_msk, i);
- seq_printf(m, "0x%04X: ", i);
+ p += scnprintf(p, end - p, "0x%04X: ", i);
break;
}
@@ -3163,77 +3375,75 @@ static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev,
default:
val8 = rtw89_read8_mask(rtwdev,
info->rd_addr, info->rd_msk);
- seq_printf(m, "0x%02X\n", val8);
+ p += scnprintf(p, end - p, "0x%02X\n", val8);
break;
case 2:
val16 = rtw89_read16_mask(rtwdev,
info->rd_addr, info->rd_msk);
- seq_printf(m, "0x%04X\n", val16);
+ p += scnprintf(p, end - p, "0x%04X\n", val16);
break;
case 4:
val32 = rtw89_read32_mask(rtwdev,
info->rd_addr, info->rd_msk);
- seq_printf(m, "0x%08X\n", val32);
+ p += scnprintf(p, end - p, "0x%08X\n", val32);
break;
}
}
- return 0;
+out:
+ return p - buf;
}
static int rtw89_debug_mac_dump_dbg_port(struct rtw89_dev *rtwdev,
- struct seq_file *m)
+ char *buf, size_t bufsz)
{
+ char *p = buf, *end = buf + bufsz;
+ ssize_t n;
u32 sel;
- int ret = 0;
for (sel = RTW89_DBG_PORT_SEL_PTCL_C0;
sel < RTW89_DBG_PORT_SEL_LAST; sel++) {
if (!is_dbg_port_valid(rtwdev, sel))
continue;
- ret = rtw89_debug_mac_dbg_port_dump(rtwdev, m, sel);
- if (ret) {
+ n = rtw89_debug_mac_dbg_port_dump(rtwdev, p, end - p, sel);
+ if (n < 0) {
rtw89_err(rtwdev,
"failed to dump debug port %d\n", sel);
break;
}
+ p += n;
}
- return ret;
+ return p - buf;
}
-static int
-rtw89_debug_priv_mac_dbg_port_dump_get(struct seq_file *m, void *v)
+static ssize_t
+rtw89_debug_priv_mac_dbg_port_dump_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
{
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
+ char *p = buf, *end = buf + bufsz;
if (debugfs_priv->dbgpkg_en.ss_dbg)
- rtw89_debug_mac_dump_ss_dbg(rtwdev, m);
+ p += rtw89_debug_mac_dump_ss_dbg(rtwdev, p, end - p);
if (debugfs_priv->dbgpkg_en.dle_dbg)
- rtw89_debug_mac_dump_dle_dbg(rtwdev, m);
+ p += rtw89_debug_mac_dump_dle_dbg(rtwdev, p, end - p);
if (debugfs_priv->dbgpkg_en.dmac_dbg)
- rtw89_debug_mac_dump_dmac_dbg(rtwdev, m);
+ p += rtw89_debug_mac_dump_dmac_dbg(rtwdev, p, end - p);
if (debugfs_priv->dbgpkg_en.cmac_dbg)
- rtw89_debug_mac_dump_cmac_dbg(rtwdev, m);
+ p += rtw89_debug_mac_dump_cmac_dbg(rtwdev, p, end - p);
if (debugfs_priv->dbgpkg_en.dbg_port)
- rtw89_debug_mac_dump_dbg_port(rtwdev, m);
+ p += rtw89_debug_mac_dump_dbg_port(rtwdev, p, end - p);
- return 0;
+ return p - buf;
};
-static u8 *rtw89_hex2bin_user(struct rtw89_dev *rtwdev,
- const char __user *user_buf, size_t count)
+static u8 *rtw89_hex2bin(struct rtw89_dev *rtwdev, const char *buf, size_t count)
{
- char *buf;
u8 *bin;
int num;
int err = 0;
- buf = memdup_user(user_buf, count);
- if (IS_ERR(buf))
- return buf;
-
num = count / 2;
bin = kmalloc(num, GFP_KERNEL);
if (!bin) {
@@ -3248,22 +3458,18 @@ static u8 *rtw89_hex2bin_user(struct rtw89_dev *rtwdev,
}
out:
- kfree(buf);
-
return err ? ERR_PTR(err) : bin;
}
-static ssize_t rtw89_debug_priv_send_h2c_set(struct file *filp,
- const char __user *user_buf,
- size_t count, loff_t *loff)
+static ssize_t rtw89_debug_priv_send_h2c_set(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
{
- struct rtw89_debugfs_priv *debugfs_priv = filp->private_data;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
u8 *h2c;
int ret;
u16 h2c_len = count / 2;
- h2c = rtw89_hex2bin_user(rtwdev, user_buf, count);
+ h2c = rtw89_hex2bin(rtwdev, buf, count);
if (IS_ERR(h2c))
return -EFAULT;
@@ -3274,34 +3480,36 @@ static ssize_t rtw89_debug_priv_send_h2c_set(struct file *filp,
return ret ? ret : count;
}
-static int
-rtw89_debug_priv_early_h2c_get(struct seq_file *m, void *v)
+static ssize_t
+rtw89_debug_priv_early_h2c_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
{
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
struct rtw89_early_h2c *early_h2c;
+ char *p = buf, *end = buf + bufsz;
int seq = 0;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list)
- seq_printf(m, "%d: %*ph\n", ++seq, early_h2c->h2c_len, early_h2c->h2c);
- mutex_unlock(&rtwdev->mutex);
+ p += scnprintf(p, end - p, "%d: %*ph\n", ++seq,
+ early_h2c->h2c_len, early_h2c->h2c);
- return 0;
+ return p - buf;
}
static ssize_t
-rtw89_debug_priv_early_h2c_set(struct file *filp, const char __user *user_buf,
- size_t count, loff_t *loff)
+rtw89_debug_priv_early_h2c_set(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
{
- struct seq_file *m = (struct seq_file *)filp->private_data;
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
struct rtw89_early_h2c *early_h2c;
u8 *h2c;
u16 h2c_len = count / 2;
- h2c = rtw89_hex2bin_user(rtwdev, user_buf, count);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ h2c = rtw89_hex2bin(rtwdev, buf, count);
if (IS_ERR(h2c))
return -EFAULT;
@@ -3320,9 +3528,7 @@ rtw89_debug_priv_early_h2c_set(struct file *filp, const char __user *user_buf,
early_h2c->h2c = h2c;
early_h2c->h2c_len = h2c_len;
- mutex_lock(&rtwdev->mutex);
list_add_tail(&early_h2c->list, &rtwdev->early_h2c_list);
- mutex_unlock(&rtwdev->mutex);
out:
return count;
@@ -3355,15 +3561,16 @@ static int rtw89_dbg_trigger_ctrl_error(struct rtw89_dev *rtwdev)
return 0;
}
-static int
-rtw89_debug_priv_fw_crash_get(struct seq_file *m, void *v)
+static ssize_t
+rtw89_debug_priv_fw_crash_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
{
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
+ char *p = buf, *end = buf + bufsz;
- seq_printf(m, "%d\n",
- test_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags));
- return 0;
+ p += scnprintf(p, end - p, "%d\n",
+ test_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags));
+ return p - buf;
}
enum rtw89_dbg_crash_simulation_type {
@@ -3372,17 +3579,17 @@ enum rtw89_dbg_crash_simulation_type {
};
static ssize_t
-rtw89_debug_priv_fw_crash_set(struct file *filp, const char __user *user_buf,
- size_t count, loff_t *loff)
+rtw89_debug_priv_fw_crash_set(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
{
- struct seq_file *m = (struct seq_file *)filp->private_data;
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
int (*sim)(struct rtw89_dev *rtwdev);
u8 crash_type;
int ret;
- ret = kstrtou8_from_user(user_buf, count, 0, &crash_type);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ ret = kstrtou8(buf, 0, &crash_type);
if (ret)
return -EINVAL;
@@ -3399,10 +3606,8 @@ rtw89_debug_priv_fw_crash_set(struct file *filp, const char __user *user_buf,
return -EINVAL;
}
- mutex_lock(&rtwdev->mutex);
set_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags);
ret = sim(rtwdev);
- mutex_unlock(&rtwdev->mutex);
if (ret)
return ret;
@@ -3410,27 +3615,22 @@ rtw89_debug_priv_fw_crash_set(struct file *filp, const char __user *user_buf,
return count;
}
-static int rtw89_debug_priv_btc_info_get(struct seq_file *m, void *v)
+static ssize_t rtw89_debug_priv_btc_info_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
{
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
-
- rtw89_btc_dump_info(rtwdev, m);
-
- return 0;
+ return rtw89_btc_dump_info(rtwdev, buf, bufsz);
}
-static ssize_t rtw89_debug_priv_btc_manual_set(struct file *filp,
- const char __user *user_buf,
- size_t count, loff_t *loff)
+static ssize_t rtw89_debug_priv_btc_manual_set(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
{
- struct rtw89_debugfs_priv *debugfs_priv = filp->private_data;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
int ret;
- ret = kstrtobool_from_user(user_buf, count, &btc->manual_ctrl);
+ ret = kstrtobool(buf, &btc->manual_ctrl);
if (ret)
return ret;
@@ -3442,29 +3642,29 @@ static ssize_t rtw89_debug_priv_btc_manual_set(struct file *filp,
return count;
}
-static ssize_t rtw89_debug_fw_log_manual_set(struct file *filp,
- const char __user *user_buf,
- size_t count, loff_t *loff)
+static ssize_t rtw89_debug_priv_fw_log_manual_set(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
{
- struct rtw89_debugfs_priv *debugfs_priv = filp->private_data;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
struct rtw89_fw_log *log = &rtwdev->fw.log;
bool fw_log_manual;
- if (kstrtobool_from_user(user_buf, count, &fw_log_manual))
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ if (kstrtobool(buf, &fw_log_manual))
goto out;
- mutex_lock(&rtwdev->mutex);
log->enable = fw_log_manual;
if (log->enable)
rtw89_fw_log_prepare(rtwdev);
rtw89_fw_h2c_fw_log(rtwdev, fw_log_manual);
- mutex_unlock(&rtwdev->mutex);
out:
return count;
}
-static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
+static int rtw89_sta_link_info_get_iter(struct rtw89_dev *rtwdev,
+ char *buf, size_t bufsz,
+ struct rtw89_sta_link *rtwsta_link)
{
static const char * const he_gi_str[] = {
[NL80211_RATE_INFO_HE_GI_0_8] = "0.8",
@@ -3476,107 +3676,156 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
[NL80211_RATE_INFO_EHT_GI_1_6] = "1.6",
[NL80211_RATE_INFO_EHT_GI_3_2] = "3.2",
};
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rate_info *rate = &rtwsta->ra_report.txrate;
- struct ieee80211_rx_status *status = &rtwsta->rx_status;
- struct seq_file *m = (struct seq_file *)data;
- struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+ struct rate_info *rate = &rtwsta_link->ra_report.txrate;
+ struct ieee80211_rx_status *status = &rtwsta_link->rx_status;
struct rtw89_hal *hal = &rtwdev->hal;
u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num;
bool ant_asterisk = hal->tx_path_diversity || hal->ant_diversity;
- u8 evm_min, evm_max;
+ struct ieee80211_link_sta *link_sta;
+ char *p = buf, *end = buf + bufsz;
+ u8 evm_min, evm_max, evm_1ss;
+ u16 max_rc_amsdu_len;
u8 rssi;
u8 snr;
int i;
- seq_printf(m, "TX rate [%d]: ", rtwsta->mac_id);
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ max_rc_amsdu_len = link_sta->agg.max_rc_amsdu_len;
+
+ rcu_read_unlock();
+
+ p += scnprintf(p, end - p, "TX rate [%u, %u]: ", rtwsta_link->mac_id,
+ rtwsta_link->link_id);
if (rate->flags & RATE_INFO_FLAGS_MCS)
- seq_printf(m, "HT MCS-%d%s", rate->mcs,
- rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : "");
+ p += scnprintf(p, end - p, "HT MCS-%d%s", rate->mcs,
+ rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : "");
else if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
- seq_printf(m, "VHT %dSS MCS-%d%s", rate->nss, rate->mcs,
- rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : "");
+ p += scnprintf(p, end - p, "VHT %dSS MCS-%d%s", rate->nss,
+ rate->mcs,
+ rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : "");
else if (rate->flags & RATE_INFO_FLAGS_HE_MCS)
- seq_printf(m, "HE %dSS MCS-%d GI:%s", rate->nss, rate->mcs,
- rate->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ?
- he_gi_str[rate->he_gi] : "N/A");
+ p += scnprintf(p, end - p, "HE %dSS MCS-%d GI:%s", rate->nss,
+ rate->mcs,
+ rate->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ?
+ he_gi_str[rate->he_gi] : "N/A");
else if (rate->flags & RATE_INFO_FLAGS_EHT_MCS)
- seq_printf(m, "EHT %dSS MCS-%d GI:%s", rate->nss, rate->mcs,
- rate->eht_gi < ARRAY_SIZE(eht_gi_str) ?
- eht_gi_str[rate->eht_gi] : "N/A");
+ p += scnprintf(p, end - p, "EHT %dSS MCS-%d GI:%s", rate->nss,
+ rate->mcs,
+ rate->eht_gi < ARRAY_SIZE(eht_gi_str) ?
+ eht_gi_str[rate->eht_gi] : "N/A");
else
- seq_printf(m, "Legacy %d", rate->legacy);
- seq_printf(m, "%s", rtwsta->ra_report.might_fallback_legacy ? " FB_G" : "");
- seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(rate->bw));
- seq_printf(m, "\t(hw_rate=0x%x)", rtwsta->ra_report.hw_rate);
- seq_printf(m, "\t==> agg_wait=%d (%d)\n", rtwsta->max_agg_wait,
- sta->deflink.agg.max_rc_amsdu_len);
-
- seq_printf(m, "RX rate [%d]: ", rtwsta->mac_id);
+ p += scnprintf(p, end - p, "Legacy %d", rate->legacy);
+ p += scnprintf(p, end - p, "%s",
+ rtwsta_link->ra_report.might_fallback_legacy ? " FB_G" : "");
+ p += scnprintf(p, end - p, " BW:%u",
+ rtw89_rate_info_bw_to_mhz(rate->bw));
+ p += scnprintf(p, end - p, " (hw_rate=0x%x)",
+ rtwsta_link->ra_report.hw_rate);
+ p += scnprintf(p, end - p, " ==> agg_wait=%d (%d)\n",
+ rtwsta_link->max_agg_wait,
+ max_rc_amsdu_len);
+
+ p += scnprintf(p, end - p, "RX rate [%u, %u]: ", rtwsta_link->mac_id,
+ rtwsta_link->link_id);
switch (status->encoding) {
case RX_ENC_LEGACY:
- seq_printf(m, "Legacy %d", status->rate_idx +
- (status->band != NL80211_BAND_2GHZ ? 4 : 0));
+ p += scnprintf(p, end - p, "Legacy %d", status->rate_idx +
+ (status->band != NL80211_BAND_2GHZ ? 4 : 0));
break;
case RX_ENC_HT:
- seq_printf(m, "HT MCS-%d%s", status->rate_idx,
- status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : "");
+ p += scnprintf(p, end - p, "HT MCS-%d%s", status->rate_idx,
+ status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : "");
break;
case RX_ENC_VHT:
- seq_printf(m, "VHT %dSS MCS-%d%s", status->nss, status->rate_idx,
- status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : "");
+ p += scnprintf(p, end - p, "VHT %dSS MCS-%d%s", status->nss,
+ status->rate_idx,
+ status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : "");
break;
case RX_ENC_HE:
- seq_printf(m, "HE %dSS MCS-%d GI:%s", status->nss, status->rate_idx,
- status->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ?
- he_gi_str[rate->he_gi] : "N/A");
+ p += scnprintf(p, end - p, "HE %dSS MCS-%d GI:%s",
+ status->nss, status->rate_idx,
+ status->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ?
+ he_gi_str[status->he_gi] : "N/A");
break;
case RX_ENC_EHT:
- seq_printf(m, "EHT %dSS MCS-%d GI:%s", status->nss, status->rate_idx,
- status->eht.gi < ARRAY_SIZE(eht_gi_str) ?
- eht_gi_str[status->eht.gi] : "N/A");
+ p += scnprintf(p, end - p, "EHT %dSS MCS-%d GI:%s",
+ status->nss, status->rate_idx,
+ status->eht.gi < ARRAY_SIZE(eht_gi_str) ?
+ eht_gi_str[status->eht.gi] : "N/A");
break;
}
- seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(status->bw));
- seq_printf(m, "\t(hw_rate=0x%x)\n", rtwsta->rx_hw_rate);
-
- rssi = ewma_rssi_read(&rtwsta->avg_rssi);
- seq_printf(m, "RSSI: %d dBm (raw=%d, prev=%d) [",
- RTW89_RSSI_RAW_TO_DBM(rssi), rssi, rtwsta->prev_rssi);
+ p += scnprintf(p, end - p, " BW:%u",
+ rtw89_rate_info_bw_to_mhz(status->bw));
+ p += scnprintf(p, end - p, " (hw_rate=0x%x)\n",
+ rtwsta_link->rx_hw_rate);
+
+ rssi = ewma_rssi_read(&rtwsta_link->avg_rssi);
+ p += scnprintf(p, end - p, "RSSI: %d dBm (raw=%d, prev=%d) [",
+ RTW89_RSSI_RAW_TO_DBM(rssi), rssi,
+ rtwsta_link->prev_rssi);
for (i = 0; i < ant_num; i++) {
- rssi = ewma_rssi_read(&rtwsta->rssi[i]);
- seq_printf(m, "%d%s%s", RTW89_RSSI_RAW_TO_DBM(rssi),
- ant_asterisk && (hal->antenna_tx & BIT(i)) ? "*" : "",
- i + 1 == ant_num ? "" : ", ");
+ rssi = ewma_rssi_read(&rtwsta_link->rssi[i]);
+ p += scnprintf(p, end - p, "%d%s%s",
+ RTW89_RSSI_RAW_TO_DBM(rssi),
+ ant_asterisk && (hal->antenna_tx & BIT(i)) ? "*" : "",
+ i + 1 == ant_num ? "" : ", ");
}
- seq_puts(m, "]\n");
+ p += scnprintf(p, end - p, "]\n");
- seq_puts(m, "EVM: [");
+ evm_1ss = ewma_evm_read(&rtwsta_link->evm_1ss);
+ p += scnprintf(p, end - p, "EVM: [%2u.%02u, ", evm_1ss >> 2,
+ (evm_1ss & 0x3) * 25);
for (i = 0; i < (hal->ant_diversity ? 2 : 1); i++) {
- evm_min = ewma_evm_read(&rtwsta->evm_min[i]);
- evm_max = ewma_evm_read(&rtwsta->evm_max[i]);
+ evm_min = ewma_evm_read(&rtwsta_link->evm_min[i]);
+ evm_max = ewma_evm_read(&rtwsta_link->evm_max[i]);
- seq_printf(m, "%s(%2u.%02u, %2u.%02u)", i == 0 ? "" : " ",
- evm_min >> 2, (evm_min & 0x3) * 25,
- evm_max >> 2, (evm_max & 0x3) * 25);
+ p += scnprintf(p, end - p, "%s(%2u.%02u, %2u.%02u)",
+ i == 0 ? "" : " ",
+ evm_min >> 2, (evm_min & 0x3) * 25,
+ evm_max >> 2, (evm_max & 0x3) * 25);
}
- seq_puts(m, "]\t");
+ p += scnprintf(p, end - p, "]\t");
+
+ snr = ewma_snr_read(&rtwsta_link->avg_snr);
+ p += scnprintf(p, end - p, "SNR: %u\n", snr);
- snr = ewma_snr_read(&rtwsta->avg_snr);
- seq_printf(m, "SNR: %u\n", snr);
+ return p - buf;
}
-static void
-rtw89_debug_append_rx_rate(struct seq_file *m, struct rtw89_pkt_stat *pkt_stat,
+static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
+{
+ struct rtw89_debugfs_iter_data *iter_data =
+ (struct rtw89_debugfs_iter_data *)data;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+ struct rtw89_sta_link *rtwsta_link;
+ size_t bufsz = iter_data->bufsz;
+ char *buf = iter_data->buf;
+ char *p = buf, *end = buf + bufsz;
+ unsigned int link_id;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id)
+ p += rtw89_sta_link_info_get_iter(rtwdev, p, end - p, rtwsta_link);
+
+ rtw89_debugfs_iter_data_next(iter_data, p, end - p, p - buf);
+}
+
+static int
+rtw89_debug_append_rx_rate(char *buf, size_t bufsz, struct rtw89_pkt_stat *pkt_stat,
enum rtw89_hw_rate first_rate, int len)
{
+ char *p = buf, *end = buf + bufsz;
int i;
for (i = 0; i < len; i++)
- seq_printf(m, "%s%u", i == 0 ? "" : ", ",
- pkt_stat->rx_rate_cnt[first_rate + i]);
+ p += scnprintf(p, end - p, "%s%u", i == 0 ? "" : ", ",
+ pkt_stat->rx_rate_cnt[first_rate + i]);
+
+ return p - buf;
}
#define FIRST_RATE_SAME(rate) {RTW89_HW_RATE_ ## rate, RTW89_HW_RATE_ ## rate}
@@ -3601,26 +3850,40 @@ static const struct rtw89_rx_rate_cnt_info {
{FIRST_RATE_GEV1(EHT_NSS2_MCS0), 14, 0, "EHT 2SS:"},
};
-static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v)
+static ssize_t rtw89_debug_priv_phy_info_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
{
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
struct rtw89_traffic_stats *stats = &rtwdev->stats;
struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.last_pkt_stat;
const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct rtw89_debugfs_iter_data iter_data;
const struct rtw89_rx_rate_cnt_info *info;
+ struct rtw89_hal *hal = &rtwdev->hal;
+ char *p = buf, *end = buf + bufsz;
enum rtw89_hw_rate first_rate;
+ u8 rssi;
int i;
- seq_printf(m, "TP TX: %u [%u] Mbps (lv: %d), RX: %u [%u] Mbps (lv: %d)\n",
- stats->tx_throughput, stats->tx_throughput_raw, stats->tx_tfc_lv,
- stats->rx_throughput, stats->rx_throughput_raw, stats->rx_tfc_lv);
- seq_printf(m, "Beacon: %u, TF: %u\n", pkt_stat->beacon_nr,
- stats->rx_tf_periodic);
- seq_printf(m, "Avg packet length: TX=%u, RX=%u\n", stats->tx_avg_len,
- stats->rx_avg_len);
-
- seq_puts(m, "RX count:\n");
+ rssi = ewma_rssi_read(&rtwdev->phystat.bcn_rssi);
+
+ p += scnprintf(p, end - p, "TP TX: %u [%u] Mbps (lv: %d",
+ stats->tx_throughput, stats->tx_throughput_raw,
+ stats->tx_tfc_lv);
+ if (hal->thermal_prot_lv)
+ p += scnprintf(p, end - p, ", duty: %d%%",
+ 100 - hal->thermal_prot_lv * RTW89_THERMAL_PROT_STEP);
+ p += scnprintf(p, end - p, "), RX: %u [%u] Mbps (lv: %d)\n",
+ stats->rx_throughput, stats->rx_throughput_raw,
+ stats->rx_tfc_lv);
+ p += scnprintf(p, end - p, "Beacon: %u (%d dBm), TF: %u\n",
+ pkt_stat->beacon_nr,
+ RTW89_RSSI_RAW_TO_DBM(rssi), stats->rx_tf_periodic);
+ p += scnprintf(p, end - p, "Avg packet length: TX=%u, RX=%u\n",
+ stats->tx_avg_len,
+ stats->rx_avg_len);
+
+ p += scnprintf(p, end - p, "RX count:\n");
for (i = 0; i < ARRAY_SIZE(rtw89_rx_rate_cnt_infos); i++) {
info = &rtw89_rx_rate_cnt_infos[i];
@@ -3628,150 +3891,279 @@ static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v)
if (first_rate >= RTW89_HW_RATE_NR)
continue;
- seq_printf(m, "%10s [", info->rate_mode);
- rtw89_debug_append_rx_rate(m, pkt_stat,
- first_rate, info->len);
+ p += scnprintf(p, end - p, "%10s [", info->rate_mode);
+ p += rtw89_debug_append_rx_rate(p, end - p, pkt_stat,
+ first_rate, info->len);
if (info->ext) {
- seq_puts(m, "][");
- rtw89_debug_append_rx_rate(m, pkt_stat,
- first_rate + info->len, info->ext);
+ p += scnprintf(p, end - p, "][");
+ p += rtw89_debug_append_rx_rate(p, end - p, pkt_stat,
+ first_rate + info->len, info->ext);
}
- seq_puts(m, "]\n");
+ p += scnprintf(p, end - p, "]\n");
}
- ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_info_get_iter, m);
+ rtw89_debugfs_iter_data_setup(&iter_data, p, end - p);
+ ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_info_get_iter, &iter_data);
+ p += iter_data.written_sz;
- return 0;
+ return p - buf;
}
-static void rtw89_dump_addr_cam(struct seq_file *m,
- struct rtw89_addr_cam_entry *addr_cam)
+static int rtw89_dump_addr_cam(struct rtw89_dev *rtwdev,
+ char *buf, size_t bufsz,
+ struct rtw89_addr_cam_entry *addr_cam)
{
- struct rtw89_sec_cam_entry *sec_entry;
+ struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
+ const struct rtw89_sec_cam_entry *sec_entry;
+ char *p = buf, *end = buf + bufsz;
+ u8 sec_cam_idx;
int i;
- seq_printf(m, "\taddr_cam_idx=%u\n", addr_cam->addr_cam_idx);
- seq_printf(m, "\t-> bssid_cam_idx=%u\n", addr_cam->bssid_cam_idx);
- seq_printf(m, "\tsec_cam_bitmap=%*ph\n", (int)sizeof(addr_cam->sec_cam_map),
- addr_cam->sec_cam_map);
- for (i = 0; i < RTW89_SEC_CAM_IN_ADDR_CAM; i++) {
- sec_entry = addr_cam->sec_entries[i];
+ p += scnprintf(p, end - p, "\taddr_cam_idx=%u\n",
+ addr_cam->addr_cam_idx);
+ p += scnprintf(p, end - p, "\t-> bssid_cam_idx=%u\n",
+ addr_cam->bssid_cam_idx);
+ p += scnprintf(p, end - p, "\tsec_cam_bitmap=%*ph\n",
+ (int)sizeof(addr_cam->sec_cam_map),
+ addr_cam->sec_cam_map);
+ for_each_set_bit(i, addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM) {
+ sec_cam_idx = addr_cam->sec_ent[i];
+ sec_entry = cam_info->sec_entries[sec_cam_idx];
if (!sec_entry)
continue;
- seq_printf(m, "\tsec[%d]: sec_cam_idx %u", i, sec_entry->sec_cam_idx);
+ p += scnprintf(p, end - p, "\tsec[%d]: sec_cam_idx %u", i,
+ sec_entry->sec_cam_idx);
if (sec_entry->ext_key)
- seq_printf(m, ", %u", sec_entry->sec_cam_idx + 1);
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, ", %u",
+ sec_entry->sec_cam_idx + 1);
+ p += scnprintf(p, end - p, "\n");
}
+
+ return p - buf;
}
-__printf(3, 4)
-static void rtw89_dump_pkt_offload(struct seq_file *m, struct list_head *pkt_list,
- const char *fmt, ...)
+__printf(4, 5)
+static int rtw89_dump_pkt_offload(char *buf, size_t bufsz, struct list_head *pkt_list,
+ const char *fmt, ...)
{
+ char *p = buf, *end = buf + bufsz;
struct rtw89_pktofld_info *info;
struct va_format vaf;
va_list args;
if (list_empty(pkt_list))
- return;
+ return 0;
va_start(args, fmt);
vaf.va = &args;
vaf.fmt = fmt;
- seq_printf(m, "%pV", &vaf);
+ p += scnprintf(p, end - p, "%pV", &vaf);
va_end(args);
list_for_each_entry(info, pkt_list, list)
- seq_printf(m, "%d ", info->id);
+ p += scnprintf(p, end - p, "%d ", info->id);
+
+ p += scnprintf(p, end - p, "\n");
+
+ return p - buf;
+}
- seq_puts(m, "\n");
+static int rtw89_vif_link_ids_get(struct rtw89_dev *rtwdev,
+ char *buf, size_t bufsz, u8 *mac,
+ struct rtw89_vif_link *rtwvif_link,
+ bool designated)
+{
+ struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
+ char *p = buf, *end = buf + bufsz;
+
+ p += scnprintf(p, end - p, " [%u] %pM\n", rtwvif_link->mac_id,
+ rtwvif_link->mac_addr);
+ p += scnprintf(p, end - p, "\tlink_id=%u%s\n", rtwvif_link->link_id,
+ designated ? " (*)" : "");
+ p += scnprintf(p, end - p, "\tbssid_cam_idx=%u\n",
+ bssid_cam->bssid_cam_idx);
+ p += rtw89_dump_addr_cam(rtwdev, p, end - p, &rtwvif_link->addr_cam);
+ p += rtw89_dump_pkt_offload(p, end - p, &rtwvif_link->general_pkt_list,
+ "\tpkt_ofld[GENERAL]: ");
+
+ return p - buf;
}
static
void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct seq_file *m = (struct seq_file *)data;
- struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
+ struct rtw89_debugfs_iter_data *iter_data =
+ (struct rtw89_debugfs_iter_data *)data;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_dev *rtwdev = rtwvif->rtwdev;
+ struct rtw89_vif_link *designated_link;
+ struct rtw89_vif_link *rtwvif_link;
+ size_t bufsz = iter_data->bufsz;
+ char *buf = iter_data->buf;
+ char *p = buf, *end = buf + bufsz;
+ unsigned int link_id;
+
+ designated_link = rtw89_get_designated_link(rtwvif);
- seq_printf(m, "VIF [%d] %pM\n", rtwvif->mac_id, rtwvif->mac_addr);
- seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx);
- rtw89_dump_addr_cam(m, &rtwvif->addr_cam);
- rtw89_dump_pkt_offload(m, &rtwvif->general_pkt_list, "\tpkt_ofld[GENERAL]: ");
+ p += scnprintf(p, end - p, "VIF %pM\n", rtwvif->mac_addr);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ p += rtw89_vif_link_ids_get(rtwdev, p, end - p, mac, rtwvif_link,
+ rtwvif_link == designated_link);
+
+ rtw89_debugfs_iter_data_next(iter_data, p, end - p, p - buf);
}
-static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta *rtwsta)
+static int rtw89_dump_ba_cam(struct rtw89_dev *rtwdev,
+ char *buf, size_t bufsz,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
- struct rtw89_dev *rtwdev = rtwvif->rtwdev;
struct rtw89_ba_cam_entry *entry;
+ char *p = buf, *end = buf + bufsz;
bool first = true;
- list_for_each_entry(entry, &rtwsta->ba_cam_list, list) {
+ list_for_each_entry(entry, &rtwsta_link->ba_cam_list, list) {
if (first) {
- seq_puts(m, "\tba_cam ");
+ p += scnprintf(p, end - p, "\tba_cam ");
first = false;
} else {
- seq_puts(m, ", ");
+ p += scnprintf(p, end - p, ", ");
}
- seq_printf(m, "tid[%u]=%d", entry->tid,
- (int)(entry - rtwdev->cam_info.ba_cam_entry));
+ p += scnprintf(p, end - p, "tid[%u]=%d", entry->tid,
+ (int)(entry - rtwdev->cam_info.ba_cam_entry));
}
- seq_puts(m, "\n");
+ p += scnprintf(p, end - p, "\n");
+
+ return p - buf;
}
-static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta)
+static int rtw89_sta_link_ids_get(struct rtw89_dev *rtwdev,
+ char *buf, size_t bufsz,
+ struct rtw89_sta_link *rtwsta_link,
+ bool designated)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct seq_file *m = (struct seq_file *)data;
+ struct ieee80211_link_sta *link_sta;
+ char *p = buf, *end = buf + bufsz;
+
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+
+ p += scnprintf(p, end - p, " [%u] %pM\n", rtwsta_link->mac_id,
+ link_sta->addr);
- seq_printf(m, "STA [%d] %pM %s\n", rtwsta->mac_id, sta->addr,
- sta->tdls ? "(TDLS)" : "");
- rtw89_dump_addr_cam(m, &rtwsta->addr_cam);
- rtw89_dump_ba_cam(m, rtwsta);
+ rcu_read_unlock();
+
+ p += scnprintf(p, end - p, "\tlink_id=%u%s\n", rtwsta_link->link_id,
+ designated ? " (*)" : "");
+ p += rtw89_dump_addr_cam(rtwdev, p, end - p, &rtwsta_link->addr_cam);
+ p += rtw89_dump_ba_cam(rtwdev, p, end - p, rtwsta_link);
+
+ return p - buf;
}
-static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v)
+static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta)
+{
+ struct rtw89_debugfs_iter_data *iter_data =
+ (struct rtw89_debugfs_iter_data *)data;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+ struct rtw89_sta_link *designated_link;
+ struct rtw89_sta_link *rtwsta_link;
+ size_t bufsz = iter_data->bufsz;
+ char *buf = iter_data->buf;
+ char *p = buf, *end = buf + bufsz;
+ unsigned int link_id;
+
+ designated_link = rtw89_get_designated_link(rtwsta);
+
+ p += scnprintf(p, end - p, "STA %pM %s\n", sta->addr,
+ sta->tdls ? "(TDLS)" : "");
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id)
+ p += rtw89_sta_link_ids_get(rtwdev, p, end - p, rtwsta_link,
+ rtwsta_link == designated_link);
+
+ rtw89_debugfs_iter_data_next(iter_data, p, end - p, p - buf);
+}
+
+static ssize_t rtw89_debug_priv_stations_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
{
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
+ struct rtw89_debugfs_iter_data iter_data;
+ char *p = buf, *end = buf + bufsz;
u8 idx;
- mutex_lock(&rtwdev->mutex);
-
- seq_puts(m, "map:\n");
- seq_printf(m, "\tmac_id: %*ph\n", (int)sizeof(rtwdev->mac_id_map),
- rtwdev->mac_id_map);
- seq_printf(m, "\taddr_cam: %*ph\n", (int)sizeof(cam_info->addr_cam_map),
- cam_info->addr_cam_map);
- seq_printf(m, "\tbssid_cam: %*ph\n", (int)sizeof(cam_info->bssid_cam_map),
- cam_info->bssid_cam_map);
- seq_printf(m, "\tsec_cam: %*ph\n", (int)sizeof(cam_info->sec_cam_map),
- cam_info->sec_cam_map);
- seq_printf(m, "\tba_cam: %*ph\n", (int)sizeof(cam_info->ba_cam_map),
- cam_info->ba_cam_map);
- seq_printf(m, "\tpkt_ofld: %*ph\n", (int)sizeof(rtwdev->pkt_offload),
- rtwdev->pkt_offload);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ p += scnprintf(p, end - p, "map:\n");
+ p += scnprintf(p, end - p, "\tmac_id: %*ph\n",
+ (int)sizeof(rtwdev->mac_id_map),
+ rtwdev->mac_id_map);
+ p += scnprintf(p, end - p, "\taddr_cam: %*ph\n",
+ (int)sizeof(cam_info->addr_cam_map),
+ cam_info->addr_cam_map);
+ p += scnprintf(p, end - p, "\tbssid_cam: %*ph\n",
+ (int)sizeof(cam_info->bssid_cam_map),
+ cam_info->bssid_cam_map);
+ p += scnprintf(p, end - p, "\tsec_cam: %*ph\n",
+ (int)sizeof(cam_info->sec_cam_map),
+ cam_info->sec_cam_map);
+ p += scnprintf(p, end - p, "\tba_cam: %*ph\n",
+ (int)sizeof(cam_info->ba_cam_map),
+ cam_info->ba_cam_map);
+ p += scnprintf(p, end - p, "\tpkt_ofld: %*ph\n",
+ (int)sizeof(rtwdev->pkt_offload),
+ rtwdev->pkt_offload);
for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) {
if (!(rtwdev->chip->support_bands & BIT(idx)))
continue;
- rtw89_dump_pkt_offload(m, &rtwdev->scan_info.pkt_list[idx],
- "\t\t[SCAN %u]: ", idx);
+ p += rtw89_dump_pkt_offload(p, end - p, &rtwdev->scan_info.pkt_list[idx],
+ "\t\t[SCAN %u]: ", idx);
}
+ rtw89_debugfs_iter_data_setup(&iter_data, p, end - p);
ieee80211_iterate_active_interfaces_atomic(rtwdev->hw,
- IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, m);
+ IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, &iter_data);
+ p += iter_data.written_sz;
- ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_ids_get_iter, m);
+ rtw89_debugfs_iter_data_setup(&iter_data, p, end - p);
+ ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_ids_get_iter, &iter_data);
+ p += iter_data.written_sz;
- mutex_unlock(&rtwdev->mutex);
+ return p - buf;
+}
- return 0;
+static void rtw89_debug_disable_dm_cfg_bmap(struct rtw89_dev *rtwdev, u32 new)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ u32 old = hal->disabled_dm_bitmap;
+
+ if (new == old)
+ return;
+
+ hal->disabled_dm_bitmap = new;
+
+ rtw89_debug(rtwdev, RTW89_DBG_STATE, "Disable DM: 0x%x -> 0x%x\n", old, new);
+}
+
+static void rtw89_debug_disable_dm_set_flag(struct rtw89_dev *rtwdev, u8 flag)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ u32 cur = hal->disabled_dm_bitmap;
+
+ rtw89_debug_disable_dm_cfg_bmap(rtwdev, cur | BIT(flag));
+}
+
+static void rtw89_debug_disable_dm_clr_flag(struct rtw89_dev *rtwdev, u8 flag)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ u32 cur = hal->disabled_dm_bitmap;
+
+ rtw89_debug_disable_dm_cfg_bmap(rtwdev, cur & ~BIT(flag));
}
#define DM_INFO(type) {RTW89_DM_ ## type, #type}
@@ -3781,137 +4173,196 @@ static const struct rtw89_disabled_dm_info {
const char *name;
} rtw89_disabled_dm_infos[] = {
DM_INFO(DYNAMIC_EDCCA),
+ DM_INFO(THERMAL_PROTECT),
+ DM_INFO(TAS),
+ DM_INFO(MLO),
};
-static int
-rtw89_debug_priv_disable_dm_get(struct seq_file *m, void *v)
+static ssize_t
+rtw89_debug_priv_disable_dm_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
{
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
const struct rtw89_disabled_dm_info *info;
struct rtw89_hal *hal = &rtwdev->hal;
+ char *p = buf, *end = buf + bufsz;
u32 disabled;
int i;
- seq_printf(m, "Disabled DM: 0x%x\n", hal->disabled_dm_bitmap);
+ p += scnprintf(p, end - p, "Disabled DM: 0x%x\n",
+ hal->disabled_dm_bitmap);
for (i = 0; i < ARRAY_SIZE(rtw89_disabled_dm_infos); i++) {
info = &rtw89_disabled_dm_infos[i];
disabled = BIT(info->type) & hal->disabled_dm_bitmap;
- seq_printf(m, "[%d] %s: %c\n", info->type, info->name,
- disabled ? 'X' : 'O');
+ p += scnprintf(p, end - p, "[%d] %s: %c\n", info->type,
+ info->name,
+ disabled ? 'X' : 'O');
}
- return 0;
+ return p - buf;
}
static ssize_t
-rtw89_debug_priv_disable_dm_set(struct file *filp, const char __user *user_buf,
- size_t count, loff_t *loff)
+rtw89_debug_priv_disable_dm_set(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
{
- struct seq_file *m = (struct seq_file *)filp->private_data;
- struct rtw89_debugfs_priv *debugfs_priv = m->private;
- struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
- struct rtw89_hal *hal = &rtwdev->hal;
u32 conf;
int ret;
- ret = kstrtou32_from_user(user_buf, count, 0, &conf);
+ ret = kstrtou32(buf, 0, &conf);
if (ret)
return -EINVAL;
- hal->disabled_dm_bitmap = conf;
+ rtw89_debug_disable_dm_cfg_bmap(rtwdev, conf);
return count;
}
-static struct rtw89_debugfs_priv rtw89_debug_priv_read_reg = {
- .cb_read = rtw89_debug_priv_read_reg_get,
- .cb_write = rtw89_debug_priv_read_reg_select,
-};
+static void rtw89_debug_mlo_mode_set_mlsr(struct rtw89_dev *rtwdev,
+ unsigned int link_id)
+{
+ struct ieee80211_vif *vif;
+ struct rtw89_vif *rtwvif;
-static struct rtw89_debugfs_priv rtw89_debug_priv_write_reg = {
- .cb_write = rtw89_debug_priv_write_reg_set,
-};
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+ vif = rtwvif_to_vif(rtwvif);
+ if (!ieee80211_vif_is_mld(vif))
+ continue;
-static struct rtw89_debugfs_priv rtw89_debug_priv_read_rf = {
- .cb_read = rtw89_debug_priv_read_rf_get,
- .cb_write = rtw89_debug_priv_read_rf_select,
-};
+ rtw89_core_mlsr_switch(rtwdev, rtwvif, link_id);
+ }
+}
-static struct rtw89_debugfs_priv rtw89_debug_priv_write_rf = {
- .cb_write = rtw89_debug_priv_write_rf_set,
-};
+static ssize_t
+rtw89_debug_priv_mlo_mode_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
+{
+ bool mlo_dm_dis = rtwdev->hal.disabled_dm_bitmap & BIT(RTW89_DM_MLO);
+ char *p = buf, *end = buf + bufsz;
+ struct ieee80211_vif *vif;
+ struct rtw89_vif *rtwvif;
+ int count = 0;
+
+ p += scnprintf(p, end - p, "MLD(s) status: (MLO DM: %s)\n",
+ str_disable_enable(mlo_dm_dis));
+
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+ vif = rtwvif_to_vif(rtwvif);
+ if (!ieee80211_vif_is_mld(vif))
+ continue;
-static struct rtw89_debugfs_priv rtw89_debug_priv_rf_reg_dump = {
- .cb_read = rtw89_debug_priv_rf_reg_dump_get,
-};
+ p += scnprintf(p, end - p,
+ "\t#%u: MLO mode %x, valid 0x%x, active 0x%x\n",
+ count++, rtwvif->mlo_mode, vif->valid_links,
+ vif->active_links);
+ }
-static struct rtw89_debugfs_priv rtw89_debug_priv_txpwr_table = {
- .cb_read = rtw89_debug_priv_txpwr_table_get,
-};
+ if (count == 0)
+ p += scnprintf(p, end - p, "\t(None)\n");
-static struct rtw89_debugfs_priv rtw89_debug_priv_mac_reg_dump = {
- .cb_read = rtw89_debug_priv_mac_reg_dump_get,
- .cb_write = rtw89_debug_priv_mac_reg_dump_select,
-};
+ return p - buf;
+}
-static struct rtw89_debugfs_priv rtw89_debug_priv_mac_mem_dump = {
- .cb_read = rtw89_debug_priv_mac_mem_dump_get,
- .cb_write = rtw89_debug_priv_mac_mem_dump_select,
-};
+static ssize_t
+rtw89_debug_priv_mlo_mode_set(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
+{
+ u8 num, mlo_mode;
+ u32 argv;
-static struct rtw89_debugfs_priv rtw89_debug_priv_mac_dbg_port_dump = {
- .cb_read = rtw89_debug_priv_mac_dbg_port_dump_get,
- .cb_write = rtw89_debug_priv_mac_dbg_port_dump_select,
-};
+ num = sscanf(buf, "%hhx %u", &mlo_mode, &argv);
+ if (num != 2)
+ return -EINVAL;
-static struct rtw89_debugfs_priv rtw89_debug_priv_send_h2c = {
- .cb_write = rtw89_debug_priv_send_h2c_set,
-};
+ rtw89_debug_disable_dm_set_flag(rtwdev, RTW89_DM_MLO);
-static struct rtw89_debugfs_priv rtw89_debug_priv_early_h2c = {
- .cb_read = rtw89_debug_priv_early_h2c_get,
- .cb_write = rtw89_debug_priv_early_h2c_set,
-};
+ rtw89_debug(rtwdev, RTW89_DBG_STATE, "Set MLO mode to %x\n", mlo_mode);
-static struct rtw89_debugfs_priv rtw89_debug_priv_fw_crash = {
- .cb_read = rtw89_debug_priv_fw_crash_get,
- .cb_write = rtw89_debug_priv_fw_crash_set,
-};
+ switch (mlo_mode) {
+ case RTW89_MLO_MODE_MLSR:
+ rtw89_debug_mlo_mode_set_mlsr(rtwdev, argv);
+ break;
+ default:
+ rtw89_debug(rtwdev, RTW89_DBG_STATE, "Unsupported MLO mode\n");
+ rtw89_debug_disable_dm_clr_flag(rtwdev, RTW89_DM_MLO);
-static struct rtw89_debugfs_priv rtw89_debug_priv_btc_info = {
- .cb_read = rtw89_debug_priv_btc_info_get,
-};
+ return -EOPNOTSUPP;
+ }
-static struct rtw89_debugfs_priv rtw89_debug_priv_btc_manual = {
- .cb_write = rtw89_debug_priv_btc_manual_set,
-};
+ return count;
+}
-static struct rtw89_debugfs_priv rtw89_debug_priv_fw_log_manual = {
- .cb_write = rtw89_debug_fw_log_manual_set,
-};
+#define rtw89_debug_priv_get(name, opts...) \
+{ \
+ .cb_read = rtw89_debug_priv_ ##name## _get, \
+ .opt = { opts }, \
+}
-static struct rtw89_debugfs_priv rtw89_debug_priv_phy_info = {
- .cb_read = rtw89_debug_priv_phy_info_get,
-};
+#define rtw89_debug_priv_set(name, opts...) \
+{ \
+ .cb_write = rtw89_debug_priv_ ##name## _set, \
+ .opt = { opts }, \
+}
-static struct rtw89_debugfs_priv rtw89_debug_priv_stations = {
- .cb_read = rtw89_debug_priv_stations_get,
-};
+#define rtw89_debug_priv_select_and_get(name, opts...) \
+{ \
+ .cb_write = rtw89_debug_priv_ ##name## _select, \
+ .cb_read = rtw89_debug_priv_ ##name## _get, \
+ .opt = { opts }, \
+}
-static struct rtw89_debugfs_priv rtw89_debug_priv_disable_dm = {
- .cb_read = rtw89_debug_priv_disable_dm_get,
- .cb_write = rtw89_debug_priv_disable_dm_set,
+#define rtw89_debug_priv_set_and_get(name, opts...) \
+{ \
+ .cb_write = rtw89_debug_priv_ ##name## _set, \
+ .cb_read = rtw89_debug_priv_ ##name## _get, \
+ .opt = { opts }, \
+}
+
+#define RSIZE_8K .rsize = 0x2000
+#define RSIZE_12K .rsize = 0x3000
+#define RSIZE_16K .rsize = 0x4000
+#define RSIZE_20K .rsize = 0x5000
+#define RSIZE_32K .rsize = 0x8000
+#define RSIZE_64K .rsize = 0x10000
+#define RSIZE_128K .rsize = 0x20000
+#define RSIZE_1M .rsize = 0x100000
+#define RLOCK .rlock = 1
+#define WLOCK .wlock = 1
+#define RWLOCK RLOCK, WLOCK
+
+static const struct rtw89_debugfs rtw89_debugfs_templ = {
+ .read_reg = rtw89_debug_priv_select_and_get(read_reg),
+ .write_reg = rtw89_debug_priv_set(write_reg),
+ .read_rf = rtw89_debug_priv_select_and_get(read_rf),
+ .write_rf = rtw89_debug_priv_set(write_rf),
+ .rf_reg_dump = rtw89_debug_priv_get(rf_reg_dump, RSIZE_8K),
+ .txpwr_table = rtw89_debug_priv_get(txpwr_table, RSIZE_20K, RLOCK),
+ .mac_reg_dump = rtw89_debug_priv_select_and_get(mac_reg_dump, RSIZE_128K),
+ .mac_mem_dump = rtw89_debug_priv_select_and_get(mac_mem_dump, RSIZE_16K, RLOCK),
+ .mac_dbg_port_dump = rtw89_debug_priv_select_and_get(mac_dbg_port_dump, RSIZE_1M),
+ .send_h2c = rtw89_debug_priv_set(send_h2c),
+ .early_h2c = rtw89_debug_priv_set_and_get(early_h2c, RWLOCK),
+ .fw_crash = rtw89_debug_priv_set_and_get(fw_crash, WLOCK),
+ .btc_info = rtw89_debug_priv_get(btc_info, RSIZE_12K),
+ .btc_manual = rtw89_debug_priv_set(btc_manual),
+ .fw_log_manual = rtw89_debug_priv_set(fw_log_manual, WLOCK),
+ .phy_info = rtw89_debug_priv_get(phy_info),
+ .stations = rtw89_debug_priv_get(stations, RLOCK),
+ .disable_dm = rtw89_debug_priv_set_and_get(disable_dm, RWLOCK),
+ .mlo_mode = rtw89_debug_priv_set_and_get(mlo_mode, RWLOCK),
};
#define rtw89_debugfs_add(name, mode, fopname, parent) \
do { \
- rtw89_debug_priv_ ##name.rtwdev = rtwdev; \
- if (!debugfs_create_file(#name, mode, \
- parent, &rtw89_debug_priv_ ##name, \
- &file_ops_ ##fopname)) \
+ struct rtw89_debugfs_priv *priv = &rtwdev->debugfs->name; \
+ priv->rtwdev = rtwdev; \
+ if (IS_ERR(debugfs_create_file(#name, mode, parent, priv, \
+ &file_ops_ ##fopname))) \
pr_debug("Unable to initialize debugfs:%s\n", #name); \
} while (0)
@@ -3922,13 +4373,9 @@ static struct rtw89_debugfs_priv rtw89_debug_priv_disable_dm = {
#define rtw89_debugfs_add_r(name) \
rtw89_debugfs_add(name, S_IFREG | 0444, single_r, debugfs_topdir)
-void rtw89_debugfs_init(struct rtw89_dev *rtwdev)
+static
+void rtw89_debugfs_add_sec0(struct rtw89_dev *rtwdev, struct dentry *debugfs_topdir)
{
- struct dentry *debugfs_topdir;
-
- debugfs_topdir = debugfs_create_dir("rtw89",
- rtwdev->hw->wiphy->debugfsdir);
-
rtw89_debugfs_add_rw(read_reg);
rtw89_debugfs_add_w(write_reg);
rtw89_debugfs_add_rw(read_rf);
@@ -3938,6 +4385,11 @@ void rtw89_debugfs_init(struct rtw89_dev *rtwdev)
rtw89_debugfs_add_rw(mac_reg_dump);
rtw89_debugfs_add_rw(mac_mem_dump);
rtw89_debugfs_add_rw(mac_dbg_port_dump);
+}
+
+static
+void rtw89_debugfs_add_sec1(struct rtw89_dev *rtwdev, struct dentry *debugfs_topdir)
+{
rtw89_debugfs_add_w(send_h2c);
rtw89_debugfs_add_rw(early_h2c);
rtw89_debugfs_add_rw(fw_crash);
@@ -3947,6 +4399,28 @@ void rtw89_debugfs_init(struct rtw89_dev *rtwdev)
rtw89_debugfs_add_r(phy_info);
rtw89_debugfs_add_r(stations);
rtw89_debugfs_add_rw(disable_dm);
+ rtw89_debugfs_add_rw(mlo_mode);
+}
+
+void rtw89_debugfs_init(struct rtw89_dev *rtwdev)
+{
+ struct dentry *debugfs_topdir;
+
+ rtwdev->debugfs = kmemdup(&rtw89_debugfs_templ,
+ sizeof(rtw89_debugfs_templ), GFP_KERNEL);
+ if (!rtwdev->debugfs)
+ return;
+
+ debugfs_topdir = debugfs_create_dir("rtw89",
+ rtwdev->hw->wiphy->debugfsdir);
+
+ rtw89_debugfs_add_sec0(rtwdev, debugfs_topdir);
+ rtw89_debugfs_add_sec1(rtwdev, debugfs_topdir);
+}
+
+void rtw89_debugfs_deinit(struct rtw89_dev *rtwdev)
+{
+ kfree(rtwdev->debugfs);
}
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/debug.h b/drivers/net/wireless/realtek/rtw89/debug.h
index 800ea59873a1..fc690f7c55dc 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.h
+++ b/drivers/net/wireless/realtek/rtw89/debug.h
@@ -49,8 +49,10 @@ enum rtw89_debug_mac_reg_sel {
#ifdef CONFIG_RTW89_DEBUGFS
void rtw89_debugfs_init(struct rtw89_dev *rtwdev);
+void rtw89_debugfs_deinit(struct rtw89_dev *rtwdev);
#else
static inline void rtw89_debugfs_init(struct rtw89_dev *rtwdev) {}
+static inline void rtw89_debugfs_deinit(struct rtw89_dev *rtwdev) {}
#endif
#define rtw89_info(rtwdev, a...) dev_info((rtwdev)->dev, ##a)
diff --git a/drivers/net/wireless/realtek/rtw89/efuse.c b/drivers/net/wireless/realtek/rtw89/efuse.c
index e1236079a84a..6c6c763510af 100644
--- a/drivers/net/wireless/realtek/rtw89/efuse.c
+++ b/drivers/net/wireless/realtek/rtw89/efuse.c
@@ -11,11 +11,38 @@
#define EF_CV_MASK GENMASK(7, 4)
#define EF_CV_INV 15
+#define EFUSE_B1_MSSDEVTYPE_MASK GENMASK(3, 0)
+#define EFUSE_B1_MSSCUSTIDX0_MASK GENMASK(7, 4)
+#define EFUSE_B2_MSSKEYNUM_MASK GENMASK(3, 0)
+#define EFUSE_B2_MSSCUSTIDX1_MASK BIT(6)
+
+#define EFUSE_EXTERNALPN_ADDR_AX 0x5EC
+#define EFUSE_CUSTOMER_ADDR_AX 0x5ED
+#define EFUSE_SERIALNUM_ADDR_AX 0x5ED
+
+#define EFUSE_B1_EXTERNALPN_MASK GENMASK(7, 0)
+#define EFUSE_B2_CUSTOMER_MASK GENMASK(3, 0)
+#define EFUSE_B2_SERIALNUM_MASK GENMASK(6, 4)
+
+#define OTP_KEY_INFO_NUM 2
+
+static const u8 otp_key_info_externalPN[OTP_KEY_INFO_NUM] = {0x0, 0x0};
+static const u8 otp_key_info_customer[OTP_KEY_INFO_NUM] = {0x0, 0x1};
+static const u8 otp_key_info_serialNum[OTP_KEY_INFO_NUM] = {0x0, 0x1};
+
enum rtw89_efuse_bank {
RTW89_EFUSE_BANK_WIFI,
RTW89_EFUSE_BANK_BT,
};
+enum rtw89_efuse_mss_dev_type {
+ MSS_DEV_TYPE_FWSEC_DEF = 0xF,
+ MSS_DEV_TYPE_FWSEC_WINLIN_INBOX = 0xC,
+ MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB = 0xA,
+ MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB = 0x9,
+ MSS_DEV_TYPE_FWSEC_NONWIN_INBOX = 0x6,
+};
+
static int rtw89_switch_efuse_bank(struct rtw89_dev *rtwdev,
enum rtw89_efuse_bank bank)
{
@@ -354,3 +381,126 @@ int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *ecv)
return 0;
}
EXPORT_SYMBOL(rtw89_read_efuse_ver);
+
+static u8 get_mss_dev_type_idx(struct rtw89_dev *rtwdev, u8 mss_dev_type)
+{
+ switch (mss_dev_type) {
+ case MSS_DEV_TYPE_FWSEC_WINLIN_INBOX:
+ mss_dev_type = 0x0;
+ break;
+ case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB:
+ mss_dev_type = 0x1;
+ break;
+ case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB:
+ mss_dev_type = 0x2;
+ break;
+ case MSS_DEV_TYPE_FWSEC_NONWIN_INBOX:
+ mss_dev_type = 0x3;
+ break;
+ case MSS_DEV_TYPE_FWSEC_DEF:
+ mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF;
+ break;
+ default:
+ rtw89_warn(rtwdev, "unknown mss_dev_type %d", mss_dev_type);
+ mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_INV;
+ break;
+ }
+
+ return mss_dev_type;
+}
+
+int rtw89_efuse_recognize_mss_info_v1(struct rtw89_dev *rtwdev, u8 b1, u8 b2)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+ u8 mss_dev_type;
+
+ if (chip->chip_id == RTL8852B && b1 == 0xFF && b2 == 0x6E) {
+ mss_dev_type = MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB;
+ sec->mss_cust_idx = 0;
+ sec->mss_key_num = 0;
+
+ goto mss_dev_type;
+ }
+
+ mss_dev_type = u8_get_bits(b1, EFUSE_B1_MSSDEVTYPE_MASK);
+ sec->mss_cust_idx = 0x1F - (u8_get_bits(b1, EFUSE_B1_MSSCUSTIDX0_MASK) |
+ u8_get_bits(b2, EFUSE_B2_MSSCUSTIDX1_MASK) << 4);
+ sec->mss_key_num = 0xF - u8_get_bits(b2, EFUSE_B2_MSSKEYNUM_MASK);
+
+mss_dev_type:
+ sec->mss_dev_type = get_mss_dev_type_idx(rtwdev, mss_dev_type);
+ if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_INV) {
+ rtw89_warn(rtwdev, "invalid mss_dev_type %d\n", mss_dev_type);
+ return -ENOENT;
+ }
+
+ sec->can_mss_v1 = true;
+
+ return 0;
+}
+
+static
+int rtw89_efuse_recognize_mss_index_v0(struct rtw89_dev *rtwdev, u8 b1, u8 b2)
+{
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+ u8 externalPN;
+ u8 serialNum;
+ u8 customer;
+ u8 i;
+
+ externalPN = 0xFF - u8_get_bits(b1, EFUSE_B1_EXTERNALPN_MASK);
+ customer = 0xF - u8_get_bits(b2, EFUSE_B2_CUSTOMER_MASK);
+ serialNum = 0x7 - u8_get_bits(b2, EFUSE_B2_SERIALNUM_MASK);
+
+ for (i = 0; i < OTP_KEY_INFO_NUM; i++) {
+ if (externalPN == otp_key_info_externalPN[i] &&
+ customer == otp_key_info_customer[i] &&
+ serialNum == otp_key_info_serialNum[i]) {
+ sec->mss_idx = i;
+ sec->can_mss_v0 = true;
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
+int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+ u32 sec_addr = EFUSE_EXTERNALPN_ADDR_AX;
+ u32 sec_size = 2;
+ u8 sec_map[2];
+ u8 b1, b2;
+ int ret;
+
+ ret = rtw89_dump_physical_efuse_map(rtwdev, sec_map,
+ sec_addr, sec_size, false);
+ if (ret) {
+ rtw89_warn(rtwdev, "failed to dump secsel map\n");
+ return ret;
+ }
+
+ b1 = sec_map[0];
+ b2 = sec_map[1];
+
+ if (b1 == 0xFF && b2 == 0xFF)
+ return 0;
+
+ rtw89_efuse_recognize_mss_index_v0(rtwdev, b1, b2);
+ rtw89_efuse_recognize_mss_info_v1(rtwdev, b1, b2);
+ if (!sec->can_mss_v1 && !sec->can_mss_v0)
+ goto out;
+
+ sec->secure_boot = true;
+
+out:
+ rtw89_debug(rtwdev, RTW89_DBG_FW,
+ "MSS secure_boot=%d(%d/%d) dev_type=%d cust_idx=%d key_num=%d mss_index=%d\n",
+ sec->secure_boot, sec->can_mss_v0, sec->can_mss_v1,
+ sec->mss_dev_type, sec->mss_cust_idx,
+ sec->mss_key_num, sec->mss_idx);
+
+ return 0;
+}
diff --git a/drivers/net/wireless/realtek/rtw89/efuse.h b/drivers/net/wireless/realtek/rtw89/efuse.h
index 72416f56a071..a96fc1044791 100644
--- a/drivers/net/wireless/realtek/rtw89/efuse.h
+++ b/drivers/net/wireless/realtek/rtw89/efuse.h
@@ -23,6 +23,8 @@ int rtw89_parse_efuse_map_be(struct rtw89_dev *rtwdev);
int rtw89_parse_phycap_map_be(struct rtw89_dev *rtwdev);
int rtw89_cnv_efuse_state_be(struct rtw89_dev *rtwdev, bool idle);
int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *efv);
+int rtw89_efuse_recognize_mss_info_v1(struct rtw89_dev *rtwdev, u8 b1, u8 b2);
+int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev);
int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/efuse_be.c b/drivers/net/wireless/realtek/rtw89/efuse_be.c
index 0be26d5fdf7c..64768923b0f0 100644
--- a/drivers/net/wireless/realtek/rtw89/efuse_be.c
+++ b/drivers/net/wireless/realtek/rtw89/efuse_be.c
@@ -8,11 +8,7 @@
#include "reg.h"
#define EFUSE_EXTERNALPN_ADDR_BE 0x1580
-#define EFUSE_B1_MSSDEVTYPE_MASK GENMASK(3, 0)
-#define EFUSE_B1_MSSCUSTIDX0_MASK GENMASK(7, 4)
#define EFUSE_SERIALNUM_ADDR_BE 0x1581
-#define EFUSE_B2_MSSKEYNUM_MASK GENMASK(3, 0)
-#define EFUSE_B2_MSSCUSTIDX1_MASK BIT(6)
#define EFUSE_SB_CRYP_SEL_ADDR 0x1582
#define EFUSE_SB_CRYP_SEL_SIZE 2
#define EFUSE_SB_CRYP_SEL_DEFAULT 0xFFFF
@@ -20,14 +16,6 @@
#define EFUSE_SEC_BE_START 0x1580
#define EFUSE_SEC_BE_SIZE 4
-enum rtw89_efuse_mss_dev_type {
- MSS_DEV_TYPE_FWSEC_DEF = 0xF,
- MSS_DEV_TYPE_FWSEC_WINLIN_INBOX = 0xC,
- MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB = 0xA,
- MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB = 0x9,
- MSS_DEV_TYPE_FWSEC_NONWIN_INBOX = 0x6,
-};
-
static const u32 sb_sel_mgn[SB_SEL_MGN_MAX_SIZE] = {
0x8000100, 0xC000180
};
@@ -477,33 +465,6 @@ static u16 get_sb_cryp_sel_idx(u16 sb_cryp_sel)
return sb_cryp_sel_v + low_bit;
}
-static u8 get_mss_dev_type_idx(struct rtw89_dev *rtwdev, u8 mss_dev_type)
-{
- switch (mss_dev_type) {
- case MSS_DEV_TYPE_FWSEC_WINLIN_INBOX:
- mss_dev_type = 0x0;
- break;
- case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB:
- mss_dev_type = 0x1;
- break;
- case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB:
- mss_dev_type = 0x2;
- break;
- case MSS_DEV_TYPE_FWSEC_NONWIN_INBOX:
- mss_dev_type = 0x3;
- break;
- case MSS_DEV_TYPE_FWSEC_DEF:
- mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF;
- break;
- default:
- rtw89_warn(rtwdev, "unknown mss_dev_type %d", mss_dev_type);
- mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_INV;
- break;
- }
-
- return mss_dev_type;
-}
-
int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
{
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
@@ -511,7 +472,6 @@ int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
u32 sec_size = EFUSE_SEC_BE_SIZE;
u16 sb_cryp_sel, sb_cryp_sel_idx;
u8 sec_map[EFUSE_SEC_BE_SIZE];
- u8 mss_dev_type;
u8 b1, b2;
int ret;
@@ -538,16 +498,9 @@ int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
b1 = sec_map[EFUSE_EXTERNALPN_ADDR_BE - sec_addr];
b2 = sec_map[EFUSE_SERIALNUM_ADDR_BE - sec_addr];
- mss_dev_type = u8_get_bits(b1, EFUSE_B1_MSSDEVTYPE_MASK);
- sec->mss_cust_idx = 0x1F - (u8_get_bits(b1, EFUSE_B1_MSSCUSTIDX0_MASK) |
- u8_get_bits(b2, EFUSE_B2_MSSCUSTIDX1_MASK) << 4);
- sec->mss_key_num = 0xF - u8_get_bits(b2, EFUSE_B2_MSSKEYNUM_MASK);
-
- sec->mss_dev_type = get_mss_dev_type_idx(rtwdev, mss_dev_type);
- if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_INV) {
- rtw89_warn(rtwdev, "invalid mss_dev_type %d\n", mss_dev_type);
+ ret = rtw89_efuse_recognize_mss_info_v1(rtwdev, b1, b2);
+ if (ret)
goto out;
- }
sec->secure_boot = true;
@@ -559,4 +512,3 @@ out:
return 0;
}
-EXPORT_SYMBOL(rtw89_efuse_read_fw_secure_be);
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 185cd339c085..00b65b2995cf 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -2,6 +2,7 @@
/* Copyright(c) 2019-2020 Realtek Corporation
*/
+#include <linux/if_arp.h>
#include "cam.h"
#include "chan.h"
#include "coex.h"
@@ -12,9 +13,43 @@
#include "ps.h"
#include "reg.h"
#include "util.h"
+#include "wow.h"
+
+static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev);
+
+struct rtw89_eapol_2_of_2 {
+ u8 gtkbody[14];
+ u8 key_des_ver;
+ u8 rsvd[92];
+} __packed;
+
+struct rtw89_sa_query {
+ u8 category;
+ u8 action;
+} __packed;
+
+struct rtw89_arp_rsp {
+ u8 llc_hdr[sizeof(rfc1042_header)];
+ __be16 llc_type;
+ struct arphdr arp_hdr;
+ u8 sender_hw[ETH_ALEN];
+ __be32 sender_ip;
+ u8 target_hw[ETH_ALEN];
+ __be32 target_ip;
+} __packed;
static const u8 mss_signature[] = {0x4D, 0x53, 0x53, 0x4B, 0x50, 0x4F, 0x4F, 0x4C};
+const struct rtw89_fw_blacklist rtw89_fw_blacklist_default = {
+ .ver = 0x00,
+ .list = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ },
+};
+EXPORT_SYMBOL(rtw89_fw_blacklist_default);
+
union rtw89_fw_element_arg {
size_t offset;
enum rtw89_rf_path rf_path;
@@ -33,6 +68,11 @@ static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
struct sk_buff *skb);
static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb,
struct rtw89_wait_info *wait, unsigned int cond);
+static int __parse_security_section(struct rtw89_dev *rtwdev,
+ struct rtw89_fw_bin_info *info,
+ struct rtw89_fw_hdr_section_info *section_info,
+ const void *content,
+ u32 *mssc_len);
static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len,
bool header)
@@ -101,13 +141,16 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
struct rtw89_fw_bin_info *info)
{
const struct rtw89_fw_hdr *fw_hdr = (const struct rtw89_fw_hdr *)fw;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_fw_hdr_section_info *section_info;
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
const struct rtw89_fw_dynhdr_hdr *fwdynhdr;
const struct rtw89_fw_hdr_section *section;
const u8 *fw_end = fw + len;
const u8 *bin;
u32 base_hdr_len;
- u32 mssc_len = 0;
+ u32 mssc_len;
+ int ret;
u32 i;
if (!info)
@@ -116,6 +159,7 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_W6_SEC_NUM);
base_hdr_len = struct_size(fw_hdr, sections, info->section_num);
info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_W7_DYN_HDR);
+ info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_W7_IDMEM_SHARE_MODE);
if (info->dynamic_hdr_en) {
info->hdr_len = le32_get_bits(fw_hdr->w3, FW_HDR_W3_LEN);
@@ -138,26 +182,47 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
section = &fw_hdr->sections[i];
section_info->type =
le32_get_bits(section->w1, FWSECTION_HDR_W1_SECTIONTYPE);
- if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
- section_info->mssc =
- le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC);
- mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN;
- } else {
- section_info->mssc = 0;
- }
-
section_info->len = le32_get_bits(section->w1, FWSECTION_HDR_W1_SEC_SIZE);
+
if (le32_get_bits(section->w1, FWSECTION_HDR_W1_CHECKSUM))
section_info->len += FWDL_SECTION_CHKSUM_LEN;
section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_W1_REDL);
section_info->dladdr =
le32_get_bits(section->w0, FWSECTION_HDR_W0_DL_ADDR) & 0x1fffffff;
section_info->addr = bin;
- bin += section_info->len;
+
+ if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
+ section_info->mssc =
+ le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC);
+
+ ret = __parse_security_section(rtwdev, info, section_info,
+ bin, &mssc_len);
+ if (ret)
+ return ret;
+
+ if (sec->secure_boot && chip->chip_id == RTL8852B)
+ section_info->len_override = 960;
+ } else {
+ section_info->mssc = 0;
+ mssc_len = 0;
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_FW,
+ "section[%d] type=%d len=0x%-6x mssc=%d mssc_len=%d addr=%tx\n",
+ i, section_info->type, section_info->len,
+ section_info->mssc, mssc_len, bin - fw);
+ rtw89_debug(rtwdev, RTW89_DBG_FW,
+ " ignore=%d key_addr=%p (0x%tx) key_len=%d key_idx=%d\n",
+ section_info->ignore, section_info->key_addr,
+ section_info->key_addr ?
+ section_info->key_addr - section_info->addr : 0,
+ section_info->key_len, section_info->key_idx);
+
+ bin += section_info->len + mssc_len;
section_info++;
}
- if (fw_end != bin + mssc_len) {
+ if (fw_end != bin) {
rtw89_err(rtwdev, "[ERR]fw bin size\n");
return -EINVAL;
}
@@ -212,7 +277,6 @@ static int __get_mssc_key_idx(struct rtw89_dev *rtwdev,
static int __parse_formatted_mssc(struct rtw89_dev *rtwdev,
struct rtw89_fw_bin_info *info,
struct rtw89_fw_hdr_section_info *section_info,
- const struct rtw89_fw_hdr_section_v1 *section,
const void *content,
u32 *mssc_len)
{
@@ -262,7 +326,7 @@ static int __parse_formatted_mssc(struct rtw89_dev *rtwdev,
if (!sec->secure_boot)
goto out;
- sb_sel_ver = le32_to_cpu(section_content->sb_sel_ver.v);
+ sb_sel_ver = get_unaligned_le32(&section_content->sb_sel_ver.v);
if (sb_sel_ver && sb_sel_ver != sec->sb_sel_mgn)
goto ignore;
@@ -292,21 +356,58 @@ ignore:
return 0;
}
+static int __check_secure_blacklist(struct rtw89_dev *rtwdev,
+ struct rtw89_fw_bin_info *info,
+ struct rtw89_fw_hdr_section_info *section_info,
+ const void *content)
+{
+ const struct rtw89_fw_blacklist *chip_blacklist = rtwdev->chip->fw_blacklist;
+ const union rtw89_fw_section_mssc_content *section_content = content;
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+ u8 byte_idx;
+ u8 bit_mask;
+
+ if (!sec->secure_boot)
+ return 0;
+
+ if (!info->secure_section_exist || section_info->ignore)
+ return 0;
+
+ if (!chip_blacklist) {
+ rtw89_warn(rtwdev, "chip no blacklist for secure firmware\n");
+ return -ENOENT;
+ }
+
+ byte_idx = section_content->blacklist.bit_in_chip_list >> 3;
+ bit_mask = BIT(section_content->blacklist.bit_in_chip_list & 0x7);
+
+ if (section_content->blacklist.ver > chip_blacklist->ver) {
+ rtw89_warn(rtwdev, "chip blacklist out of date (%u, %u)\n",
+ section_content->blacklist.ver, chip_blacklist->ver);
+ return -EINVAL;
+ }
+
+ if (chip_blacklist->list[byte_idx] & bit_mask) {
+ rtw89_warn(rtwdev, "firmware %u in chip blacklist\n",
+ section_content->blacklist.ver);
+ return -EPERM;
+ }
+
+ return 0;
+}
+
static int __parse_security_section(struct rtw89_dev *rtwdev,
struct rtw89_fw_bin_info *info,
struct rtw89_fw_hdr_section_info *section_info,
- const struct rtw89_fw_hdr_section_v1 *section,
const void *content,
u32 *mssc_len)
{
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
int ret;
- section_info->mssc =
- le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC);
-
- if (section_info->mssc == FORMATTED_MSSC) {
+ if ((section_info->mssc & FORMATTED_MSSC_MASK) == FORMATTED_MSSC) {
ret = __parse_formatted_mssc(rtwdev, info, section_info,
- section, content, mssc_len);
+ content, mssc_len);
if (ret)
return -EINVAL;
} else {
@@ -314,9 +415,23 @@ static int __parse_security_section(struct rtw89_dev *rtwdev,
if (info->dsp_checksum)
*mssc_len += section_info->mssc * FWDL_SECURITY_CHKSUM_LEN;
+ if (sec->secure_boot) {
+ if (sec->mss_idx >= section_info->mssc) {
+ rtw89_err(rtwdev, "unexpected MSS %d >= %d\n",
+ sec->mss_idx, section_info->mssc);
+ return -EFAULT;
+ }
+ section_info->key_addr = content + section_info->len +
+ sec->mss_idx * FWDL_SECURITY_SIGLEN;
+ section_info->key_len = FWDL_SECURITY_SIGLEN;
+ }
+
info->secure_section_exist = true;
}
+ ret = __check_secure_blacklist(rtwdev, info, section_info, content);
+ WARN_ONCE(ret, "Current firmware in blacklist. Please update firmware.\n");
+
return 0;
}
@@ -338,6 +453,7 @@ static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
info->dsp_checksum = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_DSP_CHKSUM);
base_hdr_len = struct_size(fw_hdr, sections, info->section_num);
info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_DYN_HDR);
+ info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_IDMEM_SHARE_MODE);
if (info->dynamic_hdr_en) {
info->hdr_len = le32_get_bits(fw_hdr->w5, FW_HDR_V1_W5_HDR_SIZE);
@@ -371,8 +487,11 @@ static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
section_info->addr = bin;
if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
+ section_info->mssc =
+ le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC);
+
ret = __parse_security_section(rtwdev, info, section_info,
- section, bin, &mssc_len);
+ bin, &mssc_len);
if (ret)
return ret;
} else {
@@ -429,18 +548,61 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev,
}
static
+const struct rtw89_mfw_hdr *rtw89_mfw_get_hdr_ptr(struct rtw89_dev *rtwdev,
+ const struct firmware *firmware)
+{
+ const struct rtw89_mfw_hdr *mfw_hdr;
+
+ if (sizeof(*mfw_hdr) > firmware->size)
+ return NULL;
+
+ mfw_hdr = (const struct rtw89_mfw_hdr *)&firmware->data[0];
+
+ if (mfw_hdr->sig != RTW89_MFW_SIG)
+ return NULL;
+
+ return mfw_hdr;
+}
+
+static int rtw89_mfw_validate_hdr(struct rtw89_dev *rtwdev,
+ const struct firmware *firmware,
+ const struct rtw89_mfw_hdr *mfw_hdr)
+{
+ const void *mfw = firmware->data;
+ u32 mfw_len = firmware->size;
+ u8 fw_nr = mfw_hdr->fw_nr;
+ const void *ptr;
+
+ if (fw_nr == 0) {
+ rtw89_err(rtwdev, "mfw header has no fw entry\n");
+ return -ENOENT;
+ }
+
+ ptr = &mfw_hdr->info[fw_nr];
+
+ if (ptr > mfw + mfw_len) {
+ rtw89_err(rtwdev, "mfw header out of address\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static
int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
struct rtw89_fw_suit *fw_suit, bool nowarn)
{
struct rtw89_fw_info *fw_info = &rtwdev->fw;
const struct firmware *firmware = fw_info->req.firmware;
+ const struct rtw89_mfw_info *mfw_info = NULL, *tmp;
+ const struct rtw89_mfw_hdr *mfw_hdr;
const u8 *mfw = firmware->data;
u32 mfw_len = firmware->size;
- const struct rtw89_mfw_hdr *mfw_hdr = (const struct rtw89_mfw_hdr *)mfw;
- const struct rtw89_mfw_info *mfw_info;
+ int ret;
int i;
- if (mfw_hdr->sig != RTW89_MFW_SIG) {
+ mfw_hdr = rtw89_mfw_get_hdr_ptr(rtwdev, firmware);
+ if (!mfw_hdr) {
rtw89_debug(rtwdev, RTW89_DBG_FW, "use legacy firmware\n");
/* legacy firmware support normal type only */
if (type != RTW89_FW_NORMAL)
@@ -450,16 +612,32 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
return 0;
}
+ ret = rtw89_mfw_validate_hdr(rtwdev, firmware, mfw_hdr);
+ if (ret)
+ return ret;
+
for (i = 0; i < mfw_hdr->fw_nr; i++) {
- mfw_info = &mfw_hdr->info[i];
- if (mfw_info->type == type) {
- if (mfw_info->cv == rtwdev->hal.cv && !mfw_info->mp)
- goto found;
- if (type == RTW89_FW_LOGFMT)
- goto found;
+ tmp = &mfw_hdr->info[i];
+ if (tmp->type != type)
+ continue;
+
+ if (type == RTW89_FW_LOGFMT) {
+ mfw_info = tmp;
+ goto found;
+ }
+
+ /* Version order of WiFi firmware in firmware file are not in order,
+ * pass all firmware to find the equal or less but closest version.
+ */
+ if (tmp->cv <= rtwdev->hal.cv && !tmp->mp) {
+ if (!mfw_info || mfw_info->cv < tmp->cv)
+ mfw_info = tmp;
}
}
+ if (mfw_info)
+ goto found;
+
if (!nowarn)
rtw89_err(rtwdev, "no suitable firmware found\n");
return -ENOENT;
@@ -467,6 +645,12 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
found:
fw_suit->data = mfw + le32_to_cpu(mfw_info->shift);
fw_suit->size = le32_to_cpu(mfw_info->size);
+
+ if (fw_suit->data + fw_suit->size > mfw + mfw_len) {
+ rtw89_err(rtwdev, "fw_suit %d out of address\n", type);
+ return -EFAULT;
+ }
+
return 0;
}
@@ -474,16 +658,21 @@ static u32 rtw89_mfw_get_size(struct rtw89_dev *rtwdev)
{
struct rtw89_fw_info *fw_info = &rtwdev->fw;
const struct firmware *firmware = fw_info->req.firmware;
- const struct rtw89_mfw_hdr *mfw_hdr =
- (const struct rtw89_mfw_hdr *)firmware->data;
const struct rtw89_mfw_info *mfw_info;
+ const struct rtw89_mfw_hdr *mfw_hdr;
u32 size;
+ int ret;
- if (mfw_hdr->sig != RTW89_MFW_SIG) {
+ mfw_hdr = rtw89_mfw_get_hdr_ptr(rtwdev, firmware);
+ if (!mfw_hdr) {
rtw89_warn(rtwdev, "not mfw format\n");
return 0;
}
+ ret = rtw89_mfw_validate_hdr(rtwdev, firmware, mfw_hdr);
+ if (ret)
+ return ret;
+
mfw_info = &mfw_hdr->info[mfw_hdr->fw_nr - 1];
size = le32_to_cpu(mfw_info->shift) + le32_to_cpu(mfw_info->size);
@@ -581,10 +770,16 @@ int __rtw89_fw_recognize_from_elm(struct rtw89_dev *rtwdev,
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_fw_suit *fw_suit;
- if (hal->cv != elm->u.bbmcu.cv)
+ /* Version of BB MCU is in decreasing order in firmware file, so take
+ * first equal or less version, which is equal or less but closest version.
+ */
+ if (hal->cv < elm->u.bbmcu.cv)
return 1; /* ignore this element */
fw_suit = rtw89_fw_suit_get(rtwdev, type);
+ if (fw_suit->data)
+ return 1; /* ignore this element (a firmware is taken already) */
+
fw_suit->data = elm->u.bbmcu.contents;
fw_suit->size = le32_to_cpu(elm->size);
@@ -624,19 +819,40 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE),
__CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER),
+ __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 37, 0, NO_WOW_CPU_IO_RX),
__CFG_FW_FEAT(RTL8852A, lt, 0, 13, 38, 0, NO_PACKET_DROP),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD),
+ __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 7, BEACON_FILTER),
+ __CFG_FW_FEAT(RTL8852B, lt, 0, 29, 30, 0, NO_WOW_CPU_IO_RX),
+ __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, NO_LPS_PG),
+ __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, TX_WAKE),
+ __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 90, 0, CRASH_TRIGGER),
+ __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 91, 0, SCAN_OFFLOAD),
+ __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 110, 0, BEACON_FILTER),
__CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 56, 10, BEACON_FILTER),
+ __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 80, 0, WOW_REASON_V1),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 11, 0, MACID_PAUSE_SLEEP),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD),
+ __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 21, 0, SCAN_OFFLOAD_BE_V0),
+ __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 12, 0, BEACON_FILTER),
+ __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 22, 0, WOW_REASON_V1),
+ __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, RFK_PRE_NOTIFY_V0),
+ __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, LPS_CH_INFO),
+ __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 42, 0, RFK_RXDCK_V0),
+ __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 46, 0, NOTIFY_AP_INFO),
+ __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 47, 0, CH_INFO_BE_V0),
+ __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 49, 0, RFK_PRE_NOTIFY_V1),
+ __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 51, 0, NO_PHYCAP_P1),
+ __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 64, 0, NO_POWER_DIFFERENCE),
+ __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 71, 0, BEACON_LOSS_COUNT_V1),
};
static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw,
@@ -708,6 +924,27 @@ out:
return firmware;
}
+static int rtw89_fw_validate_ver_required(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_chip_variant *variant = rtwdev->variant;
+ const struct rtw89_fw_suit *fw_suit;
+ u32 suit_ver_code;
+
+ if (!variant)
+ return 0;
+
+ fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL);
+ suit_ver_code = RTW89_FW_SUIT_VER_CODE(fw_suit);
+
+ if (variant->fw_min_ver_code > suit_ver_code) {
+ rtw89_err(rtwdev, "minimum required firmware version is 0x%x\n",
+ variant->fw_min_ver_code);
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
int rtw89_fw_recognize(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
@@ -724,6 +961,10 @@ int rtw89_fw_recognize(struct rtw89_dev *rtwdev)
return ret;
normal_done:
+ ret = rtw89_fw_validate_ver_required(rtwdev);
+ if (ret)
+ return ret;
+
/* It still works if wowlan firmware isn't existing. */
__rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN, false);
@@ -780,7 +1021,7 @@ int rtw89_build_phy_tbl_from_elm(struct rtw89_dev *rtwdev,
}
n_regs = le32_to_cpu(elm->size) / sizeof(tbl->regs[0]);
- regs = kcalloc(n_regs, sizeof(tbl->regs[0]), GFP_KERNEL);
+ regs = kcalloc(n_regs, sizeof(*regs), GFP_KERNEL);
if (!regs)
goto out;
@@ -865,7 +1106,7 @@ int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev,
bitmap = le32_to_cpu(elm->u.txpwr_trk.bitmap);
if ((bitmap & needed_bitmap) != needed_bitmap) {
- rtw89_warn(rtwdev, "needed txpwr trk bitmap %08x but %0x8x\n",
+ rtw89_warn(rtwdev, "needed txpwr trk bitmap %08x but %08x\n",
needed_bitmap, bitmap);
return -ENOENT;
}
@@ -933,6 +1174,101 @@ allocated:
return 0;
}
+static bool rtw89_regd_entcpy(struct rtw89_regd *regd, const void *cursor,
+ u8 cursor_size)
+{
+ /* fill default values if needed for backward compatibility */
+ struct rtw89_fw_regd_entry entry = {
+ .rule_2ghz = RTW89_NA,
+ .rule_5ghz = RTW89_NA,
+ .rule_6ghz = RTW89_NA,
+ .fmap = cpu_to_le32(0x0),
+ };
+ u8 valid_size = min_t(u8, sizeof(entry), cursor_size);
+ unsigned int i;
+ u32 fmap;
+
+ memcpy(&entry, cursor, valid_size);
+ memset(regd, 0, sizeof(*regd));
+
+ regd->alpha2[0] = entry.alpha2_0;
+ regd->alpha2[1] = entry.alpha2_1;
+ regd->alpha2[2] = '\0';
+
+ /* also need to consider forward compatibility */
+ regd->txpwr_regd[RTW89_BAND_2G] = entry.rule_2ghz < RTW89_REGD_NUM ?
+ entry.rule_2ghz : RTW89_NA;
+ regd->txpwr_regd[RTW89_BAND_5G] = entry.rule_5ghz < RTW89_REGD_NUM ?
+ entry.rule_5ghz : RTW89_NA;
+ regd->txpwr_regd[RTW89_BAND_6G] = entry.rule_6ghz < RTW89_REGD_NUM ?
+ entry.rule_6ghz : RTW89_NA;
+
+ BUILD_BUG_ON(sizeof(fmap) != sizeof(entry.fmap));
+ BUILD_BUG_ON(sizeof(fmap) * 8 < NUM_OF_RTW89_REGD_FUNC);
+
+ fmap = le32_to_cpu(entry.fmap);
+ for (i = 0; i < NUM_OF_RTW89_REGD_FUNC; i++) {
+ if (fmap & BIT(i))
+ set_bit(i, regd->func_bitmap);
+ }
+
+ return true;
+}
+
+#define rtw89_for_each_in_regd_element(regd, element) \
+ for (const void *cursor = (element)->content, \
+ *end = (element)->content + \
+ le32_to_cpu((element)->num_ents) * (element)->ent_sz; \
+ cursor < end; cursor += (element)->ent_sz) \
+ if (rtw89_regd_entcpy(regd, cursor, (element)->ent_sz))
+
+static
+int rtw89_recognize_regd_from_elm(struct rtw89_dev *rtwdev,
+ const struct rtw89_fw_element_hdr *elm,
+ const union rtw89_fw_element_arg arg)
+{
+ const struct __rtw89_fw_regd_element *regd_elm = &elm->u.regd;
+ struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
+ u32 num_ents = le32_to_cpu(regd_elm->num_ents);
+ struct rtw89_regd_data *p;
+ struct rtw89_regd regd;
+ u32 i = 0;
+
+ if (num_ents > RTW89_REGD_MAX_COUNTRY_NUM) {
+ rtw89_warn(rtwdev,
+ "regd element ents (%d) are over max num (%d)\n",
+ num_ents, RTW89_REGD_MAX_COUNTRY_NUM);
+ rtw89_warn(rtwdev,
+ "regd element ignore and take another/common\n");
+ return 1;
+ }
+
+ if (elm_info->regd) {
+ rtw89_debug(rtwdev, RTW89_DBG_REGD,
+ "regd element take the latter\n");
+ devm_kfree(rtwdev->dev, elm_info->regd);
+ elm_info->regd = NULL;
+ }
+
+ p = devm_kzalloc(rtwdev->dev, struct_size(p, map, num_ents), GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+
+ p->nr = num_ents;
+ rtw89_for_each_in_regd_element(&regd, regd_elm)
+ p->map[i++] = regd;
+
+ if (i != num_ents) {
+ rtw89_err(rtwdev, "regd element has %d invalid ents\n",
+ num_ents - i);
+ devm_kfree(rtwdev->dev, p);
+ return -EINVAL;
+ }
+
+ elm_info->regd = p;
+ return 0;
+}
+
static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
[RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm,
{ .fw_type = RTW89_FW_BBMCU0 }, NULL},
@@ -965,6 +1301,18 @@ static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
rtw89_fw_recognize_txpwr_from_elm,
{ .offset = offsetof(struct rtw89_rfe_data, lmt_6ghz.conf) }, NULL,
},
+ [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_2GHZ] = {
+ rtw89_fw_recognize_txpwr_from_elm,
+ { .offset = offsetof(struct rtw89_rfe_data, da_lmt_2ghz.conf) }, NULL,
+ },
+ [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_5GHZ] = {
+ rtw89_fw_recognize_txpwr_from_elm,
+ { .offset = offsetof(struct rtw89_rfe_data, da_lmt_5ghz.conf) }, NULL,
+ },
+ [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_6GHZ] = {
+ rtw89_fw_recognize_txpwr_from_elm,
+ { .offset = offsetof(struct rtw89_rfe_data, da_lmt_6ghz.conf) }, NULL,
+ },
[RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_2GHZ] = {
rtw89_fw_recognize_txpwr_from_elm,
{ .offset = offsetof(struct rtw89_rfe_data, lmt_ru_2ghz.conf) }, NULL,
@@ -977,6 +1325,18 @@ static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
rtw89_fw_recognize_txpwr_from_elm,
{ .offset = offsetof(struct rtw89_rfe_data, lmt_ru_6ghz.conf) }, NULL,
},
+ [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_2GHZ] = {
+ rtw89_fw_recognize_txpwr_from_elm,
+ { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_2ghz.conf) }, NULL,
+ },
+ [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_5GHZ] = {
+ rtw89_fw_recognize_txpwr_from_elm,
+ { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_5ghz.conf) }, NULL,
+ },
+ [RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_6GHZ] = {
+ rtw89_fw_recognize_txpwr_from_elm,
+ { .offset = offsetof(struct rtw89_rfe_data, da_lmt_ru_6ghz.conf) }, NULL,
+ },
[RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT] = {
rtw89_fw_recognize_txpwr_from_elm,
{ .offset = offsetof(struct rtw89_rfe_data, tx_shape_lmt.conf) }, NULL,
@@ -991,6 +1351,9 @@ static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
[RTW89_FW_ELEMENT_ID_RFKLOG_FMT] = {
rtw89_build_rfk_log_fmt_from_elm, {}, NULL,
},
+ [RTW89_FW_ELEMENT_ID_REGD] = {
+ rtw89_recognize_regd_from_elm, {}, "REGD",
+ },
};
int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev)
@@ -1102,9 +1465,24 @@ static u32 __rtw89_fw_download_tweak_hdr_v0(struct rtw89_dev *rtwdev,
struct rtw89_fw_bin_info *info,
struct rtw89_fw_hdr *fw_hdr)
{
+ struct rtw89_fw_hdr_section_info *section_info;
+ struct rtw89_fw_hdr_section *section;
+ int i;
+
le32p_replace_bits(&fw_hdr->w7, FWDL_SECTION_PER_PKT_LEN,
FW_HDR_W7_PART_SIZE);
+ for (i = 0; i < info->section_num; i++) {
+ section_info = &info->section_info[i];
+
+ if (!section_info->len_override)
+ continue;
+
+ section = &fw_hdr->sections[i];
+ le32p_replace_bits(&section->w1, section_info->len_override,
+ FWSECTION_HDR_W1_SEC_SIZE);
+ }
+
return 0;
}
@@ -1184,7 +1562,6 @@ static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev,
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
rtw89_err(rtwdev, "failed to send h2c\n");
- ret = -1;
goto fail;
}
@@ -1233,10 +1610,20 @@ static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev,
if (info->ignore)
return 0;
+ if (info->len_override) {
+ if (info->len_override > info->len)
+ rtw89_warn(rtwdev, "override length %u larger than original %u\n",
+ info->len_override, info->len);
+ else
+ residue_len = info->len_override;
+ }
+
if (info->key_addr && info->key_len) {
- if (info->len > FWDL_SECTION_PER_PKT_LEN || info->len < info->key_len)
- rtw89_warn(rtwdev, "ignore to copy key data because of len %d, %d, %d\n",
- info->len, FWDL_SECTION_PER_PKT_LEN, info->key_len);
+ if (residue_len > FWDL_SECTION_PER_PKT_LEN || info->len < info->key_len)
+ rtw89_warn(rtwdev,
+ "ignore to copy key data because of len %d, %d, %d, %d\n",
+ info->len, FWDL_SECTION_PER_PKT_LEN,
+ info->key_len, residue_len);
else
copy_key = true;
}
@@ -1261,7 +1648,6 @@ static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev,
ret = rtw89_h2c_tx(rtwdev, skb, true);
if (ret) {
rtw89_err(rtwdev, "failed to send h2c\n");
- ret = -1;
goto fail;
}
@@ -1349,13 +1735,12 @@ dump:
static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev)
{
u32 val32;
- u16 val16;
val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL);
rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32);
- val16 = rtw89_read16(rtwdev, R_AX_BOOT_DBG + 2);
- rtw89_err(rtwdev, "[ERR]fwdl 0x83F2 = 0x%x\n", val16);
+ val32 = rtw89_read32(rtwdev, R_AX_BOOT_DBG);
+ rtw89_err(rtwdev, "[ERR]fwdl 0x83F0 = 0x%x\n", val32);
rtw89_fw_prog_cnt_dump(rtwdev);
}
@@ -1373,6 +1758,8 @@ static int rtw89_fw_download_suit(struct rtw89_dev *rtwdev,
return ret;
}
+ rtw89_fwdl_secure_idmem_share_mode(rtwdev, info.idmem_share_mode);
+
if (rtwdev->chip->chip_id == RTL8922A &&
(fw_suit->type == RTW89_FW_NORMAL || fw_suit->type == RTW89_FW_WOWLAN))
rtw89_write32(rtwdev, R_BE_SECURE_BOOT_MALLOC_INFO, 0x20248000);
@@ -1394,8 +1781,9 @@ static int rtw89_fw_download_suit(struct rtw89_dev *rtwdev,
return 0;
}
-int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
- bool include_bb)
+static
+int __rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
+ bool include_bb)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct rtw89_fw_info *fw_info = &rtwdev->fw;
@@ -1433,7 +1821,7 @@ int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE);
if (ret) {
rtw89_warn(rtwdev, "download firmware fail\n");
- return ret;
+ goto fwdl_err;
}
return ret;
@@ -1443,6 +1831,21 @@ fwdl_err:
return ret;
}
+int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
+ bool include_bb)
+{
+ int retry;
+ int ret;
+
+ for (retry = 0; retry < 5; retry++) {
+ ret = __rtw89_fw_download(rtwdev, type, include_bb);
+ if (!ret)
+ return 0;
+ }
+
+ return ret;
+}
+
int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev)
{
struct rtw89_fw_info *fw = &rtwdev->fw;
@@ -1676,8 +2079,8 @@ plain_log:
}
#define H2C_CAM_LEN 60
-int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta, const u8 *scan_mac_addr)
+int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr)
{
struct sk_buff *skb;
int ret;
@@ -1688,8 +2091,9 @@ int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
return -ENOMEM;
}
skb_put(skb, H2C_CAM_LEN);
- rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif, rtwsta, scan_mac_addr, skb->data);
- rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif, rtwsta, skb->data);
+ rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif_link, rtwsta_link, scan_mac_addr,
+ skb->data);
+ rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif_link, rtwsta_link, skb->data);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
@@ -1710,28 +2114,30 @@ fail:
return ret;
}
-#define H2C_DCTL_SEC_CAM_LEN 68
int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
+ struct rtw89_h2c_dctlinfo_ud_v1 *h2c;
+ u32 len = sizeof(*h2c);
struct sk_buff *skb;
int ret;
- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DCTL_SEC_CAM_LEN);
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n");
return -ENOMEM;
}
- skb_put(skb, H2C_DCTL_SEC_CAM_LEN);
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_dctlinfo_ud_v1 *)skb->data;
- rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif, rtwsta, skb->data);
+ rtw89_cam_fill_dctl_sec_cam_info_v1(rtwdev, rtwvif_link, rtwsta_link, h2c);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
H2C_CL_MAC_FR_EXCHG,
H2C_FUNC_MAC_DCTLINFO_UD_V1, 0, 0,
- H2C_DCTL_SEC_CAM_LEN);
+ len);
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
@@ -1748,8 +2154,8 @@ fail:
EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1);
int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
struct rtw89_h2c_dctlinfo_ud_v2 *h2c;
u32 len = sizeof(*h2c);
@@ -1764,7 +2170,7 @@ int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev,
skb_put(skb, len);
h2c = (struct rtw89_h2c_dctlinfo_ud_v2 *)skb->data;
- rtw89_cam_fill_dctl_sec_cam_info_v2(rtwdev, rtwvif, rtwsta, h2c);
+ rtw89_cam_fill_dctl_sec_cam_info_v2(rtwdev, rtwvif_link, rtwsta_link, h2c);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
@@ -1787,10 +2193,10 @@ fail:
EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v2);
int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
+ u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
struct rtw89_h2c_dctlinfo_ud_v2 *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
@@ -1841,21 +2247,24 @@ fail:
}
EXPORT_SYMBOL(rtw89_fw_h2c_default_dmac_tbl_v2);
-int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
bool valid, struct ieee80211_ampdu_params *params)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_h2c_ba_cam *h2c;
- u8 macid = rtwsta->mac_id;
+ u8 macid = rtwsta_link->mac_id;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
u8 entry_idx;
int ret;
ret = valid ?
- rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx) :
- rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx);
+ rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta_link, params->tid,
+ &entry_idx) :
+ rtw89_core_release_sta_ba_entry(rtwdev, rtwsta_link, params->tid,
+ &entry_idx);
if (ret) {
/* it still works even if we don't have static BA CAM, because
* hardware can create dynamic BA CAM automatically.
@@ -1893,7 +2302,8 @@ int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
if (chip->bacam_ver == RTW89_BACAM_V0_EXT) {
h2c->w1 |= le32_encode_bits(1, RTW89_H2C_BA_CAM_W1_STD_EN) |
- le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_BA_CAM_W1_BAND);
+ le32_encode_bits(rtwvif_link->mac_idx,
+ RTW89_H2C_BA_CAM_W1_BAND);
}
end:
@@ -1972,13 +2382,14 @@ void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev)
}
}
-int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
bool valid, struct ieee80211_ampdu_params *params)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_h2c_ba_cam_v1 *h2c;
- u8 macid = rtwsta->mac_id;
+ u8 macid = rtwsta_link->mac_id;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
u8 entry_idx;
@@ -1986,8 +2397,10 @@ int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
int ret;
ret = valid ?
- rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx) :
- rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx);
+ rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta_link, params->tid,
+ &entry_idx) :
+ rtw89_core_release_sta_ba_entry(rtwdev, rtwsta_link, params->tid,
+ &entry_idx);
if (ret) {
/* it still works even if we don't have static BA CAM, because
* hardware can create dynamic BA CAM automatically.
@@ -2025,7 +2438,8 @@ int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
entry_idx += chip->bacam_dynamic_num; /* std entry right after dynamic ones */
h2c->w1 = le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_V1_W1_ENTRY_IDX_MASK) |
le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W1_STD_ENTRY_EN) |
- le32_encode_bits(!!rtwvif->mac_idx, RTW89_H2C_BA_CAM_V1_W1_BAND_SEL);
+ le32_encode_bits(!!rtwvif_link->mac_idx,
+ RTW89_H2C_BA_CAM_V1_W1_BAND_SEL);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
@@ -2096,7 +2510,7 @@ int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable)
if (enable)
comp = BIT(RTW89_FW_LOG_COMP_INIT) | BIT(RTW89_FW_LOG_COMP_TASK) |
BIT(RTW89_FW_LOG_COMP_PS) | BIT(RTW89_FW_LOG_COMP_ERROR) |
- BIT(RTW89_FW_LOG_COMP_SCAN);
+ BIT(RTW89_FW_LOG_COMP_MLO) | BIT(RTW89_FW_LOG_COMP_SCAN);
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LOG_CFG_LEN);
if (!skb) {
@@ -2129,12 +2543,148 @@ fail:
return ret;
}
+static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ static const u8 gtkbody[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88,
+ 0x8E, 0x01, 0x03, 0x00, 0x5F, 0x02, 0x03};
+ u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev);
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_eapol_2_of_2 *eapol_pkt;
+ struct ieee80211_bss_conf *bss_conf;
+ struct ieee80211_hdr_3addr *hdr;
+ struct sk_buff *skb;
+ u8 key_des_ver;
+
+ if (rtw_wow->ptk_alg == 3)
+ key_des_ver = 1;
+ else if (rtw_wow->akm == 1 || rtw_wow->akm == 2)
+ key_des_ver = 2;
+ else if (rtw_wow->akm > 2 && rtw_wow->akm < 7)
+ key_des_ver = 3;
+ else
+ key_des_ver = 0;
+
+ skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*eapol_pkt));
+ if (!skb)
+ return NULL;
+
+ hdr = skb_put_zero(skb, sizeof(*hdr));
+ hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
+ IEEE80211_FCTL_TODS |
+ IEEE80211_FCTL_PROTECTED);
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
+ ether_addr_copy(hdr->addr1, bss_conf->bssid);
+ ether_addr_copy(hdr->addr2, bss_conf->addr);
+ ether_addr_copy(hdr->addr3, bss_conf->bssid);
+
+ rcu_read_unlock();
+
+ skb_put_zero(skb, sec_hdr_len);
+
+ eapol_pkt = skb_put_zero(skb, sizeof(*eapol_pkt));
+ memcpy(eapol_pkt->gtkbody, gtkbody, sizeof(gtkbody));
+ eapol_pkt->key_des_ver = key_des_ver;
+
+ return skb;
+}
+
+static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev);
+ struct ieee80211_bss_conf *bss_conf;
+ struct ieee80211_hdr_3addr *hdr;
+ struct rtw89_sa_query *sa_query;
+ struct sk_buff *skb;
+
+ skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*sa_query));
+ if (!skb)
+ return NULL;
+
+ hdr = skb_put_zero(skb, sizeof(*hdr));
+ hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ACTION |
+ IEEE80211_FCTL_PROTECTED);
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
+ ether_addr_copy(hdr->addr1, bss_conf->bssid);
+ ether_addr_copy(hdr->addr2, bss_conf->addr);
+ ether_addr_copy(hdr->addr3, bss_conf->bssid);
+
+ rcu_read_unlock();
+
+ skb_put_zero(skb, sec_hdr_len);
+
+ sa_query = skb_put_zero(skb, sizeof(*sa_query));
+ sa_query->category = WLAN_CATEGORY_SA_QUERY;
+ sa_query->action = WLAN_ACTION_SA_QUERY_RESPONSE;
+
+ return skb;
+}
+
+static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev);
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct ieee80211_hdr_3addr *hdr;
+ struct rtw89_arp_rsp *arp_skb;
+ struct arphdr *arp_hdr;
+ struct sk_buff *skb;
+ __le16 fc;
+
+ skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*arp_skb));
+ if (!skb)
+ return NULL;
+
+ hdr = skb_put_zero(skb, sizeof(*hdr));
+
+ if (rtw_wow->ptk_alg)
+ fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS |
+ IEEE80211_FCTL_PROTECTED);
+ else
+ fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS);
+
+ hdr->frame_control = fc;
+ ether_addr_copy(hdr->addr1, rtwvif_link->bssid);
+ ether_addr_copy(hdr->addr2, rtwvif_link->mac_addr);
+ ether_addr_copy(hdr->addr3, rtwvif_link->bssid);
+
+ skb_put_zero(skb, sec_hdr_len);
+
+ arp_skb = skb_put_zero(skb, sizeof(*arp_skb));
+ memcpy(arp_skb->llc_hdr, rfc1042_header, sizeof(rfc1042_header));
+ arp_skb->llc_type = htons(ETH_P_ARP);
+
+ arp_hdr = &arp_skb->arp_hdr;
+ arp_hdr->ar_hrd = htons(ARPHRD_ETHER);
+ arp_hdr->ar_pro = htons(ETH_P_IP);
+ arp_hdr->ar_hln = ETH_ALEN;
+ arp_hdr->ar_pln = 4;
+ arp_hdr->ar_op = htons(ARPOP_REPLY);
+
+ ether_addr_copy(arp_skb->sender_hw, rtwvif_link->mac_addr);
+ arp_skb->sender_ip = rtwvif->ip_addr;
+
+ return skb;
+}
+
static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
enum rtw89_fw_pkt_ofld_type type,
u8 *id)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ int link_id = ieee80211_vif_is_mld(vif) ? rtwvif_link->link_id : -1;
struct rtw89_pktofld_info *info;
struct sk_buff *skb;
int ret;
@@ -2151,10 +2701,19 @@ static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev,
skb = ieee80211_proberesp_get(rtwdev->hw, vif);
break;
case RTW89_PKT_OFLD_TYPE_NULL_DATA:
- skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, false);
+ skb = ieee80211_nullfunc_get(rtwdev->hw, vif, link_id, false);
break;
case RTW89_PKT_OFLD_TYPE_QOS_NULL:
- skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, true);
+ skb = ieee80211_nullfunc_get(rtwdev->hw, vif, link_id, true);
+ break;
+ case RTW89_PKT_OFLD_TYPE_EAPOL_KEY:
+ skb = rtw89_eapol_get(rtwdev, rtwvif_link);
+ break;
+ case RTW89_PKT_OFLD_TYPE_SA_QUERY:
+ skb = rtw89_sa_query_get(rtwdev, rtwvif_link);
+ break;
+ case RTW89_PKT_OFLD_TYPE_ARP_RSP:
+ skb = rtw89_arp_response_get(rtwdev, rtwvif_link);
break;
default:
goto err;
@@ -2169,7 +2728,7 @@ static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev,
if (ret)
goto err;
- list_add_tail(&info->list, &rtwvif->general_pkt_list);
+ list_add_tail(&info->list, &rtwvif_link->general_pkt_list);
*id = info->id;
return 0;
@@ -2179,9 +2738,10 @@ err:
}
void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool notify_fw)
+ struct rtw89_vif_link *rtwvif_link,
+ bool notify_fw)
{
- struct list_head *pkt_list = &rtwvif->general_pkt_list;
+ struct list_head *pkt_list = &rtwvif_link->general_pkt_list;
struct rtw89_pktofld_info *info, *tmp;
list_for_each_entry_safe(info, tmp, pkt_list, list) {
@@ -2196,16 +2756,20 @@ void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev,
void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, notify_fw);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif_link,
+ notify_fw);
}
#define H2C_GENERAL_PKT_LEN 6
#define H2C_GENERAL_PKT_ID_UND 0xff
int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, u8 macid)
+ struct rtw89_vif_link *rtwvif_link, u8 macid)
{
u8 pkt_id_ps_poll = H2C_GENERAL_PKT_ID_UND;
u8 pkt_id_null = H2C_GENERAL_PKT_ID_UND;
@@ -2213,11 +2777,11 @@ int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev,
struct sk_buff *skb;
int ret;
- rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
+ rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
RTW89_PKT_OFLD_TYPE_PS_POLL, &pkt_id_ps_poll);
- rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
+ rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id_null);
- rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
+ rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
RTW89_PKT_OFLD_TYPE_QOS_NULL, &pkt_id_qos_null);
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN);
@@ -2280,7 +2844,7 @@ int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
H2C_CL_MAC_PS,
- H2C_FUNC_MAC_LPS_PARM, 0, 1,
+ H2C_FUNC_MAC_LPS_PARM, 0, !lps_param->psmode,
H2C_LPS_PARM_LEN);
ret = rtw89_h2c_tx(rtwdev, skb, false);
@@ -2298,12 +2862,16 @@ fail:
int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->sub_entity_idx);
const struct rtw89_chip_info *chip = rtwdev->chip;
+ const struct rtw89_chan *chan;
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_h2c_lps_ch_info *h2c;
u32 len = sizeof(*h2c);
+ unsigned int link_id;
struct sk_buff *skb;
+ bool no_chan = true;
+ u8 phy_idx;
+ u32 done;
int ret;
if (chip->chip_gen != RTW89_CHIP_BE)
@@ -2317,22 +2885,141 @@ int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
skb_put(skb, len);
h2c = (struct rtw89_h2c_lps_ch_info *)skb->data;
- h2c->info[0].central_ch = chan->channel;
- h2c->info[0].pri_ch = chan->primary_channel;
- h2c->info[0].band = chan->band_type;
- h2c->info[0].bw = chan->band_width;
- h2c->mlo_dbcc_mode_lps = cpu_to_le32(MLO_2_PLUS_0_1RF);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ phy_idx = rtwvif_link->phy_idx;
+ if (phy_idx >= ARRAY_SIZE(h2c->info))
+ continue;
+
+ chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
+ no_chan = false;
+
+ h2c->info[phy_idx].central_ch = chan->channel;
+ h2c->info[phy_idx].pri_ch = chan->primary_channel;
+ h2c->info[phy_idx].band = chan->band_type;
+ h2c->info[phy_idx].bw = chan->band_width;
+ }
+
+ if (no_chan) {
+ rtw89_err(rtwdev, "no chan for h2c lps_ch_info\n");
+ ret = -ENOENT;
+ goto fail;
+ }
+
+ h2c->mlo_dbcc_mode_lps = cpu_to_le32(rtwdev->mlo_dbcc_mode);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM,
H2C_FUNC_FW_LPS_CH_INFO, 0, 0, len);
+ rtw89_phy_write32_mask(rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT, 0);
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ ret = read_poll_timeout(rtw89_phy_read32_mask, done, done, 50, 5000,
+ true, rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT);
+ if (ret)
+ rtw89_warn(rtwdev, "h2c_lps_ch_info done polling timeout\n");
+
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
+int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev,
+ struct rtw89_vif *rtwvif)
+{
+ const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be;
+ struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.cur_pkt_stat;
+ static const u8 bcn_bw_ofst[] = {0, 0, 0, 3, 6, 9, 0, 12};
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct rtw89_efuse *efuse = &rtwdev->efuse;
+ struct rtw89_h2c_lps_ml_cmn_info *h2c;
+ struct rtw89_vif_link *rtwvif_link;
+ const struct rtw89_chan *chan;
+ u8 bw_idx = RTW89_BB_BW_20_40;
+ u32 len = sizeof(*h2c);
+ unsigned int link_id;
+ struct sk_buff *skb;
+ u8 beacon_bw_ofst;
+ u8 gain_band;
+ u32 done;
+ u8 path;
+ int ret;
+ int i;
+
+ if (chip->chip_gen != RTW89_CHIP_BE)
+ return 0;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for h2c lps_ml_cmn_info\n");
+ return -ENOMEM;
+ }
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_lps_ml_cmn_info *)skb->data;
+
+ h2c->fmt_id = 0x3;
+
+ h2c->mlo_dbcc_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
+ h2c->rfe_type = efuse->rfe_type;
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ path = rtwvif_link->phy_idx == RTW89_PHY_1 ? RF_PATH_B : RF_PATH_A;
+ chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
+ gain_band = rtw89_subband_to_gain_band_be(chan->subband_type);
+
+ h2c->central_ch[rtwvif_link->phy_idx] = chan->channel;
+ h2c->pri_ch[rtwvif_link->phy_idx] = chan->primary_channel;
+ h2c->band[rtwvif_link->phy_idx] = chan->band_type;
+ h2c->bw[rtwvif_link->phy_idx] = chan->band_width;
+ if (pkt_stat->beacon_rate < RTW89_HW_RATE_OFDM6)
+ h2c->bcn_rate_type[rtwvif_link->phy_idx] = 0x1;
+ else
+ h2c->bcn_rate_type[rtwvif_link->phy_idx] = 0x2;
+
+ /* Fill BW20 RX gain table for beacon mode */
+ for (i = 0; i < TIA_GAIN_NUM; i++) {
+ h2c->tia_gain[rtwvif_link->phy_idx][i] =
+ cpu_to_le16(gain->tia_gain[gain_band][bw_idx][path][i]);
+ }
+
+ if (rtwvif_link->bcn_bw_idx < ARRAY_SIZE(bcn_bw_ofst)) {
+ beacon_bw_ofst = bcn_bw_ofst[rtwvif_link->bcn_bw_idx];
+ h2c->dup_bcn_ofst[rtwvif_link->phy_idx] = beacon_bw_ofst;
+ }
+
+ memcpy(h2c->lna_gain[rtwvif_link->phy_idx],
+ gain->lna_gain[gain_band][bw_idx][path],
+ LNA_GAIN_NUM);
+ memcpy(h2c->tia_lna_op1db[rtwvif_link->phy_idx],
+ gain->tia_lna_op1db[gain_band][bw_idx][path],
+ LNA_GAIN_NUM + 1);
+ memcpy(h2c->lna_op1db[rtwvif_link->phy_idx],
+ gain->lna_op1db[gain_band][bw_idx][path],
+ LNA_GAIN_NUM);
+ }
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM,
+ H2C_FUNC_FW_LPS_ML_CMN_INFO, 0, 0, len);
+
+ rtw89_phy_write32_mask(rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT, 0);
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
rtw89_err(rtwdev, "failed to send h2c\n");
goto fail;
}
+ ret = read_poll_timeout(rtw89_phy_read32_mask, done, done, 50, 5000,
+ true, rtwdev, R_CHK_LPS_STAT, B_CHK_LPS_STAT);
+ if (ret)
+ rtw89_warn(rtwdev, "h2c_lps_ml_cmn_info done polling timeout\n");
+
return 0;
fail:
dev_kfree_skb_any(skb);
@@ -2341,13 +3028,14 @@ fail:
}
#define H2C_P2P_ACT_LEN 20
-int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf,
struct ieee80211_p2p_noa_desc *desc,
u8 act, u8 noa_id)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- bool p2p_type_gc = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
- u8 ctwindow_oppps = vif->bss_conf.p2p_noa_attr.oppps_ctwindow;
+ bool p2p_type_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
+ u8 ctwindow_oppps = bss_conf->p2p_noa_attr.oppps_ctwindow;
struct sk_buff *skb;
u8 *cmd;
int ret;
@@ -2360,7 +3048,7 @@ int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
skb_put(skb, H2C_P2P_ACT_LEN);
cmd = skb->data;
- RTW89_SET_FWCMD_P2P_MACID(cmd, rtwvif->mac_id);
+ RTW89_SET_FWCMD_P2P_MACID(cmd, rtwvif_link->mac_id);
RTW89_SET_FWCMD_P2P_P2PID(cmd, 0);
RTW89_SET_FWCMD_P2P_NOAID(cmd, noa_id);
RTW89_SET_FWCMD_P2P_ACT(cmd, act);
@@ -2404,8 +3092,8 @@ static void __rtw89_fw_h2c_set_tx_path(struct rtw89_dev *rtwdev,
ntx_path = RF_A;
map_b = 0;
} else {
- ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_B;
- map_b = hal->antenna_tx == RF_AB ? 1 : 0;
+ ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_AB;
+ map_b = ntx_path == RF_AB ? 1 : 0;
}
SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path);
@@ -2417,11 +3105,11 @@ static void __rtw89_fw_h2c_set_tx_path(struct rtw89_dev *rtwdev,
#define H2C_CMC_TBL_LEN 68
int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- u8 macid = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
+ u8 macid = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
struct sk_buff *skb;
int ret;
@@ -2443,7 +3131,7 @@ int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
}
SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0);
SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0);
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
SET_CMC_TBL_DATA_DCM(skb->data, 0);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
@@ -2466,10 +3154,10 @@ fail:
EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl);
int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
+ u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
@@ -2550,24 +3238,25 @@ fail:
EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl_g7);
static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta, u8 *pads)
+ struct ieee80211_link_sta *link_sta,
+ u8 *pads)
{
bool ppe_th;
u8 ppe16, ppe8;
- u8 nss = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1;
- u8 ppe_thres_hdr = sta->deflink.he_cap.ppe_thres[0];
+ u8 nss = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1;
+ u8 ppe_thres_hdr = link_sta->he_cap.ppe_thres[0];
u8 ru_bitmap;
u8 n, idx, sh;
u16 ppe;
int i;
ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
- sta->deflink.he_cap.he_cap_elem.phy_cap_info[6]);
+ link_sta->he_cap.he_cap_elem.phy_cap_info[6]);
if (!ppe_th) {
u8 pad;
pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK,
- sta->deflink.he_cap.he_cap_elem.phy_cap_info[9]);
+ link_sta->he_cap.he_cap_elem.phy_cap_info[9]);
for (i = 0; i < RTW89_PPE_BW_NUM; i++)
pads[i] = pad;
@@ -2589,38 +3278,50 @@ static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev,
sh = n & 7;
n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2;
- ppe = le16_to_cpu(*((__le16 *)&sta->deflink.he_cap.ppe_thres[idx]));
+ ppe = le16_to_cpu(*((__le16 *)&link_sta->he_cap.ppe_thres[idx]));
ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
if (ppe16 != 7 && ppe8 == 7)
- pads[i] = 2;
+ pads[i] = RTW89_PE_DURATION_16;
else if (ppe8 != 7)
- pads[i] = 1;
+ pads[i] = RTW89_PE_DURATION_8;
else
- pads[i] = 0;
+ pads[i] = RTW89_PE_DURATION_0;
}
}
int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
const struct rtw89_chip_info *chip = rtwdev->chip;
- struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->sub_entity_idx);
+ rtwvif_link->chanctx_idx);
+ struct ieee80211_link_sta *link_sta;
struct sk_buff *skb;
u8 pads[RTW89_PPE_BW_NUM];
- u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
+ u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
u16 lowest_rate;
int ret;
memset(pads, 0, sizeof(pads));
- if (sta && sta->deflink.he_cap.has_he)
- __get_sta_he_pkt_padding(rtwdev, sta, pads);
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
+ return -ENOMEM;
+ }
+
+ rcu_read_lock();
+
+ if (rtwsta_link)
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+
+ if (rtwsta_link && link_sta->he_cap.has_he)
+ __get_sta_he_pkt_padding(rtwdev, link_sta, pads);
if (vif->p2p)
lowest_rate = RTW89_HW_RATE_OFDM6;
@@ -2629,11 +3330,6 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
else
lowest_rate = RTW89_HW_RATE_OFDM6;
- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CMC_TBL_LEN);
- if (!skb) {
- rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
- return -ENOMEM;
- }
skb_put(skb, H2C_CMC_TBL_LEN);
SET_CTRL_INFO_MACID(skb->data, mac_id);
SET_CTRL_INFO_OPERATION(skb->data, 1);
@@ -2646,7 +3342,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
SET_CMC_TBL_ULDL(skb->data, 1);
else
SET_CMC_TBL_ULDL(skb->data, 0);
- SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif->port);
+ SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif_link->port);
if (chip->h2c_cctl_func_id == H2C_FUNC_MAC_CCTLINFO_UD_V1) {
SET_CMC_TBL_NOMINAL_PKT_PADDING_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_20]);
SET_CMC_TBL_NOMINAL_PKT_PADDING40_V1(skb->data, pads[RTW89_CHANNEL_WIDTH_40]);
@@ -2658,12 +3354,14 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]);
SET_CMC_TBL_NOMINAL_PKT_PADDING160(skb->data, pads[RTW89_CHANNEL_WIDTH_160]);
}
- if (sta)
+ if (rtwsta_link)
SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data,
- sta->deflink.he_cap.has_he);
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
+ link_sta->he_cap.has_he);
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
SET_CMC_TBL_DATA_DCM(skb->data, 0);
+ rcu_read_unlock();
+
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
chip->h2c_cctl_func_id, 0, 1,
@@ -2684,9 +3382,10 @@ fail:
EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl);
static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta, u8 *pads)
+ struct ieee80211_link_sta *link_sta,
+ u8 *pads)
{
- u8 nss = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1;
+ u8 nss = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1;
u16 ppe_thres_hdr;
u8 ppe16, ppe8;
u8 n, idx, sh;
@@ -2695,12 +3394,12 @@ static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev,
u16 ppe;
int i;
- ppe_th = !!u8_get_bits(sta->deflink.eht_cap.eht_cap_elem.phy_cap_info[5],
+ ppe_th = !!u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5],
IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT);
if (!ppe_th) {
u8 pad;
- pad = u8_get_bits(sta->deflink.eht_cap.eht_cap_elem.phy_cap_info[5],
+ pad = u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5],
IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK);
for (i = 0; i < RTW89_PPE_BW_NUM; i++)
@@ -2709,7 +3408,7 @@ static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev,
return;
}
- ppe_thres_hdr = get_unaligned_le16(sta->deflink.eht_cap.eht_ppe_thres);
+ ppe_thres_hdr = get_unaligned_le16(link_sta->eht_cap.eht_ppe_thres);
ru_bitmap = u16_get_bits(ppe_thres_hdr,
IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK);
n = hweight8(ru_bitmap);
@@ -2726,29 +3425,30 @@ static void __get_sta_eht_pkt_padding(struct rtw89_dev *rtwdev,
sh = n & 7;
n += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2;
- ppe = get_unaligned_le16(sta->deflink.eht_cap.eht_ppe_thres + idx);
+ ppe = get_unaligned_le16(link_sta->eht_cap.eht_ppe_thres + idx);
ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
sh += IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE;
ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK;
if (ppe16 != 7 && ppe8 == 7)
- pads[i] = 2;
+ pads[i] = RTW89_PE_DURATION_16_20;
else if (ppe8 != 7)
- pads[i] = 1;
+ pads[i] = RTW89_PE_DURATION_8;
else
- pads[i] = 0;
+ pads[i] = RTW89_PE_DURATION_0;
}
}
int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
- u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
+ u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
+ struct ieee80211_bss_conf *bss_conf;
+ struct ieee80211_link_sta *link_sta;
u8 pads[RTW89_PPE_BW_NUM];
u32 len = sizeof(*h2c);
struct sk_buff *skb;
@@ -2756,11 +3456,24 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
int ret;
memset(pads, 0, sizeof(pads));
- if (sta) {
- if (sta->deflink.eht_cap.has_eht)
- __get_sta_eht_pkt_padding(rtwdev, sta, pads);
- else if (sta->deflink.he_cap.has_he)
- __get_sta_he_pkt_padding(rtwdev, sta, pads);
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n");
+ return -ENOMEM;
+ }
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
+ if (rtwsta_link) {
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+
+ if (link_sta->eht_cap.has_eht)
+ __get_sta_eht_pkt_padding(rtwdev, link_sta, pads);
+ else if (link_sta->he_cap.has_he)
+ __get_sta_he_pkt_padding(rtwdev, link_sta, pads);
}
if (vif->p2p)
@@ -2770,11 +3483,6 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
else
lowest_rate = RTW89_HW_RATE_OFDM6;
- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
- if (!skb) {
- rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n");
- return -ENOMEM;
- }
skb_put(skb, len);
h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
@@ -2795,16 +3503,16 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
h2c->w3 = le32_encode_bits(0, CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL);
h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_RTS_TXCNT_LMT_SEL);
- h2c->w4 = le32_encode_bits(rtwvif->port, CCTLINFO_G7_W4_MULTI_PORT_ID);
+ h2c->w4 = le32_encode_bits(rtwvif_link->port, CCTLINFO_G7_W4_MULTI_PORT_ID);
h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_MULTI_PORT_ID);
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) {
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) {
h2c->w4 |= le32_encode_bits(0, CCTLINFO_G7_W4_DATA_DCM);
h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_DATA_DCM);
}
- if (vif->bss_conf.eht_support) {
- u16 punct = vif->bss_conf.chanreq.oper.punctured;
+ if (bss_conf->eht_support) {
+ u16 punct = bss_conf->chanreq.oper.punctured;
h2c->w4 |= le32_encode_bits(~punct,
CCTLINFO_G7_W4_ACT_SUBCH_CBW);
@@ -2827,16 +3535,19 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3 |
CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4);
- h2c->w6 = le32_encode_bits(vif->type == NL80211_IFTYPE_STATION ? 1 : 0,
+ h2c->w6 = le32_encode_bits(vif->cfg.aid, CCTLINFO_G7_W6_AID12_PAID) |
+ le32_encode_bits(vif->type == NL80211_IFTYPE_STATION ? 1 : 0,
CCTLINFO_G7_W6_ULDL);
- h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_ULDL);
+ h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_AID12_PAID | CCTLINFO_G7_W6_ULDL);
- if (sta) {
- h2c->w8 = le32_encode_bits(sta->deflink.he_cap.has_he,
+ if (rtwsta_link) {
+ h2c->w8 = le32_encode_bits(link_sta->he_cap.has_he,
CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT);
h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT);
}
+ rcu_read_unlock();
+
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1,
@@ -2857,10 +3568,10 @@ fail:
EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl_g7);
int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = rtwsta_link->rtwsta;
struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
@@ -2897,7 +3608,7 @@ int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev,
else if (agg_num > 0x200 && agg_num <= 0x400)
ba_bmap = 5;
- h2c->c0 = le32_encode_bits(rtwsta->mac_id, CCTLINFO_G7_C0_MACID) |
+ h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, CCTLINFO_G7_C0_MACID) |
le32_encode_bits(1, CCTLINFO_G7_C0_OP);
h2c->w3 = le32_encode_bits(ba_bmap, CCTLINFO_G7_W3_BA_BMAP);
@@ -2923,7 +3634,7 @@ fail:
EXPORT_SYMBOL(rtw89_fw_h2c_ampdu_cmac_tbl_g7);
int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta)
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct sk_buff *skb;
@@ -2935,15 +3646,15 @@ int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
return -ENOMEM;
}
skb_put(skb, H2C_CMC_TBL_LEN);
- SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id);
+ SET_CTRL_INFO_MACID(skb->data, rtwsta_link->mac_id);
SET_CTRL_INFO_OPERATION(skb->data, 1);
- if (rtwsta->cctl_tx_time) {
+ if (rtwsta_link->cctl_tx_time) {
SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1);
- SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta->ampdu_max_time);
+ SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta_link->ampdu_max_time);
}
- if (rtwsta->cctl_tx_retry_limit) {
+ if (rtwsta_link->cctl_tx_retry_limit) {
SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1);
- SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta->data_tx_cnt_lmt);
+ SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta_link->data_tx_cnt_lmt);
}
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
@@ -2963,9 +3674,64 @@ fail:
return ret;
}
+EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl);
+
+int rtw89_fw_h2c_txtime_cmac_tbl_g7(struct rtw89_dev *rtwdev,
+ struct rtw89_sta_link *rtwsta_link)
+{
+ struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ int ret;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for txtime_cmac_g7\n");
+ return -ENOMEM;
+ }
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
+
+ h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, CCTLINFO_G7_C0_MACID) |
+ le32_encode_bits(1, CCTLINFO_G7_C0_OP);
+
+ if (rtwsta_link->cctl_tx_time) {
+ h2c->w3 |= le32_encode_bits(1, CCTLINFO_G7_W3_AMPDU_TIME_SEL);
+ h2c->m3 |= cpu_to_le32(CCTLINFO_G7_W3_AMPDU_TIME_SEL);
+
+ h2c->w2 |= le32_encode_bits(rtwsta_link->ampdu_max_time,
+ CCTLINFO_G7_W2_AMPDU_MAX_TIME);
+ h2c->m2 |= cpu_to_le32(CCTLINFO_G7_W2_AMPDU_MAX_TIME);
+ }
+ if (rtwsta_link->cctl_tx_retry_limit) {
+ h2c->w2 |= le32_encode_bits(1, CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL) |
+ le32_encode_bits(rtwsta_link->data_tx_cnt_lmt,
+ CCTLINFO_G7_W2_DATA_TX_CNT_LMT);
+ h2c->m2 |= cpu_to_le32(CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL |
+ CCTLINFO_G7_W2_DATA_TX_CNT_LMT);
+ }
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
+ H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1,
+ len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl_g7);
int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta)
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct sk_buff *skb;
@@ -2980,7 +3746,7 @@ int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
return -ENOMEM;
}
skb_put(skb, H2C_CMC_TBL_LEN);
- SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id);
+ SET_CTRL_INFO_MACID(skb->data, rtwsta_link->mac_id);
SET_CTRL_INFO_OPERATION(skb->data, 1);
__rtw89_fw_h2c_set_tx_path(rtwdev, skb);
@@ -3004,11 +3770,11 @@ fail:
}
int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->sub_entity_idx);
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ rtwvif_link->chanctx_idx);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
struct rtw89_h2c_bcn_upd *h2c;
struct sk_buff *skb_beacon;
struct ieee80211_hdr *hdr;
@@ -3035,7 +3801,7 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
return -ENOMEM;
}
- noa_len = rtw89_p2p_noa_fetch(rtwvif, &noa_data);
+ noa_len = rtw89_p2p_noa_fetch(rtwvif_link, &noa_data);
if (noa_len &&
(noa_len <= skb_tailroom(skb_beacon) ||
pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) {
@@ -3055,11 +3821,11 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
skb_put(skb, len);
h2c = (struct rtw89_h2c_bcn_upd *)skb->data;
- h2c->w0 = le32_encode_bits(rtwvif->port, RTW89_H2C_BCN_UPD_W0_PORT) |
+ h2c->w0 = le32_encode_bits(rtwvif_link->port, RTW89_H2C_BCN_UPD_W0_PORT) |
le32_encode_bits(0, RTW89_H2C_BCN_UPD_W0_MBSSID) |
- le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_BCN_UPD_W0_BAND) |
+ le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_BCN_UPD_W0_BAND) |
le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_W0_GRP_IE_OFST);
- h2c->w1 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_BCN_UPD_W1_MACID) |
+ h2c->w1 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCN_UPD_W1_MACID) |
le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_W1_SSN_SEL) |
le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_W1_SSN_MODE) |
le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_W1_RATE);
@@ -3084,10 +3850,10 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon);
int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
struct rtw89_h2c_bcn_upd_be *h2c;
struct sk_buff *skb_beacon;
struct ieee80211_hdr *hdr;
@@ -3114,7 +3880,7 @@ int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev,
return -ENOMEM;
}
- noa_len = rtw89_p2p_noa_fetch(rtwvif, &noa_data);
+ noa_len = rtw89_p2p_noa_fetch(rtwvif_link, &noa_data);
if (noa_len &&
(noa_len <= skb_tailroom(skb_beacon) ||
pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) {
@@ -3134,11 +3900,11 @@ int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev,
skb_put(skb, len);
h2c = (struct rtw89_h2c_bcn_upd_be *)skb->data;
- h2c->w0 = le32_encode_bits(rtwvif->port, RTW89_H2C_BCN_UPD_BE_W0_PORT) |
+ h2c->w0 = le32_encode_bits(rtwvif_link->port, RTW89_H2C_BCN_UPD_BE_W0_PORT) |
le32_encode_bits(0, RTW89_H2C_BCN_UPD_BE_W0_MBSSID) |
- le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_BCN_UPD_BE_W0_BAND) |
+ le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_BCN_UPD_BE_W0_BAND) |
le32_encode_bits(tim_offset | BIT(7), RTW89_H2C_BCN_UPD_BE_W0_GRP_IE_OFST);
- h2c->w1 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_BCN_UPD_BE_W1_MACID) |
+ h2c->w1 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCN_UPD_BE_W1_MACID) |
le32_encode_bits(RTW89_MGMT_HW_SSN_SEL, RTW89_H2C_BCN_UPD_BE_W1_SSN_SEL) |
le32_encode_bits(RTW89_MGMT_HW_SEQ_MODE, RTW89_H2C_BCN_UPD_BE_W1_SSN_MODE) |
le32_encode_bits(beacon_rate, RTW89_H2C_BCN_UPD_BE_W1_RATE);
@@ -3166,41 +3932,48 @@ fail:
}
EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon_be);
-#define H2C_ROLE_MAINTAIN_LEN 4
int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
enum rtw89_upd_mode upd_mode)
{
+ u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
+ struct rtw89_h2c_role_maintain *h2c;
+ u32 len = sizeof(*h2c);
struct sk_buff *skb;
- u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
u8 self_role;
int ret;
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) {
- if (rtwsta)
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) {
+ if (rtwsta_link)
self_role = RTW89_SELF_ROLE_AP_CLIENT;
else
- self_role = rtwvif->self_role;
+ self_role = rtwvif_link->self_role;
} else {
- self_role = rtwvif->self_role;
+ self_role = rtwvif_link->self_role;
}
- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ROLE_MAINTAIN_LEN);
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
return -ENOMEM;
}
- skb_put(skb, H2C_ROLE_MAINTAIN_LEN);
- SET_FWROLE_MAINTAIN_MACID(skb->data, mac_id);
- SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, self_role);
- SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode);
- SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif->wifi_role);
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_role_maintain *)skb->data;
+
+ h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_ROLE_MAINTAIN_W0_MACID) |
+ le32_encode_bits(self_role, RTW89_H2C_ROLE_MAINTAIN_W0_SELF_ROLE) |
+ le32_encode_bits(upd_mode, RTW89_H2C_ROLE_MAINTAIN_W0_UPD_MODE) |
+ le32_encode_bits(rtwvif_link->wifi_role,
+ RTW89_H2C_ROLE_MAINTAIN_W0_WIFI_ROLE) |
+ le32_encode_bits(rtwvif_link->mac_idx,
+ RTW89_H2C_ROLE_MAINTAIN_W0_BAND) |
+ le32_encode_bits(rtwvif_link->port, RTW89_H2C_ROLE_MAINTAIN_W0_PORT);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1,
- H2C_ROLE_MAINTAIN_LEN);
+ len);
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
@@ -3216,43 +3989,61 @@ fail:
}
static enum rtw89_fw_sta_type
-rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta);
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_bss_conf *bss_conf;
+ struct ieee80211_link_sta *link_sta;
+ enum rtw89_fw_sta_type type;
+
+ rcu_read_lock();
- if (!sta)
+ if (!rtwsta_link)
goto by_vif;
- if (sta->deflink.eht_cap.has_eht)
- return RTW89_FW_BE_STA;
- else if (sta->deflink.he_cap.has_he)
- return RTW89_FW_AX_STA;
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+
+ if (link_sta->eht_cap.has_eht)
+ type = RTW89_FW_BE_STA;
+ else if (link_sta->he_cap.has_he)
+ type = RTW89_FW_AX_STA;
else
- return RTW89_FW_N_AC_STA;
+ type = RTW89_FW_N_AC_STA;
+
+ goto out;
by_vif:
- if (vif->bss_conf.eht_support)
- return RTW89_FW_BE_STA;
- else if (vif->bss_conf.he_support)
- return RTW89_FW_AX_STA;
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
+ if (bss_conf->eht_support)
+ type = RTW89_FW_BE_STA;
+ else if (bss_conf->he_support)
+ type = RTW89_FW_AX_STA;
else
- return RTW89_FW_N_AC_STA;
+ type = RTW89_FW_N_AC_STA;
+
+out:
+ rcu_read_unlock();
+
+ return type;
}
-int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta, bool dis_conn)
+int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link, bool dis_conn)
{
- struct sk_buff *skb;
- u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
- u8 self_role = rtwvif->self_role;
+ u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ bool is_mld = ieee80211_vif_is_mld(vif);
+ u8 self_role = rtwvif_link->self_role;
enum rtw89_fw_sta_type sta_type;
- u8 net_type = rtwvif->net_type;
+ u8 net_type = rtwvif_link->net_type;
struct rtw89_h2c_join_v1 *h2c_v1;
struct rtw89_h2c_join *h2c;
u32 len = sizeof(*h2c);
bool format_v1 = false;
+ struct sk_buff *skb;
+ u8 main_mac_id;
+ bool init_ps;
int ret;
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
@@ -3260,7 +4051,7 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
format_v1 = true;
}
- if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta) {
+ if (net_type == RTW89_NET_TYPE_AP_MODE && rtwsta_link) {
self_role = RTW89_SELF_ROLE_AP_CLIENT;
net_type = dis_conn ? RTW89_NET_TYPE_NO_LINK : net_type;
}
@@ -3275,16 +4066,17 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_JOININFO_W0_MACID) |
le32_encode_bits(dis_conn, RTW89_H2C_JOININFO_W0_OP) |
- le32_encode_bits(rtwvif->mac_idx, RTW89_H2C_JOININFO_W0_BAND) |
- le32_encode_bits(rtwvif->wmm, RTW89_H2C_JOININFO_W0_WMM) |
- le32_encode_bits(rtwvif->trigger, RTW89_H2C_JOININFO_W0_TGR) |
+ le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_JOININFO_W0_BAND) |
+ le32_encode_bits(rtwvif_link->wmm, RTW89_H2C_JOININFO_W0_WMM) |
+ le32_encode_bits(rtwvif_link->trigger, RTW89_H2C_JOININFO_W0_TGR) |
le32_encode_bits(0, RTW89_H2C_JOININFO_W0_ISHESTA) |
le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DLBW) |
le32_encode_bits(0, RTW89_H2C_JOININFO_W0_TF_MAC_PAD) |
le32_encode_bits(0, RTW89_H2C_JOININFO_W0_DL_T_PE) |
- le32_encode_bits(rtwvif->port, RTW89_H2C_JOININFO_W0_PORT_ID) |
+ le32_encode_bits(rtwvif_link->port, RTW89_H2C_JOININFO_W0_PORT_ID) |
le32_encode_bits(net_type, RTW89_H2C_JOININFO_W0_NET_TYPE) |
- le32_encode_bits(rtwvif->wifi_role, RTW89_H2C_JOININFO_W0_WIFI_ROLE) |
+ le32_encode_bits(rtwvif_link->wifi_role,
+ RTW89_H2C_JOININFO_W0_WIFI_ROLE) |
le32_encode_bits(self_role, RTW89_H2C_JOININFO_W0_SELF_ROLE);
if (!format_v1)
@@ -3292,9 +4084,29 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
h2c_v1 = (struct rtw89_h2c_join_v1 *)skb->data;
- sta_type = rtw89_fw_get_sta_type(rtwdev, rtwvif, rtwsta);
+ sta_type = rtw89_fw_get_sta_type(rtwdev, rtwvif_link, rtwsta_link);
+ init_ps = rtwvif_link != rtw89_get_designated_link(rtwvif_link->rtwvif);
+
+ if (rtwsta_link)
+ main_mac_id = rtw89_sta_get_main_macid(rtwsta_link->rtwsta);
+ else
+ main_mac_id = rtw89_vif_get_main_macid(rtwvif_link->rtwvif);
+
+ h2c_v1->w1 = le32_encode_bits(sta_type, RTW89_H2C_JOININFO_W1_STA_TYPE) |
+ le32_encode_bits(is_mld, RTW89_H2C_JOININFO_W1_IS_MLD) |
+ le32_encode_bits(main_mac_id, RTW89_H2C_JOININFO_W1_MAIN_MACID) |
+ le32_encode_bits(RTW89_H2C_JOININFO_MLO_MODE_MLSR,
+ RTW89_H2C_JOININFO_W1_MLO_MODE) |
+ le32_encode_bits(0, RTW89_H2C_JOININFO_W1_EMLSR_CAB) |
+ le32_encode_bits(0, RTW89_H2C_JOININFO_W1_NSTR_EN) |
+ le32_encode_bits(init_ps, RTW89_H2C_JOININFO_W1_INIT_PWR_STATE) |
+ le32_encode_bits(IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_256US,
+ RTW89_H2C_JOININFO_W1_EMLSR_PADDING) |
+ le32_encode_bits(IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_256US,
+ RTW89_H2C_JOININFO_W1_EMLSR_TRANS_DELAY) |
+ le32_encode_bits(0, RTW89_H2C_JOININFO_W2_MACID_EXT) |
+ le32_encode_bits(0, RTW89_H2C_JOININFO_W2_MAIN_MACID_EXT);
- h2c_v1->w1 = le32_encode_bits(sta_type, RTW89_H2C_JOININFO_W1_STA_TYPE);
h2c_v1->w2 = 0;
done:
@@ -3413,7 +4225,7 @@ fail:
}
#define H2C_EDCA_LEN 12
-int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u8 ac, u32 val)
{
struct sk_buff *skb;
@@ -3426,7 +4238,7 @@ int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
}
skb_put(skb, H2C_EDCA_LEN);
RTW89_SET_EDCA_SEL(skb->data, 0);
- RTW89_SET_EDCA_BAND(skb->data, rtwvif->mac_idx);
+ RTW89_SET_EDCA_BAND(skb->data, rtwvif_link->mac_idx);
RTW89_SET_EDCA_WMM(skb->data, 0);
RTW89_SET_EDCA_AC(skb->data, ac);
RTW89_SET_EDCA_PARAM(skb->data, val);
@@ -3450,7 +4262,8 @@ fail:
}
#define H2C_TSF32_TOGL_LEN 4
-int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool en)
{
struct sk_buff *skb;
@@ -3466,9 +4279,9 @@ int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif
skb_put(skb, H2C_TSF32_TOGL_LEN);
cmd = skb->data;
- RTW89_SET_FWCMD_TSF32_TOGL_BAND(cmd, rtwvif->mac_idx);
+ RTW89_SET_FWCMD_TSF32_TOGL_BAND(cmd, rtwvif_link->mac_idx);
RTW89_SET_FWCMD_TSF32_TOGL_EN(cmd, en);
- RTW89_SET_FWCMD_TSF32_TOGL_PORT(cmd, rtwvif->port);
+ RTW89_SET_FWCMD_TSF32_TOGL_PORT(cmd, rtwvif_link->port);
RTW89_SET_FWCMD_TSF32_TOGL_EARLY(cmd, early_us);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
@@ -3521,25 +4334,82 @@ fail:
return ret;
}
+int rtw89_fw_h2c_tx_duty(struct rtw89_dev *rtwdev, u8 lv)
+{
+ struct rtw89_h2c_tx_duty *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ u16 pause, active;
+ int ret;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for h2c tx duty\n");
+ return -ENOMEM;
+ }
+
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_tx_duty *)skb->data;
+
+ static_assert(RTW89_THERMAL_PROT_LV_MAX * RTW89_THERMAL_PROT_STEP < 100);
+
+ if (lv == 0 || lv > RTW89_THERMAL_PROT_LV_MAX) {
+ h2c->w1 = le32_encode_bits(1, RTW89_H2C_TX_DUTY_W1_STOP);
+ } else {
+ active = 100 - lv * RTW89_THERMAL_PROT_STEP;
+ pause = 100 - active;
+
+ h2c->w0 = le32_encode_bits(pause, RTW89_H2C_TX_DUTY_W0_PAUSE_INTVL_MASK) |
+ le32_encode_bits(active, RTW89_H2C_TX_DUTY_W0_TX_INTVL_MASK);
+ }
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
+ H2C_FUNC_TX_DUTY, 0, 0, len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
+ struct rtw89_vif_link *rtwvif_link,
bool connect)
{
- struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
- struct ieee80211_bss_conf *bss_conf = vif ? &vif->bss_conf : NULL;
+ struct ieee80211_bss_conf *bss_conf;
s32 thold = RTW89_DEFAULT_CQM_THOLD;
u32 hyst = RTW89_DEFAULT_CQM_HYST;
struct rtw89_h2c_bcnfltr *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
+ u8 max_cnt, cnt;
int ret;
if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw))
return -EINVAL;
- if (!rtwvif || !bss_conf || rtwvif->net_type != RTW89_NET_TYPE_INFRA)
+ if (!rtwvif_link || rtwvif_link->net_type != RTW89_NET_TYPE_INFRA)
return -EINVAL;
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+
+ if (bss_conf->cqm_rssi_hyst)
+ hyst = bss_conf->cqm_rssi_hyst;
+ if (bss_conf->cqm_rssi_thold)
+ thold = bss_conf->cqm_rssi_thold;
+
+ rcu_read_unlock();
+
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c bcn filter\n");
@@ -3549,21 +4419,24 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
skb_put(skb, len);
h2c = (struct rtw89_h2c_bcnfltr *)skb->data;
- if (bss_conf->cqm_rssi_hyst)
- hyst = bss_conf->cqm_rssi_hyst;
- if (bss_conf->cqm_rssi_thold)
- thold = bss_conf->cqm_rssi_thold;
+ if (RTW89_CHK_FW_FEATURE(BEACON_LOSS_COUNT_V1, &rtwdev->fw))
+ max_cnt = BIT(7) - 1;
+ else
+ max_cnt = BIT(4) - 1;
+
+ cnt = min(RTW89_BCN_LOSS_CNT, max_cnt);
h2c->w0 = le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_RSSI) |
le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_BCN) |
le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_EN) |
le32_encode_bits(RTW89_BCN_FLTR_OFFLOAD_MODE_DEFAULT,
RTW89_H2C_BCNFLTR_W0_MODE) |
- le32_encode_bits(RTW89_BCN_LOSS_CNT, RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT) |
+ le32_encode_bits(cnt >> 4, RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT_H3) |
+ le32_encode_bits(cnt & 0xf, RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT_L4) |
le32_encode_bits(hyst, RTW89_H2C_BCNFLTR_W0_RSSI_HYST) |
le32_encode_bits(thold + MAX_RSSI,
RTW89_H2C_BCNFLTR_W0_RSSI_THRESHOLD) |
- le32_encode_bits(rtwvif->mac_id, RTW89_H2C_BCNFLTR_W0_MAC_ID);
+ le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_BCNFLTR_W0_MAC_ID);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
@@ -3628,15 +4501,16 @@ fail:
return ret;
}
-int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_traffic_stats *stats = &rtwvif->stats;
struct rtw89_h2c_ofld *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
int ret;
- if (rtwvif->net_type != RTW89_NET_TYPE_INFRA)
+ if (rtwvif_link->net_type != RTW89_NET_TYPE_INFRA)
return -EINVAL;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
@@ -3648,7 +4522,7 @@ int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
skb_put(skb, len);
h2c = (struct rtw89_h2c_ofld *)skb->data;
- h2c->w0 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_OFLD_W0_MAC_ID) |
+ h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_OFLD_W0_MAC_ID) |
le32_encode_bits(stats->tx_throughput, RTW89_H2C_OFLD_W0_TX_TP) |
le32_encode_bits(stats->rx_throughput, RTW89_H2C_OFLD_W0_RX_TP);
@@ -4120,6 +4994,95 @@ fail:
return ret;
}
+int rtw89_fw_h2c_cxdrv_role_v7(struct rtw89_dev *rtwdev, u8 type)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_wl_role_info_v7 *role = &btc->cx.wl.role_info_v7;
+ struct rtw89_h2c_cxrole_v7 *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ int ret;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
+ return -ENOMEM;
+ }
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_cxrole_v7 *)skb->data;
+
+ h2c->hdr.type = type;
+ h2c->hdr.ver = btc->ver->fwlrole;
+ h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7;
+ memcpy(&h2c->_u8, role, sizeof(h2c->_u8));
+ h2c->_u32.role_map = cpu_to_le32(role->role_map);
+ h2c->_u32.mrole_type = cpu_to_le32(role->mrole_type);
+ h2c->_u32.mrole_noa_duration = cpu_to_le32(role->mrole_noa_duration);
+ h2c->_u32.dbcc_en = cpu_to_le32(role->dbcc_en);
+ h2c->_u32.dbcc_chg = cpu_to_le32(role->dbcc_chg);
+ h2c->_u32.dbcc_2g_phy = cpu_to_le32(role->dbcc_2g_phy);
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_OUTSRC, BTFC_SET,
+ SET_DRV_INFO, 0, 0,
+ len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
+int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_wl_role_info_v8 *role = &btc->cx.wl.role_info_v8;
+ struct rtw89_h2c_cxrole_v8 *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ int ret;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
+ return -ENOMEM;
+ }
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_cxrole_v8 *)skb->data;
+
+ h2c->hdr.type = type;
+ h2c->hdr.ver = btc->ver->fwlrole;
+ h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7;
+ memcpy(&h2c->_u8, role, sizeof(h2c->_u8));
+ h2c->_u32.role_map = cpu_to_le32(role->role_map);
+ h2c->_u32.mrole_type = cpu_to_le32(role->mrole_type);
+ h2c->_u32.mrole_noa_duration = cpu_to_le32(role->mrole_noa_duration);
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_OUTSRC, BTFC_SET,
+ SET_DRV_INFO, 0, 0,
+ len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
#define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR)
int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type)
{
@@ -4176,7 +5139,7 @@ int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type)
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
- rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
+ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl_v7\n");
return -ENOMEM;
}
skb_put(skb, len);
@@ -4394,12 +5357,13 @@ int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id,
return 0;
}
-int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int ch_num,
- struct list_head *chan_list)
+static
+int rtw89_fw_h2c_scan_list_offload_ax(struct rtw89_dev *rtwdev, int ch_num,
+ struct list_head *chan_list)
{
struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
struct rtw89_h2c_chinfo_elem *elem;
- struct rtw89_mac_chinfo *ch_info;
+ struct rtw89_mac_chinfo_ax *ch_info;
struct rtw89_h2c_chinfo *h2c;
struct sk_buff *skb;
unsigned int cond;
@@ -4465,19 +5429,22 @@ int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int ch_num,
return 0;
}
+static
int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
- struct list_head *chan_list)
+ struct list_head *chan_list,
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
struct rtw89_h2c_chinfo_elem_be *elem;
struct rtw89_mac_chinfo_be *ch_info;
- struct rtw89_h2c_chinfo *h2c;
+ struct rtw89_h2c_chinfo_be *h2c;
struct sk_buff *skb;
unsigned int cond;
+ u8 ver = U8_MAX;
int skb_len;
int ret;
- static_assert(sizeof(*elem) == RTW89_MAC_CHINFO_SIZE);
+ static_assert(sizeof(*elem) == RTW89_MAC_CHINFO_SIZE_BE);
skb_len = struct_size(h2c, elem, ch_num);
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, skb_len);
@@ -4486,18 +5453,21 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
return -ENOMEM;
}
+ if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw))
+ ver = 0;
+
skb_put(skb, sizeof(*h2c));
- h2c = (struct rtw89_h2c_chinfo *)skb->data;
+ h2c = (struct rtw89_h2c_chinfo_be *)skb->data;
h2c->ch_num = ch_num;
h2c->elem_size = sizeof(*elem) / 4; /* in unit of 4 bytes */
- h2c->arg = u8_encode_bits(RTW89_PHY_0, RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK);
+ h2c->arg = u8_encode_bits(rtwvif_link->mac_idx,
+ RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK);
list_for_each_entry(ch_info, chan_list, list) {
elem = (struct rtw89_h2c_chinfo_elem_be *)skb_put(skb, sizeof(*elem));
- elem->w0 = le32_encode_bits(ch_info->period, RTW89_H2C_CHINFO_BE_W0_PERIOD) |
- le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_BE_W0_DWELL) |
+ elem->w0 = le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_BE_W0_DWELL) |
le32_encode_bits(ch_info->central_ch,
RTW89_H2C_CHINFO_BE_W0_CENTER_CH) |
le32_encode_bits(ch_info->pri_ch, RTW89_H2C_CHINFO_BE_W0_PRI_CH);
@@ -4544,6 +5514,12 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_SHORTSSIDS) |
le32_encode_bits(ch_info->fw_probe0_bssids,
RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_BSSIDS);
+ if (ver == 0)
+ elem->w0 |=
+ le32_encode_bits(ch_info->period, RTW89_H2C_CHINFO_BE_W0_PERIOD);
+ else
+ elem->w7 = le32_encode_bits(ch_info->period,
+ RTW89_H2C_CHINFO_BE_W7_PERIOD_V1);
}
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
@@ -4561,16 +5537,20 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
return 0;
}
-int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev,
- struct rtw89_scan_option *option,
- struct rtw89_vif *rtwvif)
+#define RTW89_SCAN_DELAY_TSF_UNIT 1000000
+int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
+ struct rtw89_scan_option *option,
+ struct rtw89_vif_link *rtwvif_link,
+ bool wowlan)
{
struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
struct rtw89_chan *op = &rtwdev->scan_info.op_chan;
+ enum rtw89_scan_mode scan_mode = RTW89_SCAN_IMMEDIATE;
struct rtw89_h2c_scanofld *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
unsigned int cond;
+ u64 tsf = 0;
int ret;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
@@ -4581,17 +5561,30 @@ int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev,
skb_put(skb, len);
h2c = (struct rtw89_h2c_scanofld *)skb->data;
- h2c->w0 = le32_encode_bits(rtwvif->mac_id, RTW89_H2C_SCANOFLD_W0_MACID) |
- le32_encode_bits(rtwvif->port, RTW89_H2C_SCANOFLD_W0_PORT_ID) |
- le32_encode_bits(RTW89_PHY_0, RTW89_H2C_SCANOFLD_W0_BAND) |
+ if (option->delay) {
+ ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
+ if (ret) {
+ rtw89_warn(rtwdev, "NLO failed to get port tsf: %d\n", ret);
+ scan_mode = RTW89_SCAN_IMMEDIATE;
+ } else {
+ scan_mode = RTW89_SCAN_DELAY;
+ tsf += (u64)option->delay * RTW89_SCAN_DELAY_TSF_UNIT;
+ }
+ }
+
+ h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_W0_MACID) |
+ le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_W0_PORT_ID) |
+ le32_encode_bits(rtwvif_link->mac_idx, RTW89_H2C_SCANOFLD_W0_BAND) |
le32_encode_bits(option->enable, RTW89_H2C_SCANOFLD_W0_OPERATION);
h2c->w1 = le32_encode_bits(true, RTW89_H2C_SCANOFLD_W1_NOTIFY_END) |
le32_encode_bits(option->target_ch_mode,
RTW89_H2C_SCANOFLD_W1_TARGET_CH_MODE) |
- le32_encode_bits(RTW89_SCAN_IMMEDIATE,
- RTW89_H2C_SCANOFLD_W1_START_MODE) |
- le32_encode_bits(RTW89_SCAN_ONCE, RTW89_H2C_SCANOFLD_W1_SCAN_TYPE);
+ le32_encode_bits(scan_mode, RTW89_H2C_SCANOFLD_W1_START_MODE) |
+ le32_encode_bits(option->repeat, RTW89_H2C_SCANOFLD_W1_SCAN_TYPE);
+
+ h2c->w2 = le32_encode_bits(option->norm_pd, RTW89_H2C_SCANOFLD_W2_NORM_PD) |
+ le32_encode_bits(option->slow_pd, RTW89_H2C_SCANOFLD_W2_SLOW_PD);
if (option->target_ch_mode) {
h2c->w1 |= le32_encode_bits(op->band_width,
@@ -4604,6 +5597,11 @@ int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev,
RTW89_H2C_SCANOFLD_W0_TARGET_CH_BAND);
}
+ h2c->tsf_high = le32_encode_bits(upper_32_bits(tsf),
+ RTW89_H2C_SCANOFLD_W3_TSF_HIGH);
+ h2c->tsf_low = le32_encode_bits(lower_32_bits(tsf),
+ RTW89_H2C_SCANOFLD_W4_TSF_LOW);
+
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
H2C_FUNC_SCANOFLD, 1, 1,
@@ -4631,6 +5629,10 @@ static void rtw89_scan_get_6g_disabled_chan(struct rtw89_dev *rtwdev,
u8 i, idx;
sband = rtwdev->hw->wiphy->bands[NL80211_BAND_6GHZ];
+ if (!sband) {
+ option->prohib_chan = U64_MAX;
+ return;
+ }
for (i = 0; i < sband->n_channels; i++) {
chan = &sband->channels[i];
@@ -4643,19 +5645,26 @@ static void rtw89_scan_get_6g_disabled_chan(struct rtw89_dev *rtwdev,
int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
struct rtw89_scan_option *option,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link,
+ bool wowlan)
{
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
+ struct cfg80211_scan_request *req = rtwvif->scan_req;
struct rtw89_h2c_scanofld_be_macc_role *macc_role;
struct rtw89_chan *op = &scan_info->op_chan;
struct rtw89_h2c_scanofld_be_opch *opch;
+ struct rtw89_pktofld_info *pkt_info;
struct rtw89_h2c_scanofld_be *h2c;
struct sk_buff *skb;
u8 macc_role_size = sizeof(*macc_role) * option->num_macc_role;
u8 opch_size = sizeof(*opch) * option->num_opch;
u8 probe_id[NUM_NL80211_BANDS];
+ u8 scan_offload_ver = U8_MAX;
+ u8 cfg_len = sizeof(*h2c);
unsigned int cond;
+ u8 ver = U8_MAX;
void *ptr;
int ret;
u32 len;
@@ -4663,7 +5672,12 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
rtw89_scan_get_6g_disabled_chan(rtwdev, option);
- len = sizeof(*h2c) + macc_role_size + opch_size;
+ if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw)) {
+ cfg_len = offsetofend(typeof(*h2c), w8);
+ scan_offload_ver = 0;
+ }
+
+ len = cfg_len + macc_role_size + opch_size;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n");
@@ -4674,14 +5688,29 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
h2c = (struct rtw89_h2c_scanofld_be *)skb->data;
ptr = skb->data;
+ memset(probe_id, RTW89_SCANOFLD_PKT_NONE, sizeof(probe_id));
+
+ if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw))
+ ver = 0;
+
+ if (!wowlan) {
+ list_for_each_entry(pkt_info, &scan_info->pkt_list[NL80211_BAND_6GHZ], list) {
+ if (pkt_info->wildcard_6ghz) {
+ /* Provide wildcard as template */
+ probe_id[NL80211_BAND_6GHZ] = pkt_info->id;
+ break;
+ }
+ }
+ }
+
h2c->w0 = le32_encode_bits(option->operation, RTW89_H2C_SCANOFLD_BE_W0_OP) |
le32_encode_bits(option->scan_mode,
RTW89_H2C_SCANOFLD_BE_W0_SCAN_MODE) |
le32_encode_bits(option->repeat, RTW89_H2C_SCANOFLD_BE_W0_REPEAT) |
le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_NOTIFY_END) |
le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_LEARN_CH) |
- le32_encode_bits(rtwvif->mac_id, RTW89_H2C_SCANOFLD_BE_W0_MACID) |
- le32_encode_bits(rtwvif->port, RTW89_H2C_SCANOFLD_BE_W0_PORT) |
+ le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_SCANOFLD_BE_W0_MACID) |
+ le32_encode_bits(rtwvif_link->port, RTW89_H2C_SCANOFLD_BE_W0_PORT) |
le32_encode_bits(option->band, RTW89_H2C_SCANOFLD_BE_W0_BAND);
h2c->w1 = le32_encode_bits(option->num_macc_role, RTW89_H2C_SCANOFLD_BE_W1_NUM_MACC_ROLE) |
@@ -4701,7 +5730,7 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
RTW89_H2C_SCANOFLD_BE_W4_PROBE_5G) |
le32_encode_bits(probe_id[NL80211_BAND_6GHZ],
RTW89_H2C_SCANOFLD_BE_W4_PROBE_6G) |
- le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W4_DELAY_START);
+ le32_encode_bits(option->delay, RTW89_H2C_SCANOFLD_BE_W4_DELAY_START);
h2c->w5 = le32_encode_bits(option->mlo_mode, RTW89_H2C_SCANOFLD_BE_W5_MLO_MODE);
@@ -4709,10 +5738,31 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
RTW89_H2C_SCANOFLD_BE_W6_CHAN_PROHIB_LOW);
h2c->w7 = le32_encode_bits(option->prohib_chan >> 32,
RTW89_H2C_SCANOFLD_BE_W7_CHAN_PROHIB_HIGH);
- ptr += sizeof(*h2c);
+ if (!wowlan && req->no_cck) {
+ h2c->w0 |= le32_encode_bits(true, RTW89_H2C_SCANOFLD_BE_W0_PROBE_WITH_RATE);
+ h2c->w8 = le32_encode_bits(RTW89_HW_RATE_OFDM6,
+ RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_2GHZ) |
+ le32_encode_bits(RTW89_HW_RATE_OFDM6,
+ RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_5GHZ) |
+ le32_encode_bits(RTW89_HW_RATE_OFDM6,
+ RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_6GHZ);
+ }
+
+ if (scan_offload_ver == 0)
+ goto flex_member;
+
+ h2c->w9 = le32_encode_bits(sizeof(*h2c) / sizeof(h2c->w0),
+ RTW89_H2C_SCANOFLD_BE_W9_SIZE_CFG) |
+ le32_encode_bits(sizeof(*macc_role) / sizeof(macc_role->w0),
+ RTW89_H2C_SCANOFLD_BE_W9_SIZE_MACC) |
+ le32_encode_bits(sizeof(*opch) / sizeof(opch->w0),
+ RTW89_H2C_SCANOFLD_BE_W9_SIZE_OP);
+
+flex_member:
+ ptr += cfg_len;
for (i = 0; i < option->num_macc_role; i++) {
- macc_role = (struct rtw89_h2c_scanofld_be_macc_role *)&h2c->role[i];
+ macc_role = ptr;
macc_role->w0 =
le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_BAND) |
le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_PORT) |
@@ -4723,11 +5773,11 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
for (i = 0; i < option->num_opch; i++) {
opch = ptr;
- opch->w0 = le32_encode_bits(rtwvif->mac_id,
+ opch->w0 = le32_encode_bits(rtwvif_link->mac_id,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_MACID) |
le32_encode_bits(option->band,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_BAND) |
- le32_encode_bits(rtwvif->port,
+ le32_encode_bits(rtwvif_link->port,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_PORT) |
le32_encode_bits(RTW89_SCAN_OPMODE_INTV,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY) |
@@ -4736,9 +5786,7 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
le32_encode_bits(RTW89_OFF_CHAN_TIME / 10,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY_VAL);
- opch->w1 = le32_encode_bits(RTW89_CHANNEL_TIME,
- RTW89_H2C_SCANOFLD_BE_OPCH_W1_DURATION) |
- le32_encode_bits(op->band_type,
+ opch->w1 = le32_encode_bits(op->band_type,
RTW89_H2C_SCANOFLD_BE_OPCH_W1_CH_BAND) |
le32_encode_bits(op->band_width,
RTW89_H2C_SCANOFLD_BE_OPCH_W1_BW) |
@@ -4753,7 +5801,7 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
RTW89_H2C_SCANOFLD_BE_OPCH_W2_PKTS_CTRL) |
le32_encode_bits(0,
RTW89_H2C_SCANOFLD_BE_OPCH_W2_SW_DEF) |
- le32_encode_bits(2,
+ le32_encode_bits(rtw89_is_mlo_1_1(rtwdev) ? 1 : 2,
RTW89_H2C_SCANOFLD_BE_OPCH_W2_SS);
opch->w3 = le32_encode_bits(RTW89_SCANOFLD_PKT_NONE,
@@ -4764,6 +5812,13 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT2) |
le32_encode_bits(RTW89_SCANOFLD_PKT_NONE,
RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT3);
+
+ if (ver == 0)
+ opch->w1 |= le32_encode_bits(RTW89_CHANNEL_TIME,
+ RTW89_H2C_SCANOFLD_BE_OPCH_W1_DURATION);
+ else
+ opch->w4 = le32_encode_bits(RTW89_CHANNEL_TIME,
+ RTW89_H2C_SCANOFLD_BE_OPCH_W4_DURATION_V1);
ptr += sizeof(*opch);
}
@@ -4821,7 +5876,7 @@ fail:
int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
{
- struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
+ struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_fw_h2c_rf_get_mccch *mccch;
struct sk_buff *skb;
int ret;
@@ -4866,14 +5921,26 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
+ struct rtw89_fw_h2c_rfk_pre_info_common *common;
+ struct rtw89_fw_h2c_rfk_pre_info_v0 *h2c_v0;
+ struct rtw89_fw_h2c_rfk_pre_info_v1 *h2c_v1;
struct rtw89_fw_h2c_rfk_pre_info *h2c;
- u8 tbl_sel = rfk_mcc->table_idx;
+ u8 tbl_sel[NUM_OF_RTW89_FW_RFK_PATH];
u32 len = sizeof(*h2c);
struct sk_buff *skb;
+ u8 ver = U8_MAX;
u8 tbl, path;
u32 val32;
int ret;
+ if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V1, &rtwdev->fw)) {
+ len = sizeof(*h2c_v1);
+ ver = 1;
+ } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V0, &rtwdev->fw)) {
+ len = sizeof(*h2c_v0);
+ ver = 0;
+ }
+
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c rfk_pre_ntfy\n");
@@ -4881,42 +5948,68 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
}
skb_put(skb, len);
h2c = (struct rtw89_fw_h2c_rfk_pre_info *)skb->data;
+ common = &h2c->base_v1.common;
- h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
+ common->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR);
+ BUILD_BUG_ON(ARRAY_SIZE(rfk_mcc->data) < NUM_OF_RTW89_FW_RFK_PATH);
for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) {
for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) {
- h2c->dbcc.ch[path][tbl] = cpu_to_le32(rfk_mcc->ch[tbl]);
- h2c->dbcc.band[path][tbl] = cpu_to_le32(rfk_mcc->band[tbl]);
+ common->dbcc.ch[path][tbl] =
+ cpu_to_le32(rfk_mcc->data[path].ch[tbl]);
+ common->dbcc.band[path][tbl] =
+ cpu_to_le32(rfk_mcc->data[path].band[tbl]);
}
}
for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) {
- h2c->tbl.cur_ch[path] = cpu_to_le32(rfk_mcc->ch[tbl_sel]);
- h2c->tbl.cur_band[path] = cpu_to_le32(rfk_mcc->band[tbl_sel]);
+ tbl_sel[path] = rfk_mcc->data[path].table_idx;
+
+ common->tbl.cur_ch[path] =
+ cpu_to_le32(rfk_mcc->data[path].ch[tbl_sel[path]]);
+ common->tbl.cur_band[path] =
+ cpu_to_le32(rfk_mcc->data[path].band[tbl_sel[path]]);
+
+ if (ver <= 1)
+ continue;
+
+ h2c->cur_bandwidth[path] =
+ cpu_to_le32(rfk_mcc->data[path].bw[tbl_sel[path]]);
}
- h2c->phy_idx = cpu_to_le32(phy_idx);
- h2c->cur_band = cpu_to_le32(rfk_mcc->band[tbl_sel]);
- h2c->cur_bw = cpu_to_le32(rfk_mcc->bw[tbl_sel]);
- h2c->cur_center_ch = cpu_to_le32(rfk_mcc->ch[tbl_sel]);
+ common->phy_idx = cpu_to_le32(phy_idx);
+
+ if (ver == 0) { /* RFK_PRE_NOTIFY_V0 */
+ h2c_v0 = (struct rtw89_fw_h2c_rfk_pre_info_v0 *)skb->data;
- val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_IQC_V1);
- h2c->ktbl_sel0 = cpu_to_le32(val32);
- val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_IQC_V1);
- h2c->ktbl_sel1 = cpu_to_le32(val32);
- val32 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK);
- h2c->rfmod0 = cpu_to_le32(val32);
- val32 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CFGCH, RFREG_MASK);
- h2c->rfmod1 = cpu_to_le32(val32);
+ h2c_v0->cur_band = cpu_to_le32(rfk_mcc->data[0].band[tbl_sel[0]]);
+ h2c_v0->cur_bw = cpu_to_le32(rfk_mcc->data[0].bw[tbl_sel[0]]);
+ h2c_v0->cur_center_ch = cpu_to_le32(rfk_mcc->data[0].ch[tbl_sel[0]]);
- if (rtw89_is_mlo_1_1(rtwdev))
- h2c->mlo_1_1 = cpu_to_le32(1);
+ val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_IQC_V1);
+ h2c_v0->ktbl_sel0 = cpu_to_le32(val32);
+ val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_IQC_V1);
+ h2c_v0->ktbl_sel1 = cpu_to_le32(val32);
+ val32 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK);
+ h2c_v0->rfmod0 = cpu_to_le32(val32);
+ val32 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_CFGCH, RFREG_MASK);
+ h2c_v0->rfmod1 = cpu_to_le32(val32);
- h2c->rfe_type = cpu_to_le32(rtwdev->efuse.rfe_type);
+ if (rtw89_is_mlo_1_1(rtwdev))
+ h2c_v0->mlo_1_1 = cpu_to_le32(1);
+
+ h2c_v0->rfe_type = cpu_to_le32(rtwdev->efuse.rfe_type);
+
+ goto done;
+ }
+ if (rtw89_is_mlo_1_1(rtwdev)) {
+ h2c_v1 = &h2c->base_v1;
+ h2c_v1->mlo_1_1 = cpu_to_le32(1);
+ }
+done:
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
H2C_FUNC_RFK_PRE_NOTIFY, 0, 0,
@@ -4936,10 +6029,8 @@ fail:
}
int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
- enum rtw89_tssi_mode tssi_mode)
+ const struct rtw89_chan *chan, enum rtw89_tssi_mode tssi_mode)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- RTW89_SUB_ENTITY_0);
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_h2c_rf_tssi *h2c;
u32 len = sizeof(*h2c);
@@ -4983,7 +6074,8 @@ fail:
return ret;
}
-int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan)
{
struct rtw89_h2c_rf_iqk *h2c;
u32 len = sizeof(*h2c);
@@ -5018,10 +6110,9 @@ fail:
return ret;
}
-int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- RTW89_SUB_ENTITY_0);
struct rtw89_h2c_rf_dpk *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
@@ -5061,10 +6152,9 @@ fail:
return ret;
}
-int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- RTW89_SUB_ENTITY_0);
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_h2c_rf_txgapk *h2c;
u32 len = sizeof(*h2c);
@@ -5105,7 +6195,8 @@ fail:
return ret;
}
-int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan)
{
struct rtw89_h2c_rf_dack *h2c;
u32 len = sizeof(*h2c);
@@ -5141,32 +6232,45 @@ fail:
return ret;
}
-int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan, bool is_chl_k)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- RTW89_SUB_ENTITY_0);
+ struct rtw89_h2c_rf_rxdck_v0 *v0;
struct rtw89_h2c_rf_rxdck *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
+ int ver = -1;
int ret;
+ if (RTW89_CHK_FW_FEATURE(RFK_RXDCK_V0, &rtwdev->fw)) {
+ len = sizeof(*v0);
+ ver = 0;
+ }
+
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c RF RXDCK\n");
return -ENOMEM;
}
skb_put(skb, len);
- h2c = (struct rtw89_h2c_rf_rxdck *)skb->data;
+ v0 = (struct rtw89_h2c_rf_rxdck_v0 *)skb->data;
- h2c->len = len;
- h2c->phy = phy_idx;
- h2c->is_afe = false;
- h2c->kpath = RF_AB;
- h2c->cur_band = chan->band_type;
- h2c->cur_bw = chan->band_width;
- h2c->cur_ch = chan->channel;
- h2c->rxdck_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK);
+ v0->len = len;
+ v0->phy = phy_idx;
+ v0->is_afe = false;
+ v0->kpath = RF_AB;
+ v0->cur_band = chan->band_type;
+ v0->cur_bw = chan->band_width;
+ v0->cur_ch = chan->channel;
+ v0->rxdck_dbg_en = rtw89_debug_is_enabled(rtwdev, RTW89_DBG_RFK);
+
+ if (ver == 0)
+ goto hdr;
+ h2c = (struct rtw89_h2c_rf_rxdck *)skb->data;
+ h2c->is_chl_k = is_chl_k;
+
+hdr:
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
H2C_FUNC_RFK_RXDCK_OFFLOAD, 0, 0, len);
@@ -5244,24 +6348,29 @@ void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev)
{
struct rtw89_early_h2c *early_h2c;
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) {
rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len);
}
}
-void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev)
+void __rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev)
{
struct rtw89_early_h2c *early_h2c, *tmp;
- mutex_lock(&rtwdev->mutex);
list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) {
list_del(&early_h2c->list);
kfree(early_h2c->h2c);
kfree(early_h2c);
}
- mutex_unlock(&rtwdev->mutex);
+}
+
+void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev)
+{
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ __rtw89_fw_free_all_early_h2c(rtwdev);
}
static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h)
@@ -5305,7 +6414,7 @@ void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h)
enqueue:
skb_queue_tail(&rtwdev->c2h_queue, c2h);
- ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work);
+ wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->c2h_work);
}
static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
@@ -5343,17 +6452,17 @@ static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len);
}
-void rtw89_fw_c2h_work(struct work_struct *work)
+void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
c2h_work);
struct sk_buff *skb, *tmp;
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) {
skb_unlink(skb, &rtwdev->c2h_queue);
- mutex_lock(&rtwdev->mutex);
rtw89_fw_c2h_cmd_handle(rtwdev, skb);
- mutex_unlock(&rtwdev->mutex);
dev_kfree_skb_any(skb);
}
}
@@ -5434,7 +6543,7 @@ int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev,
u32 ret;
if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE)
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (!h2c_info && !c2h_info)
return -EINVAL;
@@ -5476,7 +6585,7 @@ void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev)
rtw89_fw_prog_cnt_dump(rtwdev);
}
-static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev)
+static void rtw89_hw_scan_release_pkt_list(struct rtw89_dev *rtwdev)
{
struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
struct rtw89_pktofld_info *info, *tmp;
@@ -5495,13 +6604,28 @@ static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev)
}
}
+static void rtw89_hw_scan_cleanup(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+
+ mac->free_chan_list(rtwdev);
+ rtw89_hw_scan_release_pkt_list(rtwdev);
+
+ rtwvif->scan_req = NULL;
+ rtwvif->scan_ies = NULL;
+ scan_info->scanning_vif = NULL;
+ scan_info->abort = false;
+ scan_info->connected = false;
+}
+
static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct cfg80211_scan_request *req,
struct rtw89_pktofld_info *info,
enum nl80211_band band, u8 ssid_idx)
{
- struct cfg80211_scan_request *req = rtwvif->scan_req;
-
if (band != NL80211_BAND_6GHZ)
return false;
@@ -5511,16 +6635,19 @@ static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev,
info->ssid_len = req->ssids[ssid_idx].ssid_len;
return false;
} else {
+ info->wildcard_6ghz = true;
return true;
}
}
static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct sk_buff *skb, u8 ssid_idx)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
+ struct cfg80211_scan_request *req = rtwvif->scan_req;
struct rtw89_pktofld_info *info;
struct sk_buff *new;
int ret = 0;
@@ -5545,12 +6672,7 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev,
goto out;
}
- if (rtw89_is_6ghz_wildcard_probe_req(rtwdev, rtwvif, info, band,
- ssid_idx)) {
- kfree_skb(new);
- kfree(info);
- goto out;
- }
+ rtw89_is_6ghz_wildcard_probe_req(rtwdev, req, info, band, ssid_idx);
ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, new);
if (ret) {
@@ -5567,22 +6689,24 @@ out:
}
static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link,
+ const u8 *mac_addr)
{
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct cfg80211_scan_request *req = rtwvif->scan_req;
struct sk_buff *skb;
u8 num = req->n_ssids, i;
int ret;
for (i = 0; i < num; i++) {
- skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr,
+ skb = ieee80211_probereq_get(rtwdev->hw, mac_addr,
req->ssids[i].ssid,
req->ssids[i].ssid_len,
req->ie_len);
if (!skb)
return -ENOMEM;
- ret = rtw89_append_probe_req_ie(rtwdev, rtwvif, skb, i);
+ ret = rtw89_append_probe_req_ie(rtwdev, rtwvif_link, skb, i);
kfree_skb(skb);
if (ret)
@@ -5592,14 +6716,13 @@ static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev,
return 0;
}
-static int rtw89_update_6ghz_rnr_chan(struct rtw89_dev *rtwdev,
- struct cfg80211_scan_request *req,
- struct rtw89_mac_chinfo *ch_info)
+static int rtw89_update_6ghz_rnr_chan_ax(struct rtw89_dev *rtwdev,
+ struct ieee80211_scan_ies *ies,
+ struct cfg80211_scan_request *req,
+ struct rtw89_mac_chinfo_ax *ch_info)
{
- struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
- struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
- struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
struct cfg80211_scan_6ghz_params *params;
struct rtw89_pktofld_info *info, *tmp;
struct ieee80211_hdr *hdr;
@@ -5628,8 +6751,11 @@ static int rtw89_update_6ghz_rnr_chan(struct rtw89_dev *rtwdev,
if (found)
continue;
- skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr,
+ skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr,
NULL, 0, req->ie_len);
+ if (!skb)
+ return -ENOMEM;
+
skb_put_data(skb, ies->ies[NL80211_BAND_6GHZ], ies->len[NL80211_BAND_6GHZ]);
skb_put_data(skb, ies->common_ies, ies->common_ie_len);
hdr = (struct ieee80211_hdr *)skb->data;
@@ -5663,13 +6789,64 @@ out:
return ret;
}
-static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
- int ssid_num,
- struct rtw89_mac_chinfo *ch_info)
+static void rtw89_pno_scan_add_chan_ax(struct rtw89_dev *rtwdev,
+ int chan_type, int ssid_num,
+ struct rtw89_mac_chinfo_ax *ch_info)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_pktofld_info *info;
+ u8 probe_count = 0;
+
+ ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK;
+ ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS;
+ ch_info->bw = RTW89_SCAN_WIDTH;
+ ch_info->tx_pkt = true;
+ ch_info->cfg_tx_pwr = false;
+ ch_info->tx_pwr_idx = 0;
+ ch_info->tx_null = false;
+ ch_info->pause_data = false;
+ ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE;
+
+ if (ssid_num) {
+ list_for_each_entry(info, &rtw_wow->pno_pkt_list, list) {
+ if (info->channel_6ghz &&
+ ch_info->pri_ch != info->channel_6ghz)
+ continue;
+ else if (info->channel_6ghz && probe_count != 0)
+ ch_info->period += RTW89_CHANNEL_TIME_6G;
+
+ if (info->wildcard_6ghz)
+ continue;
+
+ ch_info->pkt_id[probe_count++] = info->id;
+ if (probe_count >= RTW89_SCANOFLD_MAX_SSID)
+ break;
+ }
+ ch_info->num_pkt = probe_count;
+ }
+
+ switch (chan_type) {
+ case RTW89_CHAN_DFS:
+ if (ch_info->ch_band != RTW89_BAND_6G)
+ ch_info->period = max_t(u8, ch_info->period,
+ RTW89_DFS_CHAN_TIME);
+ ch_info->dwell_time = RTW89_DWELL_TIME;
+ break;
+ case RTW89_CHAN_ACTIVE:
+ break;
+ default:
+ rtw89_err(rtwdev, "Channel type out of bound\n");
+ }
+}
+
+static void rtw89_hw_scan_add_chan_ax(struct rtw89_dev *rtwdev, int chan_type,
+ int ssid_num,
+ struct rtw89_mac_chinfo_ax *ch_info)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
- struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
struct cfg80211_scan_request *req = rtwvif->scan_req;
struct rtw89_chan *op = &rtwdev->scan_info.op_chan;
struct rtw89_pktofld_info *info;
@@ -5695,7 +6872,7 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
}
}
- ret = rtw89_update_6ghz_rnr_chan(rtwdev, req, ch_info);
+ ret = rtw89_update_6ghz_rnr_chan_ax(rtwdev, ies, req, ch_info);
if (ret)
rtw89_warn(rtwdev, "RNR fails: %d\n", ret);
@@ -5708,6 +6885,10 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
continue;
else if (info->channel_6ghz && probe_count != 0)
ch_info->period += RTW89_CHANNEL_TIME_6G;
+
+ if (info->wildcard_6ghz)
+ continue;
+
ch_info->pkt_id[probe_count++] = info->id;
if (probe_count >= RTW89_SCANOFLD_MAX_SSID)
break;
@@ -5729,21 +6910,62 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
ch_info->period = max_t(u8, ch_info->period,
RTW89_DFS_CHAN_TIME);
ch_info->dwell_time = RTW89_DWELL_TIME;
+ ch_info->pause_data = true;
break;
case RTW89_CHAN_ACTIVE:
+ ch_info->pause_data = true;
break;
default:
rtw89_err(rtwdev, "Channel type out of bound\n");
}
}
+static void rtw89_pno_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type,
+ int ssid_num,
+ struct rtw89_mac_chinfo_be *ch_info)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_pktofld_info *info;
+ u8 probe_count = 0, i;
+
+ ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK;
+ ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS;
+ ch_info->bw = RTW89_SCAN_WIDTH;
+ ch_info->tx_null = false;
+ ch_info->pause_data = false;
+ ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE;
+
+ if (ssid_num) {
+ list_for_each_entry(info, &rtw_wow->pno_pkt_list, list) {
+ ch_info->pkt_id[probe_count++] = info->id;
+ if (probe_count >= RTW89_SCANOFLD_MAX_SSID)
+ break;
+ }
+ }
+
+ for (i = probe_count; i < RTW89_SCANOFLD_MAX_SSID; i++)
+ ch_info->pkt_id[i] = RTW89_SCANOFLD_PKT_NONE;
+
+ switch (chan_type) {
+ case RTW89_CHAN_DFS:
+ ch_info->period = max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME);
+ ch_info->dwell_time = RTW89_DWELL_TIME;
+ break;
+ case RTW89_CHAN_ACTIVE:
+ break;
+ default:
+ rtw89_warn(rtwdev, "Channel type out of bound\n");
+ break;
+ }
+}
+
static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type,
int ssid_num,
struct rtw89_mac_chinfo_be *ch_info)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
- struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct cfg80211_scan_request *req = rtwvif->scan_req;
struct rtw89_pktofld_info *info;
u8 band, probe_count = 0, i;
@@ -5762,6 +6984,10 @@ static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type,
if (info->channel_6ghz &&
ch_info->pri_ch != info->channel_6ghz)
continue;
+
+ if (info->wildcard_6ghz)
+ continue;
+
ch_info->pkt_id[probe_count++] = info->id;
if (probe_count >= RTW89_SCANOFLD_MAX_SSID)
break;
@@ -5786,8 +7012,10 @@ static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type,
ch_info->period =
max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME);
ch_info->dwell_time = RTW89_DWELL_TIME;
+ ch_info->pause_data = true;
break;
case RTW89_CHAN_ACTIVE:
+ ch_info->pause_data = true;
break;
default:
rtw89_warn(rtwdev, "Channel type out of bound\n");
@@ -5795,23 +7023,74 @@ static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type,
}
}
-int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool connected)
+int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- struct cfg80211_scan_request *req = rtwvif->scan_req;
- struct rtw89_mac_chinfo *ch_info, *tmp;
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config;
+ struct rtw89_mac_chinfo_ax *ch_info, *tmp;
struct ieee80211_channel *channel;
struct list_head chan_list;
- bool random_seq = req->flags & NL80211_SCAN_FLAG_RANDOM_SN;
- int list_len, off_chan_time = 0;
+ int list_len;
enum rtw89_chan_type type;
int ret = 0;
u32 idx;
INIT_LIST_HEAD(&chan_list);
- for (idx = rtwdev->scan_info.last_chan_idx, list_len = 0;
- idx < req->n_channels && list_len < RTW89_SCAN_LIST_LIMIT;
+ for (idx = 0, list_len = 0;
+ idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_AX;
idx++, list_len++) {
+ channel = nd_config->channels[idx];
+ ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
+ if (!ch_info) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ch_info->period = RTW89_CHANNEL_TIME;
+ ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band);
+ ch_info->central_ch = channel->hw_value;
+ ch_info->pri_ch = channel->hw_value;
+ ch_info->is_psc = cfg80211_channel_is_psc(channel);
+
+ if (channel->flags &
+ (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR))
+ type = RTW89_CHAN_DFS;
+ else
+ type = RTW89_CHAN_ACTIVE;
+
+ rtw89_pno_scan_add_chan_ax(rtwdev, type, nd_config->n_match_sets, ch_info);
+ list_add_tail(&ch_info->list, &chan_list);
+ }
+ ret = rtw89_fw_h2c_scan_list_offload_ax(rtwdev, list_len, &chan_list);
+
+out:
+ list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
+ list_del(&ch_info->list);
+ kfree(ch_info);
+ }
+
+ return ret;
+}
+
+int rtw89_hw_scan_prep_chan_list_ax(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ struct cfg80211_scan_request *req = rtwvif->scan_req;
+ struct rtw89_mac_chinfo_ax *ch_info, *tmp;
+ struct ieee80211_channel *channel;
+ struct list_head chan_list;
+ bool random_seq = req->flags & NL80211_SCAN_FLAG_RANDOM_SN;
+ enum rtw89_chan_type type;
+ int off_chan_time = 0;
+ int ret;
+ u32 idx;
+
+ INIT_LIST_HEAD(&chan_list);
+
+ for (idx = 0; idx < req->n_channels; idx++) {
channel = req->channels[idx];
ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
if (!ch_info) {
@@ -5838,9 +7117,9 @@ int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev,
type = RTW89_CHAN_DFS;
else
type = RTW89_CHAN_ACTIVE;
- rtw89_hw_scan_add_chan(rtwdev, type, req->n_ssids, ch_info);
+ rtw89_hw_scan_add_chan_ax(rtwdev, type, req->n_ssids, ch_info);
- if (connected &&
+ if (scan_info->connected &&
off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME) {
tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
if (!tmp) {
@@ -5852,16 +7131,16 @@ int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev,
type = RTW89_CHAN_OPERATE;
tmp->period = req->duration_mandatory ?
req->duration : RTW89_CHANNEL_TIME;
- rtw89_hw_scan_add_chan(rtwdev, type, 0, tmp);
+ rtw89_hw_scan_add_chan_ax(rtwdev, type, 0, tmp);
list_add_tail(&tmp->list, &chan_list);
off_chan_time = 0;
- list_len++;
}
list_add_tail(&ch_info->list, &chan_list);
off_chan_time += ch_info->period;
}
- rtwdev->scan_info.last_chan_idx = idx;
- ret = rtw89_fw_h2c_scan_list_offload(rtwdev, list_len, &chan_list);
+
+ list_splice_tail(&chan_list, &scan_info->chan_list);
+ return 0;
out:
list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
@@ -5872,24 +7151,117 @@ out:
return ret;
}
-int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool connected)
+void rtw89_hw_scan_free_chan_list_ax(struct rtw89_dev *rtwdev)
{
- struct cfg80211_scan_request *req = rtwvif->scan_req;
+ struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+ struct rtw89_mac_chinfo_ax *ch_info, *tmp;
+
+ list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) {
+ list_del(&ch_info->list);
+ kfree(ch_info);
+ }
+}
+
+int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+ struct rtw89_mac_chinfo_ax *ch_info, *tmp;
+ unsigned int list_len = 0;
+ struct list_head list;
+ int ret;
+
+ INIT_LIST_HEAD(&list);
+
+ list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) {
+ list_move_tail(&ch_info->list, &list);
+
+ list_len++;
+ if (list_len == RTW89_SCAN_LIST_LIMIT_AX)
+ break;
+ }
+
+ ret = rtw89_fw_h2c_scan_list_offload_ax(rtwdev, list_len, &list);
+
+ list_for_each_entry_safe(ch_info, tmp, &list, list) {
+ list_del(&ch_info->list);
+ kfree(ch_info);
+ }
+
+ return ret;
+}
+
+int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config;
struct rtw89_mac_chinfo_be *ch_info, *tmp;
struct ieee80211_channel *channel;
struct list_head chan_list;
enum rtw89_chan_type type;
int list_len, ret;
+ u32 idx;
+
+ INIT_LIST_HEAD(&chan_list);
+
+ for (idx = 0, list_len = 0;
+ idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_BE;
+ idx++, list_len++) {
+ channel = nd_config->channels[idx];
+ ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
+ if (!ch_info) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ch_info->period = RTW89_CHANNEL_TIME;
+ ch_info->ch_band = rtw89_nl80211_to_hw_band(channel->band);
+ ch_info->central_ch = channel->hw_value;
+ ch_info->pri_ch = channel->hw_value;
+ ch_info->is_psc = cfg80211_channel_is_psc(channel);
+
+ if (channel->flags &
+ (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR))
+ type = RTW89_CHAN_DFS;
+ else
+ type = RTW89_CHAN_ACTIVE;
+
+ rtw89_pno_scan_add_chan_be(rtwdev, type,
+ nd_config->n_match_sets, ch_info);
+ list_add_tail(&ch_info->list, &chan_list);
+ }
+
+ ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list,
+ rtwvif_link);
+
+out:
+ list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
+ list_del(&ch_info->list);
+ kfree(ch_info);
+ }
+
+ return ret;
+}
+
+int rtw89_hw_scan_prep_chan_list_be(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ struct cfg80211_scan_request *req = rtwvif->scan_req;
+ struct rtw89_mac_chinfo_be *ch_info, *tmp;
+ struct ieee80211_channel *channel;
+ struct list_head chan_list;
+ enum rtw89_chan_type type;
bool random_seq;
+ int ret;
u32 idx;
random_seq = !!(req->flags & NL80211_SCAN_FLAG_RANDOM_SN);
INIT_LIST_HEAD(&chan_list);
- for (idx = rtwdev->scan_info.last_chan_idx, list_len = 0;
- idx < req->n_channels && list_len < RTW89_SCAN_LIST_LIMIT;
- idx++, list_len++) {
+ for (idx = 0; idx < req->n_channels; idx++) {
channel = req->channels[idx];
ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
if (!ch_info) {
@@ -5919,8 +7291,8 @@ int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
list_add_tail(&ch_info->list, &chan_list);
}
- rtwdev->scan_info.last_chan_idx = idx;
- ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &chan_list);
+ list_splice_tail(&chan_list, &scan_info->chan_list);
+ return 0;
out:
list_for_each_entry_safe(ch_info, tmp, &chan_list, list) {
@@ -5931,135 +7303,306 @@ out:
return ret;
}
+void rtw89_hw_scan_free_chan_list_be(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+ struct rtw89_mac_chinfo_be *ch_info, *tmp;
+
+ list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) {
+ list_del(&ch_info->list);
+ kfree(ch_info);
+ }
+}
+
+int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+ struct rtw89_mac_chinfo_be *ch_info, *tmp;
+ unsigned int list_len = 0;
+ struct list_head list;
+ int ret;
+
+ INIT_LIST_HEAD(&list);
+
+ list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) {
+ list_move_tail(&ch_info->list, &list);
+
+ list_len++;
+ if (list_len == RTW89_SCAN_LIST_LIMIT_BE)
+ break;
+ }
+
+ ret = rtw89_fw_h2c_scan_list_offload_be(rtwdev, list_len, &list,
+ rtwvif_link);
+
+ list_for_each_entry_safe(ch_info, tmp, &list, list) {
+ list_del(&ch_info->list);
+ kfree(ch_info);
+ }
+
+ return ret;
+}
+
static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool connected)
+ struct rtw89_vif_link *rtwvif_link,
+ const u8 *mac_addr)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
int ret;
- ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif);
+ ret = rtw89_hw_scan_update_probe_req(rtwdev, rtwvif_link, mac_addr);
if (ret) {
rtw89_err(rtwdev, "Update probe request failed\n");
goto out;
}
- ret = mac->add_chan_list(rtwdev, rtwvif, connected);
+ ret = mac->prep_chan_list(rtwdev, rtwvif_link);
out:
return ret;
}
-void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
- struct ieee80211_scan_request *scan_req)
+static void rtw89_hw_scan_update_link_beacon_noa(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ u16 tu)
+{
+ struct ieee80211_p2p_noa_desc noa_desc = {};
+ u64 tsf;
+ int ret;
+
+ ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
+ if (ret) {
+ rtw89_warn(rtwdev, "%s: failed to get tsf\n", __func__);
+ return;
+ }
+
+ noa_desc.start_time = cpu_to_le32(tsf);
+ noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(tu));
+ noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(tu));
+ noa_desc.count = 1;
+
+ rtw89_p2p_noa_renew(rtwvif_link);
+ rtw89_p2p_noa_append(rtwvif_link, &noa_desc);
+ rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link);
+}
+
+static void rtw89_hw_scan_update_beacon_noa(struct rtw89_dev *rtwdev,
+ const struct cfg80211_scan_request *req)
+{
+ const struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt;
+ const struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct rtw89_mac_chinfo_ax *chinfo_ax;
+ struct rtw89_mac_chinfo_be *chinfo_be;
+ struct rtw89_vif_link *rtwvif_link;
+ struct list_head *pos, *tmp;
+ struct ieee80211_vif *vif;
+ struct rtw89_vif *rtwvif;
+ u16 tu = 0;
+
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ list_for_each_safe(pos, tmp, &scan_info->chan_list) {
+ switch (chip->chip_gen) {
+ case RTW89_CHIP_AX:
+ chinfo_ax = list_entry(pos, typeof(*chinfo_ax), list);
+ tu += chinfo_ax->period;
+ break;
+ case RTW89_CHIP_BE:
+ chinfo_be = list_entry(pos, typeof(*chinfo_be), list);
+ tu += chinfo_be->period;
+ break;
+ default:
+ rtw89_warn(rtwdev, "%s: invalid chip gen %d\n",
+ __func__, chip->chip_gen);
+ return;
+ }
+ }
+
+ if (unlikely(tu == 0)) {
+ rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
+ "%s: cannot estimate needed TU\n", __func__);
+ return;
+ }
+
+ list_for_each_entry(rtwvif, &mgnt->active_list, mgnt_entry) {
+ unsigned int link_id;
+
+ vif = rtwvif_to_vif(rtwvif);
+ if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
+ continue;
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_hw_scan_update_link_beacon_noa(rtwdev, rtwvif_link, tu);
+ }
+}
+
+int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_scan_request *scan_req)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev);
struct cfg80211_scan_request *req = &scan_req->req;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+ rtwvif_link->chanctx_idx);
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ struct rtw89_chanctx_pause_parm pause_parm = {
+ .rsn = RTW89_CHANCTX_PAUSE_REASON_HW_SCAN,
+ .trigger = rtwvif_link,
+ };
u32 rx_fltr = rtwdev->hal.rx_fltr;
u8 mac_addr[ETH_ALEN];
+ u32 reg;
+ int ret;
+
+ /* clone op and keep it during scan */
+ rtwdev->scan_info.op_chan = *chan;
- rtw89_get_channel(rtwdev, rtwvif, &rtwdev->scan_info.op_chan);
- rtwdev->scan_info.scanning_vif = vif;
- rtwdev->scan_info.last_chan_idx = 0;
+ rtwdev->scan_info.connected = rtw89_is_any_vif_connected_or_connecting(rtwdev);
+ rtwdev->scan_info.scanning_vif = rtwvif_link;
rtwdev->scan_info.abort = false;
rtwvif->scan_ies = &scan_req->ies;
rtwvif->scan_req = req;
- ieee80211_stop_queues(rtwdev->hw);
- rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif, false);
if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
get_random_mask_addr(mac_addr, req->mac_addr,
req->mac_addr_mask);
else
- ether_addr_copy(mac_addr, vif->addr);
- rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, true);
+ ether_addr_copy(mac_addr, rtwvif_link->mac_addr);
+
+ ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif_link, mac_addr);
+ if (ret) {
+ rtw89_hw_scan_cleanup(rtwdev, rtwvif_link);
+ return ret;
+ }
+
+ ieee80211_stop_queues(rtwdev->hw);
+ rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, false);
+
+ rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, true);
rx_fltr &= ~B_AX_A_BCN_CHK_EN;
rx_fltr &= ~B_AX_A_BC;
rx_fltr &= ~B_AX_A_A1_MATCH;
- rtw89_write32_mask(rtwdev,
- rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
- B_AX_RX_FLTR_CFG_MASK,
- rx_fltr);
- rtw89_chanctx_pause(rtwdev, RTW89_CHANCTX_PAUSE_REASON_HW_SCAN);
+ reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
+ rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rx_fltr);
+
+ rtw89_chanctx_pause(rtwdev, &pause_parm);
+
+ if (mode == RTW89_ENTITY_MODE_MCC)
+ rtw89_hw_scan_update_beacon_noa(rtwdev, req);
+
+ return 0;
}
-void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
- bool aborted)
+struct rtw89_hw_scan_complete_cb_data {
+ struct rtw89_vif_link *rtwvif_link;
+ bool aborted;
+};
+
+static int rtw89_hw_scan_complete_cb(struct rtw89_dev *rtwdev, void *data)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
- struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
- struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
+ struct rtw89_hw_scan_complete_cb_data *cb_data = data;
+ struct rtw89_vif_link *rtwvif_link = cb_data->rtwvif_link;
struct cfg80211_scan_info info = {
- .aborted = aborted,
+ .aborted = cb_data->aborted,
};
+ u32 reg;
- if (!vif)
- return;
+ if (!rtwvif_link)
+ return -EINVAL;
- rtw89_write32_mask(rtwdev,
- rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
- B_AX_RX_FLTR_CFG_MASK,
- rtwdev->hal.rx_fltr);
+ reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
+ rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rtwdev->hal.rx_fltr);
- rtw89_core_scan_complete(rtwdev, vif, true);
+ rtw89_core_scan_complete(rtwdev, rtwvif_link, true);
ieee80211_scan_completed(rtwdev->hw, &info);
ieee80211_wake_queues(rtwdev->hw);
- rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif, true);
+ rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, true);
rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true);
- rtw89_release_pkt_list(rtwdev);
- rtwvif->scan_req = NULL;
- rtwvif->scan_ies = NULL;
- scan_info->last_chan_idx = 0;
- scan_info->scanning_vif = NULL;
- scan_info->abort = false;
+ rtw89_hw_scan_cleanup(rtwdev, rtwvif_link);
+
+ return 0;
+}
+
+void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ bool aborted)
+{
+ struct rtw89_hw_scan_complete_cb_data cb_data = {
+ .rtwvif_link = rtwvif_link,
+ .aborted = aborted,
+ };
+ const struct rtw89_chanctx_cb_parm cb_parm = {
+ .cb = rtw89_hw_scan_complete_cb,
+ .data = &cb_data,
+ .caller = __func__,
+ };
- rtw89_chanctx_proceed(rtwdev);
+ /* The things here needs to be done after setting channel (for coex)
+ * and before proceeding entity mode (for MCC). So, pass a callback
+ * of them for the right sequence rather than doing them directly.
+ */
+ rtw89_chanctx_proceed(rtwdev, &cb_parm);
}
-void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
+void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
int ret;
scan_info->abort = true;
- ret = rtw89_hw_scan_offload(rtwdev, vif, false);
+ ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, false);
if (ret)
- rtw89_hw_scan_complete(rtwdev, vif, true);
+ rtw89_warn(rtwdev, "rtw89_hw_scan_offload failed ret %d\n", ret);
+
+ /* Indicate ieee80211_scan_completed() before returning, which is safe
+ * because scan abort command always waits for completion of
+ * RTW89_SCAN_END_SCAN_NOTIFY, so that ieee80211_stop() can flush scan
+ * work properly.
+ */
+ rtw89_hw_scan_complete(rtwdev, rtwvif_link, true);
}
static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
- /* This variable implies connected or during attempt to connect */
- if (!is_zero_ether_addr(rtwvif->bssid))
- return true;
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ /* This variable implies connected or during attempt to connect */
+ if (!is_zero_ether_addr(rtwvif_link->bssid))
+ return true;
+ }
}
return false;
}
-int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool enable)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct rtw89_scan_option opt = {0};
- struct rtw89_vif *rtwvif;
bool connected;
int ret = 0;
- rtwvif = vif ? (struct rtw89_vif *)vif->drv_priv : NULL;
- if (!rtwvif)
+ if (!rtwvif_link)
return -EINVAL;
- connected = rtw89_is_any_vif_connected_or_connecting(rtwdev);
+ connected = rtwdev->scan_info.connected;
opt.enable = enable;
opt.target_ch_mode = connected;
if (enable) {
- ret = rtw89_hw_scan_prehandle(rtwdev, rtwvif, connected);
+ ret = mac->add_chan_list(rtwdev, rtwvif_link);
if (ret)
goto out;
}
@@ -6067,14 +7610,14 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
opt.operation = enable ? RTW89_SCAN_OP_START : RTW89_SCAN_OP_STOP;
opt.scan_mode = RTW89_SCAN_MODE_SA;
- opt.band = RTW89_PHY_0;
+ opt.band = rtwvif_link->mac_idx;
opt.num_macc_role = 0;
opt.mlo_mode = rtwdev->mlo_dbcc_mode;
opt.num_opch = connected ? 1 : 0;
opt.opch_end = connected ? 0 : RTW89_CHAN_INVALID;
}
- ret = mac->scan_offload(rtwdev, &opt, rtwvif);
+ ret = mac->scan_offload(rtwdev, &opt, rtwvif_link, false);
out:
return ret;
}
@@ -6180,7 +7723,7 @@ fail:
}
#define H2C_KEEP_ALIVE_LEN 4
-int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable)
{
struct sk_buff *skb;
@@ -6188,7 +7731,7 @@ int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
int ret;
if (enable) {
- ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
+ ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
RTW89_PKT_OFLD_TYPE_NULL_DATA,
&pkt_id);
if (ret)
@@ -6206,7 +7749,7 @@ int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
RTW89_SET_KEEP_ALIVE_ENABLE(skb->data, enable);
RTW89_SET_KEEP_ALIVE_PKT_NULL_ID(skb->data, pkt_id);
RTW89_SET_KEEP_ALIVE_PERIOD(skb->data, 5);
- RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif->mac_id);
+ RTW89_SET_KEEP_ALIVE_MACID(skb->data, rtwvif_link->mac_id);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
@@ -6228,13 +7771,64 @@ fail:
return ret;
}
+int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ bool enable)
+{
+ struct rtw89_h2c_arp_offload *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ u8 pkt_id = 0;
+ int ret;
+
+ if (enable) {
+ ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
+ RTW89_PKT_OFLD_TYPE_ARP_RSP,
+ &pkt_id);
+ if (ret)
+ return ret;
+ }
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for arp offload\n");
+ return -ENOMEM;
+ }
+
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_arp_offload *)skb->data;
+
+ h2c->w0 = le32_encode_bits(enable, RTW89_H2C_ARP_OFFLOAD_W0_ENABLE) |
+ le32_encode_bits(0, RTW89_H2C_ARP_OFFLOAD_W0_ACTION) |
+ le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_ARP_OFFLOAD_W0_MACID) |
+ le32_encode_bits(pkt_id, RTW89_H2C_ARP_OFFLOAD_W0_PKT_ID);
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_MAC,
+ H2C_CL_MAC_WOW,
+ H2C_FUNC_ARP_OFLD, 0, 1,
+ len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
#define H2C_DISCONNECT_DETECT_LEN 8
int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool enable)
+ struct rtw89_vif_link *rtwvif_link, bool enable)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct sk_buff *skb;
- u8 macid = rtwvif->mac_id;
+ u8 macid = rtwvif_link->mac_id;
int ret;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_DISCONNECT_DETECT_LEN);
@@ -6273,30 +7867,89 @@ fail:
return ret;
}
-#define H2C_WOW_GLOBAL_LEN 8
-int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ bool enable)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config;
+ struct rtw89_h2c_cfg_nlo *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ int ret, i;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for nlo\n");
+ return -ENOMEM;
+ }
+
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_cfg_nlo *)skb->data;
+
+ h2c->w0 = le32_encode_bits(enable, RTW89_H2C_NLO_W0_ENABLE) |
+ le32_encode_bits(enable, RTW89_H2C_NLO_W0_IGNORE_CIPHER) |
+ le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_NLO_W0_MACID);
+
+ if (enable) {
+ h2c->nlo_cnt = nd_config->n_match_sets;
+ for (i = 0 ; i < nd_config->n_match_sets; i++) {
+ h2c->ssid_len[i] = nd_config->match_sets[i].ssid.ssid_len;
+ memcpy(h2c->ssid[i], nd_config->match_sets[i].ssid.ssid,
+ nd_config->match_sets[i].ssid.ssid_len);
+ }
+ }
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_MAC,
+ H2C_CL_MAC_WOW,
+ H2C_FUNC_NLO, 0, 1,
+ len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ dev_kfree_skb_any(skb);
+ return ret;
+}
+
+int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable)
{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_h2c_wow_global *h2c;
+ u8 macid = rtwvif_link->mac_id;
+ u32 len = sizeof(*h2c);
struct sk_buff *skb;
- u8 macid = rtwvif->mac_id;
int ret;
- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_GLOBAL_LEN);
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
- rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
+ rtw89_err(rtwdev, "failed to alloc skb for wow global\n");
return -ENOMEM;
}
- skb_put(skb, H2C_WOW_GLOBAL_LEN);
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_wow_global *)skb->data;
- RTW89_SET_WOW_GLOBAL_ENABLE(skb->data, enable);
- RTW89_SET_WOW_GLOBAL_MAC_ID(skb->data, macid);
+ h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GLOBAL_W0_ENABLE) |
+ le32_encode_bits(macid, RTW89_H2C_WOW_GLOBAL_W0_MAC_ID) |
+ le32_encode_bits(rtw_wow->ptk_alg,
+ RTW89_H2C_WOW_GLOBAL_W0_PAIRWISE_SEC_ALGO) |
+ le32_encode_bits(rtw_wow->gtk_alg,
+ RTW89_H2C_WOW_GLOBAL_W0_GROUP_SEC_ALGO);
+ h2c->key_info = rtw_wow->key_info;
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
H2C_CL_MAC_WOW,
H2C_FUNC_WOW_GLOBAL, 0, 1,
- H2C_WOW_GLOBAL_LEN);
+ len);
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
@@ -6314,17 +7967,17 @@ fail:
#define H2C_WAKEUP_CTRL_LEN 4
int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
bool enable)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct sk_buff *skb;
- u8 macid = rtwvif->mac_id;
+ u8 macid = rtwvif_link->mac_id;
int ret;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WAKEUP_CTRL_LEN);
if (!skb) {
- rtw89_err(rtwdev, "failed to alloc skb for keep alive\n");
+ rtw89_err(rtwdev, "failed to alloc skb for wakeup ctrl\n");
return -ENOMEM;
}
@@ -6411,6 +8064,135 @@ fail:
return ret;
}
+int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ bool enable)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info;
+ struct rtw89_h2c_wow_gtk_ofld *h2c;
+ u8 macid = rtwvif_link->mac_id;
+ u32 len = sizeof(*h2c);
+ u8 pkt_id_sa_query = 0;
+ struct sk_buff *skb;
+ u8 pkt_id_eapol = 0;
+ int ret;
+
+ if (!rtw_wow->gtk_alg)
+ return 0;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for gtk ofld\n");
+ return -ENOMEM;
+ }
+
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_wow_gtk_ofld *)skb->data;
+
+ if (!enable)
+ goto hdr;
+
+ ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
+ RTW89_PKT_OFLD_TYPE_EAPOL_KEY,
+ &pkt_id_eapol);
+ if (ret)
+ goto fail;
+
+ if (gtk_info->igtk_keyid) {
+ ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif_link,
+ RTW89_PKT_OFLD_TYPE_SA_QUERY,
+ &pkt_id_sa_query);
+ if (ret)
+ goto fail;
+ }
+
+ /* not support TKIP yet */
+ h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GTK_OFLD_W0_EN) |
+ le32_encode_bits(0, RTW89_H2C_WOW_GTK_OFLD_W0_TKIP_EN) |
+ le32_encode_bits(gtk_info->igtk_keyid ? 1 : 0,
+ RTW89_H2C_WOW_GTK_OFLD_W0_IEEE80211W_EN) |
+ le32_encode_bits(macid, RTW89_H2C_WOW_GTK_OFLD_W0_MAC_ID) |
+ le32_encode_bits(pkt_id_eapol, RTW89_H2C_WOW_GTK_OFLD_W0_GTK_RSP_ID);
+ h2c->w1 = le32_encode_bits(gtk_info->igtk_keyid ? pkt_id_sa_query : 0,
+ RTW89_H2C_WOW_GTK_OFLD_W1_PMF_SA_QUERY_ID) |
+ le32_encode_bits(rtw_wow->akm, RTW89_H2C_WOW_GTK_OFLD_W1_ALGO_AKM_SUIT);
+ h2c->gtk_info = rtw_wow->gtk_info;
+
+hdr:
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_MAC,
+ H2C_CL_MAC_WOW,
+ H2C_FUNC_GTK_OFLD, 0, 1,
+ len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
+int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ bool enable)
+{
+ struct rtw89_wait_info *wait = &rtwdev->mac.ps_wait;
+ struct rtw89_h2c_fwips *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for fw ips\n");
+ return -ENOMEM;
+ }
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_fwips *)skb->data;
+
+ h2c->w0 = le32_encode_bits(rtwvif_link->mac_id, RTW89_H2C_FW_IPS_W0_MACID) |
+ le32_encode_bits(enable, RTW89_H2C_FW_IPS_W0_ENABLE);
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_MAC,
+ H2C_CL_MAC_PS,
+ H2C_FUNC_IPS_CFG, 0, 1,
+ len);
+
+ return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_PS_WAIT_COND_IPS_CFG);
+}
+
+int rtw89_fw_h2c_wow_request_aoac(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_wait_info *wait = &rtwdev->wow.wait;
+ struct rtw89_h2c_wow_aoac *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for aoac\n");
+ return -ENOMEM;
+ }
+
+ skb_put(skb, len);
+
+ /* This H2C only nofity firmware to generate AOAC report C2H,
+ * no need any parameter.
+ */
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_MAC,
+ H2C_CL_MAC_WOW,
+ H2C_FUNC_AOAC_REPORT_REQ, 1, 0,
+ len);
+
+ return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, RTW89_WOW_WAIT_COND_AOAC);
+}
+
/* Return < 0, if failures happen during waiting for the condition.
* Return 0, when waiting for the condition succeeds.
* Return > 0, if the wait is considered unreachable due to driver/FW design,
@@ -6900,7 +8682,7 @@ int rtw89_fw_h2c_mrc_start(struct rtw89_dev *rtwdev,
return rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
}
-int rtw89_fw_h2c_mrc_del(struct rtw89_dev *rtwdev, u8 sch_idx)
+int rtw89_fw_h2c_mrc_del(struct rtw89_dev *rtwdev, u8 sch_idx, u8 slot_idx)
{
struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
struct rtw89_h2c_mrc_del *h2c;
@@ -6917,7 +8699,8 @@ int rtw89_fw_h2c_mrc_del(struct rtw89_dev *rtwdev, u8 sch_idx)
skb_put(skb, len);
h2c = (struct rtw89_h2c_mrc_del *)skb->data;
- h2c->w0 = le32_encode_bits(sch_idx, RTW89_H2C_MRC_DEL_W0_SCH_IDX);
+ h2c->w0 = le32_encode_bits(sch_idx, RTW89_H2C_MRC_DEL_W0_SCH_IDX) |
+ le32_encode_bits(slot_idx, RTW89_H2C_MRC_DEL_W0_STOP_SLOT_IDX);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
@@ -7114,6 +8897,112 @@ int rtw89_fw_h2c_mrc_upd_duration(struct rtw89_dev *rtwdev,
return 0;
}
+static int rtw89_fw_h2c_ap_info(struct rtw89_dev *rtwdev, bool en)
+{
+ struct rtw89_h2c_ap_info *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ int ret;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for ap info\n");
+ return -ENOMEM;
+ }
+
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_ap_info *)skb->data;
+
+ h2c->w0 = le32_encode_bits(en, RTW89_H2C_AP_INFO_W0_PWR_INT_EN);
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_MAC,
+ H2C_CL_AP,
+ H2C_FUNC_AP_INFO, 0, 0,
+ len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ dev_kfree_skb_any(skb);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+int rtw89_fw_h2c_ap_info_refcount(struct rtw89_dev *rtwdev, bool en)
+{
+ int ret;
+
+ if (en) {
+ if (refcount_inc_not_zero(&rtwdev->refcount_ap_info))
+ return 0;
+ } else {
+ if (!refcount_dec_and_test(&rtwdev->refcount_ap_info))
+ return 0;
+ }
+
+ ret = rtw89_fw_h2c_ap_info(rtwdev, en);
+ if (ret) {
+ if (!test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags))
+ return ret;
+
+ /* During recovery, neither driver nor stack has full error
+ * handling, so show a warning, but return 0 with refcount
+ * increased normally. It can avoid underflow when calling
+ * with @en == false later.
+ */
+ rtw89_warn(rtwdev, "h2c ap_info failed during SER\n");
+ }
+
+ if (en)
+ refcount_set(&rtwdev->refcount_ap_info, 1);
+
+ return 0;
+}
+
+int rtw89_fw_h2c_mlo_link_cfg(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ bool enable)
+{
+ struct rtw89_wait_info *wait = &rtwdev->mlo.wait;
+ struct rtw89_h2c_mlo_link_cfg *h2c;
+ u8 mac_id = rtwvif_link->mac_id;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ unsigned int cond;
+ int ret;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for mlo link cfg\n");
+ return -ENOMEM;
+ }
+
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_mlo_link_cfg *)skb->data;
+
+ h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_MLO_LINK_CFG_W0_MACID) |
+ le32_encode_bits(enable, RTW89_H2C_MLO_LINK_CFG_W0_OPTION);
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_MAC,
+ H2C_CL_MLO,
+ H2C_FUNC_MLO_LINK_CFG, 0, 0,
+ len);
+
+ cond = RTW89_MLO_WAIT_COND(mac_id, H2C_FUNC_MLO_LINK_CFG);
+
+ ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
+ if (ret) {
+ rtw89_err(rtwdev, "mlo link cfg (%s link id %u) failed: %d\n",
+ str_enable_disable(enable), rtwvif_link->link_id, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
static bool __fw_txpwr_entry_zero_ext(const void *ext_ptr, u8 ext_len)
{
static const u8 zeros[U8_MAX] = {};
@@ -7501,6 +9390,26 @@ void rtw89_fw_load_tx_shape_lmt_ru(struct rtw89_tx_shape_lmt_ru_data *data)
}
}
+static bool rtw89_fw_has_da_txpwr_table(struct rtw89_dev *rtwdev,
+ const struct rtw89_rfe_parms *parms)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+
+ if (chip->support_bands & BIT(NL80211_BAND_2GHZ) &&
+ !(parms->rule_da_2ghz.lmt && parms->rule_da_2ghz.lmt_ru))
+ return false;
+
+ if (chip->support_bands & BIT(NL80211_BAND_5GHZ) &&
+ !(parms->rule_da_5ghz.lmt && parms->rule_da_5ghz.lmt_ru))
+ return false;
+
+ if (chip->support_bands & BIT(NL80211_BAND_6GHZ) &&
+ !(parms->rule_da_6ghz.lmt && parms->rule_da_6ghz.lmt_ru))
+ return false;
+
+ return true;
+}
+
const struct rtw89_rfe_parms *
rtw89_load_rfe_data_from_fw(struct rtw89_dev *rtwdev,
const struct rtw89_rfe_parms *init)
@@ -7537,6 +9446,21 @@ rtw89_load_rfe_data_from_fw(struct rtw89_dev *rtwdev,
parms->rule_6ghz.lmt = &rfe_data->lmt_6ghz.v;
}
+ if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_2ghz.conf)) {
+ rtw89_fw_load_txpwr_lmt_2ghz(&rfe_data->da_lmt_2ghz);
+ parms->rule_da_2ghz.lmt = &rfe_data->da_lmt_2ghz.v;
+ }
+
+ if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_5ghz.conf)) {
+ rtw89_fw_load_txpwr_lmt_5ghz(&rfe_data->da_lmt_5ghz);
+ parms->rule_da_5ghz.lmt = &rfe_data->da_lmt_5ghz.v;
+ }
+
+ if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_6ghz.conf)) {
+ rtw89_fw_load_txpwr_lmt_6ghz(&rfe_data->da_lmt_6ghz);
+ parms->rule_da_6ghz.lmt = &rfe_data->da_lmt_6ghz.v;
+ }
+
if (rtw89_txpwr_conf_valid(&rfe_data->lmt_ru_2ghz.conf)) {
rtw89_fw_load_txpwr_lmt_ru_2ghz(&rfe_data->lmt_ru_2ghz);
parms->rule_2ghz.lmt_ru = &rfe_data->lmt_ru_2ghz.v;
@@ -7552,6 +9476,21 @@ rtw89_load_rfe_data_from_fw(struct rtw89_dev *rtwdev,
parms->rule_6ghz.lmt_ru = &rfe_data->lmt_ru_6ghz.v;
}
+ if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_2ghz.conf)) {
+ rtw89_fw_load_txpwr_lmt_ru_2ghz(&rfe_data->da_lmt_ru_2ghz);
+ parms->rule_da_2ghz.lmt_ru = &rfe_data->da_lmt_ru_2ghz.v;
+ }
+
+ if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_5ghz.conf)) {
+ rtw89_fw_load_txpwr_lmt_ru_5ghz(&rfe_data->da_lmt_ru_5ghz);
+ parms->rule_da_5ghz.lmt_ru = &rfe_data->da_lmt_ru_5ghz.v;
+ }
+
+ if (rtw89_txpwr_conf_valid(&rfe_data->da_lmt_ru_6ghz.conf)) {
+ rtw89_fw_load_txpwr_lmt_ru_6ghz(&rfe_data->da_lmt_ru_6ghz);
+ parms->rule_da_6ghz.lmt_ru = &rfe_data->da_lmt_ru_6ghz.v;
+ }
+
if (rtw89_txpwr_conf_valid(&rfe_data->tx_shape_lmt.conf)) {
rtw89_fw_load_tx_shape_lmt(&rfe_data->tx_shape_lmt);
parms->tx_shape.lmt = &rfe_data->tx_shape_lmt.v;
@@ -7562,5 +9501,7 @@ rtw89_load_rfe_data_from_fw(struct rtw89_dev *rtwdev,
parms->tx_shape.lmt_ru = &rfe_data->tx_shape_lmt_ru.v;
}
+ parms->has_da = rtw89_fw_has_da_txpwr_table(rtwdev, parms);
+
return parms;
}
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index 44311f65b4fa..0fcc824e41be 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -47,6 +47,45 @@ struct rtw89_c2hreg_phycap {
#define RTW89_C2HREG_PHYCAP_W2_HW_TYPE GENMASK(7, 0)
#define RTW89_C2HREG_PHYCAP_W3_ANT_TX_NUM GENMASK(15, 8)
#define RTW89_C2HREG_PHYCAP_W3_ANT_RX_NUM GENMASK(23, 16)
+#define RTW89_C2HREG_PHYCAP_W3_BAND_SEL GENMASK(31, 24)
+
+#define RTW89_C2HREG_PHYCAP_P1_W0_B1_RX_NSS GENMASK(23, 16)
+#define RTW89_C2HREG_PHYCAP_P1_W0_B1_BW GENMASK(31, 24)
+#define RTW89_C2HREG_PHYCAP_P1_W1_B1_TX_NSS GENMASK(7, 0)
+#define RTW89_C2HREG_PHYCAP_P1_W1_B1_ANT_TX_NUM GENMASK(15, 8)
+#define RTW89_C2HREG_PHYCAP_P1_W1_B1_ANT_RX_NUM GENMASK(23, 16)
+#define RTW89_C2HREG_PHYCAP_P1_W1_B1_BAND_SEL GENMASK(31, 24)
+#define RTW89_C2HREG_PHYCAP_P1_W2_QAM GENMASK(7, 0)
+#define RTW89_C2HREG_PHYCAP_P1_W2_QAM_256 0x1
+#define RTW89_C2HREG_PHYCAP_P1_W2_QAM_1024 0x2
+#define RTW89_C2HREG_PHYCAP_P1_W2_QAM_4096 0x3
+#define RTW89_C2HREG_PHYCAP_P1_W2_B1_QAM GENMASK(15, 8)
+
+#define RTW89_C2HREG_AOAC_RPT_1_W0_KEY_IDX GENMASK(23, 16)
+#define RTW89_C2HREG_AOAC_RPT_1_W1_IV_0 GENMASK(7, 0)
+#define RTW89_C2HREG_AOAC_RPT_1_W1_IV_1 GENMASK(15, 8)
+#define RTW89_C2HREG_AOAC_RPT_1_W1_IV_2 GENMASK(23, 16)
+#define RTW89_C2HREG_AOAC_RPT_1_W1_IV_3 GENMASK(31, 24)
+#define RTW89_C2HREG_AOAC_RPT_1_W2_IV_4 GENMASK(7, 0)
+#define RTW89_C2HREG_AOAC_RPT_1_W2_IV_5 GENMASK(15, 8)
+#define RTW89_C2HREG_AOAC_RPT_1_W2_IV_6 GENMASK(23, 16)
+#define RTW89_C2HREG_AOAC_RPT_1_W2_IV_7 GENMASK(31, 24)
+#define RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_0 GENMASK(7, 0)
+#define RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_1 GENMASK(15, 8)
+#define RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_2 GENMASK(23, 16)
+#define RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_3 GENMASK(31, 24)
+#define RTW89_C2HREG_AOAC_RPT_2_W0_PTK_IV_4 GENMASK(23, 16)
+#define RTW89_C2HREG_AOAC_RPT_2_W0_PTK_IV_5 GENMASK(31, 24)
+#define RTW89_C2HREG_AOAC_RPT_2_W1_PTK_IV_6 GENMASK(7, 0)
+#define RTW89_C2HREG_AOAC_RPT_2_W1_PTK_IV_7 GENMASK(15, 8)
+#define RTW89_C2HREG_AOAC_RPT_2_W1_IGTK_IPN_IV_0 GENMASK(23, 16)
+#define RTW89_C2HREG_AOAC_RPT_2_W1_IGTK_IPN_IV_1 GENMASK(31, 24)
+#define RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_2 GENMASK(7, 0)
+#define RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_3 GENMASK(15, 8)
+#define RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_4 GENMASK(23, 16)
+#define RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_5 GENMASK(31, 24)
+#define RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_6 GENMASK(7, 0)
+#define RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_7 GENMASK(15, 8)
struct rtw89_h2creg_hdr {
u32 w0;
@@ -66,6 +105,8 @@ struct rtw89_h2creg_sch_tx_en {
#define RTW89_H2CREG_WOW_CPUIO_RX_CTRL_EN GENMASK(23, 16)
+#define RTW89_H2CREG_GET_FEATURE_PART_NUM GENMASK(23, 16)
+
#define RTW89_H2CREG_MAX 4
#define RTW89_C2HREG_MAX 4
#define RTW89_C2HREG_HDR_LEN 2
@@ -98,8 +139,11 @@ enum rtw89_mac_h2c_type {
RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE,
RTW89_FWCMD_H2CREG_FUNC_GETPKT_INFORM,
RTW89_FWCMD_H2CREG_FUNC_SCH_TX_EN,
- RTW89_FWCMD_H2CREG_FUNC_WOW_TRX_STOP = 0x6,
- RTW89_FWCMD_H2CREG_FUNC_WOW_CPUIO_RX_CTRL = 0xA,
+ RTW89_FWCMD_H2CREG_FUNC_WOW_TRX_STOP,
+ RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_1,
+ RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_2,
+ RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_3_REQ,
+ RTW89_FWCMD_H2CREG_FUNC_WOW_CPUIO_RX_CTRL,
};
enum rtw89_mac_c2h_type {
@@ -109,6 +153,7 @@ enum rtw89_mac_c2h_type {
RTW89_FWCMD_C2HREG_FUNC_PHY_CAP,
RTW89_FWCMD_C2HREG_FUNC_TX_PAUSE_RPT,
RTW89_FWCMD_C2HREG_FUNC_WOW_CPUIO_RX_ACK = 0xA,
+ RTW89_FWCMD_C2HREG_FUNC_PHY_CAP_PART1 = 0xC,
RTW89_FWCMD_C2HREG_FUNC_NULL = 0xFF,
};
@@ -154,6 +199,7 @@ enum rtw89_fw_log_comp {
RTW89_FW_LOG_COMP_TWT,
RTW89_FW_LOG_COMP_RF,
RTW89_FW_LOG_COMP_MCC = 20,
+ RTW89_FW_LOG_COMP_MLO = 26,
RTW89_FW_LOG_COMP_SCAN = 28,
};
@@ -232,6 +278,7 @@ struct rtw89_fw_hdr_section_info {
u8 redl;
const u8 *addr;
u32 len;
+ u32 len_override;
u32 dladdr;
u32 mssc;
u8 type;
@@ -246,6 +293,7 @@ struct rtw89_fw_bin_info {
u32 hdr_len;
bool dynamic_hdr_en;
u32 dynamic_hdr_len;
+ u8 idmem_share_mode;
bool dsp_checksum;
bool secure_section_exist;
struct rtw89_fw_hdr_section_info section_info[FWDL_SECTION_MAX_NUM];
@@ -279,13 +327,16 @@ struct rtw89_fw_macid_pause_sleep_grp {
#define RTW89_SCANOFLD_DEBUG_MASK 0x1F
#define RTW89_CHAN_INVALID 0xFF
#define RTW89_MAC_CHINFO_SIZE 28
+#define RTW89_MAC_CHINFO_SIZE_BE 32
#define RTW89_SCAN_LIST_GUARD 4
-#define RTW89_SCAN_LIST_LIMIT \
- ((RTW89_H2C_MAX_SIZE / RTW89_MAC_CHINFO_SIZE) - RTW89_SCAN_LIST_GUARD)
+#define RTW89_SCAN_LIST_LIMIT(size) \
+ ((RTW89_H2C_MAX_SIZE / (size)) - RTW89_SCAN_LIST_GUARD)
+#define RTW89_SCAN_LIST_LIMIT_AX RTW89_SCAN_LIST_LIMIT(RTW89_MAC_CHINFO_SIZE)
+#define RTW89_SCAN_LIST_LIMIT_BE RTW89_SCAN_LIST_LIMIT(RTW89_MAC_CHINFO_SIZE_BE)
-#define RTW89_BCN_LOSS_CNT 10
+#define RTW89_BCN_LOSS_CNT 60
-struct rtw89_mac_chinfo {
+struct rtw89_mac_chinfo_ax {
u8 period;
u8 dwell_time;
u8 central_ch;
@@ -340,8 +391,9 @@ struct rtw89_mac_chinfo_be {
struct rtw89_pktofld_info {
struct list_head list;
u8 id;
+ bool wildcard_6ghz;
- /* Below fields are for 6 GHz RNR use only */
+ /* Below fields are for WiFi 6 chips 6 GHz RNR use only */
u8 ssid[IEEE80211_MAX_SSID_LEN];
u8 ssid_len;
u8 bssid[ETH_ALEN];
@@ -533,6 +585,7 @@ struct rtw89_fw_hdr {
#define FW_HDR_W6_SEC_NUM GENMASK(15, 8)
#define FW_HDR_W7_PART_SIZE GENMASK(15, 0)
#define FW_HDR_W7_DYN_HDR BIT(16)
+#define FW_HDR_W7_IDMEM_SHARE_MODE GENMASK(21, 18)
#define FW_HDR_W7_CMD_VERSERION GENMASK(31, 24)
struct rtw89_fw_hdr_section_v1 {
@@ -550,6 +603,7 @@ struct rtw89_fw_hdr_section_v1 {
#define FWSECTION_HDR_V1_W1_REDL BIT(29)
#define FWSECTION_HDR_V1_W2_MSSC GENMASK(7, 0)
#define FORMATTED_MSSC 0xFF
+#define FORMATTED_MSSC_MASK GENMASK(7, 0)
#define FWSECTION_HDR_V1_W2_BBMCU_IDX GENMASK(27, 24)
struct rtw89_fw_hdr_v1 {
@@ -585,6 +639,7 @@ struct rtw89_fw_hdr_v1 {
#define FW_HDR_V1_W6_DSP_CHKSUM BIT(24)
#define FW_HDR_V1_W7_PART_SIZE GENMASK(15, 0)
#define FW_HDR_V1_W7_DYN_HDR BIT(16)
+#define FW_HDR_V1_W7_IDMEM_SHARE_MODE GENMASK(21, 18)
enum rtw89_fw_mss_pool_rmp_tbl_type {
MSS_POOL_RMP_TBL_BITMASK = 0x0,
@@ -610,6 +665,11 @@ struct rtw89_fw_mss_pool_hdr {
union rtw89_fw_section_mssc_content {
struct {
+ u8 pad[0x20];
+ u8 bit_in_chip_list;
+ u8 ver;
+ } __packed blacklist;
+ struct {
u8 pad[58];
__le32 v;
} __packed sb_sel_ver;
@@ -619,6 +679,13 @@ union rtw89_fw_section_mssc_content {
} __packed key_sign_len;
} __packed;
+struct rtw89_fw_blacklist {
+ u8 ver;
+ u8 list[32];
+};
+
+extern const struct rtw89_fw_blacklist rtw89_fw_blacklist_default;
+
static inline void SET_CTRL_INFO_MACID(void *table, u32 val)
{
le32p_replace_bits((__le32 *)(table) + 0, val, GENMASK(6, 0));
@@ -1432,308 +1499,6 @@ struct rtw89_h2c_cctlinfo_ud_g7 {
#define CCTLINFO_G7_W15_MGNT_CURR_RATE GENMASK(27, 16)
#define CCTLINFO_G7_W15_ALL GENMASK(27, 0)
-static inline void SET_DCTL_MACID_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 0, val, GENMASK(6, 0));
-}
-
-static inline void SET_DCTL_OPERATION_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 0, val, BIT(7));
-}
-
-#define SET_DCTL_MASK_QOS_FIELD_V1 GENMASK(7, 0)
-static inline void SET_DCTL_QOS_FIELD_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(7, 0));
- le32p_replace_bits((__le32 *)(table) + 9, SET_DCTL_MASK_QOS_FIELD_V1,
- GENMASK(7, 0));
-}
-
-#define SET_DCTL_MASK_SET_DCTL_HW_EXSEQ_MACID GENMASK(6, 0)
-static inline void SET_DCTL_HW_EXSEQ_MACID_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(14, 8));
- le32p_replace_bits((__le32 *)(table) + 9, SET_DCTL_MASK_SET_DCTL_HW_EXSEQ_MACID,
- GENMASK(14, 8));
-}
-
-#define SET_DCTL_MASK_QOS_DATA BIT(0)
-static inline void SET_DCTL_QOS_DATA_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 1, val, BIT(15));
- le32p_replace_bits((__le32 *)(table) + 9, SET_DCTL_MASK_QOS_DATA,
- BIT(15));
-}
-
-#define SET_DCTL_MASK_AES_IV_L GENMASK(15, 0)
-static inline void SET_DCTL_AES_IV_L_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(31, 16));
- le32p_replace_bits((__le32 *)(table) + 9, SET_DCTL_MASK_AES_IV_L,
- GENMASK(31, 16));
-}
-
-#define SET_DCTL_MASK_AES_IV_H GENMASK(31, 0)
-static inline void SET_DCTL_AES_IV_H_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(31, 0));
- le32p_replace_bits((__le32 *)(table) + 10, SET_DCTL_MASK_AES_IV_H,
- GENMASK(31, 0));
-}
-
-#define SET_DCTL_MASK_SEQ0 GENMASK(11, 0)
-static inline void SET_DCTL_SEQ0_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(11, 0));
- le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_SEQ0,
- GENMASK(11, 0));
-}
-
-#define SET_DCTL_MASK_SEQ1 GENMASK(11, 0)
-static inline void SET_DCTL_SEQ1_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(23, 12));
- le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_SEQ1,
- GENMASK(23, 12));
-}
-
-#define SET_DCTL_MASK_AMSDU_MAX_LEN GENMASK(2, 0)
-static inline void SET_DCTL_AMSDU_MAX_LEN_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(26, 24));
- le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_AMSDU_MAX_LEN,
- GENMASK(26, 24));
-}
-
-#define SET_DCTL_MASK_STA_AMSDU_EN BIT(0)
-static inline void SET_DCTL_STA_AMSDU_EN_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 3, val, BIT(27));
- le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_STA_AMSDU_EN,
- BIT(27));
-}
-
-#define SET_DCTL_MASK_CHKSUM_OFLD_EN BIT(0)
-static inline void SET_DCTL_CHKSUM_OFLD_EN_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 3, val, BIT(28));
- le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_CHKSUM_OFLD_EN,
- BIT(28));
-}
-
-#define SET_DCTL_MASK_WITH_LLC BIT(0)
-static inline void SET_DCTL_WITH_LLC_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 3, val, BIT(29));
- le32p_replace_bits((__le32 *)(table) + 11, SET_DCTL_MASK_WITH_LLC,
- BIT(29));
-}
-
-#define SET_DCTL_MASK_SEQ2 GENMASK(11, 0)
-static inline void SET_DCTL_SEQ2_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(11, 0));
- le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_SEQ2,
- GENMASK(11, 0));
-}
-
-#define SET_DCTL_MASK_SEQ3 GENMASK(11, 0)
-static inline void SET_DCTL_SEQ3_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(23, 12));
- le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_SEQ3,
- GENMASK(23, 12));
-}
-
-#define SET_DCTL_MASK_TGT_IND GENMASK(3, 0)
-static inline void SET_DCTL_TGT_IND_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(27, 24));
- le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_TGT_IND,
- GENMASK(27, 24));
-}
-
-#define SET_DCTL_MASK_TGT_IND_EN BIT(0)
-static inline void SET_DCTL_TGT_IND_EN_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 4, val, BIT(28));
- le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_TGT_IND_EN,
- BIT(28));
-}
-
-#define SET_DCTL_MASK_HTC_LB GENMASK(2, 0)
-static inline void SET_DCTL_HTC_LB_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(31, 29));
- le32p_replace_bits((__le32 *)(table) + 12, SET_DCTL_MASK_HTC_LB,
- GENMASK(31, 29));
-}
-
-#define SET_DCTL_MASK_MHDR_LEN GENMASK(4, 0)
-static inline void SET_DCTL_MHDR_LEN_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(4, 0));
- le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_MHDR_LEN,
- GENMASK(4, 0));
-}
-
-#define SET_DCTL_MASK_VLAN_TAG_VALID BIT(0)
-static inline void SET_DCTL_VLAN_TAG_VALID_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 5, val, BIT(5));
- le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_VLAN_TAG_VALID,
- BIT(5));
-}
-
-#define SET_DCTL_MASK_VLAN_TAG_SEL GENMASK(1, 0)
-static inline void SET_DCTL_VLAN_TAG_SEL_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(7, 6));
- le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_VLAN_TAG_SEL,
- GENMASK(7, 6));
-}
-
-#define SET_DCTL_MASK_HTC_ORDER BIT(0)
-static inline void SET_DCTL_HTC_ORDER_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 5, val, BIT(8));
- le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_HTC_ORDER,
- BIT(8));
-}
-
-#define SET_DCTL_MASK_SEC_KEY_ID GENMASK(1, 0)
-static inline void SET_DCTL_SEC_KEY_ID_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(10, 9));
- le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_KEY_ID,
- GENMASK(10, 9));
-}
-
-#define SET_DCTL_MASK_WAPI BIT(0)
-static inline void SET_DCTL_WAPI_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 5, val, BIT(15));
- le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_WAPI,
- BIT(15));
-}
-
-#define SET_DCTL_MASK_SEC_ENT_MODE GENMASK(1, 0)
-static inline void SET_DCTL_SEC_ENT_MODE_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(17, 16));
- le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENT_MODE,
- GENMASK(17, 16));
-}
-
-#define SET_DCTL_MASK_SEC_ENTX_KEYID GENMASK(1, 0)
-static inline void SET_DCTL_SEC_ENT0_KEYID_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(19, 18));
- le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID,
- GENMASK(19, 18));
-}
-
-static inline void SET_DCTL_SEC_ENT1_KEYID_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(21, 20));
- le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID,
- GENMASK(21, 20));
-}
-
-static inline void SET_DCTL_SEC_ENT2_KEYID_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(23, 22));
- le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID,
- GENMASK(23, 22));
-}
-
-static inline void SET_DCTL_SEC_ENT3_KEYID_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(25, 24));
- le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID,
- GENMASK(25, 24));
-}
-
-static inline void SET_DCTL_SEC_ENT4_KEYID_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(27, 26));
- le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID,
- GENMASK(27, 26));
-}
-
-static inline void SET_DCTL_SEC_ENT5_KEYID_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(29, 28));
- le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID,
- GENMASK(29, 28));
-}
-
-static inline void SET_DCTL_SEC_ENT6_KEYID_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(31, 30));
- le32p_replace_bits((__le32 *)(table) + 13, SET_DCTL_MASK_SEC_ENTX_KEYID,
- GENMASK(31, 30));
-}
-
-#define SET_DCTL_MASK_SEC_ENT_VALID GENMASK(7, 0)
-static inline void SET_DCTL_SEC_ENT_VALID_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(7, 0));
- le32p_replace_bits((__le32 *)(table) + 14, SET_DCTL_MASK_SEC_ENT_VALID,
- GENMASK(7, 0));
-}
-
-#define SET_DCTL_MASK_SEC_ENTX GENMASK(7, 0)
-static inline void SET_DCTL_SEC_ENT0_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(15, 8));
- le32p_replace_bits((__le32 *)(table) + 14, SET_DCTL_MASK_SEC_ENTX,
- GENMASK(15, 8));
-}
-
-static inline void SET_DCTL_SEC_ENT1_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(23, 16));
- le32p_replace_bits((__le32 *)(table) + 14, SET_DCTL_MASK_SEC_ENTX,
- GENMASK(23, 16));
-}
-
-static inline void SET_DCTL_SEC_ENT2_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(31, 24));
- le32p_replace_bits((__le32 *)(table) + 14, SET_DCTL_MASK_SEC_ENTX,
- GENMASK(31, 24));
-}
-
-static inline void SET_DCTL_SEC_ENT3_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(7, 0));
- le32p_replace_bits((__le32 *)(table) + 15, SET_DCTL_MASK_SEC_ENTX,
- GENMASK(7, 0));
-}
-
-static inline void SET_DCTL_SEC_ENT4_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(15, 8));
- le32p_replace_bits((__le32 *)(table) + 15, SET_DCTL_MASK_SEC_ENTX,
- GENMASK(15, 8));
-}
-
-static inline void SET_DCTL_SEC_ENT5_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(23, 16));
- le32p_replace_bits((__le32 *)(table) + 15, SET_DCTL_MASK_SEC_ENTX,
- GENMASK(23, 16));
-}
-
-static inline void SET_DCTL_SEC_ENT6_V1(void *table, u32 val)
-{
- le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(31, 24));
- le32p_replace_bits((__le32 *)(table) + 15, SET_DCTL_MASK_SEC_ENTX,
- GENMASK(31, 24));
-}
-
struct rtw89_h2c_bcn_upd {
__le32 w0;
__le32 w1;
@@ -1827,25 +1592,17 @@ struct rtw89_h2c_bcn_upd_be {
#define RTW89_H2C_BCN_UPD_BE_W7_ECSA_OFST GENMASK(30, 16)
#define RTW89_H2C_BCN_UPD_BE_W7_PROTECTION_KEY_ID BIT(31)
-static inline void SET_FWROLE_MAINTAIN_MACID(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0));
-}
-
-static inline void SET_FWROLE_MAINTAIN_SELF_ROLE(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, GENMASK(9, 8));
-}
-
-static inline void SET_FWROLE_MAINTAIN_UPD_MODE(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, GENMASK(12, 10));
-}
+struct rtw89_h2c_role_maintain {
+ __le32 w0;
+};
-static inline void SET_FWROLE_MAINTAIN_WIFI_ROLE(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, GENMASK(16, 13));
-}
+#define RTW89_H2C_ROLE_MAINTAIN_W0_MACID GENMASK(7, 0)
+#define RTW89_H2C_ROLE_MAINTAIN_W0_SELF_ROLE GENMASK(9, 8)
+#define RTW89_H2C_ROLE_MAINTAIN_W0_UPD_MODE GENMASK(12, 10)
+#define RTW89_H2C_ROLE_MAINTAIN_W0_WIFI_ROLE GENMASK(16, 13)
+#define RTW89_H2C_ROLE_MAINTAIN_W0_BAND GENMASK(18, 17)
+#define RTW89_H2C_ROLE_MAINTAIN_W0_PORT GENMASK(21, 19)
+#define RTW89_H2C_ROLE_MAINTAIN_W0_MACID_EXT GENMASK(31, 24)
enum rtw89_fw_sta_type { /* value of RTW89_H2C_JOININFO_W1_STA_TYPE */
RTW89_FW_N_AC_STA = 0,
@@ -1880,6 +1637,8 @@ struct rtw89_h2c_join_v1 {
#define RTW89_H2C_JOININFO_W1_IS_MLD BIT(3)
#define RTW89_H2C_JOININFO_W1_MAIN_MACID GENMASK(11, 4)
#define RTW89_H2C_JOININFO_W1_MLO_MODE BIT(12)
+#define RTW89_H2C_JOININFO_MLO_MODE_MLMR 0
+#define RTW89_H2C_JOININFO_MLO_MODE_MLSR 1
#define RTW89_H2C_JOININFO_W1_EMLSR_CAB BIT(13)
#define RTW89_H2C_JOININFO_W1_NSTR_EN BIT(14)
#define RTW89_H2C_JOININFO_W1_INIT_PWR_STATE BIT(15)
@@ -2047,6 +1806,25 @@ struct rtw89_h2c_lps_ch_info {
__le32 mlo_dbcc_mode_lps;
} __packed;
+struct rtw89_h2c_lps_ml_cmn_info {
+ u8 fmt_id;
+ u8 rfe_type;
+ u8 rsvd0[2];
+ __le32 mlo_dbcc_mode;
+ u8 central_ch[RTW89_PHY_NUM];
+ u8 pri_ch[RTW89_PHY_NUM];
+ u8 bw[RTW89_PHY_NUM];
+ u8 band[RTW89_PHY_NUM];
+ u8 bcn_rate_type[RTW89_PHY_NUM];
+ u8 rsvd1[2];
+ __le16 tia_gain[RTW89_PHY_NUM][TIA_GAIN_NUM];
+ u8 lna_gain[RTW89_PHY_NUM][LNA_GAIN_NUM];
+ u8 rsvd2[2];
+ u8 tia_lna_op1db[RTW89_PHY_NUM][LNA_GAIN_NUM + 1];
+ u8 lna_op1db[RTW89_PHY_NUM][LNA_GAIN_NUM];
+ u8 dup_bcn_ofst[RTW89_PHY_NUM];
+} __packed;
+
static inline void RTW89_SET_FWCMD_CPU_EXCEPTION_TYPE(void *cmd, u32 val)
{
le32p_replace_bits((__le32 *)cmd, val, GENMASK(31, 0));
@@ -2157,45 +1935,36 @@ static inline void RTW89_SET_DISCONNECT_DETECT_TRYOK_BCNFAIL_COUNT_LIMIT(void *h
le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(7, 0));
}
-static inline void RTW89_SET_WOW_GLOBAL_ENABLE(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, BIT(0));
-}
-
-static inline void RTW89_SET_WOW_GLOBAL_DROP_ALL_PKT(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, BIT(1));
-}
-
-static inline void RTW89_SET_WOW_GLOBAL_RX_PARSE_AFTER_WAKE(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, BIT(2));
-}
-
-static inline void RTW89_SET_WOW_GLOBAL_WAKE_BAR_PULLED(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, BIT(3));
-}
-
-static inline void RTW89_SET_WOW_GLOBAL_MAC_ID(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8));
-}
+struct rtw89_h2c_wow_global {
+ __le32 w0;
+ struct rtw89_wow_key_info key_info;
+} __packed;
-static inline void RTW89_SET_WOW_GLOBAL_PAIRWISE_SEC_ALGO(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 16));
-}
+#define RTW89_H2C_WOW_GLOBAL_W0_ENABLE BIT(0)
+#define RTW89_H2C_WOW_GLOBAL_W0_DROP_ALL_PKT BIT(1)
+#define RTW89_H2C_WOW_GLOBAL_W0_RX_PARSE_AFTER_WAKE BIT(2)
+#define RTW89_H2C_WOW_GLOBAL_W0_WAKE_BAR_PULLED BIT(3)
+#define RTW89_H2C_WOW_GLOBAL_W0_MAC_ID GENMASK(15, 8)
+#define RTW89_H2C_WOW_GLOBAL_W0_PAIRWISE_SEC_ALGO GENMASK(23, 16)
+#define RTW89_H2C_WOW_GLOBAL_W0_GROUP_SEC_ALGO GENMASK(31, 24)
-static inline void RTW89_SET_WOW_GLOBAL_GROUP_SEC_ALGO(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24));
-}
+#define RTW89_MAX_SUPPORT_NL_NUM 16
+struct rtw89_h2c_cfg_nlo {
+ __le32 w0;
+ u8 nlo_cnt;
+ u8 rsvd[3];
+ __le32 patterncheck;
+ __le32 rsvd1;
+ __le32 rsvd2;
+ u8 ssid_len[RTW89_MAX_SUPPORT_NL_NUM];
+ u8 chiper[RTW89_MAX_SUPPORT_NL_NUM];
+ u8 rsvd3[24];
+ u8 ssid[RTW89_MAX_SUPPORT_NL_NUM][IEEE80211_MAX_SSID_LEN];
+} __packed;
-static inline void RTW89_SET_WOW_GLOBAL_REMOTECTRL_INFO_CONTENT(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(31, 0));
-}
+#define RTW89_H2C_NLO_W0_ENABLE BIT(0)
+#define RTW89_H2C_NLO_W0_IGNORE_CIPHER BIT(2)
+#define RTW89_H2C_NLO_W0_MACID GENMASK(31, 24)
static inline void RTW89_SET_WOW_WAKEUP_CTRL_PATTERN_MATCH_ENABLE(void *h2c, u32 val)
{
@@ -2307,6 +2076,34 @@ static inline void RTW89_SET_WOW_CAM_UPD_VALID(void *h2c, u32 val)
le32p_replace_bits((__le32 *)h2c + 5, val, BIT(31));
}
+struct rtw89_h2c_wow_gtk_ofld {
+ __le32 w0;
+ __le32 w1;
+ struct rtw89_wow_gtk_info gtk_info;
+} __packed;
+
+#define RTW89_H2C_WOW_GTK_OFLD_W0_EN BIT(0)
+#define RTW89_H2C_WOW_GTK_OFLD_W0_TKIP_EN BIT(1)
+#define RTW89_H2C_WOW_GTK_OFLD_W0_IEEE80211W_EN BIT(2)
+#define RTW89_H2C_WOW_GTK_OFLD_W0_PAIRWISE_WAKEUP BIT(3)
+#define RTW89_H2C_WOW_GTK_OFLD_W0_NOREKEY_WAKEUP BIT(4)
+#define RTW89_H2C_WOW_GTK_OFLD_W0_MAC_ID GENMASK(23, 16)
+#define RTW89_H2C_WOW_GTK_OFLD_W0_GTK_RSP_ID GENMASK(31, 24)
+#define RTW89_H2C_WOW_GTK_OFLD_W1_PMF_SA_QUERY_ID GENMASK(7, 0)
+#define RTW89_H2C_WOW_GTK_OFLD_W1_PMF_BIP_SEC_ALGO GENMASK(9, 8)
+#define RTW89_H2C_WOW_GTK_OFLD_W1_ALGO_AKM_SUIT GENMASK(17, 10)
+
+struct rtw89_h2c_arp_offload {
+ __le32 w0;
+ __le32 w1;
+} __packed;
+
+#define RTW89_H2C_ARP_OFFLOAD_W0_ENABLE BIT(0)
+#define RTW89_H2C_ARP_OFFLOAD_W0_ACTION BIT(1)
+#define RTW89_H2C_ARP_OFFLOAD_W0_MACID GENMASK(23, 16)
+#define RTW89_H2C_ARP_OFFLOAD_W0_PKT_ID GENMASK(31, 24)
+#define RTW89_H2C_ARP_OFFLOAD_W1_CONTENT GENMASK(31, 0)
+
enum rtw89_btc_btf_h2c_class {
BTFC_SET = 0x10,
BTFC_GET = 0x11,
@@ -2360,10 +2157,15 @@ enum rtw89_btc_cxdrvinfo {
enum rtw89_scan_mode {
RTW89_SCAN_IMMEDIATE,
+ RTW89_SCAN_DELAY,
};
enum rtw89_scan_type {
RTW89_SCAN_ONCE,
+ RTW89_SCAN_NORMAL,
+ RTW89_SCAN_NORMAL_SLOW,
+ RTW89_SCAN_SEAMLESS,
+ RTW89_SCAN_MAX,
};
static inline void RTW89_SET_FWCMD_CXHDR_TYPE(void *cmd, u8 val)
@@ -2395,6 +2197,56 @@ struct rtw89_h2c_cxctrl_v7 {
#define H2C_LEN_CXDRVHDR sizeof(struct rtw89_h2c_cxhdr)
#define H2C_LEN_CXDRVHDR_V7 sizeof(struct rtw89_h2c_cxhdr_v7)
+struct rtw89_btc_wl_role_info_v7_u8 {
+ u8 connect_cnt;
+ u8 link_mode;
+ u8 link_mode_chg;
+ u8 p2p_2g;
+
+ struct rtw89_btc_wl_active_role_v7 active_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER];
+} __packed;
+
+struct rtw89_btc_wl_role_info_v7_u32 {
+ __le32 role_map;
+ __le32 mrole_type;
+ __le32 mrole_noa_duration;
+ __le32 dbcc_en;
+ __le32 dbcc_chg;
+ __le32 dbcc_2g_phy;
+} __packed;
+
+struct rtw89_h2c_cxrole_v7 {
+ struct rtw89_h2c_cxhdr_v7 hdr;
+ struct rtw89_btc_wl_role_info_v7_u8 _u8;
+ struct rtw89_btc_wl_role_info_v7_u32 _u32;
+} __packed;
+
+struct rtw89_btc_wl_role_info_v8_u8 {
+ u8 connect_cnt;
+ u8 link_mode;
+ u8 link_mode_chg;
+ u8 p2p_2g;
+
+ u8 pta_req_band;
+ u8 dbcc_en;
+ u8 dbcc_chg;
+ u8 dbcc_2g_phy;
+
+ struct rtw89_btc_wl_rlink rlink[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM];
+} __packed;
+
+struct rtw89_btc_wl_role_info_v8_u32 {
+ __le32 role_map;
+ __le32 mrole_type;
+ __le32 mrole_noa_duration;
+} __packed;
+
+struct rtw89_h2c_cxrole_v8 {
+ struct rtw89_h2c_cxhdr_v7 hdr;
+ struct rtw89_btc_wl_role_info_v8_u8 _u8;
+ struct rtw89_btc_wl_role_info_v8_u32 _u32;
+} __packed;
+
struct rtw89_h2c_cxinit {
struct rtw89_h2c_cxhdr hdr;
u8 ant_type;
@@ -2840,6 +2692,7 @@ struct rtw89_h2c_chinfo_elem_be {
__le32 w4;
__le32 w5;
__le32 w6;
+ __le32 w7;
} __packed;
#define RTW89_H2C_CHINFO_BE_W0_PERIOD GENMASK(7, 0)
@@ -2871,6 +2724,7 @@ struct rtw89_h2c_chinfo_elem_be {
#define RTW89_H2C_CHINFO_BE_W5_FW_PROBE0_SSIDS GENMASK(31, 16)
#define RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_SHORTSSIDS GENMASK(15, 0)
#define RTW89_H2C_CHINFO_BE_W6_FW_PROBE0_BSSIDS GENMASK(31, 16)
+#define RTW89_H2C_CHINFO_BE_W7_PERIOD_V1 GENMASK(15, 0)
struct rtw89_h2c_chinfo {
u8 ch_num;
@@ -2880,6 +2734,14 @@ struct rtw89_h2c_chinfo {
struct rtw89_h2c_chinfo_elem elem[] __counted_by(ch_num);
} __packed;
+struct rtw89_h2c_chinfo_be {
+ u8 ch_num;
+ u8 elem_size;
+ u8 arg;
+ u8 rsvd0;
+ struct rtw89_h2c_chinfo_elem_be elem[] __counted_by(ch_num);
+} __packed;
+
#define RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK BIT(0)
#define RTW89_H2C_CHINFO_ARG_APPEND_MASK BIT(1)
@@ -2909,6 +2771,8 @@ struct rtw89_h2c_scanofld {
#define RTW89_H2C_SCANOFLD_W1_PROBE_REQ_PKT_ID GENMASK(31, 24)
#define RTW89_H2C_SCANOFLD_W2_NORM_PD GENMASK(15, 0)
#define RTW89_H2C_SCANOFLD_W2_SLOW_PD GENMASK(23, 16)
+#define RTW89_H2C_SCANOFLD_W3_TSF_HIGH GENMASK(31, 0)
+#define RTW89_H2C_SCANOFLD_W4_TSF_LOW GENMASK(31, 0)
struct rtw89_h2c_scanofld_be_macc_role {
__le32 w0;
@@ -2924,6 +2788,7 @@ struct rtw89_h2c_scanofld_be_opch {
__le32 w1;
__le32 w2;
__le32 w3;
+ __le32 w4;
} __packed;
#define RTW89_H2C_SCANOFLD_BE_OPCH_W0_MACID GENMASK(15, 0)
@@ -2945,6 +2810,7 @@ struct rtw89_h2c_scanofld_be_opch {
#define RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT1 GENMASK(15, 8)
#define RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT2 GENMASK(23, 16)
#define RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT3 GENMASK(31, 24)
+#define RTW89_H2C_SCANOFLD_BE_OPCH_W4_DURATION_V1 GENMASK(15, 0)
struct rtw89_h2c_scanofld_be {
__le32 w0;
@@ -2955,7 +2821,10 @@ struct rtw89_h2c_scanofld_be {
__le32 w5;
__le32 w6;
__le32 w7;
- struct rtw89_h2c_scanofld_be_macc_role role[];
+ __le32 w8;
+ __le32 w9; /* Added after SCAN_OFFLOAD_BE_V1 */
+ /* struct rtw89_h2c_scanofld_be_macc_role (flexible number) */
+ /* struct rtw89_h2c_scanofld_be_opch (flexible number) */
} __packed;
#define RTW89_H2C_SCANOFLD_BE_W0_OP GENMASK(1, 0)
@@ -2966,6 +2835,7 @@ struct rtw89_h2c_scanofld_be {
#define RTW89_H2C_SCANOFLD_BE_W0_MACID GENMASK(23, 8)
#define RTW89_H2C_SCANOFLD_BE_W0_PORT GENMASK(26, 24)
#define RTW89_H2C_SCANOFLD_BE_W0_BAND GENMASK(28, 27)
+#define RTW89_H2C_SCANOFLD_BE_W0_PROBE_WITH_RATE BIT(29)
#define RTW89_H2C_SCANOFLD_BE_W1_NUM_MACC_ROLE GENMASK(7, 0)
#define RTW89_H2C_SCANOFLD_BE_W1_NUM_OP GENMASK(15, 8)
#define RTW89_H2C_SCANOFLD_BE_W1_NORM_PD GENMASK(31, 16)
@@ -2982,6 +2852,26 @@ struct rtw89_h2c_scanofld_be {
#define RTW89_H2C_SCANOFLD_BE_W5_MLO_MODE GENMASK(31, 0)
#define RTW89_H2C_SCANOFLD_BE_W6_CHAN_PROHIB_LOW GENMASK(31, 0)
#define RTW89_H2C_SCANOFLD_BE_W7_CHAN_PROHIB_HIGH GENMASK(31, 0)
+#define RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_2GHZ GENMASK(7, 0)
+#define RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_5GHZ GENMASK(15, 8)
+#define RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_6GHZ GENMASK(23, 16)
+#define RTW89_H2C_SCANOFLD_BE_W9_SIZE_CFG GENMASK(7, 0)
+#define RTW89_H2C_SCANOFLD_BE_W9_SIZE_MACC GENMASK(15, 8)
+#define RTW89_H2C_SCANOFLD_BE_W9_SIZE_OP GENMASK(23, 16)
+
+struct rtw89_h2c_fwips {
+ __le32 w0;
+} __packed;
+
+#define RTW89_H2C_FW_IPS_W0_MACID GENMASK(7, 0)
+#define RTW89_H2C_FW_IPS_W0_ENABLE BIT(8)
+
+struct rtw89_h2c_mlo_link_cfg {
+ __le32 w0;
+};
+
+#define RTW89_H2C_MLO_LINK_CFG_W0_MACID GENMASK(15, 0)
+#define RTW89_H2C_MLO_LINK_CFG_W0_OPTION GENMASK(19, 16)
static inline void RTW89_SET_FWCMD_P2P_MACID(void *cmd, u32 val)
{
@@ -3636,6 +3526,16 @@ struct rtw89_h2c_mrc_upd_duration {
#define RTW89_H2C_MRC_UPD_DURATION_SLOT_SLOT_IDX GENMASK(7, 0)
#define RTW89_H2C_MRC_UPD_DURATION_SLOT_DURATION GENMASK(31, 16)
+struct rtw89_h2c_wow_aoac {
+ __le32 w0;
+} __packed;
+
+struct rtw89_h2c_ap_info {
+ __le32 w0;
+} __packed;
+
+#define RTW89_H2C_AP_INFO_W0_PWR_INT_EN BIT(0)
+
#define RTW89_C2H_HEADER_LEN 8
struct rtw89_c2h_hdr {
@@ -3672,6 +3572,7 @@ struct rtw89_c2h_done_ack {
#define RTW89_C2H_DONE_ACK_W2_CLASS GENMASK(7, 2)
#define RTW89_C2H_DONE_ACK_W2_FUNC GENMASK(15, 8)
#define RTW89_C2H_DONE_ACK_W2_H2C_RETURN GENMASK(23, 16)
+#define RTW89_C2H_SCAN_DONE_ACK_RETURN GENMASK(5, 0)
#define RTW89_C2H_DONE_ACK_W2_H2C_SEQ GENMASK(31, 24)
#define RTW89_GET_MAC_C2H_REV_ACK_CAT(c2h) \
@@ -3730,6 +3631,19 @@ struct rtw89_c2h_ra_rpt {
#define RTW89_C2H_RA_RPT_W3_MD_SEL_B2 BIT(15)
#define RTW89_C2H_RA_RPT_W3_BW_B2 BIT(16)
+struct rtw89_c2h_fw_scan_rpt {
+ struct rtw89_c2h_hdr hdr;
+ u8 phy_idx;
+ u8 band;
+ u8 center_ch;
+ u8 ofdm_pd_idx; /* in unit of 2 dBm */
+#define PD_LOWER_BOUND_BASE 102
+ s8 cck_pd_idx;
+ u8 rsvd0;
+ u8 rsvd1;
+ u8 rsvd2;
+} __packed;
+
/* For WiFi 6 chips:
* VHT, HE, HT-old: [6:4]: NSS, [3:0]: MCS
* HT-new: [6:5]: NA, [4:0]: MCS
@@ -3760,6 +3674,7 @@ struct rtw89_c2h_scanofld {
__le32 w5;
__le32 w6;
__le32 w7;
+ __le32 w8;
} __packed;
#define RTW89_C2H_SCANOFLD_W2_PRI_CH GENMASK(7, 0)
@@ -3774,6 +3689,8 @@ struct rtw89_c2h_scanofld {
#define RTW89_C2H_SCANOFLD_W6_EXPECT_PERIOD GENMASK(15, 8)
#define RTW89_C2H_SCANOFLD_W6_FW_DEF GENMASK(23, 16)
#define RTW89_C2H_SCANOFLD_W7_REPORT_TSF GENMASK(31, 0)
+#define RTW89_C2H_SCANOFLD_W8_PERIOD_V1 GENMASK(15, 0)
+#define RTW89_C2H_SCANOFLD_W8_EXPECT_PERIOD_V1 GENMASK(31, 16)
#define RTW89_GET_MAC_C2H_MCC_RCV_ACK_GROUP(c2h) \
le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(1, 0))
@@ -3824,6 +3741,25 @@ static_assert(sizeof(struct rtw89_mac_mcc_tsf_rpt) <= RTW89_COMPLETION_BUF_SIZE)
#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_HIGH(c2h) \
le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0))
+struct rtw89_c2h_mlo_link_cfg_rpt {
+ struct rtw89_c2h_hdr hdr;
+ __le32 w2;
+} __packed;
+
+#define RTW89_C2H_MLO_LINK_CFG_RPT_W2_MACID GENMASK(15, 0)
+#define RTW89_C2H_MLO_LINK_CFG_RPT_W2_STATUS GENMASK(19, 16)
+
+enum rtw89_c2h_mlo_link_status {
+ RTW89_C2H_MLO_LINK_CFG_IDLE = 0,
+ RTW89_C2H_MLO_LINK_CFG_DONE = 1,
+ RTW89_C2H_MLO_LINK_CFG_ISSUE_NULL_FAIL = 2,
+ RTW89_C2H_MLO_LINK_CFG_TX_NULL_FAIL = 3,
+ RTW89_C2H_MLO_LINK_CFG_ROLE_NOT_EXIST = 4,
+ RTW89_C2H_MLO_LINK_CFG_NULL_1_TIMEOUT = 5,
+ RTW89_C2H_MLO_LINK_CFG_NULL_0_TIMEOUT = 6,
+ RTW89_C2H_MLO_LINK_CFG_RUNNING = 0xff,
+};
+
struct rtw89_mac_mrc_tsf_rpt {
unsigned int num;
u64 tsfs[RTW89_MAC_MRC_MAX_REQ_TSF_NUM];
@@ -3864,6 +3800,54 @@ struct rtw89_c2h_pkt_ofld_rsp {
#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_OP GENMASK(10, 8)
#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_LEN GENMASK(31, 16)
+struct rtw89_c2h_tx_duty_rpt {
+ struct rtw89_c2h_hdr c2h_hdr;
+ __le32 w2;
+} __packed;
+
+#define RTW89_C2H_TX_DUTY_RPT_W2_TIMER_ERR GENMASK(2, 0)
+
+struct rtw89_c2h_wow_aoac_report {
+ struct rtw89_c2h_hdr c2h_hdr;
+ u8 rpt_ver;
+ u8 sec_type;
+ u8 key_idx;
+ u8 pattern_idx;
+ u8 rekey_ok;
+ u8 rsvd1[3];
+ u8 ptk_tx_iv[8];
+ u8 eapol_key_replay_count[8];
+ u8 gtk[32];
+ u8 ptk_rx_iv[8];
+ u8 gtk_rx_iv[4][8];
+ __le64 igtk_key_id;
+ __le64 igtk_ipn;
+ u8 igtk[32];
+ u8 csa_pri_ch;
+ u8 csa_bw_ch_offset;
+ u8 csa_ch_band_chsw_failed;
+ u8 csa_rsvd1;
+} __packed;
+
+#define RTW89_C2H_WOW_AOAC_RPT_REKEY_IDX BIT(0)
+
+struct rtw89_c2h_pwr_int_notify {
+ struct rtw89_c2h_hdr hdr;
+ __le32 w2;
+} __packed;
+
+#define RTW89_C2H_PWR_INT_NOTIFY_W2_MACID GENMASK(15, 0)
+#define RTW89_C2H_PWR_INT_NOTIFY_W2_PWR_STATUS BIT(16)
+
+struct rtw89_h2c_tx_duty {
+ __le32 w0;
+ __le32 w1;
+} __packed;
+
+#define RTW89_H2C_TX_DUTY_W0_PAUSE_INTVL_MASK GENMASK(15, 0)
+#define RTW89_H2C_TX_DUTY_W0_TX_INTVL_MASK GENMASK(31, 16)
+#define RTW89_H2C_TX_DUTY_W1_STOP BIT(0)
+
struct rtw89_h2c_bcnfltr {
__le32 w0;
} __packed;
@@ -3872,7 +3856,8 @@ struct rtw89_h2c_bcnfltr {
#define RTW89_H2C_BCNFLTR_W0_MON_BCN BIT(1)
#define RTW89_H2C_BCNFLTR_W0_MON_EN BIT(2)
#define RTW89_H2C_BCNFLTR_W0_MODE GENMASK(4, 3)
-#define RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT GENMASK(11, 8)
+#define RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT_H3 GENMASK(7, 5)
+#define RTW89_H2C_BCNFLTR_W0_BCN_LOSS_CNT_L4 GENMASK(11, 8)
#define RTW89_H2C_BCNFLTR_W0_RSSI_HYST GENMASK(15, 12)
#define RTW89_H2C_BCNFLTR_W0_RSSI_THRESHOLD GENMASK(23, 16)
#define RTW89_H2C_BCNFLTR_W0_MAC_ID GENMASK(31, 24)
@@ -3949,21 +3934,39 @@ enum rtw89_fw_element_id {
RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU = 17,
RTW89_FW_ELEMENT_ID_TXPWR_TRK = 18,
RTW89_FW_ELEMENT_ID_RFKLOG_FMT = 19,
+ RTW89_FW_ELEMENT_ID_REGD = 20,
+ RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_2GHZ = 21,
+ RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_5GHZ = 22,
+ RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_6GHZ = 23,
+ RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_2GHZ = 24,
+ RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_5GHZ = 25,
+ RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_6GHZ = 26,
RTW89_FW_ELEMENT_ID_NUM,
};
-#define BITS_OF_RTW89_TXPWR_FW_ELEMENTS \
+#define BITS_OF_RTW89_TXPWR_FW_ELEMENTS_NO_6GHZ \
(BIT(RTW89_FW_ELEMENT_ID_TXPWR_BYRATE) | \
BIT(RTW89_FW_ELEMENT_ID_TXPWR_LMT_2GHZ) | \
BIT(RTW89_FW_ELEMENT_ID_TXPWR_LMT_5GHZ) | \
- BIT(RTW89_FW_ELEMENT_ID_TXPWR_LMT_6GHZ) | \
BIT(RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_2GHZ) | \
BIT(RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_5GHZ) | \
- BIT(RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_6GHZ) | \
BIT(RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT) | \
BIT(RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU))
+#define BITS_OF_RTW89_TXPWR_FW_ELEMENTS \
+ (BITS_OF_RTW89_TXPWR_FW_ELEMENTS_NO_6GHZ | \
+ BIT(RTW89_FW_ELEMENT_ID_TXPWR_LMT_6GHZ) | \
+ BIT(RTW89_FW_ELEMENT_ID_TXPWR_LMT_RU_6GHZ))
+
+#define RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_NO_6GHZ \
+ (BIT(RTW89_FW_ELEMENT_ID_BB_REG) | \
+ BIT(RTW89_FW_ELEMENT_ID_RADIO_A) | \
+ BIT(RTW89_FW_ELEMENT_ID_RADIO_B) | \
+ BIT(RTW89_FW_ELEMENT_ID_RF_NCTL) | \
+ BIT(RTW89_FW_ELEMENT_ID_TXPWR_TRK) | \
+ BITS_OF_RTW89_TXPWR_FW_ELEMENTS_NO_6GHZ)
+
#define RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS (BIT(RTW89_FW_ELEMENT_ID_BBMCU0) | \
BIT(RTW89_FW_ELEMENT_ID_BB_REG) | \
BIT(RTW89_FW_ELEMENT_ID_RADIO_A) | \
@@ -3981,6 +3984,15 @@ struct __rtw89_fw_txpwr_element {
u8 content[];
} __packed;
+struct __rtw89_fw_regd_element {
+ u8 rsvd0;
+ u8 rsvd1;
+ u8 rsvd2;
+ u8 ent_sz;
+ __le32 num_ents;
+ u8 content[];
+} __packed;
+
enum rtw89_fw_txpwr_trk_type {
__RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START = 0,
RTW89_FW_TXPWR_TRK_TYPE_6GB_N = 0,
@@ -4072,6 +4084,7 @@ struct rtw89_fw_element_hdr {
__le16 offset[];
} __packed rfk_log_fmt;
struct __rtw89_fw_txpwr_element txpwr;
+ struct __rtw89_fw_regd_element regd;
} __packed u;
} __packed;
@@ -4141,16 +4154,41 @@ struct rtw89_fw_h2c_rf_reg_info {
/* CLASS 1 - WOW */
#define H2C_CL_MAC_WOW 0x1
-#define H2C_FUNC_KEEP_ALIVE 0x0
-#define H2C_FUNC_DISCONNECT_DETECT 0x1
-#define H2C_FUNC_WOW_GLOBAL 0x2
-#define H2C_FUNC_WAKEUP_CTRL 0x8
-#define H2C_FUNC_WOW_CAM_UPD 0xC
+enum rtw89_wow_h2c_func {
+ H2C_FUNC_KEEP_ALIVE = 0x0,
+ H2C_FUNC_DISCONNECT_DETECT = 0x1,
+ H2C_FUNC_WOW_GLOBAL = 0x2,
+ H2C_FUNC_GTK_OFLD = 0x3,
+ H2C_FUNC_ARP_OFLD = 0x4,
+ H2C_FUNC_NLO = 0x7,
+ H2C_FUNC_WAKEUP_CTRL = 0x8,
+ H2C_FUNC_WOW_CAM_UPD = 0xC,
+ H2C_FUNC_AOAC_REPORT_REQ = 0xD,
+
+ NUM_OF_RTW89_WOW_H2C_FUNC,
+};
+
+#define RTW89_WOW_WAIT_COND(tag, func) \
+ ((tag) * NUM_OF_RTW89_WOW_H2C_FUNC + (func))
+
+#define RTW89_WOW_WAIT_COND_AOAC \
+ RTW89_WOW_WAIT_COND(0 /* don't care */, H2C_FUNC_AOAC_REPORT_REQ)
/* CLASS 2 - PS */
#define H2C_CL_MAC_PS 0x2
-#define H2C_FUNC_MAC_LPS_PARM 0x0
-#define H2C_FUNC_P2P_ACT 0x1
+enum rtw89_ps_h2c_func {
+ H2C_FUNC_MAC_LPS_PARM = 0x0,
+ H2C_FUNC_P2P_ACT = 0x1,
+ H2C_FUNC_IPS_CFG = 0x3,
+
+ NUM_OF_RTW89_PS_H2C_FUNC,
+};
+
+#define RTW89_PS_WAIT_COND(tag, func) \
+ ((tag) * NUM_OF_RTW89_PS_H2C_FUNC + (func))
+
+#define RTW89_PS_WAIT_COND_IPS_CFG \
+ RTW89_PS_WAIT_COND(0 /* don't care */, H2C_FUNC_IPS_CFG)
/* CLASS 3 - FW download */
#define H2C_CL_MAC_FWDL 0x3
@@ -4186,6 +4224,7 @@ enum rtw89_fw_ofld_h2c_func {
H2C_FUNC_OFLD_CFG = 0x14,
H2C_FUNC_ADD_SCANOFLD_CH = 0x16,
H2C_FUNC_SCANOFLD = 0x17,
+ H2C_FUNC_TX_DUTY = 0x18,
H2C_FUNC_PKT_DROP = 0x1b,
H2C_FUNC_CFG_BCNFLTR = 0x1e,
H2C_FUNC_OFLD_RSSI = 0x1f,
@@ -4240,6 +4279,26 @@ enum rtw89_mcc_h2c_func {
#define RTW89_MCC_WAIT_COND(group, func) \
((group) * NUM_OF_RTW89_MCC_H2C_FUNC + (func))
+/* CLASS 20 - MLO */
+#define H2C_CL_MLO 0x14
+enum rtw89_mlo_h2c_func {
+ H2C_FUNC_MLO_TBL_CFG = 0x0,
+ H2C_FUNC_MLO_STA_CFG = 0x1,
+ H2C_FUNC_MLO_TTLM = 0x2,
+ H2C_FUNC_MLO_DM_CFG = 0x3,
+ H2C_FUNC_MLO_EMLSR_STA_CFG = 0x4,
+ H2C_FUNC_MLO_MCMLO_RELINK_DROP = 0x5,
+ H2C_FUNC_MLO_MCMLO_SN_SYNC = 0x6,
+ H2C_FUNC_MLO_RELINK = 0x7,
+ H2C_FUNC_MLO_LINK_CFG = 0x8,
+ H2C_FUNC_MLO_DM_DBG = 0x9,
+
+ NUM_OF_RTW89_MLO_H2C_FUNC,
+};
+
+#define RTW89_MLO_WAIT_COND(macid, func) \
+ ((macid) * NUM_OF_RTW89_MLO_H2C_FUNC + (func))
+
/* CLASS 24 - MRC */
#define H2C_CL_MRC 0x18
enum rtw89_mrc_h2c_func {
@@ -4261,6 +4320,10 @@ enum rtw89_mrc_h2c_func {
#define RTW89_MRC_WAIT_COND_REQ_TSF \
RTW89_MRC_WAIT_COND(0 /* don't care */, H2C_FUNC_MRC_REQ_TSF)
+/* CLASS 36 - AP */
+#define H2C_CL_AP 0x24
+#define H2C_FUNC_AP_INFO 0x0
+
#define H2C_CAT_OUTSRC 0x2
#define H2C_CL_OUTSRC_RA 0x1
@@ -4268,6 +4331,7 @@ enum rtw89_mrc_h2c_func {
#define H2C_CL_OUTSRC_DM 0x2
#define H2C_FUNC_FW_LPS_CH_INFO 0xb
+#define H2C_FUNC_FW_LPS_ML_CMN_INFO 0xe
#define H2C_CL_OUTSRC_RF_REG_A 0x8
#define H2C_CL_OUTSRC_RF_REG_B 0x9
@@ -4297,7 +4361,7 @@ struct rtw89_fw_h2c_rf_get_mccch {
#define NUM_OF_RTW89_FW_RFK_PATH 2
#define NUM_OF_RTW89_FW_RFK_TBL 3
-struct rtw89_fw_h2c_rfk_pre_info {
+struct rtw89_fw_h2c_rfk_pre_info_common {
struct {
__le32 ch[NUM_OF_RTW89_FW_RFK_PATH][NUM_OF_RTW89_FW_RFK_TBL];
__le32 band[NUM_OF_RTW89_FW_RFK_PATH][NUM_OF_RTW89_FW_RFK_TBL];
@@ -4310,6 +4374,11 @@ struct rtw89_fw_h2c_rfk_pre_info {
} __packed tbl;
__le32 phy_idx;
+} __packed;
+
+struct rtw89_fw_h2c_rfk_pre_info_v0 {
+ struct rtw89_fw_h2c_rfk_pre_info_common common;
+
__le32 cur_band;
__le32 cur_bw;
__le32 cur_center_ch;
@@ -4329,6 +4398,16 @@ struct rtw89_fw_h2c_rfk_pre_info {
} __packed mlo;
} __packed;
+struct rtw89_fw_h2c_rfk_pre_info_v1 {
+ struct rtw89_fw_h2c_rfk_pre_info_common common;
+ __le32 mlo_1_1;
+} __packed;
+
+struct rtw89_fw_h2c_rfk_pre_info {
+ struct rtw89_fw_h2c_rfk_pre_info_v1 base_v1;
+ __le32 cur_bandwidth[NUM_OF_RTW89_FW_RFK_PATH];
+} __packed;
+
struct rtw89_h2c_rf_tssi {
__le16 len;
u8 phy;
@@ -4391,7 +4470,7 @@ struct rtw89_h2c_rf_dack {
__le32 type;
} __packed;
-struct rtw89_h2c_rf_rxdck {
+struct rtw89_h2c_rf_rxdck_v0 {
u8 len;
u8 phy;
u8 is_afe;
@@ -4402,6 +4481,11 @@ struct rtw89_h2c_rf_rxdck {
u8 rxdck_dbg_en;
} __packed;
+struct rtw89_h2c_rf_rxdck {
+ struct rtw89_h2c_rf_rxdck_v0 v0;
+ u8 is_chl_k;
+} __packed;
+
enum rtw89_rf_log_type {
RTW89_RF_RUN_LOG = 0,
RTW89_RF_RPT_LOG = 1,
@@ -4418,6 +4502,42 @@ struct rtw89_c2h_rf_run_log {
__le32 arg[4];
} __packed;
+struct rtw89_c2h_rf_iqk_rpt_log {
+ bool iqk_tx_fail[2];
+ bool iqk_rx_fail[2];
+ bool is_iqk_init;
+ bool is_reload;
+ bool is_wb_txiqk[2];
+ bool is_wb_rxiqk[2];
+ bool is_nbiqk;
+ bool txiqk_en;
+ bool rxiqk_en;
+ bool lok_en;
+ bool iqk_xym_en;
+ bool iqk_sram_en;
+ bool iqk_fft_en;
+ bool is_fw_iqk;
+ bool is_iqk_enable;
+ bool iqk_cfir_en;
+ bool thermal_rek_en;
+ u8 iqk_band[2];
+ u8 iqk_ch[2];
+ u8 iqk_bw[2];
+ u8 iqk_times;
+ u8 version;
+ u8 phy;
+ u8 fwk_status;
+ u8 rsvd;
+ __le32 reload_cnt;
+ __le32 iqk_fail_cnt;
+ __le32 lok_idac[2];
+ __le32 lok_vbuf[2];
+ __le32 rftxgain[2][4];
+ __le32 rfrxgain[2][4];
+ __le32 tx_xym[2][4];
+ __le32 rx_xym[2][4];
+} __packed;
+
struct rtw89_c2h_rf_dpk_rpt_log {
u8 ver;
u8 idx[2];
@@ -4439,19 +4559,25 @@ struct rtw89_c2h_rf_dpk_rpt_log {
struct rtw89_c2h_rf_dack_rpt_log {
u8 fwdack_ver;
- u8 fwdack_rpt_ver;
+ u8 fwdack_info_ver;
u8 msbk_d[2][2][16];
u8 dadck_d[2][2];
u8 cdack_d[2][2][2];
- __le16 addck2_d[2][2][2];
+ u8 addck2_hd[2][2][2];
+ u8 addck2_ld[2][2][2];
u8 adgaink_d[2][2];
- __le16 biask_d[2][2];
+ u8 biask_hd[2][2];
+ u8 biask_ld[2][2];
u8 addck_timeout;
u8 cdack_timeout;
u8 dadck_timeout;
u8 msbk_timeout;
u8 adgaink_timeout;
+ u8 wbadcdck_timeout;
+ u8 drck_timeout;
u8 dack_fail;
+ u8 wbdck_d[2];
+ u8 rck_d;
} __packed;
struct rtw89_c2h_rf_rxdck_rpt_log {
@@ -4462,6 +4588,14 @@ struct rtw89_c2h_rf_rxdck_rpt_log {
u8 timeout[2];
} __packed;
+struct rtw89_c2h_rf_tssi_rpt_log {
+ s8 alignment_power[2][2][4];
+ u8 alignment_power_cw_h[2][2][4];
+ u8 alignment_power_cw_l[2][2][4];
+ u8 tssi_alimk_state[2][2];
+ u8 default_txagc_offset[2][2];
+} __packed;
+
struct rtw89_c2h_rf_txgapk_rpt_log {
__le32 r0x8010[2];
__le32 chk_cnt;
@@ -4479,6 +4613,12 @@ struct rtw89_c2h_rfk_report {
u8 version;
} __packed;
+struct rtw89_c2h_rf_tas_info {
+ struct rtw89_c2h_hdr hdr;
+ __le32 cur_idx;
+ __le16 txpwr_history[20];
+} __packed;
+
#define RTW89_FW_RSVD_PLE_SIZE 0x800
#define RTW89_FW_BACKTRACE_INFO_SIZE 8
@@ -4509,65 +4649,70 @@ void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u8 type, u8 cat, u8 class, u8 func,
bool rack, bool dack, u32 len);
int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta);
+ struct rtw89_sta_link *rtwsta_link);
+int rtw89_fw_h2c_txtime_cmac_tbl_g7(struct rtw89_dev *rtwdev,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta);
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif);
+ struct rtw89_vif_link *rtwvif_link);
int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif);
-int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *vif,
- struct rtw89_sta *rtwsta, const u8 *scan_mac_addr);
+ struct rtw89_vif_link *rtwvif_link);
+int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif,
+ struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr);
int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta);
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h);
-void rtw89_fw_c2h_work(struct work_struct *work);
+void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work);
int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
enum rtw89_upd_mode upd_mode);
-int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta, bool dis_conn);
+int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link, bool dis_conn);
int rtw89_fw_h2c_notify_dbcc(struct rtw89_dev *rtwdev, bool en);
int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
bool pause);
-int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u8 ac, u32 val);
int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev);
+int rtw89_fw_h2c_tx_duty(struct rtw89_dev *rtwdev, u8 lv);
int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
+ struct rtw89_vif_link *rtwvif_link,
bool connect);
int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu);
-int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi);
int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_init_v7(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev, u8 type);
+int rtw89_fw_h2c_cxdrv_role_v7(struct rtw89_dev *rtwdev, u8 type);
+int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_trx(struct rtw89_dev *rtwdev, u8 type);
@@ -4575,16 +4720,14 @@ int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id);
int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id,
struct sk_buff *skb_ofld);
-int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int ch_num,
- struct list_head *chan_list);
-int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
- struct list_head *chan_list);
-int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev,
- struct rtw89_scan_option *opt,
- struct rtw89_vif *vif);
+int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
+ struct rtw89_scan_option *opt,
+ struct rtw89_vif_link *vif,
+ bool wowlan);
int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
struct rtw89_scan_option *opt,
- struct rtw89_vif *vif);
+ struct rtw89_vif_link *vif,
+ bool wowlan);
int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,
struct rtw89_fw_h2c_rf_reg_info *info,
u16 len, u8 page);
@@ -4592,26 +4735,37 @@ int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx);
int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
- enum rtw89_tssi_mode tssi_mode);
-int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
-int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
-int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
-int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
-int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
+ const struct rtw89_chan *chan, enum rtw89_tssi_mode tssi_mode);
+int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan);
+int rtw89_fw_h2c_rf_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan);
+int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan);
+int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan);
+int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan, bool is_chl_k);
int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
bool rack, bool dack);
int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len);
void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev);
+void __rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev);
void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev);
-int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u8 macid);
void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool notify_fw);
+ struct rtw89_vif_link *rtwvif_link,
+ bool notify_fw);
void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw);
-int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
bool valid, struct ieee80211_ampdu_params *params);
-int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
bool valid, struct ieee80211_ampdu_params *params);
void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users,
@@ -4619,8 +4773,11 @@ int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users,
int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
struct rtw89_lps_parm *lps_param);
-int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif);
+int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev,
+ struct rtw89_vif *rtwvif);
+int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ bool enable);
struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len);
struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len);
int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev,
@@ -4628,39 +4785,64 @@ int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev,
struct rtw89_mac_c2h_info *c2h_info);
int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable);
void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev);
-void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
- struct ieee80211_scan_request *req);
-void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_scan_request *scan_req);
+void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool aborted);
-int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool enable);
-void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
-int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool connected);
+void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
+int rtw89_hw_scan_prep_chan_list_ax(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
+void rtw89_hw_scan_free_chan_list_ax(struct rtw89_dev *rtwdev);
+int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
+int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
+int rtw89_hw_scan_prep_chan_list_be(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
+void rtw89_hw_scan_free_chan_list_be(struct rtw89_dev *rtwdev);
int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool connected);
+ struct rtw89_vif_link *rtwvif_link);
+int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev,
const struct rtw89_pkt_drop_params *params);
-int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf,
struct ieee80211_p2p_noa_desc *desc,
u8 act, u8 noa_id);
-int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
bool en);
-int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable);
int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool enable);
-int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link, bool enable);
+int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ bool enable);
+int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable);
+int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link, bool enable);
int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool enable);
-int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link, bool enable);
+int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable);
int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool enable);
+ struct rtw89_vif_link *rtwvif_link, bool enable);
int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev,
struct rtw89_wow_cam_info *cam_info);
+int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ bool enable);
+int rtw89_fw_h2c_wow_request_aoac(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev,
const struct rtw89_fw_mcc_add_req *p);
int rtw89_fw_h2c_start_mcc(struct rtw89_dev *rtwdev,
@@ -4683,7 +4865,7 @@ int rtw89_fw_h2c_mrc_add(struct rtw89_dev *rtwdev,
const struct rtw89_fw_mrc_add_arg *arg);
int rtw89_fw_h2c_mrc_start(struct rtw89_dev *rtwdev,
const struct rtw89_fw_mrc_start_arg *arg);
-int rtw89_fw_h2c_mrc_del(struct rtw89_dev *rtwdev, u8 sch_idx);
+int rtw89_fw_h2c_mrc_del(struct rtw89_dev *rtwdev, u8 sch_idx, u8 slot_idx);
int rtw89_fw_h2c_mrc_req_tsf(struct rtw89_dev *rtwdev,
const struct rtw89_fw_mrc_req_tsf_arg *arg,
struct rtw89_mac_mrc_tsf_rpt *rpt);
@@ -4693,6 +4875,9 @@ int rtw89_fw_h2c_mrc_sync(struct rtw89_dev *rtwdev,
const struct rtw89_fw_mrc_sync_arg *arg);
int rtw89_fw_h2c_mrc_upd_duration(struct rtw89_dev *rtwdev,
const struct rtw89_fw_mrc_upd_duration_arg *arg);
+int rtw89_fw_h2c_ap_info_refcount(struct rtw89_dev *rtwdev, bool en);
+int rtw89_fw_h2c_mlo_link_cfg(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ bool enable);
static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev)
{
@@ -4703,64 +4888,119 @@ static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev)
}
static inline int rtw89_chip_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- return chip->ops->h2c_default_cmac_tbl(rtwdev, rtwvif, rtwsta);
+ return chip->ops->h2c_default_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
}
static inline int rtw89_chip_h2c_default_dmac_tbl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_sta *rtwsta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (chip->ops->h2c_default_dmac_tbl)
- return chip->ops->h2c_default_dmac_tbl(rtwdev, rtwvif, rtwsta);
+ return chip->ops->h2c_default_dmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
return 0;
}
static inline int rtw89_chip_h2c_update_beacon(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- return chip->ops->h2c_update_beacon(rtwdev, rtwvif);
+ return chip->ops->h2c_update_beacon(rtwdev, rtwvif_link);
}
static inline int rtw89_chip_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- return chip->ops->h2c_assoc_cmac_tbl(rtwdev, vif, sta);
+ return chip->ops->h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
}
-static inline int rtw89_chip_h2c_ampdu_cmac_tbl(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+static inline
+int rtw89_chip_h2c_ampdu_link_cmac_tbl(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (chip->ops->h2c_ampdu_cmac_tbl)
- return chip->ops->h2c_ampdu_cmac_tbl(rtwdev, vif, sta);
+ return chip->ops->h2c_ampdu_cmac_tbl(rtwdev, rtwvif_link,
+ rtwsta_link);
+
+ return 0;
+}
+
+static inline int rtw89_chip_h2c_ampdu_cmac_tbl(struct rtw89_dev *rtwdev,
+ struct rtw89_vif *rtwvif,
+ struct rtw89_sta *rtwsta)
+{
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ int ret;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ ret = rtw89_chip_h2c_ampdu_link_cmac_tbl(rtwdev, rtwvif_link,
+ rtwsta_link);
+ if (ret)
+ return ret;
+ }
return 0;
}
static inline
+int rtw89_chip_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
+ struct rtw89_sta_link *rtwsta_link)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+
+ return chip->ops->h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
+}
+
+static inline
int rtw89_chip_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
bool valid, struct ieee80211_ampdu_params *params)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ int ret;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ ret = chip->ops->h2c_ba_cam(rtwdev, rtwvif_link, rtwsta_link,
+ valid, params);
+ if (ret)
+ return ret;
+ }
- return chip->ops->h2c_ba_cam(rtwdev, rtwsta, valid, params);
+ return 0;
}
+/* Must consider compatibility; don't insert new in the mid.
+ * Fill each field's default value in rtw89_regd_entcpy().
+ */
+struct rtw89_fw_regd_entry {
+ u8 alpha2_0;
+ u8 alpha2_1;
+ u8 rule_2ghz;
+ u8 rule_5ghz;
+ u8 rule_6ghz;
+ __le32 fmap;
+} __packed;
+
/* must consider compatibility; don't insert new in the mid */
struct rtw89_fw_txpwr_byrate_entry {
u8 band;
@@ -4854,4 +5094,10 @@ const struct rtw89_rfe_parms *
rtw89_load_rfe_data_from_fw(struct rtw89_dev *rtwdev,
const struct rtw89_rfe_parms *init);
+enum rtw89_wow_wakeup_ver {
+ RTW89_WOW_REASON_V0,
+ RTW89_WOW_REASON_V1,
+ RTW89_WOW_REASON_NUM,
+};
+
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index aa5b396b5d2b..9f0e30e75009 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -1444,6 +1444,7 @@ void rtw89_mac_notify_wake(struct rtw89_dev *rtwdev)
static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
{
#define PWR_ACT 1
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_pwr_cfg * const *cfg_seq;
int (*cfg_func)(struct rtw89_dev *rtwdev);
@@ -1472,6 +1473,9 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
return ret;
if (on) {
+ if (!test_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags))
+ mac->efuse_read_fw_secure(rtwdev);
+
set_bit(RTW89_FLAG_POWERON, rtwdev->flags);
set_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags);
set_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags);
@@ -1483,13 +1487,29 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
clear_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags);
clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags);
rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_PWR_MAJOR);
- rtw89_set_entity_state(rtwdev, false);
+ rtw89_set_entity_state(rtwdev, RTW89_PHY_0, false);
+ rtw89_set_entity_state(rtwdev, RTW89_PHY_1, false);
}
return 0;
#undef PWR_ACT
}
+int rtw89_mac_pwr_on(struct rtw89_dev *rtwdev)
+{
+ int ret;
+
+ ret = rtw89_mac_power_switch(rtwdev, true);
+ if (ret) {
+ rtw89_mac_power_switch(rtwdev, false);
+ ret = rtw89_mac_power_switch(rtwdev, true);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev)
{
rtw89_mac_power_switch(rtwdev, false);
@@ -1568,6 +1588,8 @@ static int dmac_func_en_ax(struct rtw89_dev *rtwdev)
B_AX_DLE_CPUIO_CLK_EN | B_AX_PKT_IN_CLK_EN |
B_AX_STA_SCH_CLK_EN | B_AX_TXPKT_CTRL_CLK_EN |
B_AX_WD_RLS_CLK_EN | B_AX_BBRPT_CLK_EN);
+ if (chip_id == RTL8852BT)
+ val32 |= B_AX_AXIDMA_CLK_EN;
rtw89_write32(rtwdev, R_AX_DMAC_CLK_EN, val32);
return 0;
@@ -1577,7 +1599,7 @@ static int chip_func_en_ax(struct rtw89_dev *rtwdev)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
- if (chip_id == RTL8852A || chip_id == RTL8852B)
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))
rtw89_write32_set(rtwdev, R_AX_SPS_DIG_ON_CTRL0,
B_AX_OCP_L1_MASK);
@@ -1623,6 +1645,7 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
.wde_size18 = {RTW89_WDE_PG_64, 0, 2048,},
/* 8852C PCIE SCC */
.wde_size19 = {RTW89_WDE_PG_64, 3328, 0,},
+ .wde_size23 = {RTW89_WDE_PG_64, 1022, 2,},
/* PCIE */
.ple_size0 = {RTW89_PLE_PG_128, 1520, 16,},
.ple_size0_v1 = {RTW89_PLE_PG_128, 2688, 240, 212992,},
@@ -1633,6 +1656,7 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
.ple_size6 = {RTW89_PLE_PG_128, 496, 16,},
/* DLFW */
.ple_size8 = {RTW89_PLE_PG_128, 64, 960,},
+ .ple_size9 = {RTW89_PLE_PG_128, 2288, 16,},
/* 8852C DLFW */
.ple_size18 = {RTW89_PLE_PG_128, 2544, 16,},
/* 8852C PCIE SCC */
@@ -1650,6 +1674,7 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
.wde_qt17 = {0, 0, 0, 0,},
/* 8852C PCIE SCC */
.wde_qt18 = {3228, 60, 0, 40,},
+ .wde_qt23 = {958, 48, 0, 16,},
.ple_qt0 = {320, 320, 32, 16, 13, 13, 292, 292, 64, 18, 1, 4, 0,},
.ple_qt1 = {320, 320, 32, 16, 1316, 1316, 1595, 1595, 1367, 1321, 1, 1307, 0,},
/* PCIE SCC */
@@ -1669,12 +1694,16 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
.ple_qt46 = {525, 0, 16, 20, 13, 13, 178, 0, 32, 62, 8, 16,},
/* 8852C PCIE SCC */
.ple_qt47 = {525, 0, 32, 20, 1034, 13, 1199, 0, 1053, 62, 160, 1037,},
+ .ple_qt57 = {147, 0, 16, 20, 13, 13, 178, 0, 32, 14, 8, 0,},
/* PCIE 64 */
.ple_qt58 = {147, 0, 16, 20, 157, 13, 229, 0, 172, 14, 24, 0,},
+ .ple_qt59 = {147, 0, 32, 20, 1860, 13, 2025, 0, 1879, 14, 24, 0,},
/* 8852A PCIE WOW */
.ple_qt_52a_wow = {264, 0, 32, 20, 64, 13, 1005, 0, 64, 128, 120,},
/* 8852B PCIE WOW */
.ple_qt_52b_wow = {147, 0, 16, 20, 157, 13, 133, 0, 172, 14, 24, 0,},
+ /* 8852BT PCIE WOW */
+ .ple_qt_52bt_wow = {147, 0, 32, 20, 1860, 13, 1929, 0, 1879, 14, 24, 0,},
/* 8851B PCIE WOW */
.ple_qt_51b_wow = {147, 0, 16, 20, 157, 13, 133, 0, 172, 14, 24, 0,},
.ple_rsvd_qt0 = {2, 107, 107, 6, 6, 6, 6, 0, 0, 0,},
@@ -2023,11 +2052,16 @@ int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow)
void rtw89_mac_hw_mgnt_sec(struct rtw89_dev *rtwdev, bool enable)
{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
u32 msk32 = B_AX_UC_MGNT_DEC | B_AX_BMC_MGNT_DEC;
if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
return;
+ /* 8852C enable B_AX_UC_MGNT_DEC by default */
+ if (chip->chip_id == RTL8852C)
+ msk32 = B_AX_BMC_MGNT_DEC;
+
if (enable)
rtw89_write32_set(rtwdev, R_AX_SEC_ENG_CTRL, msk32);
else
@@ -2146,8 +2180,8 @@ int rtw89_mac_preload_init(struct rtw89_dev *rtwdev, enum rtw89_mac_idx mac_idx,
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B ||
- chip->chip_id == RTL8851B || !is_qta_poh(rtwdev))
+ if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev) ||
+ !is_qta_poh(rtwdev))
return 0;
return preload_init_set(rtwdev, mac_idx, mode);
@@ -2183,8 +2217,7 @@ static void _patch_ss2f_path(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B ||
- chip->chip_id == RTL8851B)
+ if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))
return;
rtw89_write32_mask(rtwdev, R_AX_SS2FINFO_PATH, B_AX_SS_DEST_QUEUE_MASK,
@@ -2253,6 +2286,8 @@ static int sec_eng_init_ax(struct rtw89_dev *rtwdev)
/* init TX encryption */
val |= (B_AX_SEC_TX_ENC | B_AX_SEC_RX_DEC);
val |= (B_AX_MC_DEC | B_AX_BC_DEC);
+ if (chip->chip_id == RTL8852C)
+ val |= B_AX_UC_MGNT_DEC;
if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B ||
chip->chip_id == RTL8851B)
val &= ~B_AX_TX_PARTIAL_MODE;
@@ -2360,7 +2395,7 @@ static int scheduler_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
rtw89_write32_mask(rtwdev, reg, B_AX_SIFS_MACTXEN_T1_MASK,
SIFS_MACTXEN_T1);
- if (rtwdev->chip->chip_id == RTL8852B || rtwdev->chip->chip_id == RTL8851B) {
+ if (rtw89_is_rtl885xb(rtwdev)) {
reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_SCH_EXT_CTRL, mac_idx);
rtw89_write32_set(rtwdev, reg, B_AX_PORT_RST_TSF_ADV);
}
@@ -2588,7 +2623,9 @@ static int trxptcl_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
case RTL8852A:
sifs = WMAC_SPEC_SIFS_OFDM_52A;
break;
+ case RTL8851B:
case RTL8852B:
+ case RTL8852BT:
sifs = WMAC_SPEC_SIFS_OFDM_52B;
break;
default:
@@ -2632,6 +2669,7 @@ static int rmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
#define RX_MAX_LEN_UNIT 512
#define PLD_RLS_MAX_PG 127
#define RX_SPEC_MAX_LEN (11454 + RX_MAX_LEN_UNIT)
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
int ret;
u32 reg, rx_max_len, rx_qta;
u16 val;
@@ -2652,6 +2690,8 @@ static int rmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
B_AX_RX_DLK_DATA_TIME_MASK);
val = u16_replace_bits(val, TRXCFG_RMAC_CCA_TO,
B_AX_RX_DLK_CCA_TIME_MASK);
+ if (chip_id == RTL8852BT)
+ val |= B_AX_RX_DLK_RST_EN;
rtw89_write16(rtwdev, reg, val);
reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RCR, mac_idx);
@@ -2668,8 +2708,7 @@ static int rmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
rx_max_len /= RX_MAX_LEN_UNIT;
rtw89_write32_mask(rtwdev, reg, B_AX_RX_MPDU_MAX_LEN_MASK, rx_max_len);
- if (rtwdev->chip->chip_id == RTL8852A &&
- rtwdev->hal.cv == CHIP_CBV) {
+ if (chip_id == RTL8852A && rtwdev->hal.cv == CHIP_CBV) {
rtw89_write16_mask(rtwdev,
rtw89_mac_reg_by_idx(rtwdev, R_AX_DLK_PROTECT_CTL, mac_idx),
B_AX_RX_DLK_CCA_TIME_MASK, 0);
@@ -2700,7 +2739,7 @@ static int cmac_com_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
val = u32_replace_bits(val, 0, B_AX_TXSC_80M_MASK);
rtw89_write32(rtwdev, reg, val);
- if (chip_id == RTL8852A || chip_id == RTL8852B) {
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) {
reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_RRSR1, mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_RRSR_RATE_EN_MASK, RRSR_OFDM_CCK_EN);
}
@@ -2723,6 +2762,7 @@ bool rtw89_mac_is_qta_dbcc(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode)
static int ptcl_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
u32 val, reg;
int ret;
@@ -2761,16 +2801,21 @@ static int ptcl_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
B_AX_SPE_RPT_PATH_MASK, FWD_TO_WLCPU);
}
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) {
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_AGG_LEN_VHT_0, mac_idx);
+ rtw89_write32_mask(rtwdev, reg,
+ B_AX_AMPDU_MAX_LEN_VHT_MASK, 0x3FF80);
+ }
+
return 0;
}
static int cmac_dma_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
{
- enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
u32 reg;
int ret;
- if (chip_id != RTL8852B)
+ if (!rtw89_is_rtl885xb(rtwdev))
return 0;
ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
@@ -2868,22 +2913,42 @@ static int cmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
}
static int rtw89_mac_read_phycap(struct rtw89_dev *rtwdev,
- struct rtw89_mac_c2h_info *c2h_info)
+ struct rtw89_mac_c2h_info *c2h_info, u8 part_num)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
- struct rtw89_mac_h2c_info h2c_info = {0};
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct rtw89_mac_h2c_info h2c_info = {};
+ enum rtw89_mac_c2h_type c2h_type;
+ u8 content_len;
u32 ret;
+ if (chip->chip_gen == RTW89_CHIP_AX)
+ content_len = 0;
+ else
+ content_len = 2;
+
+ switch (part_num) {
+ case 0:
+ c2h_type = RTW89_FWCMD_C2HREG_FUNC_PHY_CAP;
+ break;
+ case 1:
+ c2h_type = RTW89_FWCMD_C2HREG_FUNC_PHY_CAP_PART1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
mac->cnv_efuse_state(rtwdev, false);
h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE;
- h2c_info.content_len = 0;
+ h2c_info.content_len = content_len;
+ h2c_info.u.hdr.w0 = u32_encode_bits(part_num, RTW89_H2CREG_GET_FEATURE_PART_NUM);
ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, c2h_info);
if (ret)
goto out;
- if (c2h_info->id != RTW89_FWCMD_C2HREG_FUNC_PHY_CAP)
+ if (c2h_info->id != c2h_type)
ret = -EINVAL;
out:
@@ -2892,20 +2957,20 @@ out:
return ret;
}
-int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev)
+static int rtw89_mac_setup_phycap_part0(struct rtw89_dev *rtwdev)
{
- struct rtw89_efuse *efuse = &rtwdev->efuse;
- struct rtw89_hal *hal = &rtwdev->hal;
const struct rtw89_chip_info *chip = rtwdev->chip;
- struct rtw89_mac_c2h_info c2h_info = {0};
const struct rtw89_c2hreg_phycap *phycap;
+ struct rtw89_efuse *efuse = &rtwdev->efuse;
+ struct rtw89_mac_c2h_info c2h_info = {};
+ struct rtw89_hal *hal = &rtwdev->hal;
u8 tx_nss;
u8 rx_nss;
u8 tx_ant;
u8 rx_ant;
- u32 ret;
+ int ret;
- ret = rtw89_mac_read_phycap(rtwdev, &c2h_info);
+ ret = rtw89_mac_read_phycap(rtwdev, &c2h_info, 0);
if (ret)
return ret;
@@ -2949,6 +3014,60 @@ int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev)
return 0;
}
+static int rtw89_mac_setup_phycap_part1(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_chip_variant *variant = rtwdev->variant;
+ const struct rtw89_c2hreg_phycap *phycap;
+ struct rtw89_mac_c2h_info c2h_info = {};
+ struct rtw89_hal *hal = &rtwdev->hal;
+ u8 qam_raw, qam;
+ int ret;
+
+ ret = rtw89_mac_read_phycap(rtwdev, &c2h_info, 1);
+ if (ret)
+ return ret;
+
+ phycap = &c2h_info.u.phycap;
+
+ qam_raw = u32_get_bits(phycap->w2, RTW89_C2HREG_PHYCAP_P1_W2_QAM);
+
+ switch (qam_raw) {
+ case RTW89_C2HREG_PHYCAP_P1_W2_QAM_256:
+ case RTW89_C2HREG_PHYCAP_P1_W2_QAM_1024:
+ case RTW89_C2HREG_PHYCAP_P1_W2_QAM_4096:
+ qam = qam_raw;
+ break;
+ default:
+ qam = RTW89_C2HREG_PHYCAP_P1_W2_QAM_4096;
+ break;
+ }
+
+ if ((variant && variant->no_mcs_12_13) ||
+ qam <= RTW89_C2HREG_PHYCAP_P1_W2_QAM_1024)
+ hal->no_mcs_12_13 = true;
+
+ rtw89_debug(rtwdev, RTW89_DBG_FW, "phycap qam=%d/%d no_mcs_12_13=%d\n",
+ qam_raw, qam, hal->no_mcs_12_13);
+
+ return 0;
+}
+
+int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ int ret;
+
+ ret = rtw89_mac_setup_phycap_part0(rtwdev);
+ if (ret)
+ return ret;
+
+ if (chip->chip_gen == RTW89_CHIP_AX ||
+ RTW89_CHK_FW_FEATURE(NO_PHYCAP_P1, &rtwdev->fw))
+ return 0;
+
+ return rtw89_mac_setup_phycap_part1(rtwdev);
+}
+
static int rtw89_hw_sch_tx_en_h2c(struct rtw89_dev *rtwdev, u8 band,
u16 tx_en_u16, u16 mask_u16)
{
@@ -3587,13 +3706,11 @@ static int enable_imr_ax(struct rtw89_dev *rtwdev, u8 mac_idx,
static void err_imr_ctrl_ax(struct rtw89_dev *rtwdev, bool en)
{
- enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
-
rtw89_write32(rtwdev, R_AX_DMAC_ERR_IMR,
en ? DMAC_ERR_IMR_EN : DMAC_ERR_IMR_DIS);
rtw89_write32(rtwdev, R_AX_CMAC_ERR_IMR,
en ? CMAC0_ERR_IMR_EN : CMAC0_ERR_IMR_DIS);
- if (chip_id != RTL8852B && rtwdev->mac.dle_info.c1_rx_qta)
+ if (!rtw89_is_rtl885xb(rtwdev) && rtwdev->mac.dle_info.c1_rx_qta)
rtw89_write32(rtwdev, R_AX_CMAC_ERR_IMR_C1,
en ? CMAC1_ERR_IMR_EN : CMAC1_ERR_IMR_DIS);
}
@@ -3644,6 +3761,7 @@ static int set_host_rpr_ax(struct rtw89_dev *rtwdev)
static int trx_init_ax(struct rtw89_dev *rtwdev)
{
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
enum rtw89_qta_mode qta_mode = rtwdev->mac.qta_mode;
int ret;
@@ -3687,6 +3805,10 @@ static int trx_init_ax(struct rtw89_dev *rtwdev)
return ret;
}
+ if (chip_id == RTL8852C)
+ rtw89_write32_clr(rtwdev, R_AX_RSP_CHK_SIG,
+ B_AX_RSP_STATIC_RTS_CHK_SERV_BW_EN);
+
return 0;
}
@@ -3714,10 +3836,9 @@ static int rtw89_mac_feat_init(struct rtw89_dev *rtwdev)
static void rtw89_disable_fw_watchdog(struct rtw89_dev *rtwdev)
{
- enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
u32 val32;
- if (chip_id == RTL8852B || chip_id == RTL8851B) {
+ if (rtw89_is_rtl885xb(rtwdev)) {
rtw89_write32_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_APB_WRAP_EN);
rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_APB_WRAP_EN);
return;
@@ -3775,7 +3896,7 @@ static int rtw89_mac_enable_cpu_ax(struct rtw89_dev *rtwdev, u8 boot_reason,
rtw89_write32(rtwdev, R_AX_WCPU_FW_CTRL, val);
- if (rtwdev->chip->chip_id == RTL8852B)
+ if (rtw89_is_rtl885xb(rtwdev))
rtw89_write32_mask(rtwdev, R_AX_SEC_CTRL,
B_AX_SEC_IDMEM_SIZE_CONFIG_MASK, 0x2);
@@ -3813,7 +3934,7 @@ static void rtw89_mac_dmac_func_pre_en_ax(struct rtw89_dev *rtwdev)
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
u32 val;
- if (chip_id == RTL8851B)
+ if (chip_id == RTL8851B || chip_id == RTL8852BT)
val = B_AX_DISPATCHER_CLK_EN | B_AX_AXIDMA_CLK_EN;
else
val = B_AX_DISPATCHER_CLK_EN;
@@ -3890,14 +4011,6 @@ int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb)
{
int ret;
- ret = rtw89_mac_power_switch(rtwdev, true);
- if (ret) {
- rtw89_mac_power_switch(rtwdev, false);
- ret = rtw89_mac_power_switch(rtwdev, true);
- if (ret)
- return ret;
- }
-
rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
if (include_bb) {
@@ -3930,6 +4043,10 @@ int rtw89_mac_init(struct rtw89_dev *rtwdev)
bool include_bb = !!chip->bbmcu_nr;
int ret;
+ ret = rtw89_mac_pwr_on(rtwdev);
+ if (ret)
+ return ret;
+
ret = rtw89_mac_partial_init(rtwdev, include_bb);
if (ret)
goto fail;
@@ -3961,16 +4078,17 @@ int rtw89_mac_init(struct rtw89_dev *rtwdev)
return ret;
fail:
- rtw89_mac_power_switch(rtwdev, false);
+ rtw89_mac_pwr_off(rtwdev);
return ret;
}
static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
{
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
u8 i;
- if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
+ if (rtwdev->chip->chip_gen != RTW89_CHIP_AX || sec->secure_boot)
return;
for (i = 0; i < 4; i++) {
@@ -3982,7 +4100,9 @@ static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
{
- if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+
+ if (rtwdev->chip->chip_gen != RTW89_CHIP_AX || sec->secure_boot)
return;
rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR,
@@ -4049,17 +4169,17 @@ static const struct rtw89_port_reg rtw89_port_base_ax = {
};
static void rtw89_mac_check_packet_ctrl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, u8 type)
+ struct rtw89_vif_link *rtwvif_link, u8 type)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- u8 mask = B_AX_PTCL_DBG_INFO_MASK_BY_PORT(rtwvif->port);
+ u8 mask = B_AX_PTCL_DBG_INFO_MASK_BY_PORT(rtwvif_link->port);
u32 reg_info, reg_ctrl;
u32 val;
int ret;
- reg_info = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg_info, rtwvif->mac_idx);
- reg_ctrl = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg, rtwvif->mac_idx);
+ reg_info = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg_info, rtwvif_link->mac_idx);
+ reg_ctrl = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg, rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg_ctrl, B_AX_PTCL_DBG_SEL_MASK, type);
rtw89_write32_set(rtwdev, reg_ctrl, B_AX_PTCL_DBG_EN);
@@ -4071,26 +4191,32 @@ static void rtw89_mac_check_packet_ctrl(struct rtw89_dev *rtwdev,
rtw89_warn(rtwdev, "Polling beacon packet empty fail\n");
}
-static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- rtw89_write32_set(rtwdev, p->bcn_drop_all, BIT(rtwvif->port));
- rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK, 1);
- rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_area, B_AX_BCN_MSK_AREA_MASK, 0);
- rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 0);
- rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK, 2);
- rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK, 1);
- rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_space, B_AX_BCN_SPACE_MASK, 1);
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN);
-
- rtw89_mac_check_packet_ctrl(rtwdev, rtwvif, AX_PTCL_DBG_BCNQ_NUM0);
- if (rtwvif->port == RTW89_PORT_0)
- rtw89_mac_check_packet_ctrl(rtwdev, rtwvif, AX_PTCL_DBG_BCNQ_NUM1);
-
- rtw89_write32_clr(rtwdev, p->bcn_drop_all, BIT(rtwvif->port));
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TBTT_PROHIB_EN);
+ rtw89_write32_set(rtwdev, p->bcn_drop_all, BIT(rtwvif_link->port));
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK,
+ 1);
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_area, B_AX_BCN_MSK_AREA_MASK,
+ 0);
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK,
+ 0);
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_early, B_AX_BCNERLY_MASK, 2);
+ rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_early,
+ B_AX_TBTTERLY_MASK, 1);
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_space,
+ B_AX_BCN_SPACE_MASK, 1);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN);
+
+ rtw89_mac_check_packet_ctrl(rtwdev, rtwvif_link, AX_PTCL_DBG_BCNQ_NUM0);
+ if (rtwvif_link->port == RTW89_PORT_0)
+ rtw89_mac_check_packet_ctrl(rtwdev, rtwvif_link, AX_PTCL_DBG_BCNQ_NUM1);
+
+ rtw89_write32_clr(rtwdev, p->bcn_drop_all, BIT(rtwvif_link->port));
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_TBTT_PROHIB_EN);
fsleep(2000);
}
@@ -4104,286 +4230,329 @@ static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvi
#define BCN_ERLY_SET_DLY (10 * 2)
static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct ieee80211_bss_conf *bss_conf;
bool need_backup = false;
u32 backup_val;
+ u16 beacon_int;
- if (!rtw89_read32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN))
+ if (!rtw89_read32_port_mask(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN))
return;
- if (chip->chip_id == RTL8852A && rtwvif->port != RTW89_PORT_0) {
+ if (chip->chip_id == RTL8852A && rtwvif_link->port != RTW89_PORT_0) {
need_backup = true;
- backup_val = rtw89_read32_port(rtwdev, rtwvif, p->tbtt_prohib);
+ backup_val = rtw89_read32_port(rtwdev, rtwvif_link, p->tbtt_prohib);
}
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
- rtw89_mac_bcn_drop(rtwdev, rtwvif);
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
+ rtw89_mac_bcn_drop(rtwdev, rtwvif_link);
if (chip->chip_id == RTL8852A) {
- rtw89_write32_port_clr(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK);
- rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 1);
- rtw89_write16_port_clr(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK);
- rtw89_write16_port_clr(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->tbtt_prohib,
+ B_AX_TBTT_SETUP_MASK);
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib,
+ B_AX_TBTT_HOLD_MASK, 1);
+ rtw89_write16_port_clr(rtwdev, rtwvif_link, p->tbtt_early,
+ B_AX_TBTTERLY_MASK);
+ rtw89_write16_port_clr(rtwdev, rtwvif_link, p->bcn_early,
+ B_AX_BCNERLY_MASK);
}
- msleep(vif->bss_conf.beacon_int + 1);
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN |
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ beacon_int = bss_conf->beacon_int;
+
+ rcu_read_unlock();
+
+ msleep(beacon_int + 1);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN |
B_AX_BRK_SETUP);
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSFTR_RST);
- rtw89_write32_port(rtwdev, rtwvif, p->bcn_cnt_tmr, 0);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSFTR_RST);
+ rtw89_write32_port(rtwdev, rtwvif_link, p->bcn_cnt_tmr, 0);
if (need_backup)
- rtw89_write32_port(rtwdev, rtwvif, p->tbtt_prohib, backup_val);
+ rtw89_write32_port(rtwdev, rtwvif_link, p->tbtt_prohib, backup_val);
}
static void rtw89_mac_port_cfg_tx_rpt(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool en)
+ struct rtw89_vif_link *rtwvif_link, bool en)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
if (en)
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TXBCN_RPT_EN);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg,
+ B_AX_TXBCN_RPT_EN);
else
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TXBCN_RPT_EN);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg,
+ B_AX_TXBCN_RPT_EN);
}
static void rtw89_mac_port_cfg_rx_rpt(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool en)
+ struct rtw89_vif_link *rtwvif_link, bool en)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
if (en)
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_RXBCN_RPT_EN);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg,
+ B_AX_RXBCN_RPT_EN);
else
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_RXBCN_RPT_EN);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg,
+ B_AX_RXBCN_RPT_EN);
}
static void rtw89_mac_port_cfg_net_type(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- rtw89_write32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_NET_TYPE_MASK,
- rtwvif->net_type);
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->port_cfg, B_AX_NET_TYPE_MASK,
+ rtwvif_link->net_type);
}
static void rtw89_mac_port_cfg_bcn_prct(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- bool en = rtwvif->net_type != RTW89_NET_TYPE_NO_LINK;
+ bool en = rtwvif_link->net_type != RTW89_NET_TYPE_NO_LINK;
u32 bits = B_AX_TBTT_PROHIB_EN | B_AX_BRK_SETUP;
if (en)
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, bits);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, bits);
else
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, bits);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, bits);
}
static void rtw89_mac_port_cfg_rx_sw(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- bool en = rtwvif->net_type == RTW89_NET_TYPE_INFRA ||
- rtwvif->net_type == RTW89_NET_TYPE_AD_HOC;
+ bool en = rtwvif_link->net_type == RTW89_NET_TYPE_INFRA ||
+ rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC;
u32 bit = B_AX_RX_BSSID_FIT_EN;
if (en)
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, bit);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, bit);
else
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, bit);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, bit);
}
void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool en)
+ struct rtw89_vif_link *rtwvif_link, bool en)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
if (en)
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSF_UDT_EN);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSF_UDT_EN);
else
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TSF_UDT_EN);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSF_UDT_EN);
}
static void rtw89_mac_port_cfg_rx_sync_by_nettype(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
- bool en = rtwvif->net_type == RTW89_NET_TYPE_INFRA ||
- rtwvif->net_type == RTW89_NET_TYPE_AD_HOC;
+ bool en = rtwvif_link->net_type == RTW89_NET_TYPE_INFRA ||
+ rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC;
- rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif, en);
+ rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, en);
}
static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool en)
+ struct rtw89_vif_link *rtwvif_link, bool en)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
if (en)
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN);
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN);
else
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN);
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN);
}
static void rtw89_mac_port_cfg_tx_sw_by_nettype(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
- bool en = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE ||
- rtwvif->net_type == RTW89_NET_TYPE_AD_HOC;
+ bool en = rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE ||
+ rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC;
- rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif, en);
+ rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en);
}
void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
- rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif, en);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
+ rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en);
}
static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
- u16 bcn_int = vif->bss_conf.beacon_int ? vif->bss_conf.beacon_int : BCN_INTERVAL;
+ struct ieee80211_bss_conf *bss_conf;
+ u16 bcn_int;
+
+ rcu_read_lock();
- rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_space, B_AX_BCN_SPACE_MASK,
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ if (bss_conf->beacon_int)
+ bcn_int = bss_conf->beacon_int;
+ else
+ bcn_int = BCN_INTERVAL;
+
+ rcu_read_unlock();
+
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_space, B_AX_BCN_SPACE_MASK,
bcn_int);
}
static void rtw89_mac_port_cfg_hiq_win(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
- u8 win = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE ? 16 : 0;
+ u8 win = rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE ? 16 : 0;
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- u8 port = rtwvif->port;
+ u8 port = rtwvif_link->port;
u32 reg;
- reg = rtw89_mac_reg_by_idx(rtwdev, p->hiq_win[port], rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, p->hiq_win[port], rtwvif_link->mac_idx);
rtw89_write8(rtwdev, reg, win);
}
static void rtw89_mac_port_cfg_hiq_dtim(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_bss_conf *bss_conf;
+ u8 dtim_period;
u32 addr;
- addr = rtw89_mac_reg_by_idx(rtwdev, p->md_tsft, rtwvif->mac_idx);
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ dtim_period = bss_conf->dtim_period;
+
+ rcu_read_unlock();
+
+ addr = rtw89_mac_reg_by_idx(rtwdev, p->md_tsft, rtwvif_link->mac_idx);
rtw89_write8_set(rtwdev, addr, B_AX_UPD_HGQMD | B_AX_UPD_TIMIE);
- rtw89_write16_port_mask(rtwdev, rtwvif, p->dtim_ctrl, B_AX_DTIM_NUM_MASK,
- vif->bss_conf.dtim_period);
+ rtw89_write16_port_mask(rtwdev, rtwvif_link, p->dtim_ctrl, B_AX_DTIM_NUM_MASK,
+ dtim_period);
}
static void rtw89_mac_port_cfg_bcn_setup_time(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib,
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib,
B_AX_TBTT_SETUP_MASK, BCN_SETUP_DEF);
}
static void rtw89_mac_port_cfg_bcn_hold_time(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib,
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib,
B_AX_TBTT_HOLD_MASK, BCN_HOLD_DEF);
}
static void rtw89_mac_port_cfg_bcn_mask_area(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_area,
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_area,
B_AX_BCN_MSK_AREA_MASK, BCN_MASK_DEF);
}
static void rtw89_mac_port_cfg_tbtt_early(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_early,
+ rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_early,
B_AX_TBTTERLY_MASK, TBTT_ERLY_DEF);
}
static void rtw89_mac_port_cfg_bss_color(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
static const u32 masks[RTW89_PORT_NUM] = {
B_AX_BSS_COLOB_AX_PORT_0_MASK, B_AX_BSS_COLOB_AX_PORT_1_MASK,
B_AX_BSS_COLOB_AX_PORT_2_MASK, B_AX_BSS_COLOB_AX_PORT_3_MASK,
B_AX_BSS_COLOB_AX_PORT_4_MASK,
};
- u8 port = rtwvif->port;
+ struct ieee80211_bss_conf *bss_conf;
+ u8 port = rtwvif_link->port;
u32 reg_base;
u32 reg;
u8 bss_color;
- bss_color = vif->bss_conf.he_bss_color.color;
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ bss_color = bss_conf->he_bss_color.color;
+
+ rcu_read_unlock();
+
reg_base = port >= 4 ? p->bss_color + 4 : p->bss_color;
- reg = rtw89_mac_reg_by_idx(rtwdev, reg_base, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, reg_base, rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, masks[port], bss_color);
}
static void rtw89_mac_port_cfg_mbssid(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- u8 port = rtwvif->port;
+ u8 port = rtwvif_link->port;
u32 reg;
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
return;
if (port == 0) {
- reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid, rtwvif_link->mac_idx);
rtw89_write32_clr(rtwdev, reg, B_AX_P0MB_ALL_MASK);
}
}
static void rtw89_mac_port_cfg_hiq_drop(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- u8 port = rtwvif->port;
+ u8 port = rtwvif_link->port;
u32 reg;
u32 val;
- reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid_drop, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid_drop, rtwvif_link->mac_idx);
val = rtw89_read32(rtwdev, reg);
val &= ~FIELD_PREP(B_AX_PORT_DROP_4_0_MASK, BIT(port));
if (port == 0)
@@ -4392,31 +4561,31 @@ static void rtw89_mac_port_cfg_hiq_drop(struct rtw89_dev *rtwdev,
}
static void rtw89_mac_port_cfg_func_en(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool enable)
+ struct rtw89_vif_link *rtwvif_link, bool enable)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
if (enable)
- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg,
+ rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg,
B_AX_PORT_FUNC_EN);
else
- rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg,
+ rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg,
B_AX_PORT_FUNC_EN);
}
static void rtw89_mac_port_cfg_bcn_early(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
- rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK,
+ rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_early, B_AX_BCNERLY_MASK,
BCN_ERLY_DEF);
}
static void rtw89_mac_port_cfg_tbtt_shift(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_port_reg *p = mac->port_base;
@@ -4425,20 +4594,20 @@ static void rtw89_mac_port_cfg_tbtt_shift(struct rtw89_dev *rtwdev,
if (rtwdev->chip->chip_id != RTL8852C)
return;
- if (rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT &&
- rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION)
+ if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT &&
+ rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION)
return;
val = FIELD_PREP(B_AX_TBTT_SHIFT_OFST_MAG, 1) |
B_AX_TBTT_SHIFT_OFST_SIGN;
- rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_shift,
+ rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_shift,
B_AX_TBTT_SHIFT_OFST_MASK, val);
}
void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_vif *rtwvif_src,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_vif_link *rtwvif_src,
u16 offset_tu)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
@@ -4446,8 +4615,8 @@ void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
u32 val, reg;
val = RTW89_PORT_OFFSET_TU_TO_32US(offset_tu);
- reg = rtw89_mac_reg_by_idx(rtwdev, p->tsf_sync + rtwvif->port * 4,
- rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, p->tsf_sync + rtwvif_link->port * 4,
+ rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_SRC, rtwvif_src->port);
rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_OFFSET_VAL, val);
@@ -4455,32 +4624,42 @@ void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
}
static void rtw89_mac_port_tsf_sync_rand(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_vif *rtwvif_src,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_vif_link *rtwvif_src,
u8 offset, int *n_offset)
{
- if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif == rtwvif_src)
+ if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif_link == rtwvif_src)
return;
+ if (rtwvif_link->rand_tsf_done)
+ goto out;
+
/* adjust offset randomly to avoid beacon conflict */
offset = offset - offset / 4 + get_random_u32() % (offset / 2);
- rtw89_mac_port_tsf_sync(rtwdev, rtwvif, rtwvif_src,
+ rtw89_mac_port_tsf_sync(rtwdev, rtwvif_link, rtwvif_src,
(*n_offset) * offset);
+ rtwvif_link->rand_tsf_done = true;
+
+out:
(*n_offset)++;
}
static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev)
{
- struct rtw89_vif *src = NULL, *tmp;
+ struct rtw89_vif_link *src = NULL, *tmp;
u8 offset = 100, vif_aps = 0;
+ struct rtw89_vif *rtwvif;
+ unsigned int link_id;
int n_offset = 1;
- rtw89_for_each_rtwvif(rtwdev, tmp) {
- if (!src || tmp->net_type == RTW89_NET_TYPE_INFRA)
- src = tmp;
- if (tmp->net_type == RTW89_NET_TYPE_AP_MODE)
- vif_aps++;
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+ rtw89_vif_for_each_link(rtwvif, tmp, link_id) {
+ if (!src || tmp->net_type == RTW89_NET_TYPE_INFRA)
+ src = tmp;
+ if (tmp->net_type == RTW89_NET_TYPE_AP_MODE)
+ vif_aps++;
+ }
}
if (vif_aps == 0)
@@ -4488,104 +4667,106 @@ static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev)
offset /= (vif_aps + 1);
- rtw89_for_each_rtwvif(rtwdev, tmp)
- rtw89_mac_port_tsf_sync_rand(rtwdev, tmp, src, offset, &n_offset);
+ rtw89_for_each_rtwvif(rtwdev, rtwvif)
+ rtw89_vif_for_each_link(rtwvif, tmp, link_id)
+ rtw89_mac_port_tsf_sync_rand(rtwdev, tmp, src, offset,
+ &n_offset);
}
-int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
int ret;
- ret = rtw89_mac_port_update(rtwdev, rtwvif);
+ ret = rtw89_mac_port_update(rtwdev, rtwvif_link);
if (ret)
return ret;
- rtw89_mac_dmac_tbl_init(rtwdev, rtwvif->mac_id);
- rtw89_mac_cmac_tbl_init(rtwdev, rtwvif->mac_id);
+ rtw89_mac_dmac_tbl_init(rtwdev, rtwvif_link->mac_id);
+ rtw89_mac_cmac_tbl_init(rtwdev, rtwvif_link->mac_id);
- ret = rtw89_mac_set_macid_pause(rtwdev, rtwvif->mac_id, false);
+ ret = rtw89_mac_set_macid_pause(rtwdev, rtwvif_link->mac_id, false);
if (ret)
return ret;
- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_CREATE);
+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_CREATE);
if (ret)
return ret;
- ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
+ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true);
if (ret)
return ret;
- ret = rtw89_cam_init(rtwdev, rtwvif);
+ ret = rtw89_cam_init(rtwdev, rtwvif_link);
if (ret)
return ret;
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
if (ret)
return ret;
- ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif, NULL);
+ ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif_link, NULL);
if (ret)
return ret;
- ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif, NULL);
+ ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif_link, NULL);
if (ret)
return ret;
return 0;
}
-int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
int ret;
- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_REMOVE);
+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_REMOVE);
if (ret)
return ret;
- rtw89_cam_deinit(rtwdev, rtwvif);
+ rtw89_cam_deinit(rtwdev, rtwvif_link);
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
if (ret)
return ret;
return 0;
}
-int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
- u8 port = rtwvif->port;
+ u8 port = rtwvif_link->port;
if (port >= RTW89_PORT_NUM)
return -EINVAL;
- rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif);
- rtw89_mac_port_cfg_tx_rpt(rtwdev, rtwvif, false);
- rtw89_mac_port_cfg_rx_rpt(rtwdev, rtwvif, false);
- rtw89_mac_port_cfg_net_type(rtwdev, rtwvif);
- rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif);
- rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif);
- rtw89_mac_port_cfg_rx_sync_by_nettype(rtwdev, rtwvif);
- rtw89_mac_port_cfg_tx_sw_by_nettype(rtwdev, rtwvif);
- rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif);
- rtw89_mac_port_cfg_hiq_win(rtwdev, rtwvif);
- rtw89_mac_port_cfg_hiq_dtim(rtwdev, rtwvif);
- rtw89_mac_port_cfg_hiq_drop(rtwdev, rtwvif);
- rtw89_mac_port_cfg_bcn_setup_time(rtwdev, rtwvif);
- rtw89_mac_port_cfg_bcn_hold_time(rtwdev, rtwvif);
- rtw89_mac_port_cfg_bcn_mask_area(rtwdev, rtwvif);
- rtw89_mac_port_cfg_tbtt_early(rtwdev, rtwvif);
- rtw89_mac_port_cfg_tbtt_shift(rtwdev, rtwvif);
- rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif);
- rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif);
- rtw89_mac_port_cfg_func_en(rtwdev, rtwvif, true);
+ rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_tx_rpt(rtwdev, rtwvif_link, false);
+ rtw89_mac_port_cfg_rx_rpt(rtwdev, rtwvif_link, false);
+ rtw89_mac_port_cfg_net_type(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_rx_sync_by_nettype(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_tx_sw_by_nettype(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_hiq_win(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_hiq_dtim(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_hiq_drop(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_bcn_setup_time(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_bcn_hold_time(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_bcn_mask_area(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_tbtt_early(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_tbtt_shift(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif_link);
+ rtw89_mac_port_cfg_func_en(rtwdev, rtwvif_link, true);
rtw89_mac_port_tsf_resync_all(rtwdev);
fsleep(BCN_ERLY_SET_DLY);
- rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif);
+ rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif_link);
return 0;
}
-int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u64 *tsf)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
@@ -4593,12 +4774,12 @@ int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
u32 tsf_low, tsf_high;
int ret;
- ret = rtw89_mac_check_mac_en(rtwdev, rtwvif->mac_idx, RTW89_CMAC_SEL);
+ ret = rtw89_mac_check_mac_en(rtwdev, rtwvif_link->mac_idx, RTW89_CMAC_SEL);
if (ret)
return ret;
- tsf_low = rtw89_read32_port(rtwdev, rtwvif, p->tsftr_l);
- tsf_high = rtw89_read32_port(rtwdev, rtwvif, p->tsftr_h);
+ tsf_low = rtw89_read32_port(rtwdev, rtwvif_link, p->tsftr_l);
+ tsf_high = rtw89_read32_port(rtwdev, rtwvif_link, p->tsftr_h);
*tsf = (u64)tsf_high << 32 | tsf_low;
return 0;
@@ -4624,66 +4805,85 @@ static void rtw89_mac_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
}
void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif)
+ struct rtw89_vif_link *rtwvif_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct ieee80211_hw *hw = rtwdev->hw;
+ struct ieee80211_bss_conf *bss_conf;
+ struct cfg80211_chan_def oper;
bool tolerated = true;
u32 reg;
- if (!vif->bss_conf.he_support || vif->type != NL80211_IFTYPE_STATION)
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ if (!bss_conf->he_support || vif->type != NL80211_IFTYPE_STATION) {
+ rcu_read_unlock();
return;
+ }
- if (!(vif->bss_conf.chanreq.oper.chan->flags & IEEE80211_CHAN_RADAR))
+ oper = bss_conf->chanreq.oper;
+ if (!(oper.chan->flags & IEEE80211_CHAN_RADAR)) {
+ rcu_read_unlock();
return;
+ }
- cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chanreq.oper,
+ rcu_read_unlock();
+
+ cfg80211_bss_iter(hw->wiphy, &oper,
rtw89_mac_check_he_obss_narrow_bw_ru_iter,
&tolerated);
reg = rtw89_mac_reg_by_idx(rtwdev, mac->narrow_bw_ru_dis.addr,
- rtwvif->mac_idx);
+ rtwvif_link->mac_idx);
if (tolerated)
rtw89_write32_clr(rtwdev, reg, mac->narrow_bw_ru_dis.mask);
else
rtw89_write32_set(rtwdev, reg, mac->narrow_bw_ru_dis.mask);
}
-void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+void rtw89_mac_set_he_tb(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif);
-}
+ struct ieee80211_bss_conf *bss_conf;
+ bool set;
+ u32 reg;
-int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
-{
- int ret;
+ if (rtwdev->chip->chip_gen != RTW89_CHIP_BE)
+ return;
- rtwvif->mac_id = rtw89_core_acquire_bit_map(rtwdev->mac_id_map,
- RTW89_MAX_MAC_ID_NUM);
- if (rtwvif->mac_id == RTW89_MAX_MAC_ID_NUM)
- return -ENOSPC;
+ rcu_read_lock();
- ret = rtw89_mac_vif_init(rtwdev, rtwvif);
- if (ret)
- goto release_mac_id;
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ set = bss_conf->he_support && !bss_conf->eht_support;
- return 0;
+ rcu_read_unlock();
-release_mac_id:
- rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwvif->mac_id);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CLIENT_OM_CTRL,
+ rtwvif_link->mac_idx);
- return ret;
+ if (set)
+ rtw89_write32_set(rtwdev, reg, B_BE_TRIG_DIS_EHTTB);
+ else
+ rtw89_write32_clr(rtwdev, reg, B_BE_TRIG_DIS_EHTTB);
}
-int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
- int ret;
+ rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif_link);
+
+ rtwvif_link->rand_tsf_done = false;
+}
- ret = rtw89_mac_vif_deinit(rtwdev, rtwvif);
- rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwvif->mac_id);
+int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
+{
+ return rtw89_mac_vif_init(rtwdev, rtwvif_link);
+}
- return ret;
+int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
+{
+ return rtw89_mac_vif_deinit(rtwdev, rtwvif_link);
}
static void
@@ -4704,18 +4904,25 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
{
const struct rtw89_c2h_scanofld *c2h =
(const struct rtw89_c2h_scanofld *)skb->data;
- struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
- struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
+ struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
+ struct rtw89_vif *rtwvif;
struct rtw89_chan new;
- u8 reason, status, tx_fail, band, actual_period, expect_period;
- u32 last_chan = rtwdev->scan_info.last_chan_idx, report_tsf;
+ u16 actual_period, expect_period;
+ u8 reason, status, tx_fail, band;
u8 mac_idx, sw_def, fw_def;
+ u8 ver = U8_MAX;
+ u32 report_tsf;
u16 chan;
int ret;
- if (!rtwvif)
+ if (!rtwvif_link)
return;
+ rtwvif = rtwvif_link->rtwvif;
+
+ if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw))
+ ver = 0;
+
tx_fail = le32_get_bits(c2h->w5, RTW89_C2H_SCANOFLD_W5_TX_FAIL);
status = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_STATUS);
chan = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_PRI_CH);
@@ -4728,21 +4935,28 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
if (!(rtwdev->chip->support_bands & BIT(NL80211_BAND_6GHZ)))
band = chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G;
- rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
- "mac_idx[%d] band: %d, chan: %d, reason: %d, status: %d, tx_fail: %d, actual: %d\n",
- mac_idx, band, chan, reason, status, tx_fail, actual_period);
-
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
sw_def = le32_get_bits(c2h->w6, RTW89_C2H_SCANOFLD_W6_SW_DEF);
- expect_period = le32_get_bits(c2h->w6, RTW89_C2H_SCANOFLD_W6_EXPECT_PERIOD);
fw_def = le32_get_bits(c2h->w6, RTW89_C2H_SCANOFLD_W6_FW_DEF);
report_tsf = le32_get_bits(c2h->w7, RTW89_C2H_SCANOFLD_W7_REPORT_TSF);
+ if (ver == 0) {
+ expect_period =
+ le32_get_bits(c2h->w6, RTW89_C2H_SCANOFLD_W6_EXPECT_PERIOD);
+ } else {
+ actual_period = le32_get_bits(c2h->w8, RTW89_C2H_SCANOFLD_W8_PERIOD_V1);
+ expect_period =
+ le32_get_bits(c2h->w8, RTW89_C2H_SCANOFLD_W8_EXPECT_PERIOD_V1);
+ }
rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
"sw_def: %d, fw_def: %d, tsf: %x, expect: %d\n",
sw_def, fw_def, report_tsf, expect_period);
}
+ rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
+ "mac_idx[%d] band: %d, chan: %d, reason: %d, status: %d, tx_fail: %d, actual: %d\n",
+ mac_idx, band, chan, reason, status, tx_fail, actual_period);
+
switch (reason) {
case RTW89_SCAN_LEAVE_OP_NOTIFY:
case RTW89_SCAN_LEAVE_CH_NOTIFY:
@@ -4752,28 +4966,31 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
}
return;
case RTW89_SCAN_END_SCAN_NOTIFY:
- if (rtwvif && rtwvif->scan_req &&
- last_chan < rtwvif->scan_req->n_channels) {
- ret = rtw89_hw_scan_offload(rtwdev, vif, true);
+ if (rtwdev->scan_info.abort)
+ return;
+
+ if (rtwvif_link && rtwvif->scan_req &&
+ !list_empty(&rtwdev->scan_info.chan_list)) {
+ ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, true);
if (ret) {
- rtw89_hw_scan_abort(rtwdev, vif);
+ rtw89_hw_scan_abort(rtwdev, rtwvif_link);
rtw89_warn(rtwdev, "HW scan failed: %d\n", ret);
}
} else {
- rtw89_hw_scan_complete(rtwdev, vif, rtwdev->scan_info.abort);
+ rtw89_hw_scan_complete(rtwdev, rtwvif_link, false);
}
break;
case RTW89_SCAN_ENTER_OP_NOTIFY:
case RTW89_SCAN_ENTER_CH_NOTIFY:
if (rtw89_is_op_chan(rtwdev, band, chan)) {
- rtw89_assign_entity_chan(rtwdev, rtwvif->sub_entity_idx,
+ rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx,
&rtwdev->scan_info.op_chan);
rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true);
ieee80211_wake_queues(rtwdev->hw);
} else {
rtw89_chan_create(&new, chan, chan, band,
RTW89_CHANNEL_WIDTH_20);
- rtw89_assign_entity_chan(rtwdev, rtwvif->sub_entity_idx,
+ rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx,
&new);
}
break;
@@ -4783,10 +5000,11 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
}
static void
-rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
struct sk_buff *skb)
{
- struct ieee80211_vif *vif = rtwvif_to_vif_safe(rtwvif);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
enum nl80211_cqm_rssi_threshold_event nl_event;
const struct rtw89_c2h_mac_bcnfltr_rpt *c2h =
(const struct rtw89_c2h_mac_bcnfltr_rpt *)skb->data;
@@ -4798,7 +5016,7 @@ rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
event = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_EVENT);
mac_id = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_MACID);
- if (mac_id != rtwvif->mac_id)
+ if (mac_id != rtwvif_link->mac_id)
return;
rtw89_debug(rtwdev, RTW89_DBG_FW,
@@ -4807,10 +5025,11 @@ rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
switch (type) {
case RTW89_BCN_FLTR_BEACON_LOSS:
- if (!rtwdev->scanning && !rtwvif->offchan)
+ if (!rtwdev->scanning && !rtwvif->offchan &&
+ !rtwvif_link->noa_once.in_duration)
ieee80211_connection_loss(vif);
else
- rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true);
+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
return;
case RTW89_BCN_FLTR_NOTIFY:
nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
@@ -4834,10 +5053,13 @@ static void
rtw89_mac_c2h_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
u32 len)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_mac_bcn_fltr_rpt(rtwdev, rtwvif, c2h);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_mac_bcn_fltr_rpt(rtwdev, rtwvif_link, c2h);
}
static void
@@ -4858,6 +5080,7 @@ rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 le
{
/* N.B. This will run in interrupt context. */
struct rtw89_wait_info *fw_ofld_wait = &rtwdev->mac.fw_ofld_wait;
+ struct rtw89_wait_info *ps_wait = &rtwdev->mac.ps_wait;
const struct rtw89_c2h_done_ack *c2h =
(const struct rtw89_c2h_done_ack *)skb_c2h->data;
u8 h2c_cat = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_CAT);
@@ -4878,18 +5101,32 @@ rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 le
switch (h2c_class) {
default:
return;
+ case H2C_CL_MAC_PS:
+ switch (h2c_func) {
+ default:
+ return;
+ case H2C_FUNC_IPS_CFG:
+ cond = RTW89_PS_WAIT_COND_IPS_CFG;
+ break;
+ }
+
+ data.err = !!h2c_return;
+ rtw89_complete_cond(ps_wait, cond, &data);
+ return;
case H2C_CL_MAC_FW_OFLD:
switch (h2c_func) {
default:
return;
case H2C_FUNC_ADD_SCANOFLD_CH:
cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH;
+ h2c_return &= RTW89_C2H_SCAN_DONE_ACK_RETURN;
break;
case H2C_FUNC_SCANOFLD:
cond = RTW89_SCANOFLD_WAIT_COND_START;
break;
case H2C_FUNC_SCANOFLD_BE:
cond = RTW89_SCANOFLD_BE_WAIT_COND_START;
+ h2c_return &= RTW89_C2H_SCAN_DONE_ACK_RETURN;
break;
}
@@ -4933,6 +5170,18 @@ rtw89_mac_c2h_pkt_ofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h,
}
static void
+rtw89_mac_c2h_tx_duty_rpt(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len)
+{
+ struct rtw89_c2h_tx_duty_rpt *c2h =
+ (struct rtw89_c2h_tx_duty_rpt *)skb_c2h->data;
+ u8 err;
+
+ err = le32_get_bits(c2h->w2, RTW89_C2H_TX_DUTY_RPT_W2_TIMER_ERR);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "C2H TX duty rpt with err=%d\n", err);
+}
+
+static void
rtw89_mac_c2h_tsf32_toggle_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
u32 len)
{
@@ -5132,6 +5381,56 @@ rtw89_mac_c2h_mrc_tsf_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len
}
static void
+rtw89_mac_c2h_wow_aoac_rpt(struct rtw89_dev *rtwdev, struct sk_buff *skb, u32 len)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
+ struct rtw89_wait_info *wait = &rtw_wow->wait;
+ const struct rtw89_c2h_wow_aoac_report *c2h =
+ (const struct rtw89_c2h_wow_aoac_report *)skb->data;
+ struct rtw89_completion_data data = {};
+
+ aoac_rpt->rpt_ver = c2h->rpt_ver;
+ aoac_rpt->sec_type = c2h->sec_type;
+ aoac_rpt->key_idx = c2h->key_idx;
+ aoac_rpt->pattern_idx = c2h->pattern_idx;
+ aoac_rpt->rekey_ok = u8_get_bits(c2h->rekey_ok,
+ RTW89_C2H_WOW_AOAC_RPT_REKEY_IDX);
+ memcpy(aoac_rpt->ptk_tx_iv, c2h->ptk_tx_iv, sizeof(aoac_rpt->ptk_tx_iv));
+ memcpy(aoac_rpt->eapol_key_replay_count, c2h->eapol_key_replay_count,
+ sizeof(aoac_rpt->eapol_key_replay_count));
+ memcpy(aoac_rpt->gtk, c2h->gtk, sizeof(aoac_rpt->gtk));
+ memcpy(aoac_rpt->ptk_rx_iv, c2h->ptk_rx_iv, sizeof(aoac_rpt->ptk_rx_iv));
+ memcpy(aoac_rpt->gtk_rx_iv, c2h->gtk_rx_iv, sizeof(aoac_rpt->gtk_rx_iv));
+ aoac_rpt->igtk_key_id = le64_to_cpu(c2h->igtk_key_id);
+ aoac_rpt->igtk_ipn = le64_to_cpu(c2h->igtk_ipn);
+ memcpy(aoac_rpt->igtk, c2h->igtk, sizeof(aoac_rpt->igtk));
+
+ rtw89_complete_cond(wait, RTW89_WOW_WAIT_COND_AOAC, &data);
+}
+
+static void
+rtw89_mac_c2h_mlo_link_cfg_stat(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+ const struct rtw89_c2h_mlo_link_cfg_rpt *c2h_rpt;
+ struct rtw89_wait_info *wait = &rtwdev->mlo.wait;
+ struct rtw89_completion_data data = {};
+ unsigned int cond;
+ u16 mac_id;
+ u8 status;
+
+ c2h_rpt = (const struct rtw89_c2h_mlo_link_cfg_rpt *)c2h->data;
+
+ mac_id = le32_get_bits(c2h_rpt->w2, RTW89_C2H_MLO_LINK_CFG_RPT_W2_MACID);
+ status = le32_get_bits(c2h_rpt->w2, RTW89_C2H_MLO_LINK_CFG_RPT_W2_STATUS);
+
+ data.err = status == RTW89_C2H_MLO_LINK_CFG_ROLE_NOT_EXIST ||
+ status == RTW89_C2H_MLO_LINK_CFG_RUNNING;
+ cond = RTW89_MLO_WAIT_COND(mac_id, H2C_FUNC_MLO_LINK_CFG);
+ rtw89_complete_cond(wait, cond, &data);
+}
+
+static void
rtw89_mac_c2h_mrc_status_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
{
struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
@@ -5163,6 +5462,46 @@ rtw89_mac_c2h_mrc_status_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32
case RTW89_MAC_MRC_DEL_SCH_OK:
func = H2C_FUNC_DEL_MRC;
break;
+ case RTW89_MAC_MRC_EMPTY_SCH_FAIL:
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MRC C2H STS RPT: empty sch fail\n");
+ return;
+ case RTW89_MAC_MRC_ROLE_NOT_EXIST_FAIL:
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MRC C2H STS RPT: role not exist fail\n");
+ return;
+ case RTW89_MAC_MRC_DATA_NOT_FOUND_FAIL:
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MRC C2H STS RPT: data not found fail\n");
+ return;
+ case RTW89_MAC_MRC_GET_NEXT_SLOT_FAIL:
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MRC C2H STS RPT: get next slot fail\n");
+ return;
+ case RTW89_MAC_MRC_ALT_ROLE_FAIL:
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MRC C2H STS RPT: alt role fail\n");
+ return;
+ case RTW89_MAC_MRC_ADD_PSTIMER_FAIL:
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MRC C2H STS RPT: add ps timer fail\n");
+ return;
+ case RTW89_MAC_MRC_MALLOC_FAIL:
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MRC C2H STS RPT: malloc fail\n");
+ return;
+ case RTW89_MAC_MRC_SWITCH_CH_FAIL:
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MRC C2H STS RPT: switch ch fail\n");
+ return;
+ case RTW89_MAC_MRC_TXNULL0_FAIL:
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MRC C2H STS RPT: tx null-0 fail\n");
+ return;
+ case RTW89_MAC_MRC_PORT_FUNC_EN_FAIL:
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MRC C2H STS RPT: port func en fail\n");
+ return;
default:
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"invalid MRC C2H STS RPT: status %d\n", status);
@@ -5180,6 +5519,39 @@ rtw89_mac_c2h_mrc_status_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32
rtw89_complete_cond(wait, cond, &data);
}
+static void
+rtw89_mac_c2h_pwr_int_notify(struct rtw89_dev *rtwdev, struct sk_buff *skb, u32 len)
+{
+ const struct rtw89_c2h_pwr_int_notify *c2h;
+ struct rtw89_sta_link *rtwsta_link;
+ struct ieee80211_sta *sta;
+ struct rtw89_sta *rtwsta;
+ u16 macid;
+ bool ps;
+
+ c2h = (const struct rtw89_c2h_pwr_int_notify *)skb->data;
+ macid = le32_get_bits(c2h->w2, RTW89_C2H_PWR_INT_NOTIFY_W2_MACID);
+ ps = le32_get_bits(c2h->w2, RTW89_C2H_PWR_INT_NOTIFY_W2_PWR_STATUS);
+
+ rcu_read_lock();
+
+ rtwsta_link = rtw89_assoc_link_rcu_dereference(rtwdev, macid);
+ if (unlikely(!rtwsta_link))
+ goto out;
+
+ rtwsta = rtwsta_link->rtwsta;
+ if (ps)
+ set_bit(RTW89_REMOTE_STA_IN_PS, rtwsta->flags);
+ else
+ clear_bit(RTW89_REMOTE_STA_IN_PS, rtwsta->flags);
+
+ sta = rtwsta_to_sta(rtwsta);
+ ieee80211_sta_ps_transition(sta, ps);
+
+out:
+ rcu_read_unlock();
+}
+
static
void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev,
struct sk_buff *c2h, u32 len) = {
@@ -5189,6 +5561,7 @@ void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev,
[RTW89_MAC_C2H_FUNC_BCN_RESEND] = NULL,
[RTW89_MAC_C2H_FUNC_MACID_PAUSE] = rtw89_mac_c2h_macid_pause,
[RTW89_MAC_C2H_FUNC_SCANOFLD_RSP] = rtw89_mac_c2h_scanofld_rsp,
+ [RTW89_MAC_C2H_FUNC_TX_DUTY_RPT] = rtw89_mac_c2h_tx_duty_rpt,
[RTW89_MAC_C2H_FUNC_TSF32_TOGL_RPT] = rtw89_mac_c2h_tsf32_toggle_rpt,
[RTW89_MAC_C2H_FUNC_BCNFLTR_RPT] = rtw89_mac_c2h_bcn_fltr_rpt,
};
@@ -5212,12 +5585,36 @@ void (* const rtw89_mac_c2h_mcc_handler[])(struct rtw89_dev *rtwdev,
};
static
+void (* const rtw89_mac_c2h_mlo_handler[])(struct rtw89_dev *rtwdev,
+ struct sk_buff *c2h, u32 len) = {
+ [RTW89_MAC_C2H_FUNC_MLO_GET_TBL] = NULL,
+ [RTW89_MAC_C2H_FUNC_MLO_EMLSR_TRANS_DONE] = NULL,
+ [RTW89_MAC_C2H_FUNC_MLO_EMLSR_STA_CFG_DONE] = NULL,
+ [RTW89_MAC_C2H_FUNC_MCMLO_RELINK_RPT] = NULL,
+ [RTW89_MAC_C2H_FUNC_MCMLO_SN_SYNC_RPT] = NULL,
+ [RTW89_MAC_C2H_FUNC_MLO_LINK_CFG_STAT] = rtw89_mac_c2h_mlo_link_cfg_stat,
+ [RTW89_MAC_C2H_FUNC_MLO_DM_DBG_DUMP] = NULL,
+};
+
+static
void (* const rtw89_mac_c2h_mrc_handler[])(struct rtw89_dev *rtwdev,
struct sk_buff *c2h, u32 len) = {
[RTW89_MAC_C2H_FUNC_MRC_TSF_RPT] = rtw89_mac_c2h_mrc_tsf_rpt,
[RTW89_MAC_C2H_FUNC_MRC_STATUS_RPT] = rtw89_mac_c2h_mrc_status_rpt,
};
+static
+void (* const rtw89_mac_c2h_wow_handler[])(struct rtw89_dev *rtwdev,
+ struct sk_buff *c2h, u32 len) = {
+ [RTW89_MAC_C2H_FUNC_AOAC_REPORT] = rtw89_mac_c2h_wow_aoac_rpt,
+};
+
+static
+void (* const rtw89_mac_c2h_ap_handler[])(struct rtw89_dev *rtwdev,
+ struct sk_buff *c2h, u32 len) = {
+ [RTW89_MAC_C2H_FUNC_PWR_INT_NOTIFY] = rtw89_mac_c2h_pwr_int_notify,
+};
+
static void rtw89_mac_c2h_scanofld_rsp_atomic(struct rtw89_dev *rtwdev,
struct sk_buff *skb)
{
@@ -5268,8 +5665,19 @@ bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
}
case RTW89_MAC_C2H_CLASS_MCC:
return true;
+ case RTW89_MAC_C2H_CLASS_MLO:
+ return true;
case RTW89_MAC_C2H_CLASS_MRC:
return true;
+ case RTW89_MAC_C2H_CLASS_WOW:
+ return true;
+ case RTW89_MAC_C2H_CLASS_AP:
+ switch (func) {
+ default:
+ return false;
+ case RTW89_MAC_C2H_FUNC_PWR_INT_NOTIFY:
+ return true;
+ }
}
}
@@ -5292,18 +5700,30 @@ void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MCC)
handler = rtw89_mac_c2h_mcc_handler[func];
break;
+ case RTW89_MAC_C2H_CLASS_MLO:
+ if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MLO)
+ handler = rtw89_mac_c2h_mlo_handler[func];
+ break;
case RTW89_MAC_C2H_CLASS_MRC:
if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MRC)
handler = rtw89_mac_c2h_mrc_handler[func];
break;
+ case RTW89_MAC_C2H_CLASS_WOW:
+ if (func < NUM_OF_RTW89_MAC_C2H_FUNC_WOW)
+ handler = rtw89_mac_c2h_wow_handler[func];
+ break;
+ case RTW89_MAC_C2H_CLASS_AP:
+ if (func < NUM_OF_RTW89_MAC_C2H_FUNC_AP)
+ handler = rtw89_mac_c2h_ap_handler[func];
+ break;
case RTW89_MAC_C2H_CLASS_FWDBG:
return;
default:
- rtw89_info(rtwdev, "c2h class %d not support\n", class);
+ rtw89_info(rtwdev, "MAC c2h class %d not support\n", class);
return;
}
if (!handler) {
- rtw89_info(rtwdev, "c2h class %d func %d not support\n", class,
+ rtw89_info(rtwdev, "MAC c2h class %d func %d not support\n", class,
func);
return;
}
@@ -5367,7 +5787,8 @@ int rtw89_mac_cfg_ppdu_status_ax(struct rtw89_dev *rtwdev, u8 mac_idx, bool enab
return 0;
}
-void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx)
+static
+void __rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx)
{
#define MAC_AX_TIME_TH_SH 5
#define MAC_AX_LEN_TH_SH 4
@@ -5397,6 +5818,13 @@ void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx)
rtw89_write16_mask(rtwdev, reg, B_AX_RTS_LEN_TH_MASK, len_th);
}
+void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev)
+{
+ __rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0);
+ if (rtwdev->dbcc_en)
+ __rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_1);
+}
+
void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop)
{
bool empty;
@@ -5413,18 +5841,19 @@ void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop)
int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex)
{
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
u8 val;
u16 val16;
u32 val32;
int ret;
rtw89_write8_set(rtwdev, R_AX_GPIO_MUXCFG, B_AX_ENBT);
- if (rtwdev->chip->chip_id != RTL8851B)
+ if (chip_id != RTL8851B && chip_id != RTL8852BT)
rtw89_write8_set(rtwdev, R_AX_BTC_FUNC_EN, B_AX_PTA_WL_TX_EN);
rtw89_write8_set(rtwdev, R_AX_BT_COEX_CFG_2 + 1, B_AX_GNT_BT_POLARITY >> 8);
rtw89_write8_set(rtwdev, R_AX_CSR_MODE, B_AX_STATIS_BT_EN | B_AX_WL_ACT_MSK);
rtw89_write8_set(rtwdev, R_AX_CSR_MODE + 2, B_AX_BT_CNT_RST >> 16);
- if (rtwdev->chip->chip_id != RTL8851B)
+ if (chip_id != RTL8851B && chip_id != RTL8852BT)
rtw89_write8_clr(rtwdev, R_AX_TRXPTCL_RESP_0 + 3, B_AX_RSP_CHK_BTCCA >> 24);
val16 = rtw89_read16(rtwdev, R_AX_CCA_CFG_0);
@@ -5689,7 +6118,7 @@ int rtw89_mac_cfg_ctrl_path_v1(struct rtw89_dev *rtwdev, bool wl)
if (wl)
return 0;
- for (i = 0; i < RTW89_PHY_MAX; i++) {
+ for (i = 0; i < RTW89_PHY_NUM; i++) {
g[i].gnt_bt_sw_en = 1;
g[i].gnt_bt = 1;
g[i].gnt_wl_sw_en = 1;
@@ -5705,10 +6134,9 @@ bool rtw89_mac_get_ctrl_path(struct rtw89_dev *rtwdev)
const struct rtw89_chip_info *chip = rtwdev->chip;
u8 val = 0;
- if (chip->chip_id == RTL8852C)
+ if (chip->chip_id == RTL8852C || chip->chip_id == RTL8922A)
return false;
- else if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B ||
- chip->chip_id == RTL8851B)
+ else if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))
val = rtw89_read8_mask(rtwdev, R_AX_SYS_SDIO_CTRL + 3,
B_AX_LTE_MUX_CTRL_PATH >> 24);
@@ -5808,15 +6236,15 @@ static int rtw89_mac_init_bfee_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
}
static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- u8 mac_idx = rtwvif->mac_idx;
u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1;
- u8 port_sel = rtwvif->port;
+ struct ieee80211_link_sta *link_sta;
+ u8 mac_idx = rtwvif_link->mac_idx;
+ u8 port_sel = rtwvif_link->port;
u8 sound_dim = 3, t;
- u8 *phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info;
+ u8 *phy_cap;
u32 reg;
u16 val;
int ret;
@@ -5825,6 +6253,11 @@ static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev,
if (ret)
return ret;
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info;
+
if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) ||
(phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) {
ldpc_en &= !!(phy_cap[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD);
@@ -5833,17 +6266,19 @@ static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev,
phy_cap[5]);
sound_dim = min(sound_dim, t);
}
- if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
- (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
- ldpc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
- stbc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK);
+ if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
+ (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
+ ldpc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
+ stbc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK);
t = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
- sta->deflink.vht_cap.cap);
+ link_sta->vht_cap.cap);
sound_dim = min(sound_dim, t);
}
nc = min(nc, sound_dim);
nr = min(nr, sound_dim);
+ rcu_read_unlock();
+
reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL);
@@ -5866,34 +6301,41 @@ static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev,
}
static int rtw89_mac_csi_rrsc_ax(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M);
+ struct ieee80211_link_sta *link_sta;
+ u8 mac_idx = rtwvif_link->mac_idx;
u32 reg;
- u8 mac_idx = rtwvif->mac_idx;
int ret;
ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
if (ret)
return ret;
- if (sta->deflink.he_cap.has_he) {
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+
+ if (link_sta->he_cap.has_he) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) |
BIT(RTW89_MAC_BF_RRSC_HE_MSC3) |
BIT(RTW89_MAC_BF_RRSC_HE_MSC5));
}
- if (sta->deflink.vht_cap.vht_supported) {
+ if (link_sta->vht_cap.vht_supported) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) |
BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) |
BIT(RTW89_MAC_BF_RRSC_VHT_MSC5));
}
- if (sta->deflink.ht_cap.ht_supported) {
+ if (link_sta->ht_cap.ht_supported) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) |
BIT(RTW89_MAC_BF_RRSC_HT_MSC3) |
BIT(RTW89_MAC_BF_RRSC_HT_MSC5));
}
+
+ rcu_read_unlock();
+
reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL);
rtw89_write32_clr(rtwdev, reg, B_AX_BFMEE_CSI_FORCE_RETE_EN);
@@ -5905,35 +6347,53 @@ static int rtw89_mac_csi_rrsc_ax(struct rtw89_dev *rtwdev,
}
static void rtw89_mac_bf_assoc_ax(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct ieee80211_link_sta *link_sta;
+ bool has_beamformer_cap;
+
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ has_beamformer_cap = rtw89_sta_has_beamformer_cap(link_sta);
+
+ rcu_read_unlock();
- if (rtw89_sta_has_beamformer_cap(sta)) {
+ if (has_beamformer_cap) {
rtw89_debug(rtwdev, RTW89_DBG_BF,
"initialize bfee for new association\n");
- rtw89_mac_init_bfee_ax(rtwdev, rtwvif->mac_idx);
- rtw89_mac_set_csi_para_reg_ax(rtwdev, vif, sta);
- rtw89_mac_csi_rrsc_ax(rtwdev, vif, sta);
+ rtw89_mac_init_bfee_ax(rtwdev, rtwvif_link->mac_idx);
+ rtw89_mac_set_csi_para_reg_ax(rtwdev, rtwvif_link, rtwsta_link);
+ rtw89_mac_csi_rrsc_ax(rtwdev, rtwvif_link, rtwsta_link);
}
}
-void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
-
- rtw89_mac_bfee_ctrl(rtwdev, rtwvif->mac_idx, false);
+ rtw89_mac_bfee_ctrl(rtwdev, rtwvif_link->mac_idx, false);
}
void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *conf)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- u8 mac_idx = rtwvif->mac_idx;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+ u8 mac_idx;
__le32 *p;
+ rtwvif_link = rtwvif->links[conf->link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, conf->link_id);
+ return;
+ }
+
+ mac_idx = rtwvif_link->mac_idx;
+
rtw89_debug(rtwdev, RTW89_DBG_BF, "update bf GID table\n");
p = (__le32 *)conf->mu_group.membership;
@@ -5957,7 +6417,7 @@ void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *
struct rtw89_mac_bf_monitor_iter_data {
struct rtw89_dev *rtwdev;
- struct ieee80211_sta *down_sta;
+ struct rtw89_sta_link *down_rtwsta_link;
int count;
};
@@ -5966,23 +6426,41 @@ void rtw89_mac_bf_monitor_calc_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_mac_bf_monitor_iter_data *iter_data =
(struct rtw89_mac_bf_monitor_iter_data *)data;
- struct ieee80211_sta *down_sta = iter_data->down_sta;
+ struct rtw89_sta_link *down_rtwsta_link = iter_data->down_rtwsta_link;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct ieee80211_link_sta *link_sta;
+ struct rtw89_sta_link *rtwsta_link;
+ bool has_beamformer_cap = false;
int *count = &iter_data->count;
+ unsigned int link_id;
- if (down_sta == sta)
- return;
+ rcu_read_lock();
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ if (rtwsta_link == down_rtwsta_link)
+ continue;
- if (rtw89_sta_has_beamformer_cap(sta))
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
+ if (rtw89_sta_has_beamformer_cap(link_sta)) {
+ has_beamformer_cap = true;
+ break;
+ }
+ }
+
+ if (has_beamformer_cap)
(*count)++;
+
+ rcu_read_unlock();
}
void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta, bool disconnect)
+ struct rtw89_sta_link *rtwsta_link,
+ bool disconnect)
{
struct rtw89_mac_bf_monitor_iter_data data;
data.rtwdev = rtwdev;
- data.down_sta = disconnect ? sta : NULL;
+ data.down_rtwsta_link = disconnect ? rtwsta_link : NULL;
data.count = 0;
ieee80211_iterate_stations_atomic(rtwdev->hw,
rtw89_mac_bf_monitor_calc_iter,
@@ -5998,10 +6476,12 @@ void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev,
void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev)
{
struct rtw89_traffic_stats *stats = &rtwdev->stats;
- struct rtw89_vif *rtwvif;
+ struct rtw89_vif_link *rtwvif_link;
bool en = stats->tx_tfc_lv <= stats->rx_tfc_lv;
bool old = test_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags);
+ struct rtw89_vif *rtwvif;
bool keep_timer = true;
+ unsigned int link_id;
bool old_keep_timer;
old_keep_timer = test_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags);
@@ -6011,30 +6491,33 @@ void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev)
if (keep_timer != old_keep_timer) {
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_mac_bfee_standby_timer(rtwdev, rtwvif->mac_idx,
- keep_timer);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_mac_bfee_standby_timer(rtwdev, rtwvif_link->mac_idx,
+ keep_timer);
}
if (en == old)
return;
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_mac_bfee_ctrl(rtwdev, rtwvif->mac_idx, en);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_mac_bfee_ctrl(rtwdev, rtwvif_link->mac_idx, en);
}
static int
-__rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+__rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
u32 tx_time)
{
#define MAC_AX_DFLT_TX_TIME 5280
- u8 mac_idx = rtwsta->rtwvif->mac_idx;
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx;
u32 max_tx_time = tx_time == 0 ? MAC_AX_DFLT_TX_TIME : tx_time;
u32 reg;
int ret = 0;
- if (rtwsta->cctl_tx_time) {
- rtwsta->ampdu_max_time = (max_tx_time - 512) >> 9;
- ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta);
+ if (rtwsta_link->cctl_tx_time) {
+ rtwsta_link->ampdu_max_time = (max_tx_time - 512) >> 9;
+ ret = rtw89_chip_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
} else {
ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
if (ret) {
@@ -6042,39 +6525,40 @@ __rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
return ret;
}
- reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_AMPDU_AGG_LIMIT, mac_idx);
- rtw89_write32_mask(rtwdev, reg, B_AX_AMPDU_MAX_TIME_MASK,
+ reg = rtw89_mac_reg_by_idx(rtwdev, mac->agg_limit.addr, mac_idx);
+ rtw89_write32_mask(rtwdev, reg, mac->agg_limit.mask,
max_tx_time >> 5);
}
return ret;
}
-int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
bool resume, u32 tx_time)
{
int ret = 0;
if (!resume) {
- rtwsta->cctl_tx_time = true;
- ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta, tx_time);
+ rtwsta_link->cctl_tx_time = true;
+ ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta_link, tx_time);
} else {
- ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta, tx_time);
- rtwsta->cctl_tx_time = false;
+ ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta_link, tx_time);
+ rtwsta_link->cctl_tx_time = false;
}
return ret;
}
-int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
u32 *tx_time)
{
- u8 mac_idx = rtwsta->rtwvif->mac_idx;
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx;
u32 reg;
int ret = 0;
- if (rtwsta->cctl_tx_time) {
- *tx_time = (rtwsta->ampdu_max_time + 1) << 9;
+ if (rtwsta_link->cctl_tx_time) {
+ *tx_time = (rtwsta_link->ampdu_max_time + 1) << 9;
} else {
ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
if (ret) {
@@ -6082,41 +6566,42 @@ int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
return ret;
}
- reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_AMPDU_AGG_LIMIT, mac_idx);
- *tx_time = rtw89_read32_mask(rtwdev, reg, B_AX_AMPDU_MAX_TIME_MASK) << 5;
+ reg = rtw89_mac_reg_by_idx(rtwdev, mac->agg_limit.addr, mac_idx);
+ *tx_time = rtw89_read32_mask(rtwdev, reg, mac->agg_limit.mask) << 5;
}
return ret;
}
int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta,
+ struct rtw89_sta_link *rtwsta_link,
bool resume, u8 tx_retry)
{
int ret = 0;
- rtwsta->data_tx_cnt_lmt = tx_retry;
+ rtwsta_link->data_tx_cnt_lmt = tx_retry;
if (!resume) {
- rtwsta->cctl_tx_retry_limit = true;
- ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta);
+ rtwsta_link->cctl_tx_retry_limit = true;
+ ret = rtw89_chip_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
} else {
- ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta);
- rtwsta->cctl_tx_retry_limit = false;
+ ret = rtw89_chip_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
+ rtwsta_link->cctl_tx_retry_limit = false;
}
return ret;
}
int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta, u8 *tx_retry)
+ struct rtw89_sta_link *rtwsta_link, u8 *tx_retry)
{
- u8 mac_idx = rtwsta->rtwvif->mac_idx;
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx;
u32 reg;
int ret = 0;
- if (rtwsta->cctl_tx_retry_limit) {
- *tx_retry = rtwsta->data_tx_cnt_lmt;
+ if (rtwsta_link->cctl_tx_retry_limit) {
+ *tx_retry = rtwsta_link->data_tx_cnt_lmt;
} else {
ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
if (ret) {
@@ -6124,18 +6609,18 @@ int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev,
return ret;
}
- reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXCNT, mac_idx);
- *tx_retry = rtw89_read32_mask(rtwdev, reg, B_AX_L_TXCNT_LMT_MASK);
+ reg = rtw89_mac_reg_by_idx(rtwdev, mac->txcnt_limit.addr, mac_idx);
+ *tx_retry = rtw89_read32_mask(rtwdev, reg, mac->txcnt_limit.mask);
}
return ret;
}
int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool en)
+ struct rtw89_vif_link *rtwvif_link, bool en)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
- u8 mac_idx = rtwvif->mac_idx;
+ u8 mac_idx = rtwvif_link->mac_idx;
u16 set = mac->muedca_ctrl.mask;
u32 reg;
u32 ret;
@@ -6203,7 +6688,9 @@ int rtw89_mac_read_xtal_si_ax(struct rtw89_dev *rtwdev, u8 offset, u8 *val)
}
static
-void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta)
+void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
static const enum rtw89_pkt_drop_sel sels[] = {
RTW89_PKT_DROP_SEL_MACID_BE_ONCE,
@@ -6211,15 +6698,14 @@ void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta)
RTW89_PKT_DROP_SEL_MACID_VI_ONCE,
RTW89_PKT_DROP_SEL_MACID_VO_ONCE,
};
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_pkt_drop_params params = {0};
int i;
- params.mac_band = RTW89_MAC_0;
- params.macid = rtwsta->mac_id;
- params.port = rtwvif->port;
+ params.mac_band = rtwvif_link->mac_idx;
+ params.macid = rtwsta_link->mac_id;
+ params.port = rtwvif_link->port;
params.mbssid = 0;
- params.tf_trs = rtwvif->trigger;
+ params.tf_trs = rtwvif_link->trigger;
for (i = 0; i < ARRAY_SIZE(sels); i++) {
params.sel = sels[i];
@@ -6229,15 +6715,21 @@ void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta)
static void rtw89_mac_pkt_drop_vif_iter(void *data, struct ieee80211_sta *sta)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
- struct rtw89_dev *rtwdev = rtwvif->rtwdev;
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
struct rtw89_vif *target = data;
+ unsigned int link_id;
if (rtwvif != target)
return;
- rtw89_mac_pkt_drop_sta(rtwdev, rtwsta);
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ rtw89_mac_pkt_drop_sta(rtwdev, rtwvif_link, rtwsta_link);
+ }
}
void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
@@ -6269,9 +6761,33 @@ int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,
return ret;
}
+int rtw89_mac_cpu_io_rx(struct rtw89_dev *rtwdev, bool wow_enable)
+{
+ struct rtw89_mac_h2c_info h2c_info = {};
+ struct rtw89_mac_c2h_info c2h_info = {};
+ u32 ret;
+
+ if (RTW89_CHK_FW_FEATURE(NO_WOW_CPU_IO_RX, &rtwdev->fw))
+ return 0;
+
+ h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_WOW_CPUIO_RX_CTRL;
+ h2c_info.content_len = sizeof(h2c_info.u.hdr);
+ h2c_info.u.hdr.w0 = u32_encode_bits(wow_enable, RTW89_H2CREG_WOW_CPUIO_RX_CTRL_EN);
+
+ ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info);
+ if (ret)
+ return ret;
+
+ if (c2h_info.id != RTW89_FWCMD_C2HREG_FUNC_WOW_CPUIO_RX_ACK)
+ ret = -EINVAL;
+
+ return ret;
+}
+
static int rtw89_wow_config_mac_ax(struct rtw89_dev *rtwdev, bool enable_wow)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
int ret;
if (enable_wow) {
@@ -6282,12 +6798,22 @@ static int rtw89_wow_config_mac_ax(struct rtw89_dev *rtwdev, bool enable_wow)
}
rtw89_write32_set(rtwdev, R_AX_RX_FUNCTION_STOP, B_AX_HDR_RX_STOP);
+ rtw89_mac_cpu_io_rx(rtwdev, enable_wow);
rtw89_write32_clr(rtwdev, mac->rx_fltr, B_AX_SNIFFER_MODE);
rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false);
rtw89_write32(rtwdev, R_AX_ACTION_FWD0, 0);
rtw89_write32(rtwdev, R_AX_ACTION_FWD1, 0);
rtw89_write32(rtwdev, R_AX_TF_FWD, 0);
rtw89_write32(rtwdev, R_AX_HW_RPT_FWD, 0);
+
+ if (RTW89_CHK_FW_FEATURE(NO_WOW_CPU_IO_RX, &rtwdev->fw))
+ return 0;
+
+ if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))
+ rtw89_write8(rtwdev, R_BE_DBG_WOW_READY, WOWLAN_NOT_READY);
+ else
+ rtw89_write32_set(rtwdev, R_AX_DBG_WOW,
+ B_AX_DBG_WOW_CPU_IO_RX_EN);
} else {
ret = rtw89_mac_resize_ple_rx_quota(rtwdev, false);
if (ret) {
@@ -6295,6 +6821,7 @@ static int rtw89_wow_config_mac_ax(struct rtw89_dev *rtwdev, bool enable_wow)
return ret;
}
+ rtw89_mac_cpu_io_rx(rtwdev, enable_wow);
rtw89_write32_clr(rtwdev, R_AX_RX_FUNCTION_STOP, B_AX_HDR_RX_STOP);
rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true);
rtw89_write32(rtwdev, R_AX_ACTION_FWD0, TRXCFG_MPDU_PROC_ACT_FRWD);
@@ -6323,6 +6850,20 @@ int rtw89_fwdl_check_path_ready_ax(struct rtw89_dev *rtwdev,
rtwdev, R_AX_WCPU_FW_CTRL);
}
+static
+void rtw89_fwdl_secure_idmem_share_mode_ax(struct rtw89_dev *rtwdev, u8 mode)
+{
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+
+ if (!sec->secure_boot)
+ return;
+
+ rtw89_write32_mask(rtwdev, R_AX_WCPU_FW_CTRL,
+ B_AX_IDMEM_SHARE_MODE_RECORD_MASK, mode);
+ rtw89_write32_set(rtwdev, R_AX_WCPU_FW_CTRL,
+ B_AX_IDMEM_SHARE_MODE_RECORD_VALID);
+}
+
const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.band1_offset = RTW89_MAC_AX_BAND_REG_OFFSET,
.filter_model_addr = R_AX_FILTER_MODEL_ADDR,
@@ -6347,6 +6888,8 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.mask = B_AX_RXTRIG_RU26_DIS,
},
.wow_ctrl = {.addr = R_AX_WOW_CTRL, .mask = B_AX_WOW_WOWEN,},
+ .agg_limit = {.addr = R_AX_AMPDU_AGG_LIMIT, .mask = B_AX_AMPDU_MAX_TIME_MASK,},
+ .txcnt_limit = {.addr = R_AX_TXCNT, .mask = B_AX_L_TXCNT_LMT_MASK,},
.check_mac_en = rtw89_mac_check_mac_en_ax,
.sys_init = sys_init_ax,
@@ -6359,6 +6902,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.typ_fltr_opt = rtw89_mac_typ_fltr_opt_ax,
.cfg_ppdu_status = rtw89_mac_cfg_ppdu_status_ax,
+ .cfg_phy_rpt = NULL,
.dle_mix_cfg = dle_mix_cfg_ax,
.chk_dle_rdy = chk_dle_rdy_ax,
@@ -6376,9 +6920,11 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.fwdl_enable_wcpu = rtw89_mac_enable_cpu_ax,
.fwdl_get_status = rtw89_fw_get_rdy_ax,
.fwdl_check_path_ready = rtw89_fwdl_check_path_ready_ax,
+ .fwdl_secure_idmem_share_mode = rtw89_fwdl_secure_idmem_share_mode_ax,
.parse_efuse_map = rtw89_parse_efuse_map_ax,
.parse_phycap_map = rtw89_parse_phycap_map_ax,
.cnv_efuse_state = rtw89_cnv_efuse_state_ax,
+ .efuse_read_fw_secure = rtw89_efuse_read_fw_secure_ax,
.cfg_plt = rtw89_mac_cfg_plt_ax,
.get_plt_cnt = rtw89_mac_get_plt_cnt_ax,
@@ -6393,8 +6939,11 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.is_txq_empty = mac_is_txq_empty_ax,
- .add_chan_list = rtw89_hw_scan_add_chan_list,
- .scan_offload = rtw89_fw_h2c_scan_offload,
+ .prep_chan_list = rtw89_hw_scan_prep_chan_list_ax,
+ .free_chan_list = rtw89_hw_scan_free_chan_list_ax,
+ .add_chan_list = rtw89_hw_scan_add_chan_list_ax,
+ .add_chan_list_pno = rtw89_pno_scan_add_chan_list_ax,
+ .scan_offload = rtw89_fw_h2c_scan_offload_ax,
.wow_config_mac = rtw89_wow_config_mac_ax,
};
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index 6fb457153a11..8013c852d5be 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -169,6 +169,20 @@ enum rtw89_mac_ax_l0_to_l1_event {
MAC_AX_L0_TO_L1_EVENT_MAX = 15,
};
+enum rtw89_mac_phy_rpt_size {
+ MAC_AX_PHY_RPT_SIZE_0 = 0,
+ MAC_AX_PHY_RPT_SIZE_8 = 1,
+ MAC_AX_PHY_RPT_SIZE_16 = 2,
+ MAC_AX_PHY_RPT_SIZE_24 = 3,
+};
+
+enum rtw89_mac_hdr_cnv_size {
+ MAC_AX_HDR_CNV_SIZE_0 = 0,
+ MAC_AX_HDR_CNV_SIZE_32 = 1,
+ MAC_AX_HDR_CNV_SIZE_64 = 2,
+ MAC_AX_HDR_CNV_SIZE_96 = 3,
+};
+
enum rtw89_mac_wow_fw_status {
WOWLAN_NOT_READY = 0x00,
WOWLAN_SLEEP_READY = 0x01,
@@ -356,6 +370,7 @@ enum rtw89_mac_mem_sel {
RTW89_MAC_MEM_TXD_FIFO_0_V1,
RTW89_MAC_MEM_TXD_FIFO_1_V1,
RTW89_MAC_MEM_WD_PAGE,
+ RTW89_MAC_MEM_MLD_TBL,
/* keep last */
RTW89_MAC_MEM_NUM,
@@ -391,6 +406,7 @@ enum rtw89_mac_c2h_ofld_func {
RTW89_MAC_C2H_FUNC_MACID_PAUSE,
RTW89_MAC_C2H_FUNC_TSF32_TOGL_RPT = 0x6,
RTW89_MAC_C2H_FUNC_SCANOFLD_RSP = 0x9,
+ RTW89_MAC_C2H_FUNC_TX_DUTY_RPT = 0xa,
RTW89_MAC_C2H_FUNC_BCNFLTR_RPT = 0xd,
RTW89_MAC_C2H_FUNC_OFLD_MAX,
};
@@ -412,6 +428,18 @@ enum rtw89_mac_c2h_mcc_func {
NUM_OF_RTW89_MAC_C2H_FUNC_MCC,
};
+enum rtw89_mac_c2h_mlo_func {
+ RTW89_MAC_C2H_FUNC_MLO_GET_TBL = 0x0,
+ RTW89_MAC_C2H_FUNC_MLO_EMLSR_TRANS_DONE = 0x1,
+ RTW89_MAC_C2H_FUNC_MLO_EMLSR_STA_CFG_DONE = 0x2,
+ RTW89_MAC_C2H_FUNC_MCMLO_RELINK_RPT = 0x3,
+ RTW89_MAC_C2H_FUNC_MCMLO_SN_SYNC_RPT = 0x4,
+ RTW89_MAC_C2H_FUNC_MLO_LINK_CFG_STAT = 0x5,
+ RTW89_MAC_C2H_FUNC_MLO_DM_DBG_DUMP = 0x6,
+
+ NUM_OF_RTW89_MAC_C2H_FUNC_MLO,
+};
+
enum rtw89_mac_c2h_mrc_func {
RTW89_MAC_C2H_FUNC_MRC_TSF_RPT = 0,
RTW89_MAC_C2H_FUNC_MRC_STATUS_RPT = 1,
@@ -419,6 +447,18 @@ enum rtw89_mac_c2h_mrc_func {
NUM_OF_RTW89_MAC_C2H_FUNC_MRC,
};
+enum rtw89_mac_c2h_wow_func {
+ RTW89_MAC_C2H_FUNC_AOAC_REPORT,
+
+ NUM_OF_RTW89_MAC_C2H_FUNC_WOW,
+};
+
+enum rtw89_mac_c2h_ap_func {
+ RTW89_MAC_C2H_FUNC_PWR_INT_NOTIFY = 0,
+
+ NUM_OF_RTW89_MAC_C2H_FUNC_AP,
+};
+
enum rtw89_mac_c2h_class {
RTW89_MAC_C2H_CLASS_INFO = 0x0,
RTW89_MAC_C2H_CLASS_OFLD = 0x1,
@@ -426,7 +466,9 @@ enum rtw89_mac_c2h_class {
RTW89_MAC_C2H_CLASS_WOW = 0x3,
RTW89_MAC_C2H_CLASS_MCC = 0x4,
RTW89_MAC_C2H_CLASS_FWDBG = 0x5,
+ RTW89_MAC_C2H_CLASS_MLO = 0xc,
RTW89_MAC_C2H_CLASS_MRC = 0xe,
+ RTW89_MAC_C2H_CLASS_AP = 0x18,
RTW89_MAC_C2H_CLASS_MAX,
};
@@ -459,6 +501,16 @@ enum rtw89_mac_mrc_status {
RTW89_MAC_MRC_START_SCH_OK = 0,
RTW89_MAC_MRC_STOP_SCH_OK = 1,
RTW89_MAC_MRC_DEL_SCH_OK = 2,
+ RTW89_MAC_MRC_EMPTY_SCH_FAIL = 16,
+ RTW89_MAC_MRC_ROLE_NOT_EXIST_FAIL = 17,
+ RTW89_MAC_MRC_DATA_NOT_FOUND_FAIL = 18,
+ RTW89_MAC_MRC_GET_NEXT_SLOT_FAIL = 19,
+ RTW89_MAC_MRC_ALT_ROLE_FAIL = 20,
+ RTW89_MAC_MRC_ADD_PSTIMER_FAIL = 21,
+ RTW89_MAC_MRC_MALLOC_FAIL = 22,
+ RTW89_MAC_MRC_SWITCH_CH_FAIL = 23,
+ RTW89_MAC_MRC_TXNULL0_FAIL = 24,
+ RTW89_MAC_MRC_PORT_FUNC_EN_FAIL = 25,
};
struct rtw89_mac_ax_coex {
@@ -868,12 +920,14 @@ struct rtw89_mac_size_set {
const struct rtw89_dle_size wde_size9;
const struct rtw89_dle_size wde_size18;
const struct rtw89_dle_size wde_size19;
+ const struct rtw89_dle_size wde_size23;
const struct rtw89_dle_size ple_size0;
const struct rtw89_dle_size ple_size0_v1;
const struct rtw89_dle_size ple_size3_v1;
const struct rtw89_dle_size ple_size4;
const struct rtw89_dle_size ple_size6;
const struct rtw89_dle_size ple_size8;
+ const struct rtw89_dle_size ple_size9;
const struct rtw89_dle_size ple_size18;
const struct rtw89_dle_size ple_size19;
const struct rtw89_wde_quota wde_qt0;
@@ -883,6 +937,7 @@ struct rtw89_mac_size_set {
const struct rtw89_wde_quota wde_qt7;
const struct rtw89_wde_quota wde_qt17;
const struct rtw89_wde_quota wde_qt18;
+ const struct rtw89_wde_quota wde_qt23;
const struct rtw89_ple_quota ple_qt0;
const struct rtw89_ple_quota ple_qt1;
const struct rtw89_ple_quota ple_qt4;
@@ -894,9 +949,12 @@ struct rtw89_mac_size_set {
const struct rtw89_ple_quota ple_qt45;
const struct rtw89_ple_quota ple_qt46;
const struct rtw89_ple_quota ple_qt47;
+ const struct rtw89_ple_quota ple_qt57;
const struct rtw89_ple_quota ple_qt58;
+ const struct rtw89_ple_quota ple_qt59;
const struct rtw89_ple_quota ple_qt_52a_wow;
const struct rtw89_ple_quota ple_qt_52b_wow;
+ const struct rtw89_ple_quota ple_qt_52bt_wow;
const struct rtw89_ple_quota ple_qt_51b_wow;
const struct rtw89_rsvd_quota ple_rsvd_qt0;
const struct rtw89_rsvd_quota ple_rsvd_qt1;
@@ -920,6 +978,8 @@ struct rtw89_mac_gen_def {
struct rtw89_reg_def bfee_ctrl;
struct rtw89_reg_def narrow_bw_ru_dis;
struct rtw89_reg_def wow_ctrl;
+ struct rtw89_reg_def agg_limit;
+ struct rtw89_reg_def txcnt_limit;
int (*check_mac_en)(struct rtw89_dev *rtwdev, u8 band,
enum rtw89_mac_hwmod_sel sel);
@@ -929,14 +989,16 @@ struct rtw89_mac_gen_def {
void (*dmac_func_pre_en)(struct rtw89_dev *rtwdev);
void (*dle_func_en)(struct rtw89_dev *rtwdev, bool enable);
void (*dle_clk_en)(struct rtw89_dev *rtwdev, bool enable);
- void (*bf_assoc)(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ void (*bf_assoc)(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
int (*typ_fltr_opt)(struct rtw89_dev *rtwdev,
enum rtw89_machdr_frame_type type,
enum rtw89_mac_fwd_target fwd_target,
u8 mac_idx);
int (*cfg_ppdu_status)(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable);
+ void (*cfg_phy_rpt)(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable);
int (*dle_mix_cfg)(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg);
int (*chk_dle_rdy)(struct rtw89_dev *rtwdev, bool wde_or_ple);
@@ -961,9 +1023,11 @@ struct rtw89_mac_gen_def {
bool dlfw, bool include_bb);
u8 (*fwdl_get_status)(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type);
int (*fwdl_check_path_ready)(struct rtw89_dev *rtwdev, bool h2c_or_fwdl);
+ void (*fwdl_secure_idmem_share_mode)(struct rtw89_dev *rtwdev, u8 mode);
int (*parse_efuse_map)(struct rtw89_dev *rtwdev);
int (*parse_phycap_map)(struct rtw89_dev *rtwdev);
int (*cnv_efuse_state)(struct rtw89_dev *rtwdev, bool idle);
+ int (*efuse_read_fw_secure)(struct rtw89_dev *rtwdev);
int (*cfg_plt)(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt);
u16 (*get_plt_cnt)(struct rtw89_dev *rtwdev, u8 band);
@@ -981,11 +1045,17 @@ struct rtw89_mac_gen_def {
bool (*is_txq_empty)(struct rtw89_dev *rtwdev);
+ int (*prep_chan_list)(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
+ void (*free_chan_list)(struct rtw89_dev *rtwdev);
int (*add_chan_list)(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool connected);
+ struct rtw89_vif_link *rtwvif_link);
+ int (*add_chan_list_pno)(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
int (*scan_offload)(struct rtw89_dev *rtwdev,
struct rtw89_scan_option *option,
- struct rtw89_vif *rtwvif);
+ struct rtw89_vif_link *rtwvif_link,
+ bool wowlan);
int (*wow_config_mac)(struct rtw89_dev *rtwdev, bool enable_wow);
};
@@ -1008,84 +1078,93 @@ u32 rtw89_mac_reg_by_port(struct rtw89_dev *rtwdev, u32 base, u8 port, u8 mac_id
}
static inline u32
-rtw89_read32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base)
+rtw89_read32_port(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
return rtw89_read32(rtwdev, reg);
}
static inline u32
-rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 mask)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
return rtw89_read32_mask(rtwdev, reg, mask);
}
static inline void
-rtw89_write32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base,
+rtw89_write32_port(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base,
u32 data)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
rtw89_write32(rtwdev, reg, data);
}
static inline void
-rtw89_write32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+rtw89_write32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 mask, u32 data)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, mask, data);
}
static inline void
-rtw89_write16_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+rtw89_write16_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 mask, u16 data)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
rtw89_write16_mask(rtwdev, reg, mask, data);
}
static inline void
-rtw89_write32_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+rtw89_write32_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 bit)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
rtw89_write32_clr(rtwdev, reg, bit);
}
static inline void
-rtw89_write16_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+rtw89_write16_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u16 bit)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
rtw89_write16_clr(rtwdev, reg, bit);
}
static inline void
-rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 bit)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
+ rtwvif_link->mac_idx);
rtw89_write32_set(rtwdev, reg, bit);
}
+int rtw89_mac_pwr_on(struct rtw89_dev *rtwdev);
void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev);
int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb);
int rtw89_mac_init(struct rtw89_dev *rtwdev);
@@ -1114,21 +1193,23 @@ int rtw89_mac_dle_dfi_qempty_cfg(struct rtw89_dev *rtwdev,
struct rtw89_mac_dle_dfi_qempty *qempty);
void rtw89_mac_dump_l0_to_l1(struct rtw89_dev *rtwdev,
enum mac_ax_err_info err);
-int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
-int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
+int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
- struct rtw89_vif *rtwvif_src,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_vif_link *rtwvif_src,
u16 offset_tu);
-int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u64 *tsf);
void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool en);
+ struct rtw89_vif_link *rtwvif_link, bool en);
void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif);
-void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+ struct rtw89_vif_link *rtwvif_link);
+void rtw89_mac_set_he_tb(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
+void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en);
-int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
+int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev);
int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev);
@@ -1179,6 +1260,27 @@ int rtw89_mac_stop_sch_tx_v2(struct rtw89_dev *rtwdev, u8 mac_idx,
int rtw89_mac_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en);
int rtw89_mac_resume_sch_tx_v1(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en);
int rtw89_mac_resume_sch_tx_v2(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en);
+void rtw89_mac_cfg_phy_rpt_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable);
+
+static inline
+void rtw89_mac_cfg_phy_rpt(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+
+ if (mac->cfg_phy_rpt)
+ mac->cfg_phy_rpt(rtwdev, mac_idx, enable);
+}
+
+static inline
+void rtw89_mac_cfg_phy_rpt_bands(struct rtw89_dev *rtwdev, bool enable)
+{
+ rtw89_mac_cfg_phy_rpt(rtwdev, RTW89_MAC_0, enable);
+
+ if (!rtwdev->dbcc_en)
+ return;
+
+ rtw89_mac_cfg_phy_rpt(rtwdev, RTW89_MAC_1, enable);
+}
static inline
int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable)
@@ -1188,7 +1290,22 @@ int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable)
return mac->cfg_ppdu_status(rtwdev, mac_idx, enable);
}
-void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx);
+static inline
+int rtw89_mac_cfg_ppdu_status_bands(struct rtw89_dev *rtwdev, bool enable)
+{
+ int ret;
+
+ ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, enable);
+ if (ret)
+ return ret;
+
+ if (!rtwdev->dbcc_en)
+ return 0;
+
+ return rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_1, enable);
+}
+
+void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev);
void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop);
int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex);
int rtw89_mac_coex_init_v1(struct rtw89_dev *rtwdev,
@@ -1226,27 +1343,30 @@ void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter);
void rtw89_mac_notify_wake(struct rtw89_dev *rtwdev);
static inline
-void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
if (mac->bf_assoc)
- mac->bf_assoc(rtwdev, vif, sta);
+ mac->bf_assoc(rtwdev, rtwvif_link, rtwsta_link);
}
-void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link);
void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *conf);
void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta, bool disconnect);
+ struct rtw89_sta_link *rtwsta_link,
+ bool disconnect);
void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev);
void rtw89_mac_bfee_ctrl(struct rtw89_dev *rtwdev, u8 mac_idx, bool en);
-int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
-int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
+int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool en);
+ struct rtw89_vif_link *rtwvif_link, bool en);
int rtw89_mac_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause);
static inline void rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev)
@@ -1351,15 +1471,15 @@ static inline bool rtw89_mac_get_power_state(struct rtw89_dev *rtwdev)
return !!val;
}
-int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
bool resume, u32 tx_time);
-int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
u32 *tx_time);
int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta,
+ struct rtw89_sta_link *rtwsta_link,
bool resume, u8 tx_retry);
int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta, u8 *tx_retry);
+ struct rtw89_sta_link *rtwsta_link, u8 *tx_retry);
enum rtw89_mac_xtal_si_offset {
XTAL0 = 0x0,
@@ -1439,5 +1559,16 @@ int rtw89_mac_dle_quota_change(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mod
int rtw89_mac_get_dle_rsvd_qt_cfg(struct rtw89_dev *rtwdev,
enum rtw89_mac_dle_rsvd_qt_type type,
struct rtw89_mac_dle_rsvd_qt_cfg *cfg);
+int rtw89_mac_cpu_io_rx(struct rtw89_dev *rtwdev, bool wow_enable);
+static inline
+void rtw89_fwdl_secure_idmem_share_mode(struct rtw89_dev *rtwdev, u8 mode)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+
+ if (!mac->fwdl_secure_idmem_share_mode)
+ return;
+
+ return mac->fwdl_secure_idmem_share_mode(rtwdev, mode);
+}
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 31d1ffb16e83..a47971003bd4 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -23,13 +23,13 @@ static void rtw89_ops_tx(struct ieee80211_hw *hw,
struct rtw89_dev *rtwdev = hw->priv;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_vif *vif = info->control.vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct ieee80211_sta *sta = control->sta;
u32 flags = IEEE80211_SKB_CB(skb)->flags;
int ret, qsel;
if (rtwvif->offchan && !(flags & IEEE80211_TX_CTL_TX_OFFCHAN) && sta) {
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
rtw89_debug(rtwdev, RTW89_DBG_TXRX, "ops_tx during offchan\n");
skb_queue_tail(&rtwsta->roc_queue, skb);
@@ -57,32 +57,30 @@ static void rtw89_ops_wake_tx_queue(struct ieee80211_hw *hw,
static int rtw89_ops_start(struct ieee80211_hw *hw)
{
struct rtw89_dev *rtwdev = hw->priv;
- int ret;
- mutex_lock(&rtwdev->mutex);
- ret = rtw89_core_start(rtwdev);
- mutex_unlock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
- return ret;
+ return rtw89_core_start(rtwdev);
}
-static void rtw89_ops_stop(struct ieee80211_hw *hw)
+static void rtw89_ops_stop(struct ieee80211_hw *hw, bool suspend)
{
struct rtw89_dev *rtwdev = hw->priv;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
+
rtw89_core_stop(rtwdev);
- mutex_unlock(&rtwdev->mutex);
}
static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
{
struct rtw89_dev *rtwdev = hw->priv;
+ lockdep_assert_wiphy(hw->wiphy);
+
/* let previous ips work finish to ensure we don't leave ips twice */
- cancel_work_sync(&rtwdev->ips_work);
+ wiphy_work_cancel(hw->wiphy, &rtwdev->ips_work);
- mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
@@ -90,7 +88,7 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
rtw89_leave_ips(rtwdev);
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
- rtw89_config_entity_chandef(rtwdev, RTW89_SUB_ENTITY_0,
+ rtw89_config_entity_chandef(rtwdev, RTW89_CHANCTX_0,
&hw->conf.chandef);
rtw89_set_channel(rtwdev);
}
@@ -100,71 +98,130 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
!rtwdev->scanning)
rtw89_enter_ips(rtwdev);
- mutex_unlock(&rtwdev->mutex);
+ return 0;
+}
+
+static int __rtw89_ops_add_iface_link(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct ieee80211_bss_conf *bss_conf;
+ int ret;
+
+ rtw89_leave_ps_mode(rtwdev);
+
+ rtw89_vif_type_mapping(rtwvif_link, false);
+ wiphy_work_init(&rtwvif_link->update_beacon_work, rtw89_core_update_beacon_work);
+ INIT_LIST_HEAD(&rtwvif_link->general_pkt_list);
+
+ rtw89_p2p_noa_once_init(rtwvif_link);
+
+ rtwvif_link->hit_rule = 0;
+ rtwvif_link->bcn_hit_cond = 0;
+ rtwvif_link->chanctx_assigned = false;
+ rtwvif_link->chanctx_idx = RTW89_CHANCTX_0;
+ rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
+ rtwvif_link->rand_tsf_done = false;
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ ether_addr_copy(rtwvif_link->mac_addr, bss_conf->addr);
+
+ rcu_read_unlock();
+
+ ret = rtw89_mac_add_vif(rtwdev, rtwvif_link);
+ if (ret)
+ return ret;
+
+ rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, NULL, BTC_ROLE_START);
return 0;
}
+static void __rtw89_ops_remove_iface_link(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ wiphy_work_cancel(rtwdev->hw->wiphy, &rtwvif_link->update_beacon_work);
+
+ rtw89_p2p_noa_once_deinit(rtwvif_link);
+
+ rtw89_leave_ps_mode(rtwdev);
+
+ rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, NULL, BTC_ROLE_STOP);
+
+ rtw89_mac_remove_vif(rtwdev, rtwvif_link);
+}
+
static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+ u8 mac_id, port;
int ret = 0;
+ lockdep_assert_wiphy(hw->wiphy);
+
rtw89_debug(rtwdev, RTW89_DBG_STATE, "add vif %pM type %d, p2p %d\n",
vif->addr, vif->type, vif->p2p);
- mutex_lock(&rtwdev->mutex);
-
rtw89_leave_ips_by_hwflags(rtwdev);
if (RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw))
vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
IEEE80211_VIF_SUPPORTS_CQM_RSSI;
- rtwvif->rtwdev = rtwdev;
- rtwvif->roc.state = RTW89_ROC_IDLE;
- rtwvif->offchan = false;
- list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
- INIT_WORK(&rtwvif->update_beacon_work, rtw89_core_update_beacon_work);
- INIT_DELAYED_WORK(&rtwvif->roc.roc_work, rtw89_roc_work);
- rtw89_leave_ps_mode(rtwdev);
+ mac_id = rtw89_acquire_mac_id(rtwdev);
+ if (mac_id == RTW89_MAX_MAC_ID_NUM)
+ return -ENOSPC;
- rtw89_traffic_stats_init(rtwdev, &rtwvif->stats);
- rtw89_vif_type_mapping(vif, false);
- rtwvif->port = rtw89_core_acquire_bit_map(rtwdev->hw_port,
- RTW89_PORT_NUM);
- if (rtwvif->port == RTW89_PORT_NUM) {
+ port = rtw89_core_acquire_bit_map(rtwdev->hw_port, RTW89_PORT_NUM);
+ if (port == RTW89_PORT_NUM) {
ret = -ENOSPC;
- list_del_init(&rtwvif->list);
- goto out;
+ goto release_macid;
}
- rtwvif->bcn_hit_cond = 0;
- rtwvif->mac_idx = RTW89_MAC_0;
- rtwvif->phy_idx = RTW89_PHY_0;
- rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0;
- rtwvif->chanctx_assigned = false;
- rtwvif->hit_rule = 0;
- rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
- ether_addr_copy(rtwvif->mac_addr, vif->addr);
- INIT_LIST_HEAD(&rtwvif->general_pkt_list);
+ rtw89_init_vif(rtwdev, rtwvif, mac_id, port);
- ret = rtw89_mac_add_vif(rtwdev, rtwvif);
- if (ret) {
- rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
- list_del_init(&rtwvif->list);
- goto out;
+ rtw89_core_txq_init(rtwdev, vif->txq);
+
+ if (!rtw89_rtwvif_in_list(rtwdev, rtwvif)) {
+ list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
+ INIT_LIST_HEAD(&rtwvif->mgnt_entry);
+ INIT_LIST_HEAD(&rtwvif->dlink_pool);
}
- rtw89_core_txq_init(rtwdev, vif->txq);
+ ether_addr_copy(rtwvif->mac_addr, vif->addr);
- rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_START);
+ rtwvif->offchan = false;
+ rtwvif->roc.state = RTW89_ROC_IDLE;
+ wiphy_delayed_work_init(&rtwvif->roc.roc_work, rtw89_roc_work);
+
+ rtw89_traffic_stats_init(rtwdev, &rtwvif->stats);
+
+ rtwvif_link = rtw89_vif_set_link(rtwvif, RTW89_VIF_IDLE_LINK_ID);
+ if (!rtwvif_link) {
+ ret = -EINVAL;
+ goto release_port;
+ }
+
+ ret = __rtw89_ops_add_iface_link(rtwdev, rtwvif_link);
+ if (ret)
+ goto unset_link;
rtw89_recalc_lps(rtwdev);
-out:
- mutex_unlock(&rtwdev->mutex);
+ return 0;
+
+unset_link:
+ rtw89_vif_unset_link(rtwvif, RTW89_VIF_IDLE_LINK_ID);
+release_port:
+ list_del_init(&rtwvif->list);
+ rtw89_core_release_bit_map(rtwdev->hw_port, port);
+release_macid:
+ rtw89_release_mac_id(rtwdev, mac_id);
return ret;
}
@@ -173,24 +230,37 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ u8 macid = rtw89_vif_get_main_macid(rtwvif);
+ u8 port = rtw89_vif_get_main_port(rtwvif);
+ struct rtw89_vif_link *rtwvif_link;
+
+ lockdep_assert_wiphy(hw->wiphy);
rtw89_debug(rtwdev, RTW89_DBG_STATE, "remove vif %pM type %d p2p %d\n",
vif->addr, vif->type, vif->p2p);
- cancel_work_sync(&rtwvif->update_beacon_work);
- cancel_delayed_work_sync(&rtwvif->roc.roc_work);
+ wiphy_delayed_work_cancel(hw->wiphy, &rtwvif->roc.roc_work);
- mutex_lock(&rtwdev->mutex);
- rtw89_leave_ps_mode(rtwdev);
- rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_STOP);
- rtw89_mac_remove_vif(rtwdev, rtwvif);
- rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
+ rtwvif_link = rtwvif->links[RTW89_VIF_IDLE_LINK_ID];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, RTW89_VIF_IDLE_LINK_ID);
+ goto bottom;
+ }
+
+ __rtw89_ops_remove_iface_link(rtwdev, rtwvif_link);
+
+ rtw89_vif_unset_link(rtwvif, RTW89_VIF_IDLE_LINK_ID);
+
+bottom:
list_del_init(&rtwvif->list);
+ rtw89_core_release_bit_map(rtwdev->hw_port, port);
+ rtw89_release_mac_id(rtwdev, macid);
+
rtw89_recalc_lps(rtwdev);
rtw89_enter_ips_by_hwflags(rtwdev);
-
- mutex_unlock(&rtwdev->mutex);
}
static int rtw89_ops_change_interface(struct ieee80211_hw *hw,
@@ -228,7 +298,8 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u32 rx_fltr;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
+
rtw89_leave_ps_mode(rtwdev);
*new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL |
@@ -291,14 +362,11 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
B_AX_RX_FLTR_CFG_MASK,
rx_fltr);
if (!rtwdev->dbcc_en)
- goto out;
+ return;
rtw89_write32_mask(rtwdev,
rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_1),
B_AX_RX_FLTR_CFG_MASK,
rx_fltr);
-
-out:
- mutex_unlock(&rtwdev->mutex);
}
static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = {
@@ -309,24 +377,30 @@ static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = {
};
static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, u8 aifsn)
+ struct rtw89_vif_link *rtwvif_link, u8 aifsn)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->sub_entity_idx);
+ rtwvif_link->chanctx_idx);
+ struct ieee80211_bss_conf *bss_conf;
u8 slot_time;
u8 sifs;
- slot_time = vif->bss_conf.use_short_slot ? 9 : 20;
- sifs = chan->band_type == RTW89_BAND_5G ? 16 : 10;
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ slot_time = bss_conf->use_short_slot ? 9 : 20;
+
+ rcu_read_unlock();
+
+ sifs = chan->band_type == RTW89_BAND_2G ? 10 : 16;
return aifsn * slot_time + sifs;
}
static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, u16 ac)
+ struct rtw89_vif_link *rtwvif_link, u16 ac)
{
- struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
+ struct ieee80211_tx_queue_params *params = &rtwvif_link->tx_params[ac];
u32 val;
u8 ecw_max, ecw_min;
u8 aifs;
@@ -334,12 +408,12 @@ static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev,
/* 2^ecw - 1 = cw; ecw = log2(cw + 1) */
ecw_max = ilog2(params->cw_max + 1);
ecw_min = ilog2(params->cw_min + 1);
- aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif, params->aifs);
+ aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif_link, params->aifs);
val = FIELD_PREP(FW_EDCA_PARAM_TXOPLMT_MSK, params->txop) |
FIELD_PREP(FW_EDCA_PARAM_CWMAX_MSK, ecw_max) |
FIELD_PREP(FW_EDCA_PARAM_CWMIN_MSK, ecw_min) |
FIELD_PREP(FW_EDCA_PARAM_AIFS_MSK, aifs);
- rtw89_fw_h2c_set_edca(rtwdev, rtwvif, ac_to_fw_idx[ac], val);
+ rtw89_fw_h2c_set_edca(rtwdev, rtwvif_link, ac_to_fw_idx[ac], val);
}
#define R_MUEDCA_ACS_PARAM(acs) {R_AX_MUEDCA_ ## acs ## _PARAM_0, \
@@ -353,9 +427,9 @@ static const u32 ac_to_mu_edca_param[IEEE80211_NUM_ACS][RTW89_CHIP_GEN_NUM] = {
};
static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, u16 ac)
+ struct rtw89_vif_link *rtwvif_link, u16 ac)
{
- struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
+ struct ieee80211_tx_queue_params *params = &rtwvif_link->tx_params[ac];
struct ieee80211_he_mu_edca_param_ac_rec *mu_edca;
int gen = rtwdev->chip->chip_gen;
u8 aifs, aifsn;
@@ -368,72 +442,258 @@ static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev,
mu_edca = &params->mu_edca_param_rec;
aifsn = FIELD_GET(GENMASK(3, 0), mu_edca->aifsn);
- aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif, aifsn) : 0;
+ aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif_link, aifsn) : 0;
timer_32us = mu_edca->mu_edca_timer << 8;
val = FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK, timer_32us) |
FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_CW_MASK, mu_edca->ecw_min_max) |
FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK, aifs);
- reg = rtw89_mac_reg_by_idx(rtwdev, ac_to_mu_edca_param[ac][gen], rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, ac_to_mu_edca_param[ac][gen],
+ rtwvif_link->mac_idx);
rtw89_write32(rtwdev, reg, val);
- rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif, true);
+ rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif_link, true);
}
static void __rtw89_conf_tx(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, u16 ac)
+ struct rtw89_vif_link *rtwvif_link, u16 ac)
{
- ____rtw89_conf_tx_edca(rtwdev, rtwvif, ac);
- ____rtw89_conf_tx_mu_edca(rtwdev, rtwvif, ac);
+ ____rtw89_conf_tx_edca(rtwdev, rtwvif_link, ac);
+ ____rtw89_conf_tx_mu_edca(rtwdev, rtwvif_link, ac);
}
static void rtw89_conf_tx(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
u16 ac;
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
- __rtw89_conf_tx(rtwdev, rtwvif, ac);
+ __rtw89_conf_tx(rtwdev, rtwvif_link, ac);
+}
+
+static int __rtw89_ops_sta_add(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ bool acquire_macid = false;
+ u8 macid;
+ int ret;
+ int i;
+
+ if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
+ rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR;
+
+ /* for station mode, assign the mac_id from itself */
+ macid = rtw89_vif_get_main_macid(rtwvif);
+ } else {
+ macid = rtw89_acquire_mac_id(rtwdev);
+ if (macid == RTW89_MAX_MAC_ID_NUM)
+ return -ENOSPC;
+
+ acquire_macid = true;
+ }
+
+ rtw89_init_sta(rtwdev, rtwvif, rtwsta, macid);
+
+ for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
+ rtw89_core_txq_init(rtwdev, sta->txq[i]);
+
+ INIT_LIST_HEAD(&rtwsta->dlink_pool);
+
+ skb_queue_head_init(&rtwsta->roc_queue);
+ bitmap_zero(rtwsta->pairwise_sec_cam_map, RTW89_MAX_SEC_CAM_NUM);
+
+ rtwsta_link = rtw89_sta_set_link(rtwsta, sta->deflink.link_id);
+ if (!rtwsta_link) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ rtwvif_link = rtwsta_link->rtwvif_link;
+
+ ret = rtw89_core_sta_link_add(rtwdev, rtwvif_link, rtwsta_link);
+ if (ret)
+ goto unset_link;
+
+ if (vif->type == NL80211_IFTYPE_AP || sta->tdls)
+ rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE);
+
+ return 0;
+
+unset_link:
+ rtw89_sta_unset_link(rtwsta, sta->deflink.link_id);
+err:
+ if (acquire_macid)
+ rtw89_release_mac_id(rtwdev, macid);
+
+ return ret;
+}
+
+static int __rtw89_ops_sta_assoc(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ bool station_mode)
+{
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ int ret;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+
+ if (station_mode)
+ rtw89_vif_type_mapping(rtwvif_link, true);
+
+ ret = rtw89_core_sta_link_assoc(rtwdev, rtwvif_link, rtwsta_link);
+ if (ret)
+ return ret;
+ }
+
+ rtwdev->total_sta_assoc++;
+ if (sta->tdls)
+ rtwvif->tdls_peer++;
+
+ return 0;
+}
+
+static int __rtw89_ops_sta_disassoc(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ int ret;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ ret = rtw89_core_sta_link_disassoc(rtwdev, rtwvif_link, rtwsta_link);
+ if (ret)
+ return ret;
+ }
+
+ rtwsta->disassoc = true;
+
+ rtwdev->total_sta_assoc--;
+ if (sta->tdls)
+ rtwvif->tdls_peer--;
+
+ return 0;
+}
+
+static int __rtw89_ops_sta_disconnect(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ int ret;
+
+ rtw89_core_free_sta_pending_ba(rtwdev, sta);
+ rtw89_core_free_sta_pending_forbid_ba(rtwdev, sta);
+ rtw89_core_free_sta_pending_roc_tx(rtwdev, sta);
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ ret = rtw89_core_sta_link_disconnect(rtwdev, rtwvif_link, rtwsta_link);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __rtw89_ops_sta_remove(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ u8 macid = rtw89_sta_get_main_macid(rtwsta);
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ int ret;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ ret = rtw89_core_sta_link_remove(rtwdev, rtwvif_link, rtwsta_link);
+ if (ret)
+ return ret;
+
+ rtw89_sta_unset_link(rtwsta, link_id);
+ }
+
+ if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
+ rtw89_release_mac_id(rtwdev, macid);
+ rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE);
+ }
+
+ return 0;
}
static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *conf)
+ struct ieee80211_vif *vif)
{
struct ieee80211_sta *sta;
if (vif->type != NL80211_IFTYPE_STATION)
return;
- sta = ieee80211_find_sta(vif, conf->bssid);
+ sta = ieee80211_find_sta(vif, vif->cfg.ap_addr);
if (!sta) {
rtw89_err(rtwdev, "can't find sta to set sta_assoc state\n");
return;
}
- rtw89_vif_type_mapping(vif, true);
+ __rtw89_ops_sta_assoc(rtwdev, vif, sta, true);
+}
- rtw89_core_sta_assoc(rtwdev, vif, sta);
+static void __rtw89_ops_bss_link_assoc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ rtw89_phy_set_bss_color(rtwdev, rtwvif_link);
+ rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, rtwvif_link);
+ rtw89_mac_port_update(rtwdev, rtwvif_link);
+ rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, rtwvif_link);
+ rtw89_mac_set_he_tb(rtwdev, rtwvif_link);
}
-static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *conf,
- u64 changed)
+static void __rtw89_ops_bss_assoc(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif)
+{
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ __rtw89_ops_bss_link_assoc(rtwdev, rtwvif_link);
+}
+
+static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, u64 changed)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+
+ lockdep_assert_wiphy(hw->wiphy);
- mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
if (changed & BSS_CHANGED_ASSOC) {
if (vif->cfg.assoc) {
- rtw89_station_mode_sta_assoc(rtwdev, vif, conf);
- rtw89_phy_set_bss_color(rtwdev, vif);
- rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif);
- rtw89_mac_port_update(rtwdev, rtwvif);
- rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, vif);
+ rtw89_station_mode_sta_assoc(rtwdev, vif);
+ __rtw89_ops_bss_assoc(rtwdev, vif);
rtw89_queue_chanctx_work(rtwdev);
} else {
@@ -445,35 +705,61 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
}
}
+ if (changed & BSS_CHANGED_PS)
+ rtw89_recalc_lps(rtwdev);
+
+ if (changed & BSS_CHANGED_ARP_FILTER)
+ rtwvif->ip_addr = vif->cfg.arp_addr_list[0];
+}
+
+static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf,
+ u64 changed)
+{
+ struct rtw89_dev *rtwdev = hw->priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+
+ lockdep_assert_wiphy(hw->wiphy);
+
+ rtw89_leave_ps_mode(rtwdev);
+
+ rtwvif_link = rtwvif->links[conf->link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, conf->link_id);
+ return;
+ }
+
if (changed & BSS_CHANGED_BSSID) {
- ether_addr_copy(rtwvif->bssid, conf->bssid);
- rtw89_cam_bssid_changed(rtwdev, rtwvif);
- rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
- WRITE_ONCE(rtwvif->sync_bcn_tsf, 0);
+ ether_addr_copy(rtwvif_link->bssid, conf->bssid);
+ rtw89_cam_bssid_changed(rtwdev, rtwvif_link);
+ rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
+ WRITE_ONCE(rtwvif_link->sync_bcn_tsf, 0);
}
if (changed & BSS_CHANGED_BEACON)
- rtw89_chip_h2c_update_beacon(rtwdev, rtwvif);
+ rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link);
if (changed & BSS_CHANGED_ERP_SLOT)
- rtw89_conf_tx(rtwdev, rtwvif);
+ rtw89_conf_tx(rtwdev, rtwvif_link);
if (changed & BSS_CHANGED_HE_BSS_COLOR)
- rtw89_phy_set_bss_color(rtwdev, vif);
+ rtw89_phy_set_bss_color(rtwdev, rtwvif_link);
if (changed & BSS_CHANGED_MU_GROUPS)
rtw89_mac_bf_set_gid_table(rtwdev, vif, conf);
if (changed & BSS_CHANGED_P2P_PS)
- rtw89_core_update_p2p_ps(rtwdev, vif);
+ rtw89_core_update_p2p_ps(rtwdev, rtwvif_link, conf);
if (changed & BSS_CHANGED_CQM)
- rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true);
+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
- if (changed & BSS_CHANGED_PS)
- rtw89_recalc_lps(rtwdev);
-
- mutex_unlock(&rtwdev->mutex);
+ if (changed & BSS_CHANGED_TPE)
+ rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true);
}
static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
@@ -481,31 +767,44 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *link_conf)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
const struct rtw89_chan *chan;
+ int ret = 0;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
- chan = rtw89_chan_get(rtwdev, rtwvif->sub_entity_idx);
- if (chan->band_type == RTW89_BAND_6G) {
- mutex_unlock(&rtwdev->mutex);
- return -EOPNOTSUPP;
+ rtwvif_link = rtwvif->links[link_conf->link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, link_conf->link_id);
+ return -ENOLINK;
}
+ chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
+ if (chan->band_type == RTW89_BAND_6G)
+ return -EOPNOTSUPP;
+
if (rtwdev->scanning)
rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
- ether_addr_copy(rtwvif->bssid, vif->bss_conf.bssid);
- rtw89_cam_bssid_changed(rtwdev, rtwvif);
- rtw89_mac_port_update(rtwdev, rtwvif);
- rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
- rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_TYPE_CHANGE);
- rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
- rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
- rtw89_chip_rfk_channel(rtwdev);
+ ether_addr_copy(rtwvif_link->bssid, link_conf->bssid);
+ rtw89_cam_bssid_changed(rtwdev, rtwvif_link);
+ rtw89_mac_port_update(rtwdev, rtwvif_link);
+ rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, NULL);
+ rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_TYPE_CHANGE);
+ rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true);
+ rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
+ rtw89_chip_rfk_channel(rtwdev, rtwvif_link);
+
+ if (RTW89_CHK_FW_FEATURE(NOTIFY_AP_INFO, &rtwdev->fw)) {
+ ret = rtw89_fw_h2c_ap_info_refcount(rtwdev, true);
+ if (ret)
+ return ret;
+ }
rtw89_queue_chanctx_work(rtwdev);
- mutex_unlock(&rtwdev->mutex);
return 0;
}
@@ -515,23 +814,37 @@ void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+
+ lockdep_assert_wiphy(hw->wiphy);
+
+ rtwvif_link = rtwvif->links[link_conf->link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, link_conf->link_id);
+ return;
+ }
- mutex_lock(&rtwdev->mutex);
- rtw89_mac_stop_ap(rtwdev, rtwvif);
- rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
- rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
- mutex_unlock(&rtwdev->mutex);
+ if (RTW89_CHK_FW_FEATURE(NOTIFY_AP_INFO, &rtwdev->fw))
+ rtw89_fw_h2c_ap_info_refcount(rtwdev, false);
+
+ rtw89_mac_stop_ap(rtwdev, rtwvif_link);
+ rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, NULL);
+ rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true);
}
static int rtw89_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
bool set)
{
- struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
- ieee80211_queue_work(rtwdev->hw, &rtwvif->update_beacon_work);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ wiphy_work_queue(hw->wiphy, &rtwvif_link->update_beacon_work);
return 0;
}
@@ -542,13 +855,23 @@ static int rtw89_ops_conf_tx(struct ieee80211_hw *hw,
const struct ieee80211_tx_queue_params *params)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+
+ lockdep_assert_wiphy(hw->wiphy);
- mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
- rtwvif->tx_params[ac] = *params;
- __rtw89_conf_tx(rtwdev, rtwvif, ac);
- mutex_unlock(&rtwdev->mutex);
+
+ rtwvif_link = rtwvif->links[link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, link_id);
+ return -ENOLINK;
+ }
+
+ rtwvif_link->tx_params[ac] = *params;
+ __rtw89_conf_tx(rtwdev, rtwvif_link, ac);
return 0;
}
@@ -563,26 +886,26 @@ static int __rtw89_ops_sta_state(struct ieee80211_hw *hw,
if (old_state == IEEE80211_STA_NOTEXIST &&
new_state == IEEE80211_STA_NONE)
- return rtw89_core_sta_add(rtwdev, vif, sta);
+ return __rtw89_ops_sta_add(rtwdev, vif, sta);
if (old_state == IEEE80211_STA_AUTH &&
new_state == IEEE80211_STA_ASSOC) {
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
return 0; /* defer to bss_info_changed to have vif info */
- return rtw89_core_sta_assoc(rtwdev, vif, sta);
+ return __rtw89_ops_sta_assoc(rtwdev, vif, sta, false);
}
if (old_state == IEEE80211_STA_ASSOC &&
new_state == IEEE80211_STA_AUTH)
- return rtw89_core_sta_disassoc(rtwdev, vif, sta);
+ return __rtw89_ops_sta_disassoc(rtwdev, vif, sta);
if (old_state == IEEE80211_STA_AUTH &&
new_state == IEEE80211_STA_NONE)
- return rtw89_core_sta_disconnect(rtwdev, vif, sta);
+ return __rtw89_ops_sta_disconnect(rtwdev, vif, sta);
if (old_state == IEEE80211_STA_NONE &&
new_state == IEEE80211_STA_NOTEXIST)
- return rtw89_core_sta_remove(rtwdev, vif, sta);
+ return __rtw89_ops_sta_remove(rtwdev, vif, sta);
return 0;
}
@@ -594,14 +917,11 @@ static int rtw89_ops_sta_state(struct ieee80211_hw *hw,
enum ieee80211_sta_state new_state)
{
struct rtw89_dev *rtwdev = hw->priv;
- int ret;
- mutex_lock(&rtwdev->mutex);
- rtw89_leave_ps_mode(rtwdev);
- ret = __rtw89_ops_sta_state(hw, vif, sta, old_state, new_state);
- mutex_unlock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
- return ret;
+ rtw89_leave_ps_mode(rtwdev);
+ return __rtw89_ops_sta_state(hw, vif, sta, old_state, new_state);
}
static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -610,9 +930,10 @@ static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_key_conf *key)
{
struct rtw89_dev *rtwdev = hw->priv;
- int ret = 0;
+ int ret;
+
+ lockdep_assert_wiphy(hw->wiphy);
- mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
switch (cmd) {
@@ -621,7 +942,7 @@ static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
ret = rtw89_cam_sec_key_add(rtwdev, vif, sta, key);
if (ret && ret != -EOPNOTSUPP) {
rtw89_err(rtwdev, "failed to add key to sec cam\n");
- goto out;
+ return ret;
}
break;
case DISABLE_KEY:
@@ -631,14 +952,11 @@ static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
ret = rtw89_cam_sec_key_del(rtwdev, vif, sta, key, true);
if (ret) {
rtw89_err(rtwdev, "failed to remove key from sec cam\n");
- goto out;
+ return ret;
}
break;
}
-out:
- mutex_unlock(&rtwdev->mutex);
-
return ret;
}
@@ -648,43 +966,38 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
struct ieee80211_sta *sta = params->sta;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
u16 tid = params->tid;
struct ieee80211_txq *txq = sta->txq[tid];
struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv;
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
switch (params->action) {
case IEEE80211_AMPDU_TX_START:
return IEEE80211_AMPDU_TX_START_IMMEDIATE;
case IEEE80211_AMPDU_TX_STOP_CONT:
case IEEE80211_AMPDU_TX_STOP_FLUSH:
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
- mutex_lock(&rtwdev->mutex);
clear_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
clear_bit(tid, rtwsta->ampdu_map);
- rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, vif, sta);
- mutex_unlock(&rtwdev->mutex);
+ rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta);
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
break;
case IEEE80211_AMPDU_TX_OPERATIONAL:
- mutex_lock(&rtwdev->mutex);
set_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
rtwsta->ampdu_params[tid].agg_num = params->buf_size;
rtwsta->ampdu_params[tid].amsdu = params->amsdu;
set_bit(tid, rtwsta->ampdu_map);
rtw89_leave_ps_mode(rtwdev);
- rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, vif, sta);
- mutex_unlock(&rtwdev->mutex);
+ rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta);
break;
case IEEE80211_AMPDU_RX_START:
- mutex_lock(&rtwdev->mutex);
rtw89_chip_h2c_ba_cam(rtwdev, rtwsta, true, params);
- mutex_unlock(&rtwdev->mutex);
break;
case IEEE80211_AMPDU_RX_STOP:
- mutex_lock(&rtwdev->mutex);
rtw89_chip_h2c_ba_cam(rtwdev, rtwsta, false, params);
- mutex_unlock(&rtwdev->mutex);
break;
default:
WARN_ON(1);
@@ -698,11 +1011,11 @@ static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
{
struct rtw89_dev *rtwdev = hw->priv;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
+
rtw89_leave_ps_mode(rtwdev);
if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
- rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0);
- mutex_unlock(&rtwdev->mutex);
+ rtw89_mac_update_rts_threshold(rtwdev);
return 0;
}
@@ -712,9 +1025,14 @@ static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
struct station_info *sinfo)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_sta_link *rtwsta_link;
+
+ rtwsta_link = rtw89_get_designated_link(rtwsta);
+ if (unlikely(!rtwsta_link))
+ return;
- sinfo->txrate = rtwsta->ra_report.txrate;
+ sinfo->txrate = rtwsta_link->ra_report.txrate;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
}
@@ -724,7 +1042,7 @@ void __rtw89_drop_packets(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
struct rtw89_vif *rtwvif;
if (vif) {
- rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ rtwvif = vif_to_rtwvif(vif);
rtw89_mac_pkt_drop_vif(rtwdev, rtwvif);
} else {
rtw89_for_each_rtwvif(rtwdev, rtwvif)
@@ -737,7 +1055,8 @@ static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
{
struct rtw89_dev *rtwdev = hw->priv;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
+
rtw89_leave_lps(rtwdev);
rtw89_hci_flush_queues(rtwdev, queues, drop);
@@ -745,8 +1064,6 @@ static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
__rtw89_drop_packets(rtwdev, vif);
else
rtw89_mac_flush_txq(rtwdev, queues, drop);
-
- mutex_unlock(&rtwdev->mutex);
}
struct rtw89_iter_bitrate_mask_data {
@@ -758,15 +1075,21 @@ struct rtw89_iter_bitrate_mask_data {
static void rtw89_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_iter_bitrate_mask_data *br_data = data;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif);
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif *rtwvif = rtwsta->rtwvif;
+ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
if (vif != br_data->vif || vif->p2p)
return;
- rtwsta->use_cfg_mask = true;
- rtwsta->mask = *br_data->mask;
- rtw89_phy_ra_updata_sta(br_data->rtwdev, sta, IEEE80211_RC_SUPP_RATES_CHANGED);
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwsta_link->use_cfg_mask = true;
+ rtwsta_link->mask = *br_data->mask;
+ }
+
+ rtw89_phy_ra_update_sta(br_data->rtwdev, sta, IEEE80211_RC_SUPP_RATES_CHANGED);
}
static void rtw89_ra_mask_info_update(struct rtw89_dev *rtwdev,
@@ -787,10 +1110,10 @@ static int rtw89_ops_set_bitrate_mask(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
+
rtw89_phy_rate_pattern_vif(rtwdev, vif, mask);
rtw89_ra_mask_info_update(rtwdev, vif, mask);
- mutex_unlock(&rtwdev->mutex);
return 0;
}
@@ -801,6 +1124,8 @@ int rtw89_ops_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_hal *hal = &rtwdev->hal;
+ lockdep_assert_wiphy(hw->wiphy);
+
if (hal->ant_diversity) {
if (tx_ant != rx_ant || hweight32(tx_ant) != 1)
return -EINVAL;
@@ -808,12 +1133,10 @@ int rtw89_ops_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
return -EINVAL;
}
- mutex_lock(&rtwdev->mutex);
hal->antenna_tx = tx_ant;
hal->antenna_rx = rx_ant;
hal->tx_path_diversity = false;
hal->ant_diversity_fixed = true;
- mutex_unlock(&rtwdev->mutex);
return 0;
}
@@ -835,21 +1158,38 @@ static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw,
const u8 *mac_addr)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+
+ lockdep_assert_wiphy(hw->wiphy);
+
+ rtwvif_link = rtw89_get_designated_link(rtwvif);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "sw scan start: find no designated link\n");
+ return;
+ }
+
+ rtw89_leave_lps(rtwdev);
- mutex_lock(&rtwdev->mutex);
- rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, false);
- mutex_unlock(&rtwdev->mutex);
+ rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, false);
}
static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtw89_dev *rtwdev = hw->priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
- mutex_lock(&rtwdev->mutex);
- rtw89_core_scan_complete(rtwdev, vif, false);
- mutex_unlock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
+
+ rtwvif_link = rtw89_get_designated_link(rtwvif);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "sw scan complete: find no designated link\n");
+ return;
+ }
+
+ rtw89_core_scan_complete(rtwdev, rtwvif_link, false);
}
static void rtw89_ops_reconfig_complete(struct ieee80211_hw *hw,
@@ -865,8 +1205,11 @@ static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_scan_request *req)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
- int ret = 0;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+ int ret;
+
+ lockdep_assert_wiphy(hw->wiphy);
if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
return 1;
@@ -874,14 +1217,24 @@ static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (rtwdev->scanning || rtwvif->offchan)
return -EBUSY;
- mutex_lock(&rtwdev->mutex);
- rtw89_hw_scan_start(rtwdev, vif, req);
- ret = rtw89_hw_scan_offload(rtwdev, vif, true);
+ rtwvif_link = rtw89_get_designated_link(rtwvif);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "hw scan: find no designated link\n");
+ return -ENOLINK;
+ }
+
+ rtw89_leave_lps(rtwdev);
+ rtw89_leave_ips_by_hwflags(rtwdev);
+
+ ret = rtw89_hw_scan_start(rtwdev, rtwvif_link, req);
+ if (ret)
+ return ret;
+
+ ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, true);
if (ret) {
- rtw89_hw_scan_abort(rtwdev, vif);
+ rtw89_hw_scan_abort(rtwdev, rtwvif_link);
rtw89_err(rtwdev, "HW scan failed with status: %d\n", ret);
}
- mutex_unlock(&rtwdev->mutex);
return ret;
}
@@ -890,6 +1243,10 @@ static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtw89_dev *rtwdev = hw->priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+
+ lockdep_assert_wiphy(hw->wiphy);
if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
return;
@@ -897,31 +1254,39 @@ static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw,
if (!rtwdev->scanning)
return;
- mutex_lock(&rtwdev->mutex);
- rtw89_hw_scan_abort(rtwdev, vif);
- mutex_unlock(&rtwdev->mutex);
+ rtwvif_link = rtw89_get_designated_link(rtwvif);
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev, "cancel hw scan: find no designated link\n");
+ return;
+ }
+
+ rtw89_hw_scan_abort(rtwdev, rtwvif_link);
}
static void rtw89_ops_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, u32 changed)
+ struct ieee80211_link_sta *link_sta,
+ u32 changed)
{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(link_sta->sta);
struct rtw89_dev *rtwdev = hw->priv;
+ struct rtw89_sta_link *rtwsta_link;
+
+ rtwsta_link = rtwsta->links[link_sta->link_id];
+ if (unlikely(!rtwsta_link))
+ return;
- rtw89_phy_ra_updata_sta(rtwdev, sta, changed);
+ rtw89_phy_ra_update_sta_link(rtwdev, rtwsta_link, changed);
}
static int rtw89_ops_add_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_dev *rtwdev = hw->priv;
- int ret;
- mutex_lock(&rtwdev->mutex);
- ret = rtw89_chanctx_ops_add(rtwdev, ctx);
- mutex_unlock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
- return ret;
+ return rtw89_chanctx_ops_add(rtwdev, ctx);
}
static void rtw89_ops_remove_chanctx(struct ieee80211_hw *hw,
@@ -929,9 +1294,9 @@ static void rtw89_ops_remove_chanctx(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
+
rtw89_chanctx_ops_remove(rtwdev, ctx);
- mutex_unlock(&rtwdev->mutex);
}
static void rtw89_ops_change_chanctx(struct ieee80211_hw *hw,
@@ -940,9 +1305,9 @@ static void rtw89_ops_change_chanctx(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
+
rtw89_chanctx_ops_change(rtwdev, ctx, changed);
- mutex_unlock(&rtwdev->mutex);
}
static int rtw89_ops_assign_vif_chanctx(struct ieee80211_hw *hw,
@@ -951,14 +1316,20 @@ static int rtw89_ops_assign_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- int ret;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
- mutex_lock(&rtwdev->mutex);
- ret = rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif, ctx);
- mutex_unlock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
- return ret;
+ rtwvif_link = rtwvif->links[link_conf->link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, link_conf->link_id);
+ return -ENOLINK;
+ }
+
+ return rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif_link, ctx);
}
static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw,
@@ -967,11 +1338,20 @@ static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_dev *rtwdev = hw->priv;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+
+ lockdep_assert_wiphy(hw->wiphy);
+
+ rtwvif_link = rtwvif->links[link_conf->link_id];
+ if (unlikely(!rtwvif_link)) {
+ rtw89_err(rtwdev,
+ "%s: rtwvif link (link_id %u) is not active\n",
+ __func__, link_conf->link_id);
+ return;
+ }
- mutex_lock(&rtwdev->mutex);
- rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif, ctx);
- mutex_unlock(&rtwdev->mutex);
+ rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif_link, ctx);
}
static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw,
@@ -984,13 +1364,12 @@ static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw,
struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
struct rtw89_roc *roc = &rtwvif->roc;
- if (!vif)
- return -EINVAL;
+ lockdep_assert_wiphy(hw->wiphy);
- mutex_lock(&rtwdev->mutex);
+ if (!rtwvif)
+ return -EINVAL;
if (roc->state != RTW89_ROC_IDLE) {
- mutex_unlock(&rtwdev->mutex);
return -EBUSY;
}
@@ -1008,8 +1387,6 @@ static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw,
rtw89_roc_start(rtwdev, rtwvif);
- mutex_unlock(&rtwdev->mutex);
-
return 0;
}
@@ -1019,14 +1396,14 @@ static int rtw89_ops_cancel_remain_on_channel(struct ieee80211_hw *hw,
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
+ lockdep_assert_wiphy(hw->wiphy);
+
if (!rtwvif)
return -EINVAL;
- cancel_delayed_work_sync(&rtwvif->roc.roc_work);
+ wiphy_delayed_work_cancel(hw->wiphy, &rtwvif->roc.roc_work);
- mutex_lock(&rtwdev->mutex);
rtw89_roc_end(rtwdev, rtwvif);
- mutex_unlock(&rtwdev->mutex);
return 0;
}
@@ -1034,8 +1411,8 @@ static int rtw89_ops_cancel_remain_on_channel(struct ieee80211_hw *hw,
static void rtw89_set_tid_config_iter(void *data, struct ieee80211_sta *sta)
{
struct cfg80211_tid_config *tid_config = data;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_dev *rtwdev = rtwsta->rtwvif->rtwdev;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
rtw89_core_set_tid_config(rtwdev, sta, tid_config);
}
@@ -1047,18 +1424,271 @@ static int rtw89_ops_set_tid_config(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
+
if (sta)
rtw89_core_set_tid_config(rtwdev, sta, tid_config);
else
ieee80211_iterate_stations_atomic(rtwdev->hw,
rtw89_set_tid_config_iter,
tid_config);
- mutex_unlock(&rtwdev->mutex);
return 0;
}
+static bool rtw89_can_work_on_links(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif, u16 links)
+{
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ u8 w = hweight16(links);
+
+ if (vif->type != NL80211_IFTYPE_STATION &&
+ w > RTW89_MLD_NON_STA_LINK_NUM)
+ return false;
+
+ return w <= rtwvif->links_inst_valid_num;
+}
+
+static bool rtw89_ops_can_activate_links(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ u16 active_links)
+{
+ struct rtw89_dev *rtwdev = hw->priv;
+
+ lockdep_assert_wiphy(hw->wiphy);
+
+ return rtw89_can_work_on_links(rtwdev, vif, active_links);
+}
+
+static void __rtw89_ops_clr_vif_links(struct rtw89_dev *rtwdev,
+ struct rtw89_vif *rtwvif,
+ unsigned long clr_links)
+{
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
+
+ for_each_set_bit(link_id, &clr_links, IEEE80211_MLD_MAX_NUM_LINKS) {
+ rtwvif_link = rtwvif->links[link_id];
+ if (unlikely(!rtwvif_link))
+ continue;
+
+ __rtw89_ops_remove_iface_link(rtwdev, rtwvif_link);
+
+ rtw89_vif_unset_link(rtwvif, link_id);
+ }
+}
+
+static int __rtw89_ops_set_vif_links(struct rtw89_dev *rtwdev,
+ struct rtw89_vif *rtwvif,
+ unsigned long set_links)
+{
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
+ int ret;
+
+ for_each_set_bit(link_id, &set_links, IEEE80211_MLD_MAX_NUM_LINKS) {
+ rtwvif_link = rtw89_vif_set_link(rtwvif, link_id);
+ if (!rtwvif_link)
+ return -EINVAL;
+
+ ret = __rtw89_ops_add_iface_link(rtwdev, rtwvif_link);
+ if (ret) {
+ rtw89_err(rtwdev, "%s: failed to add iface (link id %u)\n",
+ __func__, link_id);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static
+int rtw89_ops_change_vif_links(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ u16 old_links, u16 new_links,
+ struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS])
+{
+ struct rtw89_dev *rtwdev = hw->priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ unsigned long clr_links = old_links & ~new_links;
+ unsigned long set_links = new_links & ~old_links;
+ bool removing_links = !old_links || clr_links;
+ struct rtw89_link_conf_container *snap;
+ int ret = 0;
+ int i;
+
+ lockdep_assert_wiphy(hw->wiphy);
+
+ rtw89_debug(rtwdev, RTW89_DBG_STATE,
+ "%s: old_links (0x%08x) -> new_links (0x%08x)\n",
+ __func__, old_links, new_links);
+
+ if (!rtw89_can_work_on_links(rtwdev, vif, new_links))
+ return -EOPNOTSUPP;
+
+ if (removing_links) {
+ snap = kzalloc(sizeof(*snap), GFP_KERNEL);
+ if (!snap)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(snap->link_conf); i++)
+ snap->link_conf[i] = old[i];
+
+ rcu_assign_pointer(rtwvif->snap_link_confs, snap);
+ }
+
+ /* might depend on @snap; don't change order */
+ rtw89_leave_ips_by_hwflags(rtwdev);
+
+ if (rtwdev->scanning)
+ rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
+
+ if (!old_links)
+ __rtw89_ops_clr_vif_links(rtwdev, rtwvif,
+ BIT(RTW89_VIF_IDLE_LINK_ID));
+ else if (clr_links)
+ __rtw89_ops_clr_vif_links(rtwdev, rtwvif, clr_links);
+
+ if (removing_links) {
+ /* @snap is required if and only if during removing links.
+ * However, it's done here. So, cleanup @snap immediately.
+ */
+ rcu_assign_pointer(rtwvif->snap_link_confs, NULL);
+
+ /* The pointers in @old will free after this function return,
+ * so synchronously wait for all readers of snap to be done.
+ */
+ synchronize_rcu();
+ kfree(snap);
+ }
+
+ if (set_links) {
+ ret = __rtw89_ops_set_vif_links(rtwdev, rtwvif, set_links);
+ if (ret)
+ __rtw89_ops_clr_vif_links(rtwdev, rtwvif, set_links);
+ } else if (!new_links) {
+ ret = __rtw89_ops_set_vif_links(rtwdev, rtwvif,
+ BIT(RTW89_VIF_IDLE_LINK_ID));
+ if (ret)
+ __rtw89_ops_clr_vif_links(rtwdev, rtwvif,
+ BIT(RTW89_VIF_IDLE_LINK_ID));
+ }
+
+ rtw89_enter_ips_by_hwflags(rtwdev);
+ return ret;
+}
+
+static void __rtw89_ops_clr_sta_links(struct rtw89_dev *rtwdev,
+ struct rtw89_sta *rtwsta,
+ unsigned long clr_links)
+{
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+
+ for_each_set_bit(link_id, &clr_links, IEEE80211_MLD_MAX_NUM_LINKS) {
+ rtwsta_link = rtwsta->links[link_id];
+ if (unlikely(!rtwsta_link))
+ continue;
+
+ rtwvif_link = rtwsta_link->rtwvif_link;
+
+ rtw89_core_sta_link_disassoc(rtwdev, rtwvif_link, rtwsta_link);
+ rtw89_core_sta_link_disconnect(rtwdev, rtwvif_link, rtwsta_link);
+ rtw89_core_sta_link_remove(rtwdev, rtwvif_link, rtwsta_link);
+
+ rtw89_sta_unset_link(rtwsta, link_id);
+ }
+}
+
+static int __rtw89_ops_set_sta_links(struct rtw89_dev *rtwdev,
+ struct rtw89_sta *rtwsta,
+ unsigned long set_links)
+{
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ u8 sec_cam_idx;
+ int ret;
+
+ for_each_set_bit(link_id, &set_links, IEEE80211_MLD_MAX_NUM_LINKS) {
+ rtwsta_link = rtw89_sta_set_link(rtwsta, link_id);
+ if (!rtwsta_link)
+ return -EINVAL;
+
+ rtwvif_link = rtwsta_link->rtwvif_link;
+
+ ret = rtw89_core_sta_link_add(rtwdev, rtwvif_link, rtwsta_link);
+ if (ret) {
+ rtw89_err(rtwdev, "%s: failed to add sta (link id %u)\n",
+ __func__, link_id);
+ return ret;
+ }
+
+ rtw89_vif_type_mapping(rtwvif_link, true);
+
+ ret = rtw89_core_sta_link_assoc(rtwdev, rtwvif_link, rtwsta_link);
+ if (ret) {
+ rtw89_err(rtwdev, "%s: failed to assoc sta (link id %u)\n",
+ __func__, link_id);
+ return ret;
+ }
+
+ __rtw89_ops_bss_link_assoc(rtwdev, rtwvif_link);
+
+ for_each_set_bit(sec_cam_idx, rtwsta->pairwise_sec_cam_map,
+ RTW89_MAX_SEC_CAM_NUM) {
+ ret = rtw89_cam_attach_link_sec_cam(rtwdev,
+ rtwvif_link,
+ rtwsta_link,
+ sec_cam_idx);
+ if (ret) {
+ rtw89_err(rtwdev,
+ "%s: failed to apply pairwise key (link id %u)\n",
+ __func__, link_id);
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static
+int rtw89_ops_change_sta_links(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ u16 old_links, u16 new_links)
+{
+ struct rtw89_dev *rtwdev = hw->priv;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ unsigned long clr_links = old_links & ~new_links;
+ unsigned long set_links = new_links & ~old_links;
+ int ret = 0;
+
+ lockdep_assert_wiphy(hw->wiphy);
+
+ rtw89_debug(rtwdev, RTW89_DBG_STATE,
+ "%s: old_links (0x%08x) -> new_links (0x%08x)\n",
+ __func__, old_links, new_links);
+
+ if (!rtw89_can_work_on_links(rtwdev, vif, new_links))
+ return -EOPNOTSUPP;
+
+ rtw89_leave_ps_mode(rtwdev);
+
+ if (clr_links)
+ __rtw89_ops_clr_sta_links(rtwdev, rtwsta, clr_links);
+
+ if (set_links) {
+ ret = __rtw89_ops_set_sta_links(rtwdev, rtwsta, set_links);
+ if (ret)
+ __rtw89_ops_clr_sta_links(rtwdev, rtwsta, set_links);
+ }
+
+ return ret;
+}
+
#ifdef CONFIG_PM
static int rtw89_ops_suspend(struct ieee80211_hw *hw,
struct cfg80211_wowlan *wowlan)
@@ -1066,13 +1696,12 @@ static int rtw89_ops_suspend(struct ieee80211_hw *hw,
struct rtw89_dev *rtwdev = hw->priv;
int ret;
+ lockdep_assert_wiphy(hw->wiphy);
+
set_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags);
- cancel_delayed_work_sync(&rtwdev->track_work);
+ wiphy_delayed_work_cancel(hw->wiphy, &rtwdev->track_work);
- mutex_lock(&rtwdev->mutex);
ret = rtw89_wow_suspend(rtwdev, wowlan);
- mutex_unlock(&rtwdev->mutex);
-
if (ret) {
rtw89_warn(rtwdev, "failed to suspend for wow %d\n", ret);
clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags);
@@ -1087,15 +1716,15 @@ static int rtw89_ops_resume(struct ieee80211_hw *hw)
struct rtw89_dev *rtwdev = hw->priv;
int ret;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(hw->wiphy);
+
ret = rtw89_wow_resume(rtwdev);
if (ret)
rtw89_warn(rtwdev, "failed to resume for wow %d\n", ret);
- mutex_unlock(&rtwdev->mutex);
clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags);
- ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work,
- RTW89_TRACK_WORK_PERIOD);
+ wiphy_delayed_work_queue(hw->wiphy, &rtwdev->track_work,
+ RTW89_TRACK_WORK_PERIOD);
return ret ? 1 : 0;
}
@@ -1106,8 +1735,41 @@ static void rtw89_ops_set_wakeup(struct ieee80211_hw *hw, bool enabled)
device_set_wakeup_enable(rtwdev->dev, enabled);
}
+
+static void rtw89_set_rekey_data(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct cfg80211_gtk_rekey_data *data)
+{
+ struct rtw89_dev *rtwdev = hw->priv;
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info;
+
+ lockdep_assert_wiphy(hw->wiphy);
+
+ if (data->kek_len > sizeof(gtk_info->kek) ||
+ data->kck_len > sizeof(gtk_info->kck)) {
+ rtw89_warn(rtwdev, "kek or kck length over fw limit\n");
+ return;
+ }
+
+ memcpy(gtk_info->kek, data->kek, data->kek_len);
+ memcpy(gtk_info->kck, data->kck, data->kck_len);
+}
#endif
+static void rtw89_ops_rfkill_poll(struct ieee80211_hw *hw)
+{
+ struct rtw89_dev *rtwdev = hw->priv;
+
+ lockdep_assert_wiphy(hw->wiphy);
+
+ /* wl_disable GPIO get floating when entering LPS */
+ if (test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
+ return;
+
+ rtw89_core_rfkill_poll(rtwdev, false);
+}
+
const struct ieee80211_ops rtw89_ops = {
.tx = rtw89_ops_tx,
.wake_tx_queue = rtw89_ops_wake_tx_queue,
@@ -1118,7 +1780,8 @@ const struct ieee80211_ops rtw89_ops = {
.change_interface = rtw89_ops_change_interface,
.remove_interface = rtw89_ops_remove_interface,
.configure_filter = rtw89_ops_configure_filter,
- .bss_info_changed = rtw89_ops_bss_info_changed,
+ .vif_cfg_changed = rtw89_ops_vif_cfg_changed,
+ .link_info_changed = rtw89_ops_link_info_changed,
.start_ap = rtw89_ops_start_ap,
.stop_ap = rtw89_ops_stop_ap,
.set_tim = rtw89_ops_set_tim,
@@ -1145,12 +1808,17 @@ const struct ieee80211_ops rtw89_ops = {
.remain_on_channel = rtw89_ops_remain_on_channel,
.cancel_remain_on_channel = rtw89_ops_cancel_remain_on_channel,
.set_sar_specs = rtw89_ops_set_sar_specs,
- .sta_rc_update = rtw89_ops_sta_rc_update,
+ .link_sta_rc_update = rtw89_ops_sta_rc_update,
.set_tid_config = rtw89_ops_set_tid_config,
+ .can_activate_links = rtw89_ops_can_activate_links,
+ .change_vif_links = rtw89_ops_change_vif_links,
+ .change_sta_links = rtw89_ops_change_sta_links,
#ifdef CONFIG_PM
.suspend = rtw89_ops_suspend,
.resume = rtw89_ops_resume,
.set_wakeup = rtw89_ops_set_wakeup,
+ .set_rekey_data = rtw89_set_rekey_data,
#endif
+ .rfkill_poll = rtw89_ops_rfkill_poll,
};
EXPORT_SYMBOL(rtw89_ops);
diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c
index f16467377eab..8c9d326dc907 100644
--- a/drivers/net/wireless/realtek/rtw89/mac_be.c
+++ b/drivers/net/wireless/realtek/rtw89/mac_be.c
@@ -29,6 +29,7 @@ static const u32 rtw89_mac_mem_base_addrs_be[RTW89_MAC_MEM_NUM] = {
[RTW89_MAC_MEM_CPU_LOCAL] = CPU_LOCAL_BASE_ADDR_BE,
[RTW89_MAC_MEM_BSSID_CAM] = BSSID_CAM_BASE_ADDR_BE,
[RTW89_MAC_MEM_WD_PAGE] = WD_PAGE_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_MLD_TBL] = MLD_TBL_BASE_ADDR_BE,
};
static const struct rtw89_port_reg rtw89_port_base_be = {
@@ -708,8 +709,8 @@ static int sec_eng_init_be(struct rtw89_dev *rtwdev)
val32 |= B_BE_CLK_EN_CGCMP | B_BE_CLK_EN_WAPI | B_BE_CLK_EN_WEP_TKIP |
B_BE_SEC_TX_ENC | B_BE_SEC_RX_DEC |
B_BE_MC_DEC | B_BE_BC_DEC |
- B_BE_BMC_MGNT_DEC | B_BE_UC_MGNT_DEC;
- val32 &= ~B_BE_SEC_PRE_ENQUE_TX;
+ B_BE_BMC_MGNT_DEC | B_BE_UC_MGNT_DEC |
+ B_BE_SEC_PRE_ENQUE_TX;
rtw89_write32(rtwdev, R_BE_SEC_ENG_CTRL, val32);
rtw89_write32_set(rtwdev, R_BE_SEC_MPDU_PROC, B_BE_APPEND_ICV | B_BE_APPEND_MIC);
@@ -773,7 +774,7 @@ static int dmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
return ret;
}
- ret = rtw89_mac_preload_init(rtwdev, RTW89_MAC_0, rtwdev->mac.qta_mode);
+ ret = rtw89_mac_preload_init(rtwdev, mac_idx, rtwdev->mac.qta_mode);
if (ret) {
rtw89_err(rtwdev, "[ERR]preload init %d\n", ret);
return ret;
@@ -1751,6 +1752,7 @@ static int set_host_rpr_be(struct rtw89_dev *rtwdev)
static int trx_init_be(struct rtw89_dev *rtwdev)
{
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
enum rtw89_qta_mode qta_mode = rtwdev->mac.qta_mode;
int ret;
@@ -1794,6 +1796,10 @@ static int trx_init_be(struct rtw89_dev *rtwdev)
return ret;
}
+ if (chip_id == RTL8922A)
+ rtw89_write32_clr(rtwdev, R_BE_RSP_CHK_SIG,
+ B_BE_RSP_STATIC_RTS_CHK_SERV_BW_EN);
+
return 0;
}
@@ -1860,7 +1866,7 @@ int rtw89_mac_cfg_ctrl_path_v2(struct rtw89_dev *rtwdev, bool wl)
if (wl)
return 0;
- for (i = 0; i < RTW89_PHY_MAX; i++) {
+ for (i = 0; i < RTW89_PHY_NUM; i++) {
g[i].gnt_bt_sw_en = 1;
g[i].gnt_bt = 1;
g[i].gnt_wl_sw_en = 1;
@@ -1983,6 +1989,20 @@ int rtw89_mac_resume_sch_tx_v2(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en)
}
EXPORT_SYMBOL(rtw89_mac_resume_sch_tx_v2);
+void rtw89_mac_cfg_phy_rpt_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable)
+{
+ u32 reg, val;
+
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RCR, mac_idx);
+ val = enable ? MAC_AX_PHY_RPT_SIZE_8 : MAC_AX_PHY_RPT_SIZE_0;
+ rtw89_write32_mask(rtwdev, reg, B_BE_PHY_RPT_SZ_MASK, val);
+ rtw89_write32_mask(rtwdev, reg, B_BE_HDR_CNV_SZ_MASK, MAC_AX_HDR_CNV_SIZE_0);
+
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_DRV_INFO_OPTION, mac_idx);
+ rtw89_write32_mask(rtwdev, reg, B_BE_DRV_INFO_PHYRPT_EN, enable);
+}
+EXPORT_SYMBOL(rtw89_mac_cfg_phy_rpt_be);
+
static
int rtw89_mac_cfg_ppdu_status_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable)
{
@@ -2086,13 +2106,13 @@ static int rtw89_mac_init_bfee_be(struct rtw89_dev *rtwdev, u8 mac_idx)
}
static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1;
- u8 mac_idx = rtwvif->mac_idx;
- u8 port_sel = rtwvif->port;
+ struct ieee80211_link_sta *link_sta;
+ u8 mac_idx = rtwvif_link->mac_idx;
+ u8 port_sel = rtwvif_link->port;
u8 sound_dim = 3, t;
u8 *phy_cap;
u32 reg;
@@ -2103,7 +2123,10 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
if (ret)
return ret;
- phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info;
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info;
if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) ||
(phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) {
@@ -2114,11 +2137,11 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
sound_dim = min(sound_dim, t);
}
- if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
- (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
- ldpc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
- stbc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK);
- t = u32_get_bits(sta->deflink.vht_cap.cap,
+ if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
+ (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
+ ldpc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
+ stbc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK);
+ t = u32_get_bits(link_sta->vht_cap.cap,
IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK);
sound_dim = min(sound_dim, t);
}
@@ -2126,6 +2149,8 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
nc = min(nc, sound_dim);
nr = min(nr, sound_dim);
+ rcu_read_unlock();
+
reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL);
@@ -2150,12 +2175,12 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
}
static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M);
- u8 mac_idx = rtwvif->mac_idx;
+ struct ieee80211_link_sta *link_sta;
+ u8 mac_idx = rtwvif_link->mac_idx;
int ret;
u32 reg;
@@ -2163,22 +2188,28 @@ static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev,
if (ret)
return ret;
- if (sta->deflink.he_cap.has_he) {
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+
+ if (link_sta->he_cap.has_he) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) |
BIT(RTW89_MAC_BF_RRSC_HE_MSC3) |
BIT(RTW89_MAC_BF_RRSC_HE_MSC5));
}
- if (sta->deflink.vht_cap.vht_supported) {
+ if (link_sta->vht_cap.vht_supported) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) |
BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) |
BIT(RTW89_MAC_BF_RRSC_VHT_MSC5));
}
- if (sta->deflink.ht_cap.ht_supported) {
+ if (link_sta->ht_cap.ht_supported) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) |
BIT(RTW89_MAC_BF_RRSC_HT_MSC3) |
BIT(RTW89_MAC_BF_RRSC_HT_MSC5));
}
+ rcu_read_unlock();
+
reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL);
rtw89_write32_clr(rtwdev, reg, B_BE_BFMEE_CSI_FORCE_RETE_EN);
@@ -2190,17 +2221,25 @@ static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev,
}
static void rtw89_mac_bf_assoc_be(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct ieee80211_link_sta *link_sta;
+ bool has_beamformer_cap;
+
+ rcu_read_lock();
- if (rtw89_sta_has_beamformer_cap(sta)) {
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ has_beamformer_cap = rtw89_sta_has_beamformer_cap(link_sta);
+
+ rcu_read_unlock();
+
+ if (has_beamformer_cap) {
rtw89_debug(rtwdev, RTW89_DBG_BF,
"initialize bfee for new association\n");
- rtw89_mac_init_bfee_be(rtwdev, rtwvif->mac_idx);
- rtw89_mac_set_csi_para_reg_be(rtwdev, vif, sta);
- rtw89_mac_csi_rrsc_be(rtwdev, vif, sta);
+ rtw89_mac_init_bfee_be(rtwdev, rtwvif_link->mac_idx);
+ rtw89_mac_set_csi_para_reg_be(rtwdev, rtwvif_link, rtwsta_link);
+ rtw89_mac_csi_rrsc_be(rtwdev, rtwvif_link, rtwsta_link);
}
}
@@ -2307,26 +2346,6 @@ static void rtw89_mac_dump_qta_lost_be(struct rtw89_dev *rtwdev)
dump_err_status_dispatcher_be(rtwdev);
}
-static int rtw89_mac_cpu_io_rx(struct rtw89_dev *rtwdev, bool wow_enable)
-{
- struct rtw89_mac_h2c_info h2c_info = {};
- struct rtw89_mac_c2h_info c2h_info = {};
- u32 ret;
-
- h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_WOW_CPUIO_RX_CTRL;
- h2c_info.content_len = sizeof(h2c_info.u.hdr);
- h2c_info.u.hdr.w0 = u32_encode_bits(wow_enable, RTW89_H2CREG_WOW_CPUIO_RX_CTRL_EN);
-
- ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info);
- if (ret)
- return ret;
-
- if (c2h_info.id != RTW89_FWCMD_C2HREG_FUNC_WOW_CPUIO_RX_ACK)
- ret = -EINVAL;
-
- return ret;
-}
-
static int rtw89_wow_config_mac_be(struct rtw89_dev *rtwdev, bool enable_wow)
{
if (enable_wow) {
@@ -2567,6 +2586,8 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
.mask = B_BE_RXTRIG_RU26_DIS,
},
.wow_ctrl = {.addr = R_BE_WOW_CTRL, .mask = B_BE_WOW_WOWEN,},
+ .agg_limit = {.addr = R_BE_AMPDU_AGG_LIMIT, .mask = B_BE_AMPDU_MAX_TIME_MASK,},
+ .txcnt_limit = {.addr = R_BE_TXCNT, .mask = B_BE_L_TXCNT_LMT_MASK,},
.check_mac_en = rtw89_mac_check_mac_en_be,
.sys_init = sys_init_be,
@@ -2579,6 +2600,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
.typ_fltr_opt = rtw89_mac_typ_fltr_opt_be,
.cfg_ppdu_status = rtw89_mac_cfg_ppdu_status_be,
+ .cfg_phy_rpt = rtw89_mac_cfg_phy_rpt_be,
.dle_mix_cfg = dle_mix_cfg_be,
.chk_dle_rdy = chk_dle_rdy_be,
@@ -2596,9 +2618,11 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
.fwdl_enable_wcpu = rtw89_mac_fwdl_enable_wcpu_be,
.fwdl_get_status = fwdl_get_status_be,
.fwdl_check_path_ready = rtw89_fwdl_check_path_ready_be,
+ .fwdl_secure_idmem_share_mode = NULL,
.parse_efuse_map = rtw89_parse_efuse_map_be,
.parse_phycap_map = rtw89_parse_phycap_map_be,
.cnv_efuse_state = rtw89_cnv_efuse_state_be,
+ .efuse_read_fw_secure = rtw89_efuse_read_fw_secure_be,
.cfg_plt = rtw89_mac_cfg_plt_be,
.get_plt_cnt = rtw89_mac_get_plt_cnt_be,
@@ -2613,7 +2637,10 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
.is_txq_empty = mac_is_txq_empty_be,
+ .prep_chan_list = rtw89_hw_scan_prep_chan_list_be,
+ .free_chan_list = rtw89_hw_scan_free_chan_list_be,
.add_chan_list = rtw89_hw_scan_add_chan_list_be,
+ .add_chan_list_pno = rtw89_pno_scan_add_chan_list_be,
.scan_offload = rtw89_fw_h2c_scan_offload_be,
.wow_config_mac = rtw89_wow_config_mac_be,
diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
index 19001130ad94..064f6a940107 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.c
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
@@ -19,6 +19,31 @@ MODULE_PARM_DESC(disable_clkreq, "Set Y to disable PCI clkreq support");
MODULE_PARM_DESC(disable_aspm_l1, "Set Y to disable PCI ASPM L1 support");
MODULE_PARM_DESC(disable_aspm_l1ss, "Set Y to disable PCI L1SS support");
+static int rtw89_pci_get_phy_offset_by_link_speed(struct rtw89_dev *rtwdev,
+ u32 *phy_offset)
+{
+ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
+ struct pci_dev *pdev = rtwpci->pdev;
+ u32 val;
+ int ret;
+
+ ret = pci_read_config_dword(pdev, RTW89_PCIE_L1_STS_V1, &val);
+ if (ret)
+ return ret;
+
+ val = u32_get_bits(val, RTW89_BCFG_LINK_SPEED_MASK);
+ if (val == RTW89_PCIE_GEN1_SPEED) {
+ *phy_offset = R_RAC_DIRECT_OFFSET_G1;
+ } else if (val == RTW89_PCIE_GEN2_SPEED) {
+ *phy_offset = R_RAC_DIRECT_OFFSET_G2;
+ } else {
+ rtw89_warn(rtwdev, "Unknown PCI link speed %d\n", val);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
static int rtw89_pci_rst_bdram_ax(struct rtw89_dev *rtwdev)
{
u32 val;
@@ -158,14 +183,17 @@ static void rtw89_pci_sync_skb_for_device(struct rtw89_dev *rtwdev,
static void rtw89_pci_rxbd_info_update(struct rtw89_dev *rtwdev,
struct sk_buff *skb)
{
- struct rtw89_pci_rxbd_info *rxbd_info;
struct rtw89_pci_rx_info *rx_info = RTW89_PCI_RX_SKB_CB(skb);
+ struct rtw89_pci_rxbd_info *rxbd_info;
+ __le32 info;
rxbd_info = (struct rtw89_pci_rxbd_info *)skb->data;
- rx_info->fs = le32_get_bits(rxbd_info->dword, RTW89_PCI_RXBD_FS);
- rx_info->ls = le32_get_bits(rxbd_info->dword, RTW89_PCI_RXBD_LS);
- rx_info->len = le32_get_bits(rxbd_info->dword, RTW89_PCI_RXBD_WRITE_SIZE);
- rx_info->tag = le32_get_bits(rxbd_info->dword, RTW89_PCI_RXBD_TAG);
+ info = rxbd_info->dword;
+
+ rx_info->fs = le32_get_bits(info, RTW89_PCI_RXBD_FS);
+ rx_info->ls = le32_get_bits(info, RTW89_PCI_RXBD_LS);
+ rx_info->len = le32_get_bits(info, RTW89_PCI_RXBD_WRITE_SIZE);
+ rx_info->tag = le32_get_bits(info, RTW89_PCI_RXBD_TAG);
}
static int rtw89_pci_validate_rx_tag(struct rtw89_dev *rtwdev,
@@ -200,7 +228,7 @@ int rtw89_pci_sync_skb_for_device_and_validate_rx_info(struct rtw89_dev *rtwdev,
struct sk_buff *skb)
{
struct rtw89_pci_rx_info *rx_info = RTW89_PCI_RX_SKB_CB(skb);
- int rx_tag_retry = 100;
+ int rx_tag_retry = 1000;
int ret;
do {
@@ -293,10 +321,11 @@ static u32 rtw89_pci_get_rx_skb_idx(struct rtw89_dev *rtwdev,
static u32 rtw89_pci_rxbd_deliver_skbs(struct rtw89_dev *rtwdev,
struct rtw89_pci_rx_ring *rx_ring)
{
- struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring;
- struct rtw89_pci_rx_info *rx_info;
struct rtw89_rx_desc_info *desc_info = &rx_ring->diliver_desc;
+ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring;
+ const struct rtw89_pci_info *info = rtwdev->pci_info;
struct sk_buff *new = rx_ring->diliver_skb;
+ struct rtw89_pci_rx_info *rx_info;
struct sk_buff *skb;
u32 rxinfo_size = sizeof(struct rtw89_pci_rxbd_info);
u32 skb_idx;
@@ -316,9 +345,14 @@ static u32 rtw89_pci_rxbd_deliver_skbs(struct rtw89_dev *rtwdev,
}
rx_info = RTW89_PCI_RX_SKB_CB(skb);
- fs = rx_info->fs;
+ fs = info->no_rxbd_fs ? !new : rx_info->fs;
ls = rx_info->ls;
+ if (unlikely(!fs || !ls))
+ rtw89_debug(rtwdev, RTW89_DBG_UNEXP,
+ "unexpected fs/ls=%d/%d tag=%u len=%u new->len=%u\n",
+ fs, ls, rx_info->tag, rx_info->len, new ? new->len : 0);
+
if (fs) {
if (new) {
rtw89_debug(rtwdev, RTW89_DBG_UNEXP,
@@ -1089,7 +1123,8 @@ u32 __rtw89_pci_check_and_reclaim_tx_resource_noio(struct rtw89_dev *rtwdev,
spin_lock_bh(&rtwpci->trx_lock);
cnt = rtw89_pci_get_avail_txbd_num(tx_ring);
- cnt = min(cnt, wd_ring->curr_num);
+ if (txch != RTW89_TXCH_CH12)
+ cnt = min(cnt, wd_ring->curr_num);
spin_unlock_bh(&rtwpci->trx_lock);
return cnt;
@@ -1272,10 +1307,12 @@ u32 rtw89_pci_fill_txaddr_info(struct rtw89_dev *rtwdev,
dma_addr_t dma, u8 *add_info_nr)
{
struct rtw89_pci_tx_addr_info_32 *txaddr_info = txaddr_info_addr;
+ __le16 option;
txaddr_info->length = cpu_to_le16(total_len);
- txaddr_info->option = cpu_to_le16(RTW89_PCI_ADDR_MSDU_LS |
- RTW89_PCI_ADDR_NUM(1));
+ option = cpu_to_le16(RTW89_PCI_ADDR_MSDU_LS | RTW89_PCI_ADDR_NUM(1));
+ option |= le16_encode_bits(upper_32_bits(dma), RTW89_PCI_ADDR_HIGH_MASK);
+ txaddr_info->option = option;
txaddr_info->dma = cpu_to_le32(dma);
*add_info_nr = 1;
@@ -1302,6 +1339,8 @@ u32 rtw89_pci_fill_txaddr_info_v1(struct rtw89_dev *rtwdev,
length_option = FIELD_PREP(B_PCIADDR_LEN_V1_MASK, len) |
FIELD_PREP(B_PCIADDR_HIGH_SEL_V1_MASK, 0) |
FIELD_PREP(B_PCIADDR_LS_V1_MASK, remain == 0);
+ length_option |= u16_encode_bits(upper_32_bits(dma),
+ B_PCIADDR_HIGH_SEL_V1_MASK);
txaddr_info->length_opt = cpu_to_le16(length_option);
txaddr_info->dma_low_lsb = cpu_to_le16(FIELD_GET(GENMASK(15, 0), dma));
txaddr_info->dma_low_msb = cpu_to_le16(FIELD_GET(GENMASK(31, 16), dma));
@@ -1392,6 +1431,7 @@ static int rtw89_pci_fwcmd_submit(struct rtw89_dev *rtwdev,
struct sk_buff *skb = tx_req->skb;
struct rtw89_pci_tx_data *tx_data = RTW89_PCI_TX_SKB_CB(skb);
dma_addr_t dma;
+ __le16 opt;
txdesc = skb_push(skb, txdesc_size);
memset(txdesc, 0, txdesc_size);
@@ -1404,7 +1444,9 @@ static int rtw89_pci_fwcmd_submit(struct rtw89_dev *rtwdev,
}
tx_data->dma = dma;
- txbd->option = cpu_to_le16(RTW89_PCI_TXBD_OPTION_LS);
+ opt = cpu_to_le16(RTW89_PCI_TXBD_OPT_LS);
+ opt |= le16_encode_bits(upper_32_bits(dma), RTW89_PCI_TXBD_OPT_DMA_HI);
+ txbd->opt = opt;
txbd->length = cpu_to_le16(skb->len);
txbd->dma = cpu_to_le32(tx_data->dma);
skb_queue_tail(&rtwpci->h2c_queue, skb);
@@ -1420,6 +1462,7 @@ static int rtw89_pci_txbd_submit(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
struct rtw89_pci_tx_wd *txwd;
+ __le16 opt;
int ret;
/* FWCMD queue doesn't have wd pages. Instead, it submits the CMD
@@ -1444,7 +1487,9 @@ static int rtw89_pci_txbd_submit(struct rtw89_dev *rtwdev,
list_add_tail(&txwd->list, &tx_ring->busy_pages);
- txbd->option = cpu_to_le16(RTW89_PCI_TXBD_OPTION_LS);
+ opt = cpu_to_le16(RTW89_PCI_TXBD_OPT_LS);
+ opt |= le16_encode_bits(upper_32_bits(txwd->paddr), RTW89_PCI_TXBD_OPT_DMA_HI);
+ txbd->opt = opt;
txbd->length = cpu_to_le16(txwd->len);
txbd->dma = cpu_to_le32(txwd->paddr);
@@ -1543,6 +1588,25 @@ const struct rtw89_pci_bd_ram rtw89_bd_ram_table_single[RTW89_TXCH_NUM] = {
};
EXPORT_SYMBOL(rtw89_bd_ram_table_single);
+static void rtw89_pci_init_wp_16sel(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_pci_info *info = rtwdev->pci_info;
+ u32 addr = info->wp_sel_addr;
+ u32 val;
+ int i;
+
+ if (!info->wp_sel_addr)
+ return;
+
+ for (i = 0; i < 16; i += 4) {
+ val = u32_encode_bits(i + 0, MASKBYTE0) |
+ u32_encode_bits(i + 1, MASKBYTE1) |
+ u32_encode_bits(i + 2, MASKBYTE2) |
+ u32_encode_bits(i + 3, MASKBYTE3);
+ rtw89_write32(rtwdev, addr + i, val);
+ }
+}
+
static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev)
{
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
@@ -1581,6 +1645,7 @@ static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev)
rtw89_write32(rtwdev, addr_bdram, val32);
}
rtw89_write32(rtwdev, addr_desa_l, bd_ring->dma);
+ rtw89_write32(rtwdev, addr_desa_l + 4, upper_32_bits(bd_ring->dma));
}
for (i = 0; i < RTW89_RXCH_NUM; i++) {
@@ -1600,10 +1665,13 @@ static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev)
rtw89_write16(rtwdev, addr_num, bd_ring->len);
rtw89_write32(rtwdev, addr_desa_l, bd_ring->dma);
+ rtw89_write32(rtwdev, addr_desa_l + 4, upper_32_bits(bd_ring->dma));
if (info->rx_ring_eq_is_full)
rtw89_write16(rtwdev, addr_idx, bd_ring->wp);
}
+
+ rtw89_pci_init_wp_16sel(rtwdev);
}
static void rtw89_pci_release_tx_ring(struct rtw89_dev *rtwdev,
@@ -2013,7 +2081,7 @@ static int rtw89_pci_write_config_byte(struct rtw89_dev *rtwdev, u16 addr,
if (!ret)
return 0;
- if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B)
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))
ret = rtw89_dbi_write8(rtwdev, addr, data);
return ret;
@@ -2031,7 +2099,7 @@ static int rtw89_pci_read_config_byte(struct rtw89_dev *rtwdev, u16 addr,
if (!ret)
return 0;
- if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B)
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))
ret = rtw89_dbi_read8(rtwdev, addr, value);
return ret;
@@ -2111,10 +2179,9 @@ __get_target(struct rtw89_dev *rtwdev, u16 *target, enum rtw89_pcie_phy phy_rate
static int rtw89_pci_autok_x(struct rtw89_dev *rtwdev)
{
- enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
int ret;
- if (chip_id != RTL8852B && chip_id != RTL8851B)
+ if (!rtw89_is_rtl885xb(rtwdev))
return 0;
ret = rtw89_write16_mdio_mask(rtwdev, RAC_REG_FLD_0, BAC_AUTOK_N_MASK,
@@ -2124,14 +2191,13 @@ static int rtw89_pci_autok_x(struct rtw89_dev *rtwdev)
static int rtw89_pci_auto_refclk_cal(struct rtw89_dev *rtwdev, bool autook_en)
{
- enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
enum rtw89_pcie_phy phy_rate;
u16 val16, mgn_set, div_set, tar;
u8 val8, bdr_ori;
bool l1_flag = false;
int ret = 0;
- if (chip_id != RTL8852B && chip_id != RTL8851B)
+ if (!rtw89_is_rtl885xb(rtwdev))
return 0;
ret = rtw89_pci_read_config_byte(rtwdev, RTW89_PCIE_PHY_RATE, &val8);
@@ -2298,6 +2364,92 @@ static int rtw89_pci_deglitch_setting(struct rtw89_dev *rtwdev)
return 0;
}
+static void rtw89_pci_disable_eq_ax(struct rtw89_dev *rtwdev)
+{
+ u16 g1_oobs, g2_oobs;
+ u32 backup_aspm;
+ u32 phy_offset;
+ u16 offset_cal;
+ u16 oobs_val;
+ int ret;
+ u8 gen;
+
+ if (rtwdev->chip->chip_id != RTL8852C)
+ return;
+
+ g1_oobs = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_G1 +
+ RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL);
+ g2_oobs = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_G2 +
+ RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL);
+ if (g1_oobs && g2_oobs)
+ return;
+
+ backup_aspm = rtw89_read32(rtwdev, R_AX_PCIE_MIX_CFG_V1);
+ rtw89_write32_clr(rtwdev, R_AX_PCIE_MIX_CFG_V1, B_AX_ASPM_CTRL_MASK);
+
+ ret = rtw89_pci_get_phy_offset_by_link_speed(rtwdev, &phy_offset);
+ if (ret)
+ goto out;
+
+ rtw89_write16_set(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT, BAC_RX_TEST_EN);
+ rtw89_write16(rtwdev, phy_offset + RAC_ANA10 * RAC_MULT, ADDR_SEL_PINOUT_DIS_VAL);
+ rtw89_write16_set(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT, B_PCIE_BIT_RD_SEL);
+
+ oobs_val = rtw89_read16_mask(rtwdev, phy_offset + RAC_ANA1F * RAC_MULT,
+ OOBS_LEVEL_MASK);
+
+ rtw89_write16_mask(rtwdev, R_RAC_DIRECT_OFFSET_G1 + RAC_ANA03 * RAC_MULT,
+ OOBS_SEN_MASK, oobs_val);
+ rtw89_write16_set(rtwdev, R_RAC_DIRECT_OFFSET_G1 + RAC_ANA09 * RAC_MULT,
+ BAC_OOBS_SEL);
+
+ rtw89_write16_mask(rtwdev, R_RAC_DIRECT_OFFSET_G2 + RAC_ANA03 * RAC_MULT,
+ OOBS_SEN_MASK, oobs_val);
+ rtw89_write16_set(rtwdev, R_RAC_DIRECT_OFFSET_G2 + RAC_ANA09 * RAC_MULT,
+ BAC_OOBS_SEL);
+
+ /* offset K */
+ for (gen = 1; gen <= 2; gen++) {
+ phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_G1 :
+ R_RAC_DIRECT_OFFSET_G2;
+
+ rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT,
+ B_PCIE_BIT_RD_SEL);
+ }
+
+ offset_cal = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_G1 +
+ RAC_ANA1F * RAC_MULT, OFFSET_CAL_MASK);
+
+ for (gen = 1; gen <= 2; gen++) {
+ phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_G1 :
+ R_RAC_DIRECT_OFFSET_G2;
+
+ rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA0B * RAC_MULT,
+ MANUAL_LVL_MASK, offset_cal);
+ rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT,
+ OFFSET_CAL_MODE);
+ }
+
+out:
+ rtw89_write32(rtwdev, R_AX_PCIE_MIX_CFG_V1, backup_aspm);
+}
+
+static void rtw89_pci_ber(struct rtw89_dev *rtwdev)
+{
+ u32 phy_offset;
+
+ if (!test_bit(RTW89_QUIRK_PCI_BER, rtwdev->quirks))
+ return;
+
+ phy_offset = R_RAC_DIRECT_OFFSET_G1;
+ rtw89_write16(rtwdev, phy_offset + RAC_ANA1E * RAC_MULT, RAC_ANA1E_G1_VAL);
+ rtw89_write16(rtwdev, phy_offset + RAC_ANA2E * RAC_MULT, RAC_ANA2E_VAL);
+
+ phy_offset = R_RAC_DIRECT_OFFSET_G2;
+ rtw89_write16(rtwdev, phy_offset + RAC_ANA1E * RAC_MULT, RAC_ANA1E_G2_VAL);
+ rtw89_write16(rtwdev, phy_offset + RAC_ANA2E * RAC_MULT, RAC_ANA2E_VAL);
+}
+
static void rtw89_pci_rxdma_prefth(struct rtw89_dev *rtwdev)
{
if (rtwdev->chip->chip_id != RTL8852A)
@@ -2310,7 +2462,7 @@ static void rtw89_pci_l1off_pwroff(struct rtw89_dev *rtwdev)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
- if (chip_id != RTL8852A && chip_id != RTL8852B && chip_id != RTL8851B)
+ if (chip_id != RTL8852A && !rtw89_is_rtl885xb(rtwdev))
return;
rtw89_write32_clr(rtwdev, R_AX_PCIE_PS_CTRL, B_AX_L1OFF_PWR_OFF_EN);
@@ -2340,7 +2492,7 @@ static void rtw89_pci_aphy_pwrcut(struct rtw89_dev *rtwdev)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
- if (chip_id != RTL8852A && chip_id != RTL8852B && chip_id != RTL8851B)
+ if (chip_id != RTL8852A && !rtw89_is_rtl885xb(rtwdev))
return;
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_PSUS_OFF_CAPC_EN);
@@ -2350,7 +2502,7 @@ static void rtw89_pci_hci_ldo(struct rtw89_dev *rtwdev)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
- if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) {
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) {
rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL,
B_AX_PCIE_DIS_L2_CTRL_LDO_HCI);
rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL,
@@ -2363,16 +2515,14 @@ static void rtw89_pci_hci_ldo(struct rtw89_dev *rtwdev)
static int rtw89_pci_dphy_delay(struct rtw89_dev *rtwdev)
{
- enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
-
- if (chip_id != RTL8852B && chip_id != RTL8851B)
+ if (!rtw89_is_rtl885xb(rtwdev))
return 0;
return rtw89_write16_mdio_mask(rtwdev, RAC_REG_REV2, BAC_CMU_EN_DLY_MASK,
PCIE_DPHY_DLY_25US, PCIE_PHY_GEN1);
}
-static void rtw89_pci_power_wake(struct rtw89_dev *rtwdev, bool pwr_up)
+static void rtw89_pci_power_wake_ax(struct rtw89_dev *rtwdev, bool pwr_up)
{
if (pwr_up)
rtw89_write32_set(rtwdev, R_AX_HCI_OPT_CTRL, BIT_WAKE_CTRL);
@@ -2527,9 +2677,10 @@ static void rtw89_pci_clr_idx_all_ax(struct rtw89_dev *rtwdev)
static int rtw89_pci_poll_txdma_ch_idle_ax(struct rtw89_dev *rtwdev)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
- u32 ret, check, dma_busy;
u32 dma_busy1 = info->dma_busy1.addr;
u32 dma_busy2 = info->dma_busy2_reg;
+ u32 check, dma_busy;
+ int ret;
check = info->dma_busy1.mask;
@@ -2554,8 +2705,9 @@ static int rtw89_pci_poll_txdma_ch_idle_ax(struct rtw89_dev *rtwdev)
static int rtw89_pci_poll_rxdma_ch_idle_ax(struct rtw89_dev *rtwdev)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
- u32 ret, check, dma_busy;
u32 dma_busy3 = info->dma_busy3_reg;
+ u32 check, dma_busy;
+ int ret;
check = B_AX_RXQ_BUSY | B_AX_RPQ_BUSY;
@@ -2627,7 +2779,7 @@ static int rtw89_pci_mode_op(struct rtw89_dev *rtwdev)
B_AX_PCIE_RX_APPLEN_MASK, 0);
}
- if (chip_id == RTL8852A || chip_id == RTL8852B) {
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) {
rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_PCIE_MAX_TXDMA_MASK, tx_burst);
rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_PCIE_MAX_RXDMA_MASK, rx_burst);
} else if (chip_id == RTL8852C) {
@@ -2635,7 +2787,7 @@ static int rtw89_pci_mode_op(struct rtw89_dev *rtwdev)
rtw89_write32_mask(rtwdev, R_AX_HAXI_INIT_CFG1, B_AX_HAXI_MAX_RXDMA_MASK, rx_burst);
}
- if (chip_id == RTL8852A || chip_id == RTL8852B) {
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) {
if (tag_mode == MAC_AX_TAG_SGL) {
val32 = rtw89_read32(rtwdev, R_AX_PCIE_INIT_CFG1) &
~B_AX_LATENCY_CONTROL;
@@ -2650,7 +2802,7 @@ static int rtw89_pci_mode_op(struct rtw89_dev *rtwdev)
rtw89_write32_mask(rtwdev, info->exp_ctrl_reg, info->max_tag_num_mask,
info->multi_tag_num);
- if (chip_id == RTL8852A || chip_id == RTL8852B) {
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) {
rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG2, B_AX_WD_ITVL_IDLE,
wd_dma_idle_intvl);
rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG2, B_AX_WD_ITVL_ACT,
@@ -2679,6 +2831,8 @@ static int rtw89_pci_ops_deinit(struct rtw89_dev *rtwdev)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
+ rtw89_pci_power_wake(rtwdev, false);
+
if (rtwdev->chip->chip_id == RTL8852A) {
/* ltr sw trigger */
rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_APP_LTR_IDLE);
@@ -2695,6 +2849,7 @@ static int rtw89_pci_ops_mac_pre_init_ax(struct rtw89_dev *rtwdev)
const struct rtw89_pci_info *info = rtwdev->pci_info;
int ret;
+ rtw89_pci_ber(rtwdev);
rtw89_pci_rxdma_prefth(rtwdev);
rtw89_pci_l1off_pwroff(rtwdev);
rtw89_pci_deglitch_setting(rtwdev);
@@ -2720,7 +2875,7 @@ static int rtw89_pci_ops_mac_pre_init_ax(struct rtw89_dev *rtwdev)
return ret;
}
- rtw89_pci_power_wake(rtwdev, true);
+ rtw89_pci_power_wake_ax(rtwdev, true);
rtw89_pci_autoload_hang(rtwdev);
rtw89_pci_l12_vmain(rtwdev);
rtw89_pci_gen2_force_ib(rtwdev);
@@ -2765,6 +2920,13 @@ static int rtw89_pci_ops_mac_pre_init_ax(struct rtw89_dev *rtwdev)
return 0;
}
+static int rtw89_pci_ops_mac_pre_deinit_ax(struct rtw89_dev *rtwdev)
+{
+ rtw89_pci_power_wake_ax(rtwdev, false);
+
+ return 0;
+}
+
int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev, bool en)
{
u32 val;
@@ -2862,7 +3024,7 @@ static int rtw89_pci_ops_mac_post_init_ax(struct rtw89_dev *rtwdev)
/* ltr sw trigger */
rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_APP_LTR_ACT);
}
- if (chip_id == RTL8852A || chip_id == RTL8852B) {
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) {
/* ADDR info 8-byte mode */
rtw89_write32_set(rtwdev, R_AX_TX_ADDRESS_INFO_MODE_SETTING,
B_AX_HOST_ADDR_INFO_8B_SEL);
@@ -2905,6 +3067,66 @@ static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev,
pci_disable_device(pdev);
}
+static bool rtw89_pci_chip_is_manual_dac(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+
+ switch (chip->chip_id) {
+ case RTL8852A:
+ case RTL8852B:
+ case RTL8851B:
+ case RTL8852BT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool rtw89_pci_is_dac_compatible_bridge(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
+ struct pci_dev *bridge = pci_upstream_bridge(rtwpci->pdev);
+
+ if (!rtw89_pci_chip_is_manual_dac(rtwdev))
+ return true;
+
+ if (!bridge)
+ return false;
+
+ switch (bridge->vendor) {
+ case PCI_VENDOR_ID_INTEL:
+ return true;
+ case PCI_VENDOR_ID_ASMEDIA:
+ if (bridge->device == 0x2806)
+ return true;
+ break;
+ }
+
+ return false;
+}
+
+static int rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev, bool force)
+{
+ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
+ struct pci_dev *pdev = rtwpci->pdev;
+ int ret;
+ u8 val;
+
+ if (!rtwpci->enable_dac && !force)
+ return 0;
+
+ if (!rtw89_pci_chip_is_manual_dac(rtwdev))
+ return 0;
+
+ /* Configure DAC only via PCI config API, not DBI interfaces */
+ ret = pci_read_config_byte(pdev, RTW89_PCIE_L1_CTRL, &val);
+ if (ret)
+ return ret;
+
+ val |= RTW89_PCIE_BIT_EN_64BITS;
+ return pci_write_config_byte(pdev, RTW89_PCIE_L1_CTRL, val);
+}
+
static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
struct pci_dev *pdev)
{
@@ -2919,17 +3141,25 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
goto err;
}
- ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
- if (ret) {
- rtw89_err(rtwdev, "failed to set dma mask to 32-bit\n");
- goto err_release_regions;
- }
+ if (!rtw89_pci_is_dac_compatible_bridge(rtwdev))
+ goto try_dac_done;
- ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
- if (ret) {
- rtw89_err(rtwdev, "failed to set consistent dma mask to 32-bit\n");
- goto err_release_regions;
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
+ if (!ret) {
+ ret = rtw89_pci_cfg_dac(rtwdev, true);
+ if (!ret) {
+ rtwpci->enable_dac = true;
+ goto try_dac_done;
+ }
+
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret) {
+ rtw89_err(rtwdev,
+ "failed to set dma and consistent mask to 32/36-bit\n");
+ goto err_release_regions;
+ }
}
+try_dac_done:
resource_len = pci_resource_len(pdev, bar_id);
rtwpci->mmap = pci_iomap(pdev, bar_id, resource_len);
@@ -3079,6 +3309,7 @@ static int rtw89_pci_init_rx_bd(struct rtw89_dev *rtwdev, struct pci_dev *pdev,
memset(rx_bd, 0, sizeof(*rx_bd));
rx_bd->buf_size = cpu_to_le16(buf_sz);
rx_bd->dma = cpu_to_le32(dma);
+ rx_bd->opt = le16_encode_bits(upper_32_bits(dma), RTW89_PCI_RXBD_OPT_DMA_HI);
rx_info->dma = dma;
return 0;
@@ -3547,7 +3778,7 @@ static int rtw89_pci_request_irq(struct rtw89_dev *rtwdev,
unsigned long flags = 0;
int ret;
- flags |= PCI_IRQ_LEGACY | PCI_IRQ_MSI;
+ flags |= PCI_IRQ_INTX | PCI_IRQ_MSI;
ret = pci_alloc_irq_vectors(pdev, 1, 1, flags);
if (ret < 0) {
rtw89_err(rtwdev, "failed to alloc irq vectors, ret %d\n", ret);
@@ -3580,19 +3811,16 @@ static void rtw89_pci_free_irq(struct rtw89_dev *rtwdev,
pci_free_irq_vectors(pdev);
}
-static u16 gray_code_to_bin(u16 gray_code, u32 bit_num)
+static u16 gray_code_to_bin(u16 gray_code)
{
- u16 bin = 0, gray_bit;
- u32 bit_idx;
+ u16 binary = gray_code;
- for (bit_idx = 0; bit_idx < bit_num; bit_idx++) {
- gray_bit = (gray_code >> bit_idx) & 0x1;
- if (bit_num - bit_idx > 1)
- gray_bit ^= (gray_code >> (bit_idx + 1)) & 0x1;
- bin |= (gray_bit << bit_idx);
+ while (gray_code) {
+ gray_code >>= 1;
+ binary ^= gray_code;
}
- return bin;
+ return binary;
}
static int rtw89_pci_filter_out(struct rtw89_dev *rtwdev)
@@ -3628,7 +3856,7 @@ static int rtw89_pci_filter_out(struct rtw89_dev *rtwdev)
val16 = rtw89_read16_mask(rtwdev,
phy_offset + RAC_ANA1F * RAC_MULT,
FILTER_OUT_EQ_MASK);
- val16 = gray_code_to_bin(val16, hweight16(val16));
+ val16 = gray_code_to_bin(val16);
filter_out_val = rtw89_read16(rtwdev, phy_offset + RAC_ANA24 *
RAC_MULT);
filter_out_val &= ~REG_FILTER_OUT_MASK;
@@ -3671,7 +3899,7 @@ static void rtw89_pci_clkreq_set_ax(struct rtw89_dev *rtwdev, bool enable)
if (ret)
rtw89_err(rtwdev, "failed to set CLKREQ Delay\n");
- if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) {
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) {
if (enable)
ret = rtw89_pci_config_byte_set(rtwdev,
RTW89_PCIE_L1_CTRL,
@@ -3723,7 +3951,7 @@ static void rtw89_pci_aspm_set_ax(struct rtw89_dev *rtwdev, bool enable)
if (ret)
rtw89_warn(rtwdev, "failed to read ASPM Delay\n");
- if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) {
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) {
if (enable)
ret = rtw89_pci_config_byte_set(rtwdev,
RTW89_PCIE_L1_CTRL,
@@ -3822,7 +4050,7 @@ static void rtw89_pci_l1ss_set_ax(struct rtw89_dev *rtwdev, bool enable)
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
int ret;
- if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) {
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) {
if (enable)
ret = rtw89_pci_config_byte_set(rtwdev,
RTW89_PCIE_TIMER_CTRL,
@@ -3868,6 +4096,15 @@ static void rtw89_pci_l1ss_cfg(struct rtw89_dev *rtwdev)
rtw89_pci_l1ss_set(rtwdev, true);
}
+static void rtw89_pci_cpl_timeout_cfg(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
+ struct pci_dev *pdev = rtwpci->pdev;
+
+ pcie_capability_set_word(pdev, PCI_EXP_DEVCTL2,
+ PCI_EXP_DEVCTL2_COMP_TMOUT_DIS);
+}
+
static int rtw89_pci_poll_io_idle_ax(struct rtw89_dev *rtwdev)
{
int ret = 0;
@@ -4010,6 +4247,36 @@ static int rtw89_pci_napi_poll(struct napi_struct *napi, int budget)
return work_done;
}
+static
+void rtw89_check_pci_ssid_quirks(struct rtw89_dev *rtwdev,
+ struct pci_dev *pdev,
+ const struct rtw89_pci_ssid_quirk *ssid_quirks)
+{
+ int i;
+
+ if (!ssid_quirks)
+ return;
+
+ for (i = 0; i < 200; i++, ssid_quirks++) {
+ if (ssid_quirks->vendor == 0 && ssid_quirks->device == 0)
+ break;
+
+ if (ssid_quirks->vendor != pdev->vendor ||
+ ssid_quirks->device != pdev->device ||
+ ssid_quirks->subsystem_vendor != pdev->subsystem_vendor ||
+ ssid_quirks->subsystem_device != pdev->subsystem_device)
+ continue;
+
+ bitmap_or(rtwdev->quirks, rtwdev->quirks, &ssid_quirks->bitmap,
+ NUM_OF_RTW89_QUIRKS);
+ rtwdev->custid = ssid_quirks->custid;
+ break;
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_HCI, "quirks=%*ph custid=%d\n",
+ (int)sizeof(rtwdev->quirks), rtwdev->quirks, rtwdev->custid);
+}
+
static int __maybe_unused rtw89_pci_suspend(struct device *dev)
{
struct ieee80211_hw *hw = dev_get_drvdata(dev);
@@ -4019,7 +4286,7 @@ static int __maybe_unused rtw89_pci_suspend(struct device *dev)
rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6);
rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST);
rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6);
- if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) {
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) {
rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL,
B_AX_PCIE_DIS_L2_CTRL_LDO_HCI);
rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1,
@@ -4044,6 +4311,18 @@ static void rtw89_pci_l2_hci_ldo(struct rtw89_dev *rtwdev)
RTW89_PCIE_BIT_CFG_RST_MSTATE);
}
+void rtw89_pci_basic_cfg(struct rtw89_dev *rtwdev, bool resume)
+{
+ if (resume)
+ rtw89_pci_cfg_dac(rtwdev, false);
+
+ rtw89_pci_disable_eq(rtwdev);
+ rtw89_pci_filter_out(rtwdev);
+ rtw89_pci_cpl_timeout_cfg(rtwdev);
+ rtw89_pci_link_cfg(rtwdev);
+ rtw89_pci_l1ss_cfg(rtwdev);
+}
+
static int __maybe_unused rtw89_pci_resume(struct device *dev)
{
struct ieee80211_hw *hw = dev_get_drvdata(dev);
@@ -4053,7 +4332,7 @@ static int __maybe_unused rtw89_pci_resume(struct device *dev)
rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6);
rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST);
rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6);
- if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) {
+ if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) {
rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL,
B_AX_PCIE_DIS_L2_CTRL_LDO_HCI);
rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1,
@@ -4065,9 +4344,8 @@ static int __maybe_unused rtw89_pci_resume(struct device *dev)
B_AX_SEL_REQ_ENTR_L1);
}
rtw89_pci_l2_hci_ldo(rtwdev);
- rtw89_pci_filter_out(rtwdev);
- rtw89_pci_link_cfg(rtwdev);
- rtw89_pci_l1ss_cfg(rtwdev);
+
+ rtw89_pci_basic_cfg(rtwdev, true);
return 0;
}
@@ -4084,7 +4362,7 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_ax = {
B_AX_RDU_INT},
.mac_pre_init = rtw89_pci_ops_mac_pre_init_ax,
- .mac_pre_deinit = NULL,
+ .mac_pre_deinit = rtw89_pci_ops_mac_pre_deinit_ax,
.mac_post_init = rtw89_pci_ops_mac_post_init_ax,
.clr_idx_all = rtw89_pci_clr_idx_all_ax,
@@ -4100,6 +4378,9 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_ax = {
.aspm_set = rtw89_pci_aspm_set_ax,
.clkreq_set = rtw89_pci_clkreq_set_ax,
.l1ss_set = rtw89_pci_l1ss_set_ax,
+
+ .disable_eq = rtw89_pci_disable_eq_ax,
+ .power_wake = rtw89_pci_power_wake_ax,
};
EXPORT_SYMBOL(rtw89_pci_gen_ax);
@@ -4157,7 +4438,7 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
rtwdev = rtw89_alloc_ieee80211_hw(&pdev->dev,
sizeof(struct rtw89_pci),
- info->chip);
+ info->chip, info->variant);
if (!rtwdev) {
dev_err(&pdev->dev, "failed to allocate hw\n");
return -ENOMEM;
@@ -4171,6 +4452,9 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
rtwdev->hci.rpwm_addr = pci_info->rpwm_addr;
rtwdev->hci.cpwm_addr = pci_info->cpwm_addr;
+ rtw89_check_quirks(rtwdev, info->quirks);
+ rtw89_check_pci_ssid_quirks(rtwdev, pdev, pci_info->ssid_quirks);
+
SET_IEEE80211_DEV(rtwdev->hw, &pdev->dev);
ret = rtw89_core_init(rtwdev);
@@ -4197,11 +4481,13 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_clear_resource;
}
- rtw89_pci_filter_out(rtwdev);
- rtw89_pci_link_cfg(rtwdev);
- rtw89_pci_l1ss_cfg(rtwdev);
+ rtw89_pci_basic_cfg(rtwdev, false);
- rtw89_core_napi_init(rtwdev);
+ ret = rtw89_core_napi_init(rtwdev);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to init napi\n");
+ goto err_clear_resource;
+ }
ret = rtw89_pci_request_irq(rtwdev, pdev);
if (ret) {
diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h
index a63b6b7c9bfa..79fef5f90140 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.h
+++ b/drivers/net/wireless/realtek/rtw89/pci.h
@@ -12,11 +12,23 @@
#define MDIO_PG0_G2 2
#define MDIO_PG1_G2 3
#define RAC_CTRL_PPR 0x00
+#define RAC_ANA03 0x03
+#define OOBS_SEN_MASK GENMASK(5, 1)
+#define RAC_ANA09 0x09
+#define BAC_OOBS_SEL BIT(4)
#define RAC_ANA0A 0x0A
#define B_BAC_EQ_SEL BIT(5)
+#define RAC_ANA0B 0x0B
+#define MANUAL_LVL_MASK GENMASK(8, 5)
#define RAC_ANA0C 0x0C
#define B_PCIE_BIT_PSAVE BIT(15)
+#define RAC_ANA0D 0x0D
+#define OFFSET_CAL_MODE BIT(13)
+#define BAC_RX_TEST_EN BIT(6)
#define RAC_ANA10 0x10
+#define ADDR_SEL_MASK GENMASK(9, 4)
+#define ADDR_SEL_VAL 0x3C
+#define ADDR_SEL_PINOUT_DIS_VAL 0x3C4
#define B_PCIE_BIT_PINOUT_DIS BIT(3)
#define RAC_REG_REV2 0x1B
#define BAC_CMU_EN_DLY_MASK GENMASK(15, 12)
@@ -26,11 +38,18 @@
#define RAC_REG_FLD_0 0x1D
#define BAC_AUTOK_N_MASK GENMASK(3, 2)
#define PCIE_AUTOK_4 0x3
+#define RAC_ANA1E 0x1E
+#define RAC_ANA1E_G1_VAL 0x66EA
+#define RAC_ANA1E_G2_VAL 0x6EEA
#define RAC_ANA1F 0x1F
+#define OOBS_LEVEL_MASK GENMASK(12, 8)
+#define OFFSET_CAL_MASK GENMASK(7, 4)
#define RAC_ANA24 0x24
#define B_AX_DEGLITCH GENMASK(11, 8)
#define RAC_ANA26 0x26
#define B_AX_RXEN GENMASK(15, 14)
+#define RAC_ANA2E 0x2E
+#define RAC_ANA2E_VAL 0xFFFE
#define RAC_CTRL_PPR_V1 0x30
#define B_AX_CLK_CALIB_EN BIT(12)
#define B_AX_CALIB_EN BIT(13)
@@ -121,6 +140,11 @@
#define REG_FILTER_OUT_MASK GENMASK(6, 2)
#define RAC_MULT 2
+#define R_RAC_DIRECT_OFFSET_BE_LANE0_G1 0x3800
+#define R_RAC_DIRECT_OFFSET_BE_LANE1_G1 0x3880
+#define R_RAC_DIRECT_OFFSET_BE_LANE0_G2 0x3900
+#define R_RAC_DIRECT_OFFSET_BE_LANE1_G2 0x3980
+
#define RTW89_PCI_WR_RETRY_CNT 20
/* Interrupts */
@@ -286,6 +310,7 @@
#define B_BE_L1SS_TIMEOUT_CTRL BIT(18)
#define B_BE_ASPM_CTRL_L1 BIT(17)
#define B_BE_ASPM_CTRL_L0 BIT(16)
+#define B_BE_RTK_ASPM_CTRL_MASK GENMASK(17, 16)
#define B_BE_XFER_PENDING_FW BIT(11)
#define B_BE_XFER_PENDING BIT(10)
#define B_BE_REQ_EXIT_L1 BIT(9)
@@ -430,34 +455,36 @@
#define B_BE_RX0DMA_INT_EN BIT(0)
#define R_BE_HAXI_HISR00 0xB0B4
-#define B_BE_RDU_CH6_INT BIT(28)
-#define B_BE_RDU_CH5_INT BIT(27)
-#define B_BE_RDU_CH4_INT BIT(26)
-#define B_BE_RDU_CH2_INT BIT(25)
-#define B_BE_RDU_CH1_INT BIT(24)
-#define B_BE_RDU_CH0_INT BIT(23)
-#define B_BE_RXDMA_STUCK_INT BIT(22)
-#define B_BE_TXDMA_STUCK_INT BIT(21)
-#define B_BE_TXDMA_CH14_INT BIT(20)
-#define B_BE_TXDMA_CH13_INT BIT(19)
-#define B_BE_TXDMA_CH12_INT BIT(18)
-#define B_BE_TXDMA_CH11_INT BIT(17)
-#define B_BE_TXDMA_CH10_INT BIT(16)
-#define B_BE_TXDMA_CH9_INT BIT(15)
-#define B_BE_TXDMA_CH8_INT BIT(14)
-#define B_BE_TXDMA_CH7_INT BIT(13)
-#define B_BE_TXDMA_CH6_INT BIT(12)
-#define B_BE_TXDMA_CH5_INT BIT(11)
-#define B_BE_TXDMA_CH4_INT BIT(10)
-#define B_BE_TXDMA_CH3_INT BIT(9)
-#define B_BE_TXDMA_CH2_INT BIT(8)
-#define B_BE_TXDMA_CH1_INT BIT(7)
-#define B_BE_TXDMA_CH0_INT BIT(6)
-#define B_BE_RPQ1DMA_INT BIT(5)
-#define B_BE_RX1P1DMA_INT BIT(4)
+#define B_BE_RDU_CH5_INT_V1 BIT(30)
+#define B_BE_RDU_CH4_INT_V1 BIT(29)
+#define B_BE_RDU_CH3_INT_V1 BIT(28)
+#define B_BE_RDU_CH2_INT_V1 BIT(27)
+#define B_BE_RDU_CH1_INT_V1 BIT(26)
+#define B_BE_RDU_CH0_INT_V1 BIT(25)
+#define B_BE_RXDMA_STUCK_INT_V1 BIT(24)
+#define B_BE_TXDMA_STUCK_INT_V1 BIT(23)
+#define B_BE_TXDMA_CH14_INT_V1 BIT(22)
+#define B_BE_TXDMA_CH13_INT_V1 BIT(21)
+#define B_BE_TXDMA_CH12_INT_V1 BIT(20)
+#define B_BE_TXDMA_CH11_INT_V1 BIT(19)
+#define B_BE_TXDMA_CH10_INT_V1 BIT(18)
+#define B_BE_TXDMA_CH9_INT_V1 BIT(17)
+#define B_BE_TXDMA_CH8_INT_V1 BIT(16)
+#define B_BE_TXDMA_CH7_INT_V1 BIT(15)
+#define B_BE_TXDMA_CH6_INT_V1 BIT(14)
+#define B_BE_TXDMA_CH5_INT_V1 BIT(13)
+#define B_BE_TXDMA_CH4_INT_V1 BIT(12)
+#define B_BE_TXDMA_CH3_INT_V1 BIT(11)
+#define B_BE_TXDMA_CH2_INT_V1 BIT(10)
+#define B_BE_TXDMA_CH1_INT_V1 BIT(9)
+#define B_BE_TXDMA_CH0_INT_V1 BIT(8)
+#define B_BE_RX1P1DMA_INT_V1 BIT(7)
+#define B_BE_RX0P1DMA_INT_V1 BIT(6)
+#define B_BE_RO1DMA_INT BIT(5)
+#define B_BE_RP1DMA_INT BIT(4)
#define B_BE_RX1DMA_INT BIT(3)
-#define B_BE_RPQ0DMA_INT BIT(2)
-#define B_BE_RX0P1DMA_INT BIT(1)
+#define B_BE_RO0DMA_INT BIT(2)
+#define B_BE_RP0DMA_INT BIT(1)
#define B_BE_RX0DMA_INT BIT(0)
/* TX/RX */
@@ -711,6 +738,11 @@
#define B_AX_CH11_BUSY BIT(1)
#define B_AX_CH10_BUSY BIT(0)
+#define R_AX_WP_ADDR_H_SEL0_3 0x1334
+#define R_AX_WP_ADDR_H_SEL4_7 0x1338
+#define R_AX_WP_ADDR_H_SEL8_11 0x133C
+#define R_AX_WP_ADDR_H_SEL12_15 0x1340
+
#define R_BE_HAXI_DMA_STOP1 0xB010
#define B_BE_STOP_WPDMA BIT(31)
#define B_BE_STOP_CH14 BIT(14)
@@ -810,6 +842,11 @@
#define R_BE_RPQ0_RXBD_DESA_L_V1 0xB308
#define R_BE_RPQ0_RXBD_DESA_H_V1 0xB30C
+#define R_BE_WP_ADDR_H_SEL0_3_V1 0xB420
+#define R_BE_WP_ADDR_H_SEL4_7_V1 0xB424
+#define R_BE_WP_ADDR_H_SEL8_11_V1 0xB428
+#define R_BE_WP_ADDR_H_SEL12_15_V1 0xB42C
+
/* Configure */
#define R_AX_PCIE_INIT_CFG2 0x1004
#define B_AX_WD_ITVL_IDLE GENMASK(27, 24)
@@ -1016,7 +1053,8 @@
#define RTW89_PCI_TXWD_NUM_MAX 512
#define RTW89_PCI_TXWD_PAGE_SIZE 128
#define RTW89_PCI_ADDRINFO_MAX 4
-#define RTW89_PCI_RX_BUF_SIZE (11454 + 40) /* +40 for rtw89_rxdesc_long_v2 */
+/* +40 for rtw89_rxdesc_long_v2; +4 for rtw89_pci_rxbd_info */
+#define RTW89_PCI_RX_BUF_SIZE (11454 + 40 + 4)
#define RTW89_PCI_POLL_BDRAM_RST_CNT 100
#define RTW89_PCI_MULTITAG 8
@@ -1042,6 +1080,7 @@
#define RTW89_PCIE_TIMER_CTRL 0x0718
#define RTW89_PCIE_BIT_L1SUB BIT(5)
#define RTW89_PCIE_L1_CTRL 0x0719
+#define RTW89_PCIE_BIT_EN_64BITS BIT(5)
#define RTW89_PCIE_BIT_CLK BIT(4)
#define RTW89_PCIE_BIT_L1 BIT(3)
#define RTW89_PCIE_CLK_CTRL 0x0725
@@ -1252,6 +1291,22 @@ struct rtw89_pci_gen_def {
void (*aspm_set)(struct rtw89_dev *rtwdev, bool enable);
void (*clkreq_set)(struct rtw89_dev *rtwdev, bool enable);
void (*l1ss_set)(struct rtw89_dev *rtwdev, bool enable);
+
+ void (*disable_eq)(struct rtw89_dev *rtwdev);
+ void (*power_wake)(struct rtw89_dev *rtwdev, bool pwr_up);
+};
+
+#define RTW89_PCI_SSID(v, d, ssv, ssd, cust) \
+ .vendor = v, .device = d, .subsystem_vendor = ssv, .subsystem_device = ssd, \
+ .custid = RTW89_CUSTID_ ##cust
+
+struct rtw89_pci_ssid_quirk {
+ unsigned short vendor;
+ unsigned short device;
+ unsigned short subsystem_vendor;
+ unsigned short subsystem_device;
+ enum rtw89_custid custid;
+ unsigned long bitmap; /* bitmap of rtw89_quirks */
};
struct rtw89_pci_info {
@@ -1272,6 +1327,7 @@ struct rtw89_pci_info {
enum mac_ax_io_rcy_tmr io_rcy_tmr;
bool rx_ring_eq_is_full;
bool check_rx_tag;
+ bool no_rxbd_fs;
u32 init_cfg_reg;
u32 txhci_en_bit;
@@ -1291,6 +1347,7 @@ struct rtw89_pci_info {
u32 rpwm_addr;
u32 cpwm_addr;
u32 mit_addr;
+ u32 wp_sel_addr;
u32 tx_dma_ch_mask;
const struct rtw89_pci_bd_idx_addr *bd_idx_addr_low_power;
const struct rtw89_pci_ch_dma_addr_set *dma_addr_set;
@@ -1306,6 +1363,8 @@ struct rtw89_pci_info {
void (*recognize_intrs)(struct rtw89_dev *rtwdev,
struct rtw89_pci *rtwpci,
struct rtw89_pci_isrs *isrs);
+
+ const struct rtw89_pci_ssid_quirk *ssid_quirks;
};
struct rtw89_pci_tx_data {
@@ -1317,11 +1376,11 @@ struct rtw89_pci_rx_info {
u32 fs:1, ls:1, tag:13, len:14;
};
-#define RTW89_PCI_TXBD_OPTION_LS BIT(14)
-
struct rtw89_pci_tx_bd_32 {
__le16 length;
- __le16 option;
+ __le16 opt;
+#define RTW89_PCI_TXBD_OPT_LS BIT(14)
+#define RTW89_PCI_TXBD_OPT_DMA_HI GENMASK(13, 6)
__le32 dma;
} __packed;
@@ -1336,7 +1395,7 @@ struct rtw89_pci_tx_wp_info {
#define RTW89_PCI_ADDR_MSDU_LS BIT(15)
#define RTW89_PCI_ADDR_LS BIT(14)
-#define RTW89_PCI_ADDR_HIGH(a) (((a) << 6) & GENMASK(13, 6))
+#define RTW89_PCI_ADDR_HIGH_MASK GENMASK(13, 6)
#define RTW89_PCI_ADDR_NUM(x) ((x) & GENMASK(5, 0))
struct rtw89_pci_tx_addr_info_32 {
@@ -1373,7 +1432,8 @@ struct rtw89_pci_rpp_fmt {
struct rtw89_pci_rx_bd_32 {
__le16 buf_size;
- __le16 rsvd;
+ __le16 opt;
+#define RTW89_PCI_RXBD_OPT_DMA_HI GENMASK(13, 6)
__le32 dma;
} __packed;
@@ -1462,6 +1522,7 @@ struct rtw89_pci {
bool running;
bool low_power;
bool under_recovery;
+ bool enable_dac;
struct rtw89_pci_tx_ring tx_rings[RTW89_TXCH_NUM];
struct rtw89_pci_rx_ring rx_rings[RTW89_RXCH_NUM];
struct sk_buff_head h2c_queue;
@@ -1573,6 +1634,7 @@ struct pci_device_id;
int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id);
void rtw89_pci_remove(struct pci_dev *pdev);
+void rtw89_pci_basic_cfg(struct rtw89_dev *rtwdev, bool resume);
void rtw89_pci_ops_reset(struct rtw89_dev *rtwdev);
int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev, bool en);
int rtw89_pci_ltr_set_v1(struct rtw89_dev *rtwdev, bool en);
@@ -1739,4 +1801,21 @@ static inline int rtw89_pci_poll_txdma_ch_idle(struct rtw89_dev *rtwdev)
return gen_def->poll_txdma_ch_idle(rtwdev);
}
+
+static inline void rtw89_pci_disable_eq(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_pci_info *info = rtwdev->pci_info;
+ const struct rtw89_pci_gen_def *gen_def = info->gen_def;
+
+ gen_def->disable_eq(rtwdev);
+}
+
+static inline void rtw89_pci_power_wake(struct rtw89_dev *rtwdev, bool pwr_up)
+{
+ const struct rtw89_pci_info *info = rtwdev->pci_info;
+ const struct rtw89_pci_gen_def *gen_def = info->gen_def;
+
+ gen_def->power_wake(rtwdev, pwr_up);
+}
+
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/pci_be.c b/drivers/net/wireless/realtek/rtw89/pci_be.c
index 7cc328222965..12e6a0cbb889 100644
--- a/drivers/net/wireless/realtek/rtw89/pci_be.c
+++ b/drivers/net/wireless/realtek/rtw89/pci_be.c
@@ -550,6 +550,79 @@ static int rtw89_pci_lv1rst_start_dma_be(struct rtw89_dev *rtwdev)
return 0;
}
+static void rtw89_pci_disable_eq_be(struct rtw89_dev *rtwdev)
+{
+ u32 backup_aspm, phy_offset;
+ u16 oobs_val, offset_cal;
+ u16 g1_oobs, g2_oobs;
+ u8 gen;
+
+ if (rtwdev->chip->chip_id != RTL8922A)
+ return;
+
+ g1_oobs = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 +
+ RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL);
+ g2_oobs = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G2 +
+ RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL);
+ if (g1_oobs && g2_oobs)
+ return;
+
+ backup_aspm = rtw89_read32(rtwdev, R_BE_PCIE_MIX_CFG);
+ rtw89_write32_clr(rtwdev, R_BE_PCIE_MIX_CFG, B_BE_RTK_ASPM_CTRL_MASK);
+
+ /* offset K */
+ for (gen = 1; gen <= 2; gen++) {
+ phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 :
+ R_RAC_DIRECT_OFFSET_BE_LANE0_G2;
+
+ rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT,
+ B_PCIE_BIT_RD_SEL);
+ }
+
+ offset_cal = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 +
+ RAC_ANA1F * RAC_MULT, OFFSET_CAL_MASK);
+
+ for (gen = 1; gen <= 2; gen++) {
+ phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 :
+ R_RAC_DIRECT_OFFSET_BE_LANE0_G2;
+
+ rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA0B * RAC_MULT,
+ MANUAL_LVL_MASK, offset_cal);
+ rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT,
+ OFFSET_CAL_MODE);
+ }
+
+ /* OOBS */
+ for (gen = 1; gen <= 2; gen++) {
+ phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 :
+ R_RAC_DIRECT_OFFSET_BE_LANE0_G2;
+
+ rtw89_write16_set(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT,
+ BAC_RX_TEST_EN);
+ rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA10 * RAC_MULT,
+ ADDR_SEL_MASK, ADDR_SEL_VAL);
+ rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA10 * RAC_MULT,
+ B_PCIE_BIT_PINOUT_DIS);
+ rtw89_write16_set(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT,
+ B_PCIE_BIT_RD_SEL);
+ }
+
+ oobs_val = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 +
+ RAC_ANA1F * RAC_MULT, OOBS_LEVEL_MASK);
+
+ for (gen = 1; gen <= 2; gen++) {
+ phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 :
+ R_RAC_DIRECT_OFFSET_BE_LANE0_G2;
+
+ rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA03 * RAC_MULT,
+ OOBS_SEN_MASK, oobs_val);
+ rtw89_write16_set(rtwdev, phy_offset + RAC_ANA09 * RAC_MULT,
+ BAC_OOBS_SEL);
+ }
+
+ rtw89_write32(rtwdev, R_BE_PCIE_MIX_CFG, backup_aspm);
+}
+
static int __maybe_unused rtw89_pci_suspend_be(struct device *dev)
{
struct ieee80211_hw *hw = dev_get_drvdata(dev);
@@ -584,6 +657,8 @@ static int __maybe_unused rtw89_pci_resume_be(struct device *dev)
rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
rtw89_write32_set(rtwdev, R_BE_REG_PL1_MASK, B_BE_SER_PM_MASTER_IMR);
+ rtw89_pci_basic_cfg(rtwdev, true);
+
return 0;
}
@@ -591,7 +666,7 @@ SIMPLE_DEV_PM_OPS(rtw89_pm_ops_be, rtw89_pci_suspend_be, rtw89_pci_resume_be);
EXPORT_SYMBOL(rtw89_pm_ops_be);
const struct rtw89_pci_gen_def rtw89_pci_gen_be = {
- .isr_rdu = B_BE_RDU_CH1_INT | B_BE_RDU_CH0_INT,
+ .isr_rdu = B_BE_RDU_CH1_INT_V1 | B_BE_RDU_CH0_INT_V1,
.isr_halt_c2h = B_BE_HALT_C2H_INT,
.isr_wdt_timeout = B_BE_WDT_TIMEOUT_INT,
.isr_clear_rpq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RPQ0_ISR_V1},
@@ -614,5 +689,8 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_be = {
.aspm_set = rtw89_pci_aspm_set_be,
.clkreq_set = rtw89_pci_clkreq_set_be,
.l1ss_set = rtw89_pci_l1ss_set_be,
+
+ .disable_eq = rtw89_pci_disable_eq_be,
+ .power_wake = _patch_pcie_power_wake_be,
};
EXPORT_SYMBOL(rtw89_pci_gen_be);
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index 12da63d64307..76a2e26d4a10 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -2,6 +2,8 @@
/* Copyright(c) 2019-2020 Realtek Corporation
*/
+#include "acpi.h"
+#include "chan.h"
#include "coex.h"
#include "debug.h"
#include "fw.h"
@@ -74,12 +76,12 @@ static u64 get_mcs_ra_mask(u16 mcs_map, u8 highest_mcs, u8 gap)
return ra_mask;
}
-static u64 get_he_ra_mask(struct ieee80211_sta *sta)
+static u64 get_he_ra_mask(struct ieee80211_link_sta *link_sta)
{
- struct ieee80211_sta_he_cap cap = sta->deflink.he_cap;
+ struct ieee80211_sta_he_cap cap = link_sta->he_cap;
u16 mcs_map;
- switch (sta->deflink.bandwidth) {
+ switch (link_sta->bandwidth) {
case IEEE80211_STA_RX_BW_160:
if (cap.he_cap_elem.phy_cap_info[0] &
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
@@ -117,13 +119,14 @@ static u64 get_eht_mcs_ra_mask(u8 *max_nss, u8 start_mcs, u8 n_nss)
return mask;
}
-static u64 get_eht_ra_mask(struct ieee80211_sta *sta)
+static u64 get_eht_ra_mask(struct ieee80211_link_sta *link_sta)
{
- struct ieee80211_sta_eht_cap *eht_cap = &sta->deflink.eht_cap;
+ struct ieee80211_sta_eht_cap *eht_cap = &link_sta->eht_cap;
struct ieee80211_eht_mcs_nss_supp_20mhz_only *mcs_nss_20mhz;
struct ieee80211_eht_mcs_nss_supp_bw *mcs_nss;
+ u8 *he_phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info;
- switch (sta->deflink.bandwidth) {
+ switch (link_sta->bandwidth) {
case IEEE80211_STA_RX_BW_320:
mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._320;
/* MCS 9, 11, 13 */
@@ -132,15 +135,19 @@ static u64 get_eht_ra_mask(struct ieee80211_sta *sta)
mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._160;
/* MCS 9, 11, 13 */
return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3);
+ case IEEE80211_STA_RX_BW_20:
+ if (!(he_phy_cap[0] &
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) {
+ mcs_nss_20mhz = &eht_cap->eht_mcs_nss_supp.only_20mhz;
+ /* MCS 7, 9, 11, 13 */
+ return get_eht_mcs_ra_mask(mcs_nss_20mhz->rx_tx_max_nss, 7, 4);
+ }
+ fallthrough;
case IEEE80211_STA_RX_BW_80:
default:
mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._80;
/* MCS 9, 11, 13 */
return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3);
- case IEEE80211_STA_RX_BW_20:
- mcs_nss_20mhz = &eht_cap->eht_mcs_nss_supp.only_20mhz;
- /* MCS 7, 9, 11, 13 */
- return get_eht_mcs_ra_mask(mcs_nss_20mhz->rx_tx_max_nss, 7, 4);
}
}
@@ -189,15 +196,16 @@ static u64 rtw89_phy_ra_mask_recover(u64 ra_mask, u64 ra_mask_bak)
return ra_mask;
}
-static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev,
+ struct rtw89_sta_link *rtwsta_link,
+ struct ieee80211_link_sta *link_sta,
const struct rtw89_chan *chan)
{
- struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
- struct cfg80211_bitrate_mask *mask = &rtwsta->mask;
+ struct cfg80211_bitrate_mask *mask = &rtwsta_link->mask;
enum nl80211_band band;
u64 cfg_mask;
- if (!rtwsta->use_cfg_mask)
+ if (!rtwsta_link->use_cfg_mask)
return -1;
switch (chan->band_type) {
@@ -221,17 +229,17 @@ static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtw
return -1;
}
- if (sta->deflink.he_cap.has_he) {
+ if (link_sta->he_cap.has_he) {
cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[0],
RA_MASK_HE_1SS_RATES);
cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[1],
RA_MASK_HE_2SS_RATES);
- } else if (sta->deflink.vht_cap.vht_supported) {
+ } else if (link_sta->vht_cap.vht_supported) {
cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[0],
RA_MASK_VHT_1SS_RATES);
cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[1],
RA_MASK_VHT_2SS_RATES);
- } else if (sta->deflink.ht_cap.ht_supported) {
+ } else if (link_sta->ht_cap.ht_supported) {
cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[0],
RA_MASK_HT_1SS_RATES);
cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[1],
@@ -253,19 +261,32 @@ rtw89_ra_mask_he_rates[4] = {RA_MASK_HE_1SS_RATES, RA_MASK_HE_2SS_RATES,
static const u64
rtw89_ra_mask_eht_rates[4] = {RA_MASK_EHT_1SS_RATES, RA_MASK_EHT_2SS_RATES,
RA_MASK_EHT_3SS_RATES, RA_MASK_EHT_4SS_RATES};
+static const u64
+rtw89_ra_mask_eht_mcs0_11[4] = {RA_MASK_EHT_1SS_MCS0_11, RA_MASK_EHT_2SS_MCS0_11,
+ RA_MASK_EHT_3SS_MCS0_11, RA_MASK_EHT_4SS_MCS0_11};
static void rtw89_phy_ra_gi_ltf(struct rtw89_dev *rtwdev,
- struct rtw89_sta *rtwsta,
+ struct rtw89_sta_link *rtwsta_link,
+ struct ieee80211_link_sta *link_sta,
const struct rtw89_chan *chan,
bool *fix_giltf_en, u8 *fix_giltf)
{
- struct cfg80211_bitrate_mask *mask = &rtwsta->mask;
+ struct cfg80211_bitrate_mask *mask = &rtwsta_link->mask;
u8 band = chan->band_type;
enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
- u8 he_gi = mask->control[nl_band].he_gi;
u8 he_ltf = mask->control[nl_band].he_ltf;
+ u8 he_gi = mask->control[nl_band].he_gi;
- if (!rtwsta->use_cfg_mask)
+ *fix_giltf_en = true;
+
+ if (rtwdev->chip->chip_id == RTL8852C &&
+ chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
+ rtw89_sta_link_has_su_mu_4xhe08(link_sta))
+ *fix_giltf = RTW89_GILTF_SGI_4XHE08;
+ else
+ *fix_giltf = RTW89_GILTF_2XHE08;
+
+ if (!(rtwsta_link->use_cfg_mask && link_sta->he_cap.has_he))
return;
if (he_ltf == 2 && he_gi == 2) {
@@ -280,26 +301,21 @@ static void rtw89_phy_ra_gi_ltf(struct rtw89_dev *rtwdev,
*fix_giltf = RTW89_GILTF_1XHE16;
} else if (he_ltf == 0 && he_gi == 0) {
*fix_giltf = RTW89_GILTF_1XHE08;
- } else {
- *fix_giltf_en = false;
- return;
}
-
- *fix_giltf_en = true;
}
static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
- struct ieee80211_sta *sta, bool csi)
+ struct rtw89_vif_link *rtwvif_link,
+ struct rtw89_sta_link *rtwsta_link,
+ struct ieee80211_link_sta *link_sta,
+ bool p2p, bool csi)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
- struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern;
- struct rtw89_ra_info *ra = &rtwsta->ra;
+ struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif_link->rate_pattern;
+ struct rtw89_ra_info *ra = &rtwsta_link->ra;
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->sub_entity_idx);
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif);
+ rtwvif_link->chanctx_idx);
const u64 *high_rate_masks = rtw89_ra_mask_ht_rates;
- u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi);
+ u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi);
u64 ra_mask = 0;
u64 ra_mask_bak;
u8 mode = 0;
@@ -314,62 +330,73 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
memset(ra, 0, sizeof(*ra));
/* Set the ra mask from sta's capability */
- if (sta->deflink.eht_cap.has_eht) {
+ if (link_sta->eht_cap.has_eht) {
mode |= RTW89_RA_MODE_EHT;
- ra_mask |= get_eht_ra_mask(sta);
- high_rate_masks = rtw89_ra_mask_eht_rates;
- } else if (sta->deflink.he_cap.has_he) {
+ ra_mask |= get_eht_ra_mask(link_sta);
+
+ if (rtwdev->hal.no_mcs_12_13)
+ high_rate_masks = rtw89_ra_mask_eht_mcs0_11;
+ else
+ high_rate_masks = rtw89_ra_mask_eht_rates;
+
+ rtw89_phy_ra_gi_ltf(rtwdev, rtwsta_link, link_sta,
+ chan, &fix_giltf_en, &fix_giltf);
+ } else if (link_sta->he_cap.has_he) {
mode |= RTW89_RA_MODE_HE;
csi_mode = RTW89_RA_RPT_MODE_HE;
- ra_mask |= get_he_ra_mask(sta);
+ ra_mask |= get_he_ra_mask(link_sta);
high_rate_masks = rtw89_ra_mask_he_rates;
- if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[2] &
+ if (link_sta->he_cap.he_cap_elem.phy_cap_info[2] &
IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ)
stbc_en = 1;
- if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[1] &
+ if (link_sta->he_cap.he_cap_elem.phy_cap_info[1] &
IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)
ldpc_en = 1;
- rtw89_phy_ra_gi_ltf(rtwdev, rtwsta, chan, &fix_giltf_en, &fix_giltf);
- } else if (sta->deflink.vht_cap.vht_supported) {
- u16 mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map);
+ rtw89_phy_ra_gi_ltf(rtwdev, rtwsta_link, link_sta,
+ chan, &fix_giltf_en, &fix_giltf);
+ } else if (link_sta->vht_cap.vht_supported) {
+ u16 mcs_map = le16_to_cpu(link_sta->vht_cap.vht_mcs.rx_mcs_map);
mode |= RTW89_RA_MODE_VHT;
csi_mode = RTW89_RA_RPT_MODE_VHT;
- /* MCS9, MCS8, MCS7 */
- ra_mask |= get_mcs_ra_mask(mcs_map, 9, 1);
+ /* MCS9 (non-20MHz), MCS8, MCS7 */
+ if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20)
+ ra_mask |= get_mcs_ra_mask(mcs_map, 8, 1);
+ else
+ ra_mask |= get_mcs_ra_mask(mcs_map, 9, 1);
high_rate_masks = rtw89_ra_mask_vht_rates;
- if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
+ if (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
stbc_en = 1;
- if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)
+ if (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)
ldpc_en = 1;
- } else if (sta->deflink.ht_cap.ht_supported) {
+ } else if (link_sta->ht_cap.ht_supported) {
mode |= RTW89_RA_MODE_HT;
csi_mode = RTW89_RA_RPT_MODE_HT;
- ra_mask |= ((u64)sta->deflink.ht_cap.mcs.rx_mask[3] << 48) |
- ((u64)sta->deflink.ht_cap.mcs.rx_mask[2] << 36) |
- (sta->deflink.ht_cap.mcs.rx_mask[1] << 24) |
- (sta->deflink.ht_cap.mcs.rx_mask[0] << 12);
+ ra_mask |= ((u64)link_sta->ht_cap.mcs.rx_mask[3] << 48) |
+ ((u64)link_sta->ht_cap.mcs.rx_mask[2] << 36) |
+ ((u64)link_sta->ht_cap.mcs.rx_mask[1] << 24) |
+ ((u64)link_sta->ht_cap.mcs.rx_mask[0] << 12);
high_rate_masks = rtw89_ra_mask_ht_rates;
- if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
+ if (link_sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
stbc_en = 1;
- if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)
+ if (link_sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)
ldpc_en = 1;
}
switch (chan->band_type) {
case RTW89_BAND_2G:
- ra_mask |= sta->deflink.supp_rates[NL80211_BAND_2GHZ];
- if (sta->deflink.supp_rates[NL80211_BAND_2GHZ] & 0xf)
+ ra_mask |= link_sta->supp_rates[NL80211_BAND_2GHZ];
+ if (link_sta->supp_rates[NL80211_BAND_2GHZ] & 0xf)
mode |= RTW89_RA_MODE_CCK;
- if (sta->deflink.supp_rates[NL80211_BAND_2GHZ] & 0xff0)
+ if (link_sta->supp_rates[NL80211_BAND_2GHZ] & 0xff0)
mode |= RTW89_RA_MODE_OFDM;
break;
case RTW89_BAND_5G:
- ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4;
+ ra_mask |= (u64)link_sta->supp_rates[NL80211_BAND_5GHZ] << 4;
mode |= RTW89_RA_MODE_OFDM;
break;
case RTW89_BAND_6G:
- ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_6GHZ] << 4;
+ ra_mask |= (u64)link_sta->supp_rates[NL80211_BAND_6GHZ] << 4;
mode |= RTW89_RA_MODE_OFDM;
break;
default:
@@ -396,48 +423,48 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
ra_mask &= rtw89_phy_ra_mask_rssi(rtwdev, rssi, 0);
ra_mask = rtw89_phy_ra_mask_recover(ra_mask, ra_mask_bak);
- ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta, chan);
+ ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta_link, link_sta, chan);
- switch (sta->deflink.bandwidth) {
+ switch (link_sta->bandwidth) {
case IEEE80211_STA_RX_BW_160:
bw_mode = RTW89_CHANNEL_WIDTH_160;
- sgi = sta->deflink.vht_cap.vht_supported &&
- (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160);
+ sgi = link_sta->vht_cap.vht_supported &&
+ (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160);
break;
case IEEE80211_STA_RX_BW_80:
bw_mode = RTW89_CHANNEL_WIDTH_80;
- sgi = sta->deflink.vht_cap.vht_supported &&
- (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80);
+ sgi = link_sta->vht_cap.vht_supported &&
+ (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80);
break;
case IEEE80211_STA_RX_BW_40:
bw_mode = RTW89_CHANNEL_WIDTH_40;
- sgi = sta->deflink.ht_cap.ht_supported &&
- (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40);
+ sgi = link_sta->ht_cap.ht_supported &&
+ (link_sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40);
break;
default:
bw_mode = RTW89_CHANNEL_WIDTH_20;
- sgi = sta->deflink.ht_cap.ht_supported &&
- (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20);
+ sgi = link_sta->ht_cap.ht_supported &&
+ (link_sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20);
break;
}
- if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[3] &
+ if (link_sta->he_cap.he_cap_elem.phy_cap_info[3] &
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM)
ra->dcm_cap = 1;
- if (rate_pattern->enable && !vif->p2p) {
- ra_mask = rtw89_phy_ra_mask_cfg(rtwdev, rtwsta, chan);
+ if (rate_pattern->enable && !p2p) {
+ ra_mask = rtw89_phy_ra_mask_cfg(rtwdev, rtwsta_link, link_sta, chan);
ra_mask &= rate_pattern->ra_mask;
mode = rate_pattern->ra_mode;
}
ra->bw_cap = bw_mode;
- ra->er_cap = rtwsta->er_cap;
+ ra->er_cap = rtwsta_link->er_cap;
ra->mode_ctrl = mode;
- ra->macid = rtwsta->mac_id;
+ ra->macid = rtwsta_link->mac_id;
ra->stbc_cap = stbc_en;
ra->ldpc_cap = ldpc_en;
- ra->ss_num = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1;
+ ra->ss_num = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1;
ra->en_sgi = sgi;
ra->ra_mask = ra_mask;
ra->fix_giltf_en = fix_giltf_en;
@@ -449,20 +476,29 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
ra->fixed_csi_rate_en = false;
ra->ra_csi_rate_en = true;
ra->cr_tbl_sel = false;
- ra->band_num = rtwvif->phy_idx;
+ ra->band_num = rtwvif_link->phy_idx;
ra->csi_bw = bw_mode;
ra->csi_gi_ltf = RTW89_GILTF_LGI_4XHE32;
ra->csi_mcs_ss_idx = 5;
ra->csi_mode = csi_mode;
}
-void rtw89_phy_ra_updata_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta,
- u32 changed)
+void rtw89_phy_ra_update_sta_link(struct rtw89_dev *rtwdev,
+ struct rtw89_sta_link *rtwsta_link,
+ u32 changed)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_ra_info *ra = &rtwsta->ra;
+ struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_ra_info *ra = &rtwsta_link->ra;
+ struct ieee80211_link_sta *link_sta;
+
+ rcu_read_lock();
- rtw89_phy_ra_sta_update(rtwdev, sta, false);
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
+ rtw89_phy_ra_sta_update(rtwdev, rtwvif_link, rtwsta_link,
+ link_sta, vif->p2p, false);
+
+ rcu_read_unlock();
if (changed & IEEE80211_RC_SUPP_RATES_CHANGED)
ra->upd_mask = 1;
@@ -480,6 +516,17 @@ void rtw89_phy_ra_updata_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta
rtw89_fw_h2c_ra(rtwdev, ra, false);
}
+void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta,
+ u32 changed)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id)
+ rtw89_phy_ra_update_sta_link(rtwdev, rtwsta_link, changed);
+}
+
static bool __check_rate_pattern(struct rtw89_phy_rate_pattern *next,
u16 rate_base, u64 ra_mask, u8 ra_mode,
u32 rate_ctrl, u32 ctrl_skip, bool force)
@@ -514,15 +561,15 @@ static bool __check_rate_pattern(struct rtw89_phy_rate_pattern *next,
[RTW89_CHIP_BE] = RTW89_HW_RATE_V1_ ## rate, \
}
-void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif,
- const struct cfg80211_bitrate_mask *mask)
+static
+void __rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ const struct cfg80211_bitrate_mask *mask)
{
struct ieee80211_supported_band *sband;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_phy_rate_pattern next_pattern = {0};
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->sub_entity_idx);
+ rtwvif_link->chanctx_idx);
static const u16 hw_rate_he[][RTW89_CHIP_GEN_NUM] = {
RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS1_MCS0),
RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS2_MCS0),
@@ -591,7 +638,7 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
if (!next_pattern.enable)
goto out;
- rtwvif->rate_pattern = next_pattern;
+ rtwvif_link->rate_pattern = next_pattern;
rtw89_debug(rtwdev, RTW89_DBG_RA,
"configure pattern: rate 0x%x, mask 0x%llx, mode 0x%x\n",
next_pattern.rate,
@@ -600,32 +647,54 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
return;
out:
- rtwvif->rate_pattern.enable = false;
+ rtwvif_link->rate_pattern.enable = false;
rtw89_debug(rtwdev, RTW89_DBG_RA, "unset rate pattern\n");
}
-static void rtw89_phy_ra_updata_sta_iter(void *data, struct ieee80211_sta *sta)
+void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
+ struct ieee80211_vif *vif,
+ const struct cfg80211_bitrate_mask *mask)
+{
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ __rtw89_phy_rate_pattern_vif(rtwdev, rtwvif_link, mask);
+}
+
+static void rtw89_phy_ra_update_sta_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_dev *rtwdev = (struct rtw89_dev *)data;
- rtw89_phy_ra_updata_sta(rtwdev, sta, IEEE80211_RC_SUPP_RATES_CHANGED);
+ rtw89_phy_ra_update_sta(rtwdev, sta, IEEE80211_RC_SUPP_RATES_CHANGED);
}
void rtw89_phy_ra_update(struct rtw89_dev *rtwdev)
{
ieee80211_iterate_stations_atomic(rtwdev->hw,
- rtw89_phy_ra_updata_sta_iter,
+ rtw89_phy_ra_update_sta_iter,
rtwdev);
}
-void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta)
+void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_ra_info *ra = &rtwsta->ra;
- u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi) >> RSSI_FACTOR;
- bool csi = rtw89_sta_has_beamformer_cap(sta);
+ struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link;
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_ra_info *ra = &rtwsta_link->ra;
+ u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR;
+ struct ieee80211_link_sta *link_sta;
+ bool csi;
+
+ rcu_read_lock();
+
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
+ csi = rtw89_sta_has_beamformer_cap(link_sta);
+
+ rtw89_phy_ra_sta_update(rtwdev, rtwvif_link, rtwsta_link,
+ link_sta, vif->p2p, csi);
- rtw89_phy_ra_sta_update(rtwdev, sta, csi);
+ rcu_read_unlock();
if (rssi > 40)
ra->init_rate_lv = 1;
@@ -1059,14 +1128,21 @@ static bool rtw89_chip_rf_v1(struct rtw89_dev *rtwdev)
return rtwdev->chip->ops->write_rf == rtw89_phy_write_rf_v1;
}
-static void rtw89_phy_bb_reset(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx)
+static void __rtw89_phy_bb_reset(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
chip->ops->bb_reset(rtwdev, phy_idx);
}
+static void rtw89_phy_bb_reset(struct rtw89_dev *rtwdev)
+{
+ __rtw89_phy_bb_reset(rtwdev, RTW89_PHY_0);
+ if (rtwdev->dbcc_en)
+ __rtw89_phy_bb_reset(rtwdev, RTW89_PHY_1);
+}
+
static void rtw89_phy_config_bb_reg(struct rtw89_dev *rtwdev,
const struct rtw89_reg2_def *reg,
enum rtw89_rf_path rf_path,
@@ -1612,13 +1688,15 @@ void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev)
if (rtwdev->dbcc_en)
rtw89_phy_init_reg(rtwdev, bb_table, rtw89_phy_config_bb_reg,
(void *)RTW89_PHY_1);
- rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_0);
+
+ rtw89_chip_init_txpwr_unit(rtwdev);
bb_gain_table = elm_info->bb_gain ? elm_info->bb_gain : chip->bb_gain_table;
if (bb_gain_table)
rtw89_phy_init_reg(rtwdev, bb_gain_table,
chip->phy_def->config_bb_gain, NULL);
- rtw89_phy_bb_reset(rtwdev, RTW89_PHY_0);
+
+ rtw89_phy_bb_reset(rtwdev);
}
static u32 rtw89_phy_nctl_poll(struct rtw89_dev *rtwdev)
@@ -1671,7 +1749,7 @@ static void rtw89_phy_preinit_rf_nctl_ax(struct rtw89_dev *rtwdev)
rtw89_phy_write32_set(rtwdev, R_P0_PATH_RST, 0x8000000);
if (chip->chip_id != RTL8851B)
rtw89_phy_write32_set(rtwdev, R_P1_PATH_RST, 0x8000000);
- if (chip->chip_id == RTL8852B)
+ if (chip->chip_id == RTL8852B || chip->chip_id == RTL8852BT)
rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, 0x2);
/* check 0x8080 */
@@ -1738,6 +1816,24 @@ void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
}
EXPORT_SYMBOL(rtw89_phy_write32_idx);
+void rtw89_phy_write32_idx_set(struct rtw89_dev *rtwdev, u32 addr, u32 bits,
+ enum rtw89_phy_idx phy_idx)
+{
+ if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1)
+ addr += rtw89_phy0_phy1_offset(rtwdev, addr);
+ rtw89_phy_write32_set(rtwdev, addr, bits);
+}
+EXPORT_SYMBOL(rtw89_phy_write32_idx_set);
+
+void rtw89_phy_write32_idx_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bits,
+ enum rtw89_phy_idx phy_idx)
+{
+ if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1)
+ addr += rtw89_phy0_phy1_offset(rtwdev, addr);
+ rtw89_phy_write32_clr(rtwdev, addr, bits);
+}
+EXPORT_SYMBOL(rtw89_phy_write32_idx_clr);
+
u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
enum rtw89_phy_idx phy_idx)
{
@@ -1772,6 +1868,243 @@ void rtw89_phy_write_reg3_tbl(struct rtw89_dev *rtwdev,
}
EXPORT_SYMBOL(rtw89_phy_write_reg3_tbl);
+static u8 rtw89_phy_ant_gain_domain_to_regd(struct rtw89_dev *rtwdev, u8 ant_gain_regd)
+{
+ switch (ant_gain_regd) {
+ case RTW89_ANT_GAIN_ETSI:
+ return RTW89_ETSI;
+ default:
+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
+ "unknown antenna gain domain: %d\n",
+ ant_gain_regd);
+ return RTW89_REGD_NUM;
+ }
+}
+
+/* antenna gain in unit of 0.25 dbm */
+#define RTW89_ANT_GAIN_2GHZ_MIN -8
+#define RTW89_ANT_GAIN_2GHZ_MAX 14
+#define RTW89_ANT_GAIN_5GHZ_MIN -8
+#define RTW89_ANT_GAIN_5GHZ_MAX 20
+#define RTW89_ANT_GAIN_6GHZ_MIN -8
+#define RTW89_ANT_GAIN_6GHZ_MAX 20
+
+#define RTW89_ANT_GAIN_REF_2GHZ 14
+#define RTW89_ANT_GAIN_REF_5GHZ 20
+#define RTW89_ANT_GAIN_REF_6GHZ 20
+
+void rtw89_phy_ant_gain_init(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct rtw89_acpi_rtag_result res = {};
+ u32 domain;
+ int ret;
+ u8 i, j;
+ u8 regd;
+ u8 val;
+
+ if (!chip->support_ant_gain)
+ return;
+
+ ret = rtw89_acpi_evaluate_rtag(rtwdev, &res);
+ if (ret) {
+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
+ "acpi: cannot eval rtag: %d\n", ret);
+ return;
+ }
+
+ if (res.revision != 0) {
+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
+ "unknown rtag revision: %d\n", res.revision);
+ return;
+ }
+
+ domain = get_unaligned_le32(&res.domain);
+
+ for (i = 0; i < RTW89_ANT_GAIN_DOMAIN_NUM; i++) {
+ if (!(domain & BIT(i)))
+ continue;
+
+ regd = rtw89_phy_ant_gain_domain_to_regd(rtwdev, i);
+ if (regd >= RTW89_REGD_NUM)
+ continue;
+ ant_gain->regd_enabled |= BIT(regd);
+ }
+
+ for (i = 0; i < RTW89_ANT_GAIN_CHAIN_NUM; i++) {
+ for (j = 0; j < RTW89_ANT_GAIN_SUBBAND_NR; j++) {
+ val = res.ant_gain_table[i][j];
+ switch (j) {
+ default:
+ case RTW89_ANT_GAIN_2GHZ_SUBBAND:
+ val = RTW89_ANT_GAIN_REF_2GHZ -
+ clamp_t(s8, val,
+ RTW89_ANT_GAIN_2GHZ_MIN,
+ RTW89_ANT_GAIN_2GHZ_MAX);
+ break;
+ case RTW89_ANT_GAIN_5GHZ_SUBBAND_1:
+ case RTW89_ANT_GAIN_5GHZ_SUBBAND_2:
+ case RTW89_ANT_GAIN_5GHZ_SUBBAND_2E:
+ case RTW89_ANT_GAIN_5GHZ_SUBBAND_3_4:
+ val = RTW89_ANT_GAIN_REF_5GHZ -
+ clamp_t(s8, val,
+ RTW89_ANT_GAIN_5GHZ_MIN,
+ RTW89_ANT_GAIN_5GHZ_MAX);
+ break;
+ case RTW89_ANT_GAIN_6GHZ_SUBBAND_5_L:
+ case RTW89_ANT_GAIN_6GHZ_SUBBAND_5_H:
+ case RTW89_ANT_GAIN_6GHZ_SUBBAND_6:
+ case RTW89_ANT_GAIN_6GHZ_SUBBAND_7_L:
+ case RTW89_ANT_GAIN_6GHZ_SUBBAND_7_H:
+ case RTW89_ANT_GAIN_6GHZ_SUBBAND_8:
+ val = RTW89_ANT_GAIN_REF_6GHZ -
+ clamp_t(s8, val,
+ RTW89_ANT_GAIN_6GHZ_MIN,
+ RTW89_ANT_GAIN_6GHZ_MAX);
+ }
+ ant_gain->offset[i][j] = val;
+ }
+ }
+}
+
+static
+enum rtw89_ant_gain_subband rtw89_phy_ant_gain_get_subband(struct rtw89_dev *rtwdev,
+ u32 center_freq)
+{
+ switch (center_freq) {
+ default:
+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
+ "center freq: %u to antenna gain subband is unhandled\n",
+ center_freq);
+ fallthrough;
+ case 2412 ... 2484:
+ return RTW89_ANT_GAIN_2GHZ_SUBBAND;
+ case 5180 ... 5240:
+ return RTW89_ANT_GAIN_5GHZ_SUBBAND_1;
+ case 5250 ... 5320:
+ return RTW89_ANT_GAIN_5GHZ_SUBBAND_2;
+ case 5500 ... 5720:
+ return RTW89_ANT_GAIN_5GHZ_SUBBAND_2E;
+ case 5745 ... 5885:
+ return RTW89_ANT_GAIN_5GHZ_SUBBAND_3_4;
+ case 5955 ... 6155:
+ return RTW89_ANT_GAIN_6GHZ_SUBBAND_5_L;
+ case 6175 ... 6415:
+ return RTW89_ANT_GAIN_6GHZ_SUBBAND_5_H;
+ case 6435 ... 6515:
+ return RTW89_ANT_GAIN_6GHZ_SUBBAND_6;
+ case 6535 ... 6695:
+ return RTW89_ANT_GAIN_6GHZ_SUBBAND_7_L;
+ case 6715 ... 6855:
+ return RTW89_ANT_GAIN_6GHZ_SUBBAND_7_H;
+
+ /* freq 6875 (ch 185, 20MHz) spans RTW89_ANT_GAIN_6GHZ_SUBBAND_7_H
+ * and RTW89_ANT_GAIN_6GHZ_SUBBAND_8, so directly describe it with
+ * struct rtw89_6ghz_span.
+ */
+
+ case 6895 ... 7115:
+ return RTW89_ANT_GAIN_6GHZ_SUBBAND_8;
+ }
+}
+
+static s8 rtw89_phy_ant_gain_query(struct rtw89_dev *rtwdev,
+ enum rtw89_rf_path path, u32 center_freq)
+{
+ struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain;
+ enum rtw89_ant_gain_subband subband_l, subband_h;
+ const struct rtw89_6ghz_span *span;
+
+ span = rtw89_get_6ghz_span(rtwdev, center_freq);
+
+ if (span && RTW89_ANT_GAIN_SPAN_VALID(span)) {
+ subband_l = span->ant_gain_subband_low;
+ subband_h = span->ant_gain_subband_high;
+ } else {
+ subband_l = rtw89_phy_ant_gain_get_subband(rtwdev, center_freq);
+ subband_h = subband_l;
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
+ "center_freq %u: antenna gain subband {%u, %u}\n",
+ center_freq, subband_l, subband_h);
+
+ return min(ant_gain->offset[path][subband_l],
+ ant_gain->offset[path][subband_h]);
+}
+
+static s8 rtw89_phy_ant_gain_offset(struct rtw89_dev *rtwdev, u32 center_freq)
+{
+ s8 offset_patha, offset_pathb;
+
+ offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, center_freq);
+ offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, center_freq);
+
+ if (RTW89_CHK_FW_FEATURE(NO_POWER_DIFFERENCE, &rtwdev->fw))
+ return min(offset_patha, offset_pathb);
+
+ return max(offset_patha, offset_pathb);
+}
+
+static bool rtw89_can_apply_ant_gain(struct rtw89_dev *rtwdev, u8 band)
+{
+ const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
+ struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ u8 regd = rtw89_regd_get(rtwdev, band);
+
+ if (!chip->support_ant_gain)
+ return false;
+
+ if (ant_gain->block_country || !(ant_gain->regd_enabled & BIT(regd)))
+ return false;
+
+ if (!rfe_parms->has_da)
+ return false;
+
+ return true;
+}
+
+s16 rtw89_phy_ant_gain_pwr_offset(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan)
+{
+ s8 offset_patha, offset_pathb;
+
+ if (!rtw89_can_apply_ant_gain(rtwdev, chan->band_type))
+ return 0;
+
+ if (RTW89_CHK_FW_FEATURE(NO_POWER_DIFFERENCE, &rtwdev->fw))
+ return 0;
+
+ offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, chan->freq);
+ offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, chan->freq);
+
+ return rtw89_phy_txpwr_rf_to_bb(rtwdev, offset_patha - offset_pathb);
+}
+EXPORT_SYMBOL(rtw89_phy_ant_gain_pwr_offset);
+
+int rtw89_print_ant_gain(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
+ const struct rtw89_chan *chan)
+{
+ char *p = buf, *end = buf + bufsz;
+ s8 offset_patha, offset_pathb;
+
+ if (!rtw89_can_apply_ant_gain(rtwdev, chan->band_type)) {
+ p += scnprintf(p, end - p, "no DAG is applied\n");
+ goto out;
+ }
+
+ offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, chan->freq);
+ offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, chan->freq);
+
+ p += scnprintf(p, end - p, "ChainA offset: %d dBm\n", offset_patha);
+ p += scnprintf(p, end - p, "ChainB offset: %d dBm\n", offset_pathb);
+
+out:
+ return p - buf;
+}
+
static const u8 rtw89_rs_idx_num_ax[] = {
[RTW89_RS_CCK] = RTW89_RATE_CCK_NUM,
[RTW89_RS_OFDM] = RTW89_RATE_OFDM_NUM,
@@ -1835,11 +2168,27 @@ void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev,
}
EXPORT_SYMBOL(rtw89_phy_load_txpwr_byrate);
-static s8 rtw89_phy_txpwr_rf_to_mac(struct rtw89_dev *rtwdev, s8 txpwr_rf)
+static s8 rtw89_phy_txpwr_dbm_without_tolerance(s8 dbm)
{
- const struct rtw89_chip_info *chip = rtwdev->chip;
+ const u8 tssi_deviation_point = 0;
+ const u8 tssi_max_deviation = 2;
+
+ if (dbm <= tssi_deviation_point)
+ dbm -= tssi_max_deviation;
+
+ return dbm;
+}
- return txpwr_rf >> (chip->txpwr_factor_rf - chip->txpwr_factor_mac);
+static s8 rtw89_phy_get_tpe_constraint(struct rtw89_dev *rtwdev, u8 band)
+{
+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ const struct rtw89_reg_6ghz_tpe *tpe = &regulatory->reg_6ghz_tpe;
+ s8 cstr = S8_MAX;
+
+ if (band == RTW89_BAND_6G && tpe->valid)
+ cstr = rtw89_phy_txpwr_dbm_without_tolerance(tpe->constraint);
+
+ return rtw89_phy_txpwr_dbm_to_mac(rtwdev, cstr);
}
s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band, u8 bw,
@@ -1906,19 +2255,31 @@ s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch)
{
const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
+ const struct rtw89_txpwr_rule_2ghz *rule_da_2ghz = &rfe_parms->rule_da_2ghz;
+ const struct rtw89_txpwr_rule_5ghz *rule_da_5ghz = &rfe_parms->rule_da_5ghz;
+ const struct rtw89_txpwr_rule_6ghz *rule_da_6ghz = &rfe_parms->rule_da_6ghz;
const struct rtw89_txpwr_rule_2ghz *rule_2ghz = &rfe_parms->rule_2ghz;
const struct rtw89_txpwr_rule_5ghz *rule_5ghz = &rfe_parms->rule_5ghz;
const struct rtw89_txpwr_rule_6ghz *rule_6ghz = &rfe_parms->rule_6ghz;
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
+ bool has_ant_gain = rtw89_can_apply_ant_gain(rtwdev, band);
u32 freq = ieee80211_channel_to_frequency(ch, nl_band);
u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch);
+ s8 lmt = 0, da_lmt = S8_MAX, sar, offset = 0;
u8 regd = rtw89_regd_get(rtwdev, band);
u8 reg6 = regulatory->reg_6ghz_power;
- s8 lmt = 0, sar;
+ struct rtw89_sar_parm sar_parm = {
+ .center_freq = freq,
+ .ntx = ntx,
+ };
+ s8 cstr;
switch (band) {
case RTW89_BAND_2G:
+ if (has_ant_gain)
+ da_lmt = (*rule_da_2ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx];
+
lmt = (*rule_2ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx];
if (lmt)
break;
@@ -1926,6 +2287,9 @@ s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
lmt = (*rule_2ghz->lmt)[bw][ntx][rs][bf][RTW89_WW][ch_idx];
break;
case RTW89_BAND_5G:
+ if (has_ant_gain)
+ da_lmt = (*rule_da_5ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx];
+
lmt = (*rule_5ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx];
if (lmt)
break;
@@ -1933,6 +2297,9 @@ s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
lmt = (*rule_5ghz->lmt)[bw][ntx][rs][bf][RTW89_WW][ch_idx];
break;
case RTW89_BAND_6G:
+ if (has_ant_gain)
+ da_lmt = (*rule_da_6ghz->lmt)[bw][ntx][rs][bf][regd][reg6][ch_idx];
+
lmt = (*rule_6ghz->lmt)[bw][ntx][rs][bf][regd][reg6][ch_idx];
if (lmt)
break;
@@ -1946,10 +2313,15 @@ s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
return 0;
}
- lmt = rtw89_phy_txpwr_rf_to_mac(rtwdev, lmt);
- sar = rtw89_query_sar(rtwdev, freq);
+ da_lmt = da_lmt ?: S8_MAX;
+ if (da_lmt != S8_MAX)
+ offset = rtw89_phy_ant_gain_offset(rtwdev, freq);
+
+ lmt = rtw89_phy_txpwr_rf_to_mac(rtwdev, min(lmt + offset, da_lmt));
+ sar = rtw89_query_sar(rtwdev, &sar_parm);
+ cstr = rtw89_phy_get_tpe_constraint(rtwdev, band);
- return min(lmt, sar);
+ return min3(lmt, sar, cstr);
}
EXPORT_SYMBOL(rtw89_phy_read_txpwr_limit);
@@ -2163,19 +2535,31 @@ s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, u8 band,
u8 ru, u8 ntx, u8 ch)
{
const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
+ const struct rtw89_txpwr_rule_2ghz *rule_da_2ghz = &rfe_parms->rule_da_2ghz;
+ const struct rtw89_txpwr_rule_5ghz *rule_da_5ghz = &rfe_parms->rule_da_5ghz;
+ const struct rtw89_txpwr_rule_6ghz *rule_da_6ghz = &rfe_parms->rule_da_6ghz;
const struct rtw89_txpwr_rule_2ghz *rule_2ghz = &rfe_parms->rule_2ghz;
const struct rtw89_txpwr_rule_5ghz *rule_5ghz = &rfe_parms->rule_5ghz;
const struct rtw89_txpwr_rule_6ghz *rule_6ghz = &rfe_parms->rule_6ghz;
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
+ bool has_ant_gain = rtw89_can_apply_ant_gain(rtwdev, band);
u32 freq = ieee80211_channel_to_frequency(ch, nl_band);
u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch);
+ s8 lmt_ru = 0, da_lmt_ru = S8_MAX, sar, offset = 0;
u8 regd = rtw89_regd_get(rtwdev, band);
u8 reg6 = regulatory->reg_6ghz_power;
- s8 lmt_ru = 0, sar;
+ struct rtw89_sar_parm sar_parm = {
+ .center_freq = freq,
+ .ntx = ntx,
+ };
+ s8 cstr;
switch (band) {
case RTW89_BAND_2G:
+ if (has_ant_gain)
+ da_lmt_ru = (*rule_da_2ghz->lmt_ru)[ru][ntx][regd][ch_idx];
+
lmt_ru = (*rule_2ghz->lmt_ru)[ru][ntx][regd][ch_idx];
if (lmt_ru)
break;
@@ -2183,6 +2567,9 @@ s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, u8 band,
lmt_ru = (*rule_2ghz->lmt_ru)[ru][ntx][RTW89_WW][ch_idx];
break;
case RTW89_BAND_5G:
+ if (has_ant_gain)
+ da_lmt_ru = (*rule_da_5ghz->lmt_ru)[ru][ntx][regd][ch_idx];
+
lmt_ru = (*rule_5ghz->lmt_ru)[ru][ntx][regd][ch_idx];
if (lmt_ru)
break;
@@ -2190,6 +2577,9 @@ s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, u8 band,
lmt_ru = (*rule_5ghz->lmt_ru)[ru][ntx][RTW89_WW][ch_idx];
break;
case RTW89_BAND_6G:
+ if (has_ant_gain)
+ da_lmt_ru = (*rule_da_6ghz->lmt_ru)[ru][ntx][regd][reg6][ch_idx];
+
lmt_ru = (*rule_6ghz->lmt_ru)[ru][ntx][regd][reg6][ch_idx];
if (lmt_ru)
break;
@@ -2203,10 +2593,15 @@ s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, u8 band,
return 0;
}
- lmt_ru = rtw89_phy_txpwr_rf_to_mac(rtwdev, lmt_ru);
- sar = rtw89_query_sar(rtwdev, freq);
+ da_lmt_ru = da_lmt_ru ?: S8_MAX;
+ if (da_lmt_ru != S8_MAX)
+ offset = rtw89_phy_ant_gain_offset(rtwdev, freq);
- return min(lmt_ru, sar);
+ lmt_ru = rtw89_phy_txpwr_rf_to_mac(rtwdev, min(lmt_ru + offset, da_lmt_ru));
+ sar = rtw89_query_sar(rtwdev, &sar_parm);
+ cstr = rtw89_phy_get_tpe_constraint(rtwdev, band);
+
+ return min3(lmt_ru, sar, cstr);
}
static void
@@ -2510,14 +2905,14 @@ struct rtw89_phy_iter_ra_data {
struct sk_buff *c2h;
};
-static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta)
+static void __rtw89_phy_c2h_ra_rpt_iter(struct rtw89_sta_link *rtwsta_link,
+ struct ieee80211_link_sta *link_sta,
+ struct rtw89_phy_iter_ra_data *ra_data)
{
- struct rtw89_phy_iter_ra_data *ra_data = (struct rtw89_phy_iter_ra_data *)data;
struct rtw89_dev *rtwdev = ra_data->rtwdev;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
const struct rtw89_c2h_ra_rpt *c2h =
(const struct rtw89_c2h_ra_rpt *)ra_data->c2h->data;
- struct rtw89_ra_report *ra_report = &rtwsta->ra_report;
+ struct rtw89_ra_report *ra_report = &rtwsta_link->ra_report;
const struct rtw89_chip_info *chip = rtwdev->chip;
bool format_v1 = chip->chip_gen == RTW89_CHIP_BE;
u8 mode, rate, bw, giltf, mac_id;
@@ -2527,7 +2922,7 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta)
u8 t;
mac_id = le32_get_bits(c2h->w2, RTW89_C2H_RA_RPT_W2_MACID);
- if (mac_id != rtwsta->mac_id)
+ if (mac_id != rtwsta_link->mac_id)
return;
rate = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_MCSNSS);
@@ -2618,8 +3013,26 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta)
u16_encode_bits(mode, RTW89_HW_RATE_MASK_MOD) |
u16_encode_bits(rate, RTW89_HW_RATE_MASK_VAL);
ra_report->might_fallback_legacy = mcs <= 2;
- sta->deflink.agg.max_rc_amsdu_len = get_max_amsdu_len(rtwdev, ra_report);
- rtwsta->max_agg_wait = sta->deflink.agg.max_rc_amsdu_len / 1500 - 1;
+ link_sta->agg.max_rc_amsdu_len = get_max_amsdu_len(rtwdev, ra_report);
+ rtwsta_link->max_agg_wait = link_sta->agg.max_rc_amsdu_len / 1500 - 1;
+}
+
+static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta)
+{
+ struct rtw89_phy_iter_ra_data *ra_data = (struct rtw89_phy_iter_ra_data *)data;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_sta_link *rtwsta_link;
+ struct ieee80211_link_sta *link_sta;
+ unsigned int link_id;
+
+ rcu_read_lock();
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
+ __rtw89_phy_c2h_ra_rpt_iter(rtwsta_link, link_sta, ra_data);
+ }
+
+ rcu_read_unlock();
}
static void
@@ -2642,6 +3055,35 @@ void (* const rtw89_phy_c2h_ra_handler[])(struct rtw89_dev *rtwdev,
[RTW89_PHY_C2H_FUNC_TXSTS] = NULL,
};
+static void
+rtw89_phy_c2h_lowrt_rty(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+}
+
+static void
+rtw89_phy_c2h_fw_scan_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+ const struct rtw89_c2h_fw_scan_rpt *c2h_rpt =
+ (const struct rtw89_c2h_fw_scan_rpt *)c2h->data;
+
+ rtw89_debug(rtwdev, RTW89_DBG_DIG,
+ "%s: band: %u, op_chan: %u, PD_low_bd(ofdm, cck): (-%d, %d), phy_idx: %u\n",
+ __func__, c2h_rpt->band, c2h_rpt->center_ch,
+ PD_LOWER_BOUND_BASE - (c2h_rpt->ofdm_pd_idx << 1),
+ c2h_rpt->cck_pd_idx, c2h_rpt->phy_idx);
+}
+
+static
+void (* const rtw89_phy_c2h_dm_handler[])(struct rtw89_dev *rtwdev,
+ struct sk_buff *c2h, u32 len) = {
+ [RTW89_PHY_C2H_DM_FUNC_FW_TEST] = NULL,
+ [RTW89_PHY_C2H_DM_FUNC_FW_TRIG_TX_RPT] = NULL,
+ [RTW89_PHY_C2H_DM_FUNC_SIGB] = NULL,
+ [RTW89_PHY_C2H_DM_FUNC_LOWRT_RTY] = rtw89_phy_c2h_lowrt_rty,
+ [RTW89_PHY_C2H_DM_FUNC_MCC_DIG] = NULL,
+ [RTW89_PHY_C2H_DM_FUNC_FW_SCAN] = rtw89_phy_c2h_fw_scan_rpt,
+};
+
static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
enum rtw89_phy_c2h_rfk_log_func func,
void *content, u16 len)
@@ -2649,9 +3091,85 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
struct rtw89_c2h_rf_txgapk_rpt_log *txgapk;
struct rtw89_c2h_rf_rxdck_rpt_log *rxdck;
struct rtw89_c2h_rf_dack_rpt_log *dack;
+ struct rtw89_c2h_rf_tssi_rpt_log *tssi;
struct rtw89_c2h_rf_dpk_rpt_log *dpk;
+ struct rtw89_c2h_rf_iqk_rpt_log *iqk;
+ int i, j, k;
switch (func) {
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_IQK:
+ if (len != sizeof(*iqk))
+ goto out;
+
+ iqk = content;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->is_iqk_init = %x\n", iqk->is_iqk_init);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->is_reload = %x\n", iqk->is_reload);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->is_nbiqk = %x\n", iqk->is_nbiqk);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->txiqk_en = %x\n", iqk->txiqk_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->rxiqk_en = %x\n", iqk->rxiqk_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->lok_en = %x\n", iqk->lok_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->iqk_xym_en = %x\n", iqk->iqk_xym_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->iqk_sram_en = %x\n", iqk->iqk_sram_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->iqk_fft_en = %x\n", iqk->iqk_fft_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->is_fw_iqk = %x\n", iqk->is_fw_iqk);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->is_iqk_enable = %x\n", iqk->is_iqk_enable);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->iqk_cfir_en = %x\n", iqk->iqk_cfir_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->thermal_rek_en = %x\n", iqk->thermal_rek_en);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->version = %x\n", iqk->version);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->phy = %x\n", iqk->phy);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->fwk_status = %x\n", iqk->fwk_status);
+
+ for (i = 0; i < 2; i++) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] ======== Path %x ========\n", i);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_band[%d] = %x\n",
+ i, iqk->iqk_band[i]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_ch[%d] = %x\n",
+ i, iqk->iqk_ch[i]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_bw[%d] = %x\n",
+ i, iqk->iqk_bw[i]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->lok_idac[%d] = %x\n",
+ i, le32_to_cpu(iqk->lok_idac[i]));
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->lok_vbuf[%d] = %x\n",
+ i, le32_to_cpu(iqk->lok_vbuf[i]));
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_tx_fail[%d] = %x\n",
+ i, iqk->iqk_tx_fail[i]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_rx_fail[%d] = %x\n",
+ i, iqk->iqk_rx_fail[i]);
+ for (j = 0; j < 4; j++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->rftxgain[%d][%d] = %x\n",
+ i, j, le32_to_cpu(iqk->rftxgain[i][j]));
+ for (j = 0; j < 4; j++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->tx_xym[%d][%d] = %x\n",
+ i, j, le32_to_cpu(iqk->tx_xym[i][j]));
+ for (j = 0; j < 4; j++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->rfrxgain[%d][%d] = %x\n",
+ i, j, le32_to_cpu(iqk->rfrxgain[i][j]));
+ for (j = 0; j < 4; j++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK] iqk->rx_xym[%d][%d] = %x\n",
+ i, j, le32_to_cpu(iqk->rx_xym[i][j]));
+ }
+ return;
case RTW89_PHY_C2H_RFK_LOG_FUNC_DPK:
if (len != sizeof(*dpk))
goto out;
@@ -2673,8 +3191,23 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
dack = content;
- rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ver=0x%x 0x%x\n",
- dack->fwdack_ver, dack->fwdack_rpt_ver);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]FWDACK SUMMARY!!!!!\n");
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]FWDACK ver = 0x%x, FWDACK rpt_ver = 0x%x, driver rpt_ver = 0x%x\n",
+ dack->fwdack_ver, dack->fwdack_info_ver, 0x2);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]timeout code = [0x%x 0x%x 0x%x 0x%x 0x%x]\n",
+ dack->addck_timeout, dack->cdack_timeout, dack->dadck_timeout,
+ dack->adgaink_timeout, dack->msbk_timeout);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]DACK fail = 0x%x\n", dack->dack_fail);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]S0 WBADCK = [0x%x]\n", dack->wbdck_d[0]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]S1 WBADCK = [0x%x]\n", dack->wbdck_d[1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]DRCK = [0x%x]\n", dack->rck_d);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 CDACK ic = [0x%x, 0x%x]\n",
dack->cdack_d[0][0][0], dack->cdack_d[0][0][1]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 CDACK qc = [0x%x, 0x%x]\n",
@@ -2685,13 +3218,17 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
dack->cdack_d[1][1][0], dack->cdack_d[1][1][1]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK ic = [0x%x, 0x%x]\n",
- dack->addck2_d[0][0][0], dack->addck2_d[0][0][1]);
+ ((u32)dack->addck2_hd[0][0][0] << 8) | dack->addck2_ld[0][0][0],
+ ((u32)dack->addck2_hd[0][0][1] << 8) | dack->addck2_ld[0][0][1]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK qc = [0x%x, 0x%x]\n",
- dack->addck2_d[0][1][0], dack->addck2_d[0][1][1]);
+ ((u32)dack->addck2_hd[0][1][0] << 8) | dack->addck2_ld[0][1][0],
+ ((u32)dack->addck2_hd[0][1][1] << 8) | dack->addck2_ld[0][1][1]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_DCK ic = [0x%x, 0x%x]\n",
- dack->addck2_d[1][0][0], dack->addck2_d[1][0][1]);
+ ((u32)dack->addck2_hd[1][0][0] << 8) | dack->addck2_ld[1][0][0],
+ ((u32)dack->addck2_hd[1][0][1] << 8) | dack->addck2_ld[1][0][1]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_DCK qc = [0x%x, 0x%x]\n",
- dack->addck2_d[1][1][0], dack->addck2_d[1][1][1]);
+ ((u32)dack->addck2_hd[1][1][0] << 8) | dack->addck2_ld[1][1][0],
+ ((u32)dack->addck2_hd[1][1][1] << 8) | dack->addck2_ld[1][1][1]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_GAINK ic = 0x%x, qc = 0x%x\n",
dack->adgaink_d[0][0], dack->adgaink_d[0][1]);
@@ -2704,18 +3241,29 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
dack->dadck_d[1][0], dack->dadck_d[1][1]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 biask iqc = 0x%x\n",
- dack->biask_d[0][0]);
+ ((u32)dack->biask_hd[0][0] << 8) | dack->biask_ld[0][0]);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 biask iqc = 0x%x\n",
- dack->biask_d[1][0]);
-
- rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic: %*ph\n",
- (int)sizeof(dack->msbk_d[0][0]), dack->msbk_d[0][0]);
- rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc: %*ph\n",
- (int)sizeof(dack->msbk_d[0][1]), dack->msbk_d[0][1]);
- rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic: %*ph\n",
- (int)sizeof(dack->msbk_d[1][0]), dack->msbk_d[1][0]);
- rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc: %*ph\n",
- (int)sizeof(dack->msbk_d[1][1]), dack->msbk_d[1][1]);
+ ((u32)dack->biask_hd[1][0] << 8) | dack->biask_ld[1][0]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n");
+ for (i = 0; i < 0x10; i++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n",
+ dack->msbk_d[0][0][i]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n");
+ for (i = 0; i < 0x10; i++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n",
+ dack->msbk_d[0][1][i]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n");
+ for (i = 0; i < 0x10; i++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n",
+ dack->msbk_d[1][0][i]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n");
+ for (i = 0; i < 0x10; i++)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n",
+ dack->msbk_d[1][1][i]);
return;
case RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK:
if (len != sizeof(*rxdck))
@@ -2727,6 +3275,39 @@ static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
rxdck->ver, rxdck->band, rxdck->bw, rxdck->ch,
rxdck->timeout);
return;
+ case RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI:
+ if (len != sizeof(*tssi))
+ goto out;
+
+ tssi = content;
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ for (k = 0; k < 4; k++) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI] alignment_power_cw_h[%d][%d][%d]=%d\n",
+ i, j, k, tssi->alignment_power_cw_h[i][j][k]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI] alignment_power_cw_l[%d][%d][%d]=%d\n",
+ i, j, k, tssi->alignment_power_cw_l[i][j][k]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI] alignment_power[%d][%d][%d]=%d\n",
+ i, j, k, tssi->alignment_power[i][j][k]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI] alignment_power_cw[%d][%d][%d]=%d\n",
+ i, j, k,
+ (tssi->alignment_power_cw_h[i][j][k] << 8) +
+ tssi->alignment_power_cw_l[i][j][k]);
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI] tssi_alimk_state[%d][%d]=%d\n",
+ i, j, tssi->tssi_alimk_state[i][j]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI] default_txagc_offset[%d]=%d\n",
+ j, tssi->default_txagc_offset[0][j]);
+ }
+ }
+ return;
case RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK:
if (len != sizeof(*txgapk))
goto out;
@@ -2955,10 +3536,40 @@ rtw89_phy_c2h_rfk_report_state(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u3
(int)(len - sizeof(report->hdr)), &report->state);
}
+static void
+rtw89_phy_c2h_rfk_log_tas_pwr(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
+{
+ const struct rtw89_c2h_rf_tas_info *rf_tas =
+ (const struct rtw89_c2h_rf_tas_info *)c2h->data;
+ const enum rtw89_sar_sources src = rtwdev->sar.src;
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+ u64 linear = 0;
+ u32 i, cur_idx;
+ s16 txpwr;
+
+ if (!tas->enable || src == RTW89_SAR_SOURCE_NONE)
+ return;
+
+ cur_idx = le32_to_cpu(rf_tas->cur_idx);
+ for (i = 0; i < cur_idx; i++) {
+ txpwr = (s16)le16_to_cpu(rf_tas->txpwr_history[i]);
+ linear += rtw89_db_quarter_to_linear(txpwr);
+
+ rtw89_debug(rtwdev, RTW89_DBG_SAR,
+ "tas: index: %u, txpwr: %d\n", i, txpwr);
+ }
+
+ if (cur_idx == 0)
+ tas->instant_txpwr = rtw89_db_to_linear(0);
+ else
+ tas->instant_txpwr = DIV_ROUND_DOWN_ULL(linear, cur_idx);
+}
+
static
void (* const rtw89_phy_c2h_rfk_report_handler[])(struct rtw89_dev *rtwdev,
struct sk_buff *c2h, u32 len) = {
[RTW89_PHY_C2H_RFK_REPORT_FUNC_STATE] = rtw89_phy_c2h_rfk_report_state,
+ [RTW89_PHY_C2H_RFK_LOG_TAS_PWR] = rtw89_phy_c2h_rfk_log_tas_pwr,
};
bool rtw89_phy_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func)
@@ -3008,15 +3619,15 @@ void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
handler = rtw89_phy_c2h_rfk_report_handler[func];
break;
case RTW89_PHY_C2H_CLASS_DM:
- if (func == RTW89_PHY_C2H_DM_FUNC_LOWRT_RTY)
- return;
- fallthrough;
+ if (func < ARRAY_SIZE(rtw89_phy_c2h_dm_handler))
+ handler = rtw89_phy_c2h_dm_handler[func];
+ break;
default:
- rtw89_info(rtwdev, "c2h class %d not support\n", class);
+ rtw89_info(rtwdev, "PHY c2h class %d not support\n", class);
return;
}
if (!handler) {
- rtw89_info(rtwdev, "c2h class %d func %d not support\n", class,
+ rtw89_info(rtwdev, "PHY c2h class %d func %d not support\n", class,
func);
return;
}
@@ -3041,6 +3652,7 @@ EXPORT_SYMBOL(rtw89_phy_rfk_pre_ntfy_and_wait);
int rtw89_phy_rfk_tssi_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan,
enum rtw89_tssi_mode tssi_mode,
unsigned int ms)
{
@@ -3048,7 +3660,7 @@ int rtw89_phy_rfk_tssi_and_wait(struct rtw89_dev *rtwdev,
rtw89_phy_rfk_report_prep(rtwdev);
- ret = rtw89_fw_h2c_rf_tssi(rtwdev, phy_idx, tssi_mode);
+ ret = rtw89_fw_h2c_rf_tssi(rtwdev, phy_idx, chan, tssi_mode);
if (ret)
return ret;
@@ -3058,13 +3670,14 @@ EXPORT_SYMBOL(rtw89_phy_rfk_tssi_and_wait);
int rtw89_phy_rfk_iqk_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan,
unsigned int ms)
{
int ret;
rtw89_phy_rfk_report_prep(rtwdev);
- ret = rtw89_fw_h2c_rf_iqk(rtwdev, phy_idx);
+ ret = rtw89_fw_h2c_rf_iqk(rtwdev, phy_idx, chan);
if (ret)
return ret;
@@ -3074,13 +3687,14 @@ EXPORT_SYMBOL(rtw89_phy_rfk_iqk_and_wait);
int rtw89_phy_rfk_dpk_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan,
unsigned int ms)
{
int ret;
rtw89_phy_rfk_report_prep(rtwdev);
- ret = rtw89_fw_h2c_rf_dpk(rtwdev, phy_idx);
+ ret = rtw89_fw_h2c_rf_dpk(rtwdev, phy_idx, chan);
if (ret)
return ret;
@@ -3090,13 +3704,14 @@ EXPORT_SYMBOL(rtw89_phy_rfk_dpk_and_wait);
int rtw89_phy_rfk_txgapk_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan,
unsigned int ms)
{
int ret;
rtw89_phy_rfk_report_prep(rtwdev);
- ret = rtw89_fw_h2c_rf_txgapk(rtwdev, phy_idx);
+ ret = rtw89_fw_h2c_rf_txgapk(rtwdev, phy_idx, chan);
if (ret)
return ret;
@@ -3106,13 +3721,14 @@ EXPORT_SYMBOL(rtw89_phy_rfk_txgapk_and_wait);
int rtw89_phy_rfk_dack_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan,
unsigned int ms)
{
int ret;
rtw89_phy_rfk_report_prep(rtwdev);
- ret = rtw89_fw_h2c_rf_dack(rtwdev, phy_idx);
+ ret = rtw89_fw_h2c_rf_dack(rtwdev, phy_idx, chan);
if (ret)
return ret;
@@ -3122,13 +3738,14 @@ EXPORT_SYMBOL(rtw89_phy_rfk_dack_and_wait);
int rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
- unsigned int ms)
+ const struct rtw89_chan *chan,
+ bool is_chl_k, unsigned int ms)
{
int ret;
rtw89_phy_rfk_report_prep(rtwdev);
- ret = rtw89_fw_h2c_rf_rxdck(rtwdev, phy_idx);
+ ret = rtw89_fw_h2c_rf_rxdck(rtwdev, phy_idx, chan, is_chl_k);
if (ret)
return ret;
@@ -3779,7 +4396,6 @@ static void rtw89_phy_cfo_set_crystal_cap(struct rtw89_dev *rtwdev,
if (!force && cfo->crystal_cap == crystal_cap)
return;
- crystal_cap = clamp_t(u8, crystal_cap, 0, 127);
if (chip->chip_id == RTL8852A || chip->chip_id == RTL8851B) {
rtw89_phy_cfo_set_xcap_reg(rtwdev, true, crystal_cap);
rtw89_phy_cfo_set_xcap_reg(rtwdev, false, crystal_cap);
@@ -3902,7 +4518,7 @@ static void rtw89_phy_cfo_crystal_cap_adjust(struct rtw89_dev *rtwdev,
s32 curr_cfo)
{
struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
- s8 crystal_cap = cfo->crystal_cap;
+ int crystal_cap = cfo->crystal_cap;
s32 cfo_abs = abs(curr_cfo);
int sign;
@@ -3923,15 +4539,17 @@ static void rtw89_phy_cfo_crystal_cap_adjust(struct rtw89_dev *rtwdev,
}
sign = curr_cfo > 0 ? 1 : -1;
if (cfo_abs > CFO_TRK_STOP_TH_4)
- crystal_cap += 7 * sign;
+ crystal_cap += 3 * sign;
else if (cfo_abs > CFO_TRK_STOP_TH_3)
- crystal_cap += 5 * sign;
- else if (cfo_abs > CFO_TRK_STOP_TH_2)
crystal_cap += 3 * sign;
+ else if (cfo_abs > CFO_TRK_STOP_TH_2)
+ crystal_cap += 1 * sign;
else if (cfo_abs > CFO_TRK_STOP_TH_1)
crystal_cap += 1 * sign;
else
return;
+
+ crystal_cap = clamp(crystal_cap, 0, 127);
rtw89_phy_cfo_set_crystal_cap(rtwdev, (u8)crystal_cap, false);
rtw89_debug(rtwdev, RTW89_DBG_CFO,
"X_cap{Curr,Default}={0x%x,0x%x}\n",
@@ -4090,7 +4708,7 @@ static void rtw89_phy_cfo_dm(struct rtw89_dev *rtwdev)
cfo->dcfo_avg = 0;
rtw89_debug(rtwdev, RTW89_DBG_CFO, "CFO:total_sta_assoc=%d\n",
rtwdev->total_sta_assoc);
- if (rtwdev->total_sta_assoc == 0) {
+ if (rtwdev->total_sta_assoc == 0 || rtw89_is_mlo_1_1(rtwdev)) {
rtw89_phy_cfo_reset(rtwdev);
return;
}
@@ -4141,29 +4759,28 @@ static void rtw89_phy_cfo_dm(struct rtw89_dev *rtwdev)
rtw89_phy_cfo_statistics_reset(rtwdev);
}
-void rtw89_phy_cfo_track_work(struct work_struct *work)
+void rtw89_phy_cfo_track_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
cfo_track_work.work);
struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(wiphy);
+
if (!cfo->cfo_trig_by_timer_en)
- goto out;
+ return;
rtw89_leave_ps_mode(rtwdev);
rtw89_phy_cfo_dm(rtwdev);
- ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->cfo_track_work,
- msecs_to_jiffies(cfo->cfo_timer_ms));
-out:
- mutex_unlock(&rtwdev->mutex);
+ wiphy_delayed_work_queue(wiphy, &rtwdev->cfo_track_work,
+ msecs_to_jiffies(cfo->cfo_timer_ms));
}
static void rtw89_phy_cfo_start_work(struct rtw89_dev *rtwdev)
{
struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
- ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->cfo_track_work,
- msecs_to_jiffies(cfo->cfo_timer_ms));
+ wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->cfo_track_work,
+ msecs_to_jiffies(cfo->cfo_timer_ms));
}
void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev)
@@ -4241,33 +4858,33 @@ void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val,
cfo->packet_count++;
}
-void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
- rtwvif->sub_entity_idx);
+ rtwvif_link->chanctx_idx);
struct rtw89_phy_ul_tb_info *ul_tb_info = &rtwdev->ul_tb_info;
if (!chip->ul_tb_waveform_ctrl)
return;
- rtwvif->def_tri_idx =
+ rtwvif_link->def_tri_idx =
rtw89_phy_read32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG);
if (chip->chip_id == RTL8852B && rtwdev->hal.cv > CHIP_CBV)
- rtwvif->dyn_tb_bedge_en = false;
+ rtwvif_link->dyn_tb_bedge_en = false;
else if (chan->band_type >= RTW89_BAND_5G &&
chan->band_width >= RTW89_CHANNEL_WIDTH_40)
- rtwvif->dyn_tb_bedge_en = true;
+ rtwvif_link->dyn_tb_bedge_en = true;
else
- rtwvif->dyn_tb_bedge_en = false;
+ rtwvif_link->dyn_tb_bedge_en = false;
rtw89_debug(rtwdev, RTW89_DBG_UL_TB,
"[ULTB] def_if_bandedge=%d, def_tri_idx=%d\n",
- ul_tb_info->def_if_bandedge, rtwvif->def_tri_idx);
+ ul_tb_info->def_if_bandedge, rtwvif_link->def_tri_idx);
rtw89_debug(rtwdev, RTW89_DBG_UL_TB,
"[ULTB] dyn_tb_begde_en=%d, dyn_tb_tri_en=%d\n",
- rtwvif->dyn_tb_bedge_en, ul_tb_info->dyn_tb_tri_en);
+ rtwvif_link->dyn_tb_bedge_en, ul_tb_info->dyn_tb_tri_en);
}
struct rtw89_phy_ul_tb_check_data {
@@ -4289,7 +4906,7 @@ struct rtw89_phy_power_diff {
};
static void rtw89_phy_ofdma_power_diff(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif)
+ struct rtw89_vif_link *rtwvif_link)
{
static const struct rtw89_phy_power_diff table[2] = {
{0x0, 0x0, 0x0, 0x0, 0xf4, 0x3, 0x3},
@@ -4301,13 +4918,13 @@ static void rtw89_phy_ofdma_power_diff(struct rtw89_dev *rtwdev,
if (!rtwdev->chip->ul_tb_pwr_diff)
return;
- if (rtwvif->pwr_diff_en == rtwvif->pre_pwr_diff_en) {
- rtwvif->pwr_diff_en = false;
+ if (rtwvif_link->pwr_diff_en == rtwvif_link->pre_pwr_diff_en) {
+ rtwvif_link->pwr_diff_en = false;
return;
}
- rtwvif->pre_pwr_diff_en = rtwvif->pwr_diff_en;
- param = &table[rtwvif->pwr_diff_en];
+ rtwvif_link->pre_pwr_diff_en = rtwvif_link->pwr_diff_en;
+ param = &table[rtwvif_link->pwr_diff_en];
rtw89_phy_write32_mask(rtwdev, R_Q_MATRIX_00, B_Q_MATRIX_00_REAL,
param->q_00);
@@ -4316,32 +4933,32 @@ static void rtw89_phy_ofdma_power_diff(struct rtw89_dev *rtwdev,
rtw89_phy_write32_mask(rtwdev, R_CUSTOMIZE_Q_MATRIX,
B_CUSTOMIZE_Q_MATRIX_EN, param->q_matrix_en);
- reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_NORM_BW160,
param->ultb_1t_norm_160);
- reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_NORM_BW160,
param->ultb_2t_norm_160);
- reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM1, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM1, rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_PATH_COM1_NORM_1STS,
param->com1_norm_1sts);
- reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM2, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM2, rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_PATH_COM2_RESP_1STS_PATH,
param->com2_resp_1sts_path);
}
static
void rtw89_phy_ul_tb_ctrl_check(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct rtw89_phy_ul_tb_check_data *ul_tb_data)
{
struct rtw89_traffic_stats *stats = &rtwdev->stats;
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
- if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION)
+ if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION)
return;
if (!vif->cfg.assoc)
@@ -4354,11 +4971,11 @@ void rtw89_phy_ul_tb_ctrl_check(struct rtw89_dev *rtwdev,
ul_tb_data->low_tf_client = true;
ul_tb_data->valid = true;
- ul_tb_data->def_tri_idx = rtwvif->def_tri_idx;
- ul_tb_data->dyn_tb_bedge_en = rtwvif->dyn_tb_bedge_en;
+ ul_tb_data->def_tri_idx = rtwvif_link->def_tri_idx;
+ ul_tb_data->dyn_tb_bedge_en = rtwvif_link->dyn_tb_bedge_en;
}
- rtw89_phy_ofdma_power_diff(rtwdev, rtwvif);
+ rtw89_phy_ofdma_power_diff(rtwdev, rtwvif_link);
}
static void rtw89_phy_ul_tb_waveform_ctrl(struct rtw89_dev *rtwdev,
@@ -4404,7 +5021,9 @@ void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_phy_ul_tb_check_data ul_tb_data = {};
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
if (!chip->ul_tb_waveform_ctrl && !chip->ul_tb_pwr_diff)
return;
@@ -4413,7 +5032,8 @@ void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev)
return;
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_phy_ul_tb_ctrl_check(rtwdev, rtwvif, &ul_tb_data);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_phy_ul_tb_ctrl_check(rtwdev, rtwvif_link, &ul_tb_data);
if (!ul_tb_data.valid)
return;
@@ -4554,11 +5174,36 @@ static void rtw89_phy_antdiv_init(struct rtw89_dev *rtwdev)
rtw89_phy_antdiv_reg_init(rtwdev);
}
+static void rtw89_phy_thermal_protect(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_phy_stat *phystat = &rtwdev->phystat;
+ struct rtw89_hal *hal = &rtwdev->hal;
+ u8 th_max = phystat->last_thermal_max;
+ u8 lv = hal->thermal_prot_lv;
+
+ if (!hal->thermal_prot_th ||
+ (hal->disabled_dm_bitmap & BIT(RTW89_DM_THERMAL_PROTECT)))
+ return;
+
+ if (th_max > hal->thermal_prot_th && lv < RTW89_THERMAL_PROT_LV_MAX)
+ lv++;
+ else if (th_max < hal->thermal_prot_th - 2 && lv > 0)
+ lv--;
+ else
+ return;
+
+ hal->thermal_prot_lv = lv;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "thermal protection lv=%d\n", lv);
+
+ rtw89_fw_h2c_tx_duty(rtwdev, hal->thermal_prot_lv);
+}
+
static void rtw89_phy_stat_thermal_update(struct rtw89_dev *rtwdev)
{
struct rtw89_phy_stat *phystat = &rtwdev->phystat;
+ u8 th, th_max = 0;
int i;
- u8 th;
for (i = 0; i < rtwdev->chip->rf_path_num; i++) {
th = rtw89_chip_get_thermal(rtwdev, i);
@@ -4568,46 +5213,68 @@ static void rtw89_phy_stat_thermal_update(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
"path(%d) thermal cur=%u avg=%ld", i, th,
ewma_thermal_read(&phystat->avg_thermal[i]));
+
+ th_max = max(th_max, th);
}
+
+ phystat->last_thermal_max = th_max;
}
struct rtw89_phy_iter_rssi_data {
struct rtw89_dev *rtwdev;
- struct rtw89_phy_ch_info *ch_info;
bool rssi_changed;
};
-static void rtw89_phy_stat_rssi_update_iter(void *data,
- struct ieee80211_sta *sta)
+static
+void __rtw89_phy_stat_rssi_update_iter(struct rtw89_sta_link *rtwsta_link,
+ struct rtw89_phy_iter_rssi_data *rssi_data)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_phy_iter_rssi_data *rssi_data =
- (struct rtw89_phy_iter_rssi_data *)data;
- struct rtw89_phy_ch_info *ch_info = rssi_data->ch_info;
+ struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link;
+ struct rtw89_dev *rtwdev = rssi_data->rtwdev;
+ struct rtw89_phy_ch_info *ch_info;
+ struct rtw89_bb_ctx *bb;
unsigned long rssi_curr;
- rssi_curr = ewma_rssi_read(&rtwsta->avg_rssi);
+ rssi_curr = ewma_rssi_read(&rtwsta_link->avg_rssi);
+ bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx);
+ ch_info = &bb->ch_info;
if (rssi_curr < ch_info->rssi_min) {
ch_info->rssi_min = rssi_curr;
- ch_info->rssi_min_macid = rtwsta->mac_id;
+ ch_info->rssi_min_macid = rtwsta_link->mac_id;
}
- if (rtwsta->prev_rssi == 0) {
- rtwsta->prev_rssi = rssi_curr;
- } else if (abs((int)rtwsta->prev_rssi - (int)rssi_curr) > (3 << RSSI_FACTOR)) {
- rtwsta->prev_rssi = rssi_curr;
+ if (rtwsta_link->prev_rssi == 0) {
+ rtwsta_link->prev_rssi = rssi_curr;
+ } else if (abs((int)rtwsta_link->prev_rssi - (int)rssi_curr) >
+ (3 << RSSI_FACTOR)) {
+ rtwsta_link->prev_rssi = rssi_curr;
rssi_data->rssi_changed = true;
}
}
+static void rtw89_phy_stat_rssi_update_iter(void *data,
+ struct ieee80211_sta *sta)
+{
+ struct rtw89_phy_iter_rssi_data *rssi_data =
+ (struct rtw89_phy_iter_rssi_data *)data;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id)
+ __rtw89_phy_stat_rssi_update_iter(rtwsta_link, rssi_data);
+}
+
static void rtw89_phy_stat_rssi_update(struct rtw89_dev *rtwdev)
{
- struct rtw89_phy_iter_rssi_data rssi_data = {0};
+ struct rtw89_phy_iter_rssi_data rssi_data = {};
+ struct rtw89_bb_ctx *bb;
rssi_data.rtwdev = rtwdev;
- rssi_data.ch_info = &rtwdev->ch_info;
- rssi_data.ch_info->rssi_min = U8_MAX;
+ rtw89_for_each_active_bb(rtwdev, bb)
+ bb->ch_info.rssi_min = U8_MAX;
+
ieee80211_iterate_stations_atomic(rtwdev->hw,
rtw89_phy_stat_rssi_update_iter,
&rssi_data);
@@ -4627,6 +5294,10 @@ static void rtw89_phy_stat_init(struct rtw89_dev *rtwdev)
memset(&phystat->cur_pkt_stat, 0, sizeof(phystat->cur_pkt_stat));
memset(&phystat->last_pkt_stat, 0, sizeof(phystat->last_pkt_stat));
+
+ ewma_rssi_init(&phystat->bcn_rssi);
+
+ rtwdev->hal.thermal_prot_lv = 0;
}
void rtw89_phy_stat_track(struct rtw89_dev *rtwdev)
@@ -4634,30 +5305,34 @@ void rtw89_phy_stat_track(struct rtw89_dev *rtwdev)
struct rtw89_phy_stat *phystat = &rtwdev->phystat;
rtw89_phy_stat_thermal_update(rtwdev);
+ rtw89_phy_thermal_protect(rtwdev);
rtw89_phy_stat_rssi_update(rtwdev);
phystat->last_pkt_stat = phystat->cur_pkt_stat;
memset(&phystat->cur_pkt_stat, 0, sizeof(phystat->cur_pkt_stat));
}
-static u16 rtw89_phy_ccx_us_to_idx(struct rtw89_dev *rtwdev, u32 time_us)
+static u16 rtw89_phy_ccx_us_to_idx(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb, u32 time_us)
{
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
return time_us >> (ilog2(CCX_US_BASE_RATIO) + env->ccx_unit_idx);
}
-static u32 rtw89_phy_ccx_idx_to_us(struct rtw89_dev *rtwdev, u16 idx)
+static u32 rtw89_phy_ccx_idx_to_us(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb, u16 idx)
{
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
return idx << (ilog2(CCX_US_BASE_RATIO) + env->ccx_unit_idx);
}
-static void rtw89_phy_ccx_top_setting_init(struct rtw89_dev *rtwdev)
+static void rtw89_phy_ccx_top_setting_init(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
const struct rtw89_ccx_regs *ccx = phy->ccx;
env->ccx_manual_ctrl = false;
@@ -4666,17 +5341,20 @@ static void rtw89_phy_ccx_top_setting_init(struct rtw89_dev *rtwdev)
env->ccx_period = 0;
env->ccx_unit_idx = RTW89_CCX_32_US;
- rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->en_mask, 1);
- rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->trig_opt_mask, 1);
- rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1);
- rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->edcca_opt_mask,
- RTW89_CCX_EDCCA_BW20_0);
+ rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->en_mask, 1, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->trig_opt_mask, 1,
+ bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1,
+ bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->edcca_opt_mask,
+ RTW89_CCX_EDCCA_BW20_0, bb->phy_idx);
}
-static u16 rtw89_phy_ccx_get_report(struct rtw89_dev *rtwdev, u16 report,
- u16 score)
+static u16 rtw89_phy_ccx_get_report(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb,
+ u16 report, u16 score)
{
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
u32 numer = 0;
u16 ret = 0;
@@ -4716,9 +5394,10 @@ static void rtw89_phy_ccx_ms_to_period_unit(struct rtw89_dev *rtwdev,
*period, *unit_idx);
}
-static void rtw89_phy_ccx_racing_release(struct rtw89_dev *rtwdev)
+static void rtw89_phy_ccx_racing_release(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
"lv:(%d)->(0)\n", env->ccx_rac_lv);
@@ -4729,9 +5408,10 @@ static void rtw89_phy_ccx_racing_release(struct rtw89_dev *rtwdev)
}
static bool rtw89_phy_ifs_clm_th_update_check(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb,
struct rtw89_ccx_para_info *para)
{
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
bool is_update = env->ifs_clm_app != para->ifs_clm_app;
u8 i = 0;
u16 *ifs_th_l = env->ifs_clm_th_l;
@@ -4766,12 +5446,12 @@ static bool rtw89_phy_ifs_clm_th_update_check(struct rtw89_dev *rtwdev,
*/
ifs_th_l[IFS_CLM_TH_START_IDX] = 0;
ifs_th_h_us[IFS_CLM_TH_START_IDX] = ifs_th0_us;
- ifs_th_h[IFS_CLM_TH_START_IDX] = rtw89_phy_ccx_us_to_idx(rtwdev,
+ ifs_th_h[IFS_CLM_TH_START_IDX] = rtw89_phy_ccx_us_to_idx(rtwdev, bb,
ifs_th0_us);
for (i = 1; i < RTW89_IFS_CLM_NUM; i++) {
ifs_th_l[i] = ifs_th_h[i - 1] + 1;
ifs_th_h_us[i] = ifs_th_h_us[i - 1] * ifs_th_times;
- ifs_th_h[i] = rtw89_phy_ccx_us_to_idx(rtwdev, ifs_th_h_us[i]);
+ ifs_th_h[i] = rtw89_phy_ccx_us_to_idx(rtwdev, bb, ifs_th_h_us[i]);
}
ifs_update_finished:
@@ -4782,30 +5462,31 @@ ifs_update_finished:
return is_update;
}
-static void rtw89_phy_ifs_clm_set_th_reg(struct rtw89_dev *rtwdev)
+static void rtw89_phy_ifs_clm_set_th_reg(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
const struct rtw89_ccx_regs *ccx = phy->ccx;
u8 i = 0;
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_th_l_mask,
- env->ifs_clm_th_l[0]);
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_th_l_mask,
- env->ifs_clm_th_l[1]);
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_th_l_mask,
- env->ifs_clm_th_l[2]);
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_th_l_mask,
- env->ifs_clm_th_l[3]);
-
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_th_h_mask,
- env->ifs_clm_th_h[0]);
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_th_h_mask,
- env->ifs_clm_th_h[1]);
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_th_h_mask,
- env->ifs_clm_th_h[2]);
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_th_h_mask,
- env->ifs_clm_th_h[3]);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_th_l_mask,
+ env->ifs_clm_th_l[0], bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_th_l_mask,
+ env->ifs_clm_th_l[1], bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_th_l_mask,
+ env->ifs_clm_th_l[2], bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_th_l_mask,
+ env->ifs_clm_th_l[3], bb->phy_idx);
+
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_th_h_mask,
+ env->ifs_clm_th_h[0], bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_th_h_mask,
+ env->ifs_clm_th_h[1], bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_th_h_mask,
+ env->ifs_clm_th_h[2], bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_th_h_mask,
+ env->ifs_clm_th_h[3], bb->phy_idx);
for (i = 0; i < RTW89_IFS_CLM_NUM; i++)
rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
@@ -4813,31 +5494,38 @@ static void rtw89_phy_ifs_clm_set_th_reg(struct rtw89_dev *rtwdev)
i + 1, env->ifs_clm_th_l[i], env->ifs_clm_th_h[i]);
}
-static void rtw89_phy_ifs_clm_setting_init(struct rtw89_dev *rtwdev)
+static void rtw89_phy_ifs_clm_setting_init(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
const struct rtw89_ccx_regs *ccx = phy->ccx;
- struct rtw89_ccx_para_info para = {0};
+ struct rtw89_ccx_para_info para = {};
env->ifs_clm_app = RTW89_IFS_CLM_BACKGROUND;
env->ifs_clm_mntr_time = 0;
para.ifs_clm_app = RTW89_IFS_CLM_INIT;
- if (rtw89_phy_ifs_clm_th_update_check(rtwdev, &para))
- rtw89_phy_ifs_clm_set_th_reg(rtwdev);
+ if (rtw89_phy_ifs_clm_th_update_check(rtwdev, bb, &para))
+ rtw89_phy_ifs_clm_set_th_reg(rtwdev, bb);
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_collect_en_mask, true);
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_en_mask, true);
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_en_mask, true);
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_en_mask, true);
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_en_mask, true);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_collect_en_mask, true,
+ bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_en_mask, true,
+ bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_en_mask, true,
+ bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_en_mask, true,
+ bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_en_mask, true,
+ bb->phy_idx);
}
static int rtw89_phy_ccx_racing_ctrl(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb,
enum rtw89_env_racing_lv level)
{
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
int ret = 0;
if (level >= RTW89_RAC_MAX_NUM) {
@@ -4866,56 +5554,62 @@ static int rtw89_phy_ccx_racing_ctrl(struct rtw89_dev *rtwdev,
return ret;
}
-static void rtw89_phy_ccx_trigger(struct rtw89_dev *rtwdev)
+static void rtw89_phy_ccx_trigger(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
const struct rtw89_ccx_regs *ccx = phy->ccx;
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 0);
- rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 0);
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 1);
- rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 0,
+ bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 0,
+ bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 1,
+ bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1,
+ bb->phy_idx);
env->ccx_ongoing = true;
}
-static void rtw89_phy_ifs_clm_get_utility(struct rtw89_dev *rtwdev)
+static void rtw89_phy_ifs_clm_get_utility(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
u8 i = 0;
u32 res = 0;
env->ifs_clm_tx_ratio =
- rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_tx, PERCENT);
+ rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_tx, PERCENT);
env->ifs_clm_edcca_excl_cca_ratio =
- rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_edcca_excl_cca,
+ rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_edcca_excl_cca,
PERCENT);
env->ifs_clm_cck_fa_ratio =
- rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_cckfa, PERCENT);
+ rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_cckfa, PERCENT);
env->ifs_clm_ofdm_fa_ratio =
- rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_ofdmfa, PERCENT);
+ rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_ofdmfa, PERCENT);
env->ifs_clm_cck_cca_excl_fa_ratio =
- rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_cckcca_excl_fa,
+ rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_cckcca_excl_fa,
PERCENT);
env->ifs_clm_ofdm_cca_excl_fa_ratio =
- rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_ofdmcca_excl_fa,
+ rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_ofdmcca_excl_fa,
PERCENT);
env->ifs_clm_cck_fa_permil =
- rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_cckfa, PERMIL);
+ rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_cckfa, PERMIL);
env->ifs_clm_ofdm_fa_permil =
- rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_ofdmfa, PERMIL);
+ rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_ofdmfa, PERMIL);
for (i = 0; i < RTW89_IFS_CLM_NUM; i++) {
if (env->ifs_clm_his[i] > ENV_MNTR_IFSCLM_HIS_MAX) {
env->ifs_clm_ifs_avg[i] = ENV_MNTR_FAIL_DWORD;
} else {
env->ifs_clm_ifs_avg[i] =
- rtw89_phy_ccx_idx_to_us(rtwdev,
+ rtw89_phy_ccx_idx_to_us(rtwdev, bb,
env->ifs_clm_avg[i]);
}
- res = rtw89_phy_ccx_idx_to_us(rtwdev, env->ifs_clm_cca[i]);
+ res = rtw89_phy_ccx_idx_to_us(rtwdev, bb, env->ifs_clm_cca[i]);
res += env->ifs_clm_his[i] >> 1;
if (env->ifs_clm_his[i])
res /= env->ifs_clm_his[i];
@@ -4945,81 +5639,82 @@ static void rtw89_phy_ifs_clm_get_utility(struct rtw89_dev *rtwdev)
env->ifs_clm_cca_avg[i]);
}
-static bool rtw89_phy_ifs_clm_get_result(struct rtw89_dev *rtwdev)
+static bool rtw89_phy_ifs_clm_get_result(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
const struct rtw89_ccx_regs *ccx = phy->ccx;
u8 i = 0;
- if (rtw89_phy_read32_mask(rtwdev, ccx->ifs_total_addr,
- ccx->ifs_cnt_done_mask) == 0) {
+ if (rtw89_phy_read32_idx(rtwdev, ccx->ifs_total_addr,
+ ccx->ifs_cnt_done_mask, bb->phy_idx) == 0) {
rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
"Get IFS_CLM report Fail\n");
return false;
}
env->ifs_clm_tx =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_tx_cnt_addr,
- ccx->ifs_clm_tx_cnt_msk);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_tx_cnt_addr,
+ ccx->ifs_clm_tx_cnt_msk, bb->phy_idx);
env->ifs_clm_edcca_excl_cca =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_tx_cnt_addr,
- ccx->ifs_clm_edcca_excl_cca_fa_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_tx_cnt_addr,
+ ccx->ifs_clm_edcca_excl_cca_fa_mask, bb->phy_idx);
env->ifs_clm_cckcca_excl_fa =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_cca_addr,
- ccx->ifs_clm_cckcca_excl_fa_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_cca_addr,
+ ccx->ifs_clm_cckcca_excl_fa_mask, bb->phy_idx);
env->ifs_clm_ofdmcca_excl_fa =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_cca_addr,
- ccx->ifs_clm_ofdmcca_excl_fa_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_cca_addr,
+ ccx->ifs_clm_ofdmcca_excl_fa_mask, bb->phy_idx);
env->ifs_clm_cckfa =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_fa_addr,
- ccx->ifs_clm_cck_fa_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_fa_addr,
+ ccx->ifs_clm_cck_fa_mask, bb->phy_idx);
env->ifs_clm_ofdmfa =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_fa_addr,
- ccx->ifs_clm_ofdm_fa_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_fa_addr,
+ ccx->ifs_clm_ofdm_fa_mask, bb->phy_idx);
env->ifs_clm_his[0] =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_his_addr,
- ccx->ifs_t1_his_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr,
+ ccx->ifs_t1_his_mask, bb->phy_idx);
env->ifs_clm_his[1] =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_his_addr,
- ccx->ifs_t2_his_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr,
+ ccx->ifs_t2_his_mask, bb->phy_idx);
env->ifs_clm_his[2] =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_his_addr,
- ccx->ifs_t3_his_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr,
+ ccx->ifs_t3_his_mask, bb->phy_idx);
env->ifs_clm_his[3] =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_his_addr,
- ccx->ifs_t4_his_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr,
+ ccx->ifs_t4_his_mask, bb->phy_idx);
env->ifs_clm_avg[0] =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_avg_l_addr,
- ccx->ifs_t1_avg_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_l_addr,
+ ccx->ifs_t1_avg_mask, bb->phy_idx);
env->ifs_clm_avg[1] =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_avg_l_addr,
- ccx->ifs_t2_avg_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_l_addr,
+ ccx->ifs_t2_avg_mask, bb->phy_idx);
env->ifs_clm_avg[2] =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_avg_h_addr,
- ccx->ifs_t3_avg_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_h_addr,
+ ccx->ifs_t3_avg_mask, bb->phy_idx);
env->ifs_clm_avg[3] =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_avg_h_addr,
- ccx->ifs_t4_avg_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_h_addr,
+ ccx->ifs_t4_avg_mask, bb->phy_idx);
env->ifs_clm_cca[0] =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_cca_l_addr,
- ccx->ifs_t1_cca_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_l_addr,
+ ccx->ifs_t1_cca_mask, bb->phy_idx);
env->ifs_clm_cca[1] =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_cca_l_addr,
- ccx->ifs_t2_cca_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_l_addr,
+ ccx->ifs_t2_cca_mask, bb->phy_idx);
env->ifs_clm_cca[2] =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_cca_h_addr,
- ccx->ifs_t3_cca_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_h_addr,
+ ccx->ifs_t3_cca_mask, bb->phy_idx);
env->ifs_clm_cca[3] =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_cca_h_addr,
- ccx->ifs_t4_cca_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_h_addr,
+ ccx->ifs_t4_cca_mask, bb->phy_idx);
env->ifs_clm_total_ifs =
- rtw89_phy_read32_mask(rtwdev, ccx->ifs_total_addr,
- ccx->ifs_total_mask);
+ rtw89_phy_read32_idx(rtwdev, ccx->ifs_total_addr,
+ ccx->ifs_total_mask, bb->phy_idx);
rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "IFS-CLM total_ifs = %d\n",
env->ifs_clm_total_ifs);
@@ -5039,16 +5734,17 @@ static bool rtw89_phy_ifs_clm_get_result(struct rtw89_dev *rtwdev)
"T%d:[%d, %d, %d]\n", i + 1, env->ifs_clm_his[i],
env->ifs_clm_avg[i], env->ifs_clm_cca[i]);
- rtw89_phy_ifs_clm_get_utility(rtwdev);
+ rtw89_phy_ifs_clm_get_utility(rtwdev, bb);
return true;
}
static int rtw89_phy_ifs_clm_set(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb,
struct rtw89_ccx_para_info *para)
{
const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
const struct rtw89_ccx_regs *ccx = phy->ccx;
u32 period = 0;
u32 unit_idx = 0;
@@ -5059,17 +5755,17 @@ static int rtw89_phy_ifs_clm_set(struct rtw89_dev *rtwdev,
return -EINVAL;
}
- if (rtw89_phy_ccx_racing_ctrl(rtwdev, para->rac_lv))
+ if (rtw89_phy_ccx_racing_ctrl(rtwdev, bb, para->rac_lv))
return -EINVAL;
if (para->mntr_time != env->ifs_clm_mntr_time) {
rtw89_phy_ccx_ms_to_period_unit(rtwdev, para->mntr_time,
&period, &unit_idx);
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr,
- ccx->ifs_clm_period_mask, period);
- rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr,
- ccx->ifs_clm_cnt_unit_mask,
- unit_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr,
+ ccx->ifs_clm_period_mask, period, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr,
+ ccx->ifs_clm_cnt_unit_mask,
+ unit_idx, bb->phy_idx);
rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
"Update IFS-CLM time ((%d)) -> ((%d))\n",
@@ -5080,18 +5776,19 @@ static int rtw89_phy_ifs_clm_set(struct rtw89_dev *rtwdev,
env->ccx_unit_idx = (u8)unit_idx;
}
- if (rtw89_phy_ifs_clm_th_update_check(rtwdev, para)) {
+ if (rtw89_phy_ifs_clm_th_update_check(rtwdev, bb, para)) {
env->ifs_clm_app = para->ifs_clm_app;
- rtw89_phy_ifs_clm_set_th_reg(rtwdev);
+ rtw89_phy_ifs_clm_set_th_reg(rtwdev, bb);
}
return 0;
}
-void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev)
+static void __rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
- struct rtw89_ccx_para_info para = {0};
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
+ struct rtw89_ccx_para_info para = {};
u8 chk_result = RTW89_PHY_ENV_MON_CCX_FAIL;
env->ccx_watchdog_result = RTW89_PHY_ENV_MON_CCX_FAIL;
@@ -5101,25 +5798,36 @@ void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev)
return;
}
+ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
+ "BB-%d env_monitor track\n", bb->phy_idx);
+
/* only ifs_clm for now */
- if (rtw89_phy_ifs_clm_get_result(rtwdev))
+ if (rtw89_phy_ifs_clm_get_result(rtwdev, bb))
env->ccx_watchdog_result |= RTW89_PHY_ENV_MON_IFS_CLM;
- rtw89_phy_ccx_racing_release(rtwdev);
+ rtw89_phy_ccx_racing_release(rtwdev, bb);
para.mntr_time = 1900;
para.rac_lv = RTW89_RAC_LV_1;
para.ifs_clm_app = RTW89_IFS_CLM_BACKGROUND;
- if (rtw89_phy_ifs_clm_set(rtwdev, &para) == 0)
+ if (rtw89_phy_ifs_clm_set(rtwdev, bb, &para) == 0)
chk_result |= RTW89_PHY_ENV_MON_IFS_CLM;
if (chk_result)
- rtw89_phy_ccx_trigger(rtwdev);
+ rtw89_phy_ccx_trigger(rtwdev, bb);
rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
"get_result=0x%x, chk_result:0x%x\n",
env->ccx_watchdog_result, chk_result);
}
+void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_bb_ctx *bb;
+
+ rtw89_for_each_active_bb(rtwdev, bb)
+ __rtw89_phy_env_monitor_track(rtwdev, bb);
+}
+
static bool rtw89_physts_ie_page_valid(enum rtw89_phy_status_bitmap *ie_page)
{
if (*ie_page >= RTW89_PHYSTS_BITMAP_NUM ||
@@ -5139,7 +5847,8 @@ static u32 rtw89_phy_get_ie_bitmap_addr(enum rtw89_phy_status_bitmap ie_page)
}
static u32 rtw89_physts_get_ie_bitmap(struct rtw89_dev *rtwdev,
- enum rtw89_phy_status_bitmap ie_page)
+ enum rtw89_phy_status_bitmap ie_page,
+ enum rtw89_phy_idx phy_idx)
{
u32 addr;
@@ -5148,12 +5857,12 @@ static u32 rtw89_physts_get_ie_bitmap(struct rtw89_dev *rtwdev,
addr = rtw89_phy_get_ie_bitmap_addr(ie_page);
- return rtw89_phy_read32(rtwdev, addr);
+ return rtw89_phy_read32_idx(rtwdev, addr, MASKDWORD, phy_idx);
}
static void rtw89_physts_set_ie_bitmap(struct rtw89_dev *rtwdev,
enum rtw89_phy_status_bitmap ie_page,
- u32 val)
+ u32 val, enum rtw89_phy_idx phy_idx)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
u32 addr;
@@ -5165,22 +5874,22 @@ static void rtw89_physts_set_ie_bitmap(struct rtw89_dev *rtwdev,
val &= B_PHY_STS_BITMAP_MSK_52A;
addr = rtw89_phy_get_ie_bitmap_addr(ie_page);
- rtw89_phy_write32(rtwdev, addr, val);
+ rtw89_phy_write32_idx(rtwdev, addr, MASKDWORD, val, phy_idx);
}
static void rtw89_physts_enable_ie_bitmap(struct rtw89_dev *rtwdev,
enum rtw89_phy_status_bitmap bitmap,
enum rtw89_phy_status_ie_type ie,
- bool enable)
+ bool enable, enum rtw89_phy_idx phy_idx)
{
- u32 val = rtw89_physts_get_ie_bitmap(rtwdev, bitmap);
+ u32 val = rtw89_physts_get_ie_bitmap(rtwdev, bitmap, phy_idx);
if (enable)
val |= BIT(ie);
else
val &= ~BIT(ie);
- rtw89_physts_set_ie_bitmap(rtwdev, bitmap, val);
+ rtw89_physts_set_ie_bitmap(rtwdev, bitmap, val, phy_idx);
}
static void rtw89_physts_enable_fail_report(struct rtw89_dev *rtwdev,
@@ -5191,51 +5900,60 @@ static void rtw89_physts_enable_fail_report(struct rtw89_dev *rtwdev,
const struct rtw89_physts_regs *physts = phy->physts;
if (enable) {
- rtw89_phy_write32_clr(rtwdev, physts->setting_addr,
- physts->dis_trigger_fail_mask);
- rtw89_phy_write32_clr(rtwdev, physts->setting_addr,
- physts->dis_trigger_brk_mask);
+ rtw89_phy_write32_idx_clr(rtwdev, physts->setting_addr,
+ physts->dis_trigger_fail_mask, phy_idx);
+ rtw89_phy_write32_idx_clr(rtwdev, physts->setting_addr,
+ physts->dis_trigger_brk_mask, phy_idx);
} else {
- rtw89_phy_write32_set(rtwdev, physts->setting_addr,
- physts->dis_trigger_fail_mask);
- rtw89_phy_write32_set(rtwdev, physts->setting_addr,
- physts->dis_trigger_brk_mask);
+ rtw89_phy_write32_idx_set(rtwdev, physts->setting_addr,
+ physts->dis_trigger_fail_mask, phy_idx);
+ rtw89_phy_write32_idx_set(rtwdev, physts->setting_addr,
+ physts->dis_trigger_brk_mask, phy_idx);
}
}
-static void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev)
+static void __rtw89_physts_parsing_init(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
{
u8 i;
- rtw89_physts_enable_fail_report(rtwdev, false, RTW89_PHY_0);
+ rtw89_physts_enable_fail_report(rtwdev, false, phy_idx);
for (i = 0; i < RTW89_PHYSTS_BITMAP_NUM; i++) {
if (i >= RTW89_CCK_PKT)
rtw89_physts_enable_ie_bitmap(rtwdev, i,
RTW89_PHYSTS_IE09_FTR_0,
- true);
+ true, phy_idx);
if ((i >= RTW89_CCK_BRK && i <= RTW89_VHT_MU) ||
(i >= RTW89_RSVD_9 && i <= RTW89_CCK_PKT))
continue;
rtw89_physts_enable_ie_bitmap(rtwdev, i,
RTW89_PHYSTS_IE24_OFDM_TD_PATH_A,
- true);
+ true, phy_idx);
}
rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_VHT_PKT,
- RTW89_PHYSTS_IE13_DL_MU_DEF, true);
+ RTW89_PHYSTS_IE13_DL_MU_DEF, true, phy_idx);
rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_HE_PKT,
- RTW89_PHYSTS_IE13_DL_MU_DEF, true);
+ RTW89_PHYSTS_IE13_DL_MU_DEF, true, phy_idx);
/* force IE01 for channel index, only channel field is valid */
rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_CCK_PKT,
- RTW89_PHYSTS_IE01_CMN_OFDM, true);
+ RTW89_PHYSTS_IE01_CMN_OFDM, true, phy_idx);
+}
+
+static void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev)
+{
+ __rtw89_physts_parsing_init(rtwdev, RTW89_PHY_0);
+ if (rtwdev->dbcc_en)
+ __rtw89_physts_parsing_init(rtwdev, RTW89_PHY_1);
}
-static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev, int type)
+static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb, int type)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- struct rtw89_dig_info *dig = &rtwdev->dig;
const struct rtw89_phy_dig_gain_cfg *cfg;
+ struct rtw89_dig_info *dig = &bb->dig;
const char *msg;
u8 i;
s8 gain_base;
@@ -5272,8 +5990,8 @@ static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev, int type)
}
for (i = 0; i < cfg->size; i++) {
- tmp = rtw89_phy_read32_mask(rtwdev, cfg->table[i].addr,
- cfg->table[i].mask);
+ tmp = rtw89_phy_read32_idx(rtwdev, cfg->table[i].addr,
+ cfg->table[i].mask, bb->phy_idx);
tmp >>= DIG_GAIN_SHIFT;
gain_arr[i] = sign_extend32(tmp, U4_MAX_BIT) + gain_base;
gain_base += DIG_GAIN;
@@ -5283,25 +6001,26 @@ static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev, int type)
}
}
-static void rtw89_phy_dig_update_gain_para(struct rtw89_dev *rtwdev)
+static void rtw89_phy_dig_update_gain_para(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
- struct rtw89_dig_info *dig = &rtwdev->dig;
+ struct rtw89_dig_info *dig = &bb->dig;
u32 tmp;
u8 i;
if (!rtwdev->hal.support_igi)
return;
- tmp = rtw89_phy_read32_mask(rtwdev, R_PATH0_IB_PKPW,
- B_PATH0_IB_PKPW_MSK);
+ tmp = rtw89_phy_read32_idx(rtwdev, R_PATH0_IB_PKPW,
+ B_PATH0_IB_PKPW_MSK, bb->phy_idx);
dig->ib_pkpwr = sign_extend32(tmp >> DIG_GAIN_SHIFT, U8_MAX_BIT);
- dig->ib_pbk = rtw89_phy_read32_mask(rtwdev, R_PATH0_IB_PBK,
- B_PATH0_IB_PBK_MSK);
+ dig->ib_pbk = rtw89_phy_read32_idx(rtwdev, R_PATH0_IB_PBK,
+ B_PATH0_IB_PBK_MSK, bb->phy_idx);
rtw89_debug(rtwdev, RTW89_DBG_DIG, "ib_pkpwr=%d, ib_pbk=%d\n",
dig->ib_pkpwr, dig->ib_pbk);
for (i = RTW89_DIG_GAIN_LNA_G; i < RTW89_DIG_GAIN_MAX; i++)
- rtw89_phy_dig_read_gain_table(rtwdev, i);
+ rtw89_phy_dig_read_gain_table(rtwdev, bb, i);
}
static const u8 rssi_nolink = 22;
@@ -5310,10 +6029,11 @@ static const u16 fa_th_2g[FA_TH_NUM] = {22, 44, 66, 88};
static const u16 fa_th_5g[FA_TH_NUM] = {4, 8, 12, 16};
static const u16 fa_th_nolink[FA_TH_NUM] = {196, 352, 440, 528};
-static void rtw89_phy_dig_update_rssi_info(struct rtw89_dev *rtwdev)
+static void rtw89_phy_dig_update_rssi_info(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
- struct rtw89_phy_ch_info *ch_info = &rtwdev->ch_info;
- struct rtw89_dig_info *dig = &rtwdev->dig;
+ struct rtw89_phy_ch_info *ch_info = &bb->ch_info;
+ struct rtw89_dig_info *dig = &bb->dig;
bool is_linked = rtwdev->total_sta_assoc > 0;
if (is_linked) {
@@ -5324,10 +6044,11 @@ static void rtw89_phy_dig_update_rssi_info(struct rtw89_dev *rtwdev)
}
}
-static void rtw89_phy_dig_update_para(struct rtw89_dev *rtwdev)
+static void rtw89_phy_dig_update_para(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
- struct rtw89_dig_info *dig = &rtwdev->dig;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_mgnt_chan_get(rtwdev, bb->phy_idx);
+ struct rtw89_dig_info *dig = &bb->dig;
bool is_linked = rtwdev->total_sta_assoc > 0;
const u16 *fa_th_src = NULL;
@@ -5352,13 +6073,14 @@ static void rtw89_phy_dig_update_para(struct rtw89_dev *rtwdev)
memcpy(dig->igi_rssi_th, igi_rssi_th, sizeof(dig->igi_rssi_th));
}
-static const u8 pd_low_th_offset = 20, dynamic_igi_min = 0x20;
+static const u8 pd_low_th_offset = 16, dynamic_igi_min = 0x20;
static const u8 igi_max_performance_mode = 0x5a;
static const u8 dynamic_pd_threshold_max;
-static void rtw89_phy_dig_para_reset(struct rtw89_dev *rtwdev)
+static void rtw89_phy_dig_para_reset(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
- struct rtw89_dig_info *dig = &rtwdev->dig;
+ struct rtw89_dig_info *dig = &bb->dig;
dig->cur_gaincode.lna_idx = LNA_IDX_MAX;
dig->cur_gaincode.tia_idx = TIA_IDX_MAX;
@@ -5374,15 +6096,27 @@ static void rtw89_phy_dig_para_reset(struct rtw89_dev *rtwdev)
dig->is_linked_pre = false;
}
+static void __rtw89_phy_dig_init(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
+{
+ rtw89_debug(rtwdev, RTW89_DBG_DIG, "BB-%d dig_init\n", bb->phy_idx);
+
+ rtw89_phy_dig_update_gain_para(rtwdev, bb);
+ rtw89_phy_dig_reset(rtwdev, bb);
+}
+
static void rtw89_phy_dig_init(struct rtw89_dev *rtwdev)
{
- rtw89_phy_dig_update_gain_para(rtwdev);
- rtw89_phy_dig_reset(rtwdev);
+ struct rtw89_bb_ctx *bb;
+
+ rtw89_for_each_capab_bb(rtwdev, bb)
+ __rtw89_phy_dig_init(rtwdev, bb);
}
-static u8 rtw89_phy_dig_lna_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi)
+static u8 rtw89_phy_dig_lna_idx_by_rssi(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb, u8 rssi)
{
- struct rtw89_dig_info *dig = &rtwdev->dig;
+ struct rtw89_dig_info *dig = &bb->dig;
u8 lna_idx;
if (rssi < dig->igi_rssi_th[0])
@@ -5401,9 +6135,10 @@ static u8 rtw89_phy_dig_lna_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi)
return lna_idx;
}
-static u8 rtw89_phy_dig_tia_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi)
+static u8 rtw89_phy_dig_tia_idx_by_rssi(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb, u8 rssi)
{
- struct rtw89_dig_info *dig = &rtwdev->dig;
+ struct rtw89_dig_info *dig = &bb->dig;
u8 tia_idx;
if (rssi < dig->igi_rssi_th[0])
@@ -5416,10 +6151,11 @@ static u8 rtw89_phy_dig_tia_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi)
#define IB_PBK_BASE 110
#define WB_RSSI_BASE 10
-static u8 rtw89_phy_dig_rxb_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi,
+static u8 rtw89_phy_dig_rxb_idx_by_rssi(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb, u8 rssi,
struct rtw89_agc_gaincode_set *set)
{
- struct rtw89_dig_info *dig = &rtwdev->dig;
+ struct rtw89_dig_info *dig = &bb->dig;
s8 lna_gain = dig->lna_gain[set->lna_idx];
s8 tia_gain = dig->tia_gain[set->tia_idx];
s32 wb_rssi = rssi + lna_gain + tia_gain;
@@ -5435,12 +6171,13 @@ static u8 rtw89_phy_dig_rxb_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi,
return rxb_idx;
}
-static void rtw89_phy_dig_gaincode_by_rssi(struct rtw89_dev *rtwdev, u8 rssi,
+static void rtw89_phy_dig_gaincode_by_rssi(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb, u8 rssi,
struct rtw89_agc_gaincode_set *set)
{
- set->lna_idx = rtw89_phy_dig_lna_idx_by_rssi(rtwdev, rssi);
- set->tia_idx = rtw89_phy_dig_tia_idx_by_rssi(rtwdev, rssi);
- set->rxb_idx = rtw89_phy_dig_rxb_idx_by_rssi(rtwdev, rssi, set);
+ set->lna_idx = rtw89_phy_dig_lna_idx_by_rssi(rtwdev, bb, rssi);
+ set->tia_idx = rtw89_phy_dig_tia_idx_by_rssi(rtwdev, bb, rssi);
+ set->rxb_idx = rtw89_phy_dig_rxb_idx_by_rssi(rtwdev, bb, rssi, set);
rtw89_debug(rtwdev, RTW89_DBG_DIG,
"final_rssi=%03d, (lna,tia,rab)=(%d,%d,%02d)\n",
@@ -5449,10 +6186,11 @@ static void rtw89_phy_dig_gaincode_by_rssi(struct rtw89_dev *rtwdev, u8 rssi,
#define IGI_OFFSET_MAX 25
#define IGI_OFFSET_MUL 2
-static void rtw89_phy_dig_igi_offset_by_env(struct rtw89_dev *rtwdev)
+static void rtw89_phy_dig_igi_offset_by_env(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
- struct rtw89_dig_info *dig = &rtwdev->dig;
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ struct rtw89_dig_info *dig = &bb->dig;
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
enum rtw89_dig_noisy_level noisy_lv;
u8 igi_offset = dig->fa_rssi_ofst;
u16 fa_ratio = 0;
@@ -5489,92 +6227,99 @@ static void rtw89_phy_dig_igi_offset_by_env(struct rtw89_dev *rtwdev)
noisy_lv, igi_offset);
}
-static void rtw89_phy_dig_set_lna_idx(struct rtw89_dev *rtwdev, u8 lna_idx)
+static void rtw89_phy_dig_set_lna_idx(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb, u8 lna_idx)
{
const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
- rtw89_phy_write32_mask(rtwdev, dig_regs->p0_lna_init.addr,
- dig_regs->p0_lna_init.mask, lna_idx);
- rtw89_phy_write32_mask(rtwdev, dig_regs->p1_lna_init.addr,
- dig_regs->p1_lna_init.mask, lna_idx);
+ rtw89_phy_write32_idx(rtwdev, dig_regs->p0_lna_init.addr,
+ dig_regs->p0_lna_init.mask, lna_idx, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, dig_regs->p1_lna_init.addr,
+ dig_regs->p1_lna_init.mask, lna_idx, bb->phy_idx);
}
-static void rtw89_phy_dig_set_tia_idx(struct rtw89_dev *rtwdev, u8 tia_idx)
+static void rtw89_phy_dig_set_tia_idx(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb, u8 tia_idx)
{
const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
- rtw89_phy_write32_mask(rtwdev, dig_regs->p0_tia_init.addr,
- dig_regs->p0_tia_init.mask, tia_idx);
- rtw89_phy_write32_mask(rtwdev, dig_regs->p1_tia_init.addr,
- dig_regs->p1_tia_init.mask, tia_idx);
+ rtw89_phy_write32_idx(rtwdev, dig_regs->p0_tia_init.addr,
+ dig_regs->p0_tia_init.mask, tia_idx, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, dig_regs->p1_tia_init.addr,
+ dig_regs->p1_tia_init.mask, tia_idx, bb->phy_idx);
}
-static void rtw89_phy_dig_set_rxb_idx(struct rtw89_dev *rtwdev, u8 rxb_idx)
+static void rtw89_phy_dig_set_rxb_idx(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb, u8 rxb_idx)
{
const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
- rtw89_phy_write32_mask(rtwdev, dig_regs->p0_rxb_init.addr,
- dig_regs->p0_rxb_init.mask, rxb_idx);
- rtw89_phy_write32_mask(rtwdev, dig_regs->p1_rxb_init.addr,
- dig_regs->p1_rxb_init.mask, rxb_idx);
+ rtw89_phy_write32_idx(rtwdev, dig_regs->p0_rxb_init.addr,
+ dig_regs->p0_rxb_init.mask, rxb_idx, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, dig_regs->p1_rxb_init.addr,
+ dig_regs->p1_rxb_init.mask, rxb_idx, bb->phy_idx);
}
static void rtw89_phy_dig_set_igi_cr(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb,
const struct rtw89_agc_gaincode_set set)
{
if (!rtwdev->hal.support_igi)
return;
- rtw89_phy_dig_set_lna_idx(rtwdev, set.lna_idx);
- rtw89_phy_dig_set_tia_idx(rtwdev, set.tia_idx);
- rtw89_phy_dig_set_rxb_idx(rtwdev, set.rxb_idx);
+ rtw89_phy_dig_set_lna_idx(rtwdev, bb, set.lna_idx);
+ rtw89_phy_dig_set_tia_idx(rtwdev, bb, set.tia_idx);
+ rtw89_phy_dig_set_rxb_idx(rtwdev, bb, set.rxb_idx);
rtw89_debug(rtwdev, RTW89_DBG_DIG, "Set (lna,tia,rxb)=((%d,%d,%02d))\n",
set.lna_idx, set.tia_idx, set.rxb_idx);
}
static void rtw89_phy_dig_sdagc_follow_pagc_config(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb,
bool enable)
{
const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
- rtw89_phy_write32_mask(rtwdev, dig_regs->p0_p20_pagcugc_en.addr,
- dig_regs->p0_p20_pagcugc_en.mask, enable);
- rtw89_phy_write32_mask(rtwdev, dig_regs->p0_s20_pagcugc_en.addr,
- dig_regs->p0_s20_pagcugc_en.mask, enable);
- rtw89_phy_write32_mask(rtwdev, dig_regs->p1_p20_pagcugc_en.addr,
- dig_regs->p1_p20_pagcugc_en.mask, enable);
- rtw89_phy_write32_mask(rtwdev, dig_regs->p1_s20_pagcugc_en.addr,
- dig_regs->p1_s20_pagcugc_en.mask, enable);
+ rtw89_phy_write32_idx(rtwdev, dig_regs->p0_p20_pagcugc_en.addr,
+ dig_regs->p0_p20_pagcugc_en.mask, enable, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, dig_regs->p0_s20_pagcugc_en.addr,
+ dig_regs->p0_s20_pagcugc_en.mask, enable, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, dig_regs->p1_p20_pagcugc_en.addr,
+ dig_regs->p1_p20_pagcugc_en.mask, enable, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, dig_regs->p1_s20_pagcugc_en.addr,
+ dig_regs->p1_s20_pagcugc_en.mask, enable, bb->phy_idx);
rtw89_debug(rtwdev, RTW89_DBG_DIG, "sdagc_follow_pagc=%d\n", enable);
}
-static void rtw89_phy_dig_config_igi(struct rtw89_dev *rtwdev)
+static void rtw89_phy_dig_config_igi(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
- struct rtw89_dig_info *dig = &rtwdev->dig;
+ struct rtw89_dig_info *dig = &bb->dig;
if (!rtwdev->hal.support_igi)
return;
if (dig->force_gaincode_idx_en) {
- rtw89_phy_dig_set_igi_cr(rtwdev, dig->force_gaincode);
+ rtw89_phy_dig_set_igi_cr(rtwdev, bb, dig->force_gaincode);
rtw89_debug(rtwdev, RTW89_DBG_DIG,
"Force gaincode index enabled.\n");
} else {
- rtw89_phy_dig_gaincode_by_rssi(rtwdev, dig->igi_fa_rssi,
+ rtw89_phy_dig_gaincode_by_rssi(rtwdev, bb, dig->igi_fa_rssi,
&dig->cur_gaincode);
- rtw89_phy_dig_set_igi_cr(rtwdev, dig->cur_gaincode);
+ rtw89_phy_dig_set_igi_cr(rtwdev, bb, dig->cur_gaincode);
}
}
-static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, u8 rssi,
- bool enable)
+static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb,
+ u8 rssi, bool enable)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_mgnt_chan_get(rtwdev, bb->phy_idx);
const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
enum rtw89_bandwidth cbw = chan->band_width;
- struct rtw89_dig_info *dig = &rtwdev->dig;
+ struct rtw89_dig_info *dig = &bb->dig;
u8 final_rssi = 0, under_region = dig->pd_low_th_ofst;
u8 ofdm_cca_th;
s8 cck_cca_th;
@@ -5616,10 +6361,10 @@ static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, u8 rssi,
"Dynamic PD th disabled, Set PD_low_bd=0\n");
}
- rtw89_phy_write32_mask(rtwdev, dig_regs->seg0_pd_reg,
- dig_regs->pd_lower_bound_mask, pd_val);
- rtw89_phy_write32_mask(rtwdev, dig_regs->seg0_pd_reg,
- dig_regs->pd_spatial_reuse_en, enable);
+ rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
+ dig_regs->pd_lower_bound_mask, pd_val, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
+ dig_regs->pd_spatial_reuse_en, enable, bb->phy_idx);
if (!rtwdev->hal.support_cckpd)
return;
@@ -5631,90 +6376,98 @@ static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, u8 rssi,
"igi=%d, cck_ccaTH=%d, backoff=%d, cck_PD_low=((%d))dB\n",
final_rssi, cck_cca_th, under_region, pd_val);
- rtw89_phy_write32_mask(rtwdev, dig_regs->bmode_pd_reg,
- dig_regs->bmode_cca_rssi_limit_en, enable);
- rtw89_phy_write32_mask(rtwdev, dig_regs->bmode_pd_lower_bound_reg,
- dig_regs->bmode_rssi_nocca_low_th_mask, pd_val);
+ rtw89_phy_write32_idx(rtwdev, dig_regs->bmode_pd_reg,
+ dig_regs->bmode_cca_rssi_limit_en, enable, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, dig_regs->bmode_pd_lower_bound_reg,
+ dig_regs->bmode_rssi_nocca_low_th_mask, pd_val, bb->phy_idx);
}
-void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev)
+void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
{
- struct rtw89_dig_info *dig = &rtwdev->dig;
+ struct rtw89_dig_info *dig = &bb->dig;
dig->bypass_dig = false;
- rtw89_phy_dig_para_reset(rtwdev);
- rtw89_phy_dig_set_igi_cr(rtwdev, dig->force_gaincode);
- rtw89_phy_dig_dyn_pd_th(rtwdev, rssi_nolink, false);
- rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, false);
- rtw89_phy_dig_update_para(rtwdev);
+ rtw89_phy_dig_para_reset(rtwdev, bb);
+ rtw89_phy_dig_set_igi_cr(rtwdev, bb, dig->force_gaincode);
+ rtw89_phy_dig_dyn_pd_th(rtwdev, bb, rssi_nolink, false);
+ rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, bb, false);
+ rtw89_phy_dig_update_para(rtwdev, bb);
}
#define IGI_RSSI_MIN 10
-void rtw89_phy_dig(struct rtw89_dev *rtwdev)
+#define ABS_IGI_MIN 0xc
+static void __rtw89_phy_dig(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
{
- struct rtw89_dig_info *dig = &rtwdev->dig;
+ struct rtw89_dig_info *dig = &bb->dig;
bool is_linked = rtwdev->total_sta_assoc > 0;
+ u8 igi_min;
if (unlikely(dig->bypass_dig)) {
dig->bypass_dig = false;
return;
}
+ rtw89_debug(rtwdev, RTW89_DBG_DIG, "BB-%d dig track\n", bb->phy_idx);
+
+ rtw89_phy_dig_update_rssi_info(rtwdev, bb);
+
if (!dig->is_linked_pre && is_linked) {
rtw89_debug(rtwdev, RTW89_DBG_DIG, "First connected\n");
- rtw89_phy_dig_update_para(rtwdev);
+ rtw89_phy_dig_update_para(rtwdev, bb);
+ dig->igi_fa_rssi = dig->igi_rssi;
} else if (dig->is_linked_pre && !is_linked) {
rtw89_debug(rtwdev, RTW89_DBG_DIG, "First disconnected\n");
- rtw89_phy_dig_update_para(rtwdev);
+ rtw89_phy_dig_update_para(rtwdev, bb);
+ dig->igi_fa_rssi = dig->igi_rssi;
}
dig->is_linked_pre = is_linked;
- rtw89_phy_dig_igi_offset_by_env(rtwdev);
- rtw89_phy_dig_update_rssi_info(rtwdev);
+ rtw89_phy_dig_igi_offset_by_env(rtwdev, bb);
- dig->dyn_igi_min = (dig->igi_rssi > IGI_RSSI_MIN) ?
- dig->igi_rssi - IGI_RSSI_MIN : 0;
- dig->dyn_igi_max = dig->dyn_igi_min + IGI_OFFSET_MAX;
- dig->igi_fa_rssi = dig->dyn_igi_min + dig->fa_rssi_ofst;
+ igi_min = max_t(int, dig->igi_rssi - IGI_RSSI_MIN, 0);
+ dig->dyn_igi_max = min(igi_min + IGI_OFFSET_MAX, igi_max_performance_mode);
+ dig->dyn_igi_min = max(igi_min, ABS_IGI_MIN);
- dig->igi_fa_rssi = clamp(dig->igi_fa_rssi, dig->dyn_igi_min,
- dig->dyn_igi_max);
+ if (dig->dyn_igi_max >= dig->dyn_igi_min) {
+ dig->igi_fa_rssi += dig->fa_rssi_ofst;
+ dig->igi_fa_rssi = clamp(dig->igi_fa_rssi, dig->dyn_igi_min,
+ dig->dyn_igi_max);
+ } else {
+ dig->igi_fa_rssi = dig->dyn_igi_max;
+ }
rtw89_debug(rtwdev, RTW89_DBG_DIG,
- "rssi=%03d, dyn(max,min)=(%d,%d), final_rssi=%d\n",
+ "rssi=%03d, dyn_joint(max,min)=(%d,%d), final_rssi=%d\n",
dig->igi_rssi, dig->dyn_igi_max, dig->dyn_igi_min,
dig->igi_fa_rssi);
- rtw89_phy_dig_config_igi(rtwdev);
+ rtw89_phy_dig_config_igi(rtwdev, bb);
- rtw89_phy_dig_dyn_pd_th(rtwdev, dig->igi_fa_rssi, dig->dyn_pd_th_en);
+ rtw89_phy_dig_dyn_pd_th(rtwdev, bb, dig->igi_fa_rssi, dig->dyn_pd_th_en);
if (dig->dyn_pd_th_en && dig->igi_fa_rssi > dig->dyn_pd_th_max)
- rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, true);
+ rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, bb, true);
else
- rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, false);
+ rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, bb, false);
}
-static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta)
+void rtw89_phy_dig(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_bb_ctx *bb;
+
+ rtw89_for_each_active_bb(rtwdev, bb)
+ __rtw89_phy_dig(rtwdev, bb);
+}
+
+static void __rtw89_phy_tx_path_div_sta_iter(struct rtw89_dev *rtwdev,
+ struct rtw89_sta_link *rtwsta_link)
{
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
- struct rtw89_dev *rtwdev = rtwsta->rtwdev;
- struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_hal *hal = &rtwdev->hal;
- bool *done = data;
u8 rssi_a, rssi_b;
u32 candidate;
- if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION || sta->tdls)
- return;
-
- if (*done)
- return;
-
- *done = true;
-
- rssi_a = ewma_rssi_read(&rtwsta->rssi[RF_PATH_A]);
- rssi_b = ewma_rssi_read(&rtwsta->rssi[RF_PATH_B]);
+ rssi_a = ewma_rssi_read(&rtwsta_link->rssi[RF_PATH_A]);
+ rssi_b = ewma_rssi_read(&rtwsta_link->rssi[RF_PATH_B]);
if (rssi_a > rssi_b + RTW89_TX_DIV_RSSI_RAW_TH)
candidate = RF_A;
@@ -5727,7 +6480,7 @@ static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta
return;
hal->antenna_tx = candidate;
- rtw89_fw_h2c_txpath_cmac_tbl(rtwdev, rtwsta);
+ rtw89_fw_h2c_txpath_cmac_tbl(rtwdev, rtwsta_link);
if (hal->antenna_tx == RF_A) {
rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE, B_P0_RFMODE_MUX, 0x12);
@@ -5738,6 +6491,37 @@ static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta
}
}
+static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta)
+{
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_dev *rtwdev = rtwsta->rtwdev;
+ struct rtw89_vif *rtwvif = rtwsta->rtwvif;
+ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
+ bool *done = data;
+
+ if (WARN(ieee80211_vif_is_mld(vif), "MLD mix path_div\n"))
+ return;
+
+ if (sta->tdls)
+ return;
+
+ if (*done)
+ return;
+
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+ if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION)
+ continue;
+
+ *done = true;
+ __rtw89_phy_tx_path_div_sta_iter(rtwdev, rtwsta_link);
+ return;
+ }
+}
+
void rtw89_phy_tx_path_div_track(struct rtw89_dev *rtwdev)
{
struct rtw89_hal *hal = &rtwdev->hal;
@@ -5846,17 +6630,17 @@ static void rtw89_phy_antdiv_training_state(struct rtw89_dev *rtwdev)
}
antdiv->training_count++;
- ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->antdiv_work,
- state_period);
+ wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->antdiv_work,
+ state_period);
}
-void rtw89_phy_antdiv_work(struct work_struct *work)
+void rtw89_phy_antdiv_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
antdiv_work.work);
struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv;
- mutex_lock(&rtwdev->mutex);
+ lockdep_assert_wiphy(wiphy);
if (antdiv->training_count <= ANTDIV_TRAINNING_CNT) {
rtw89_phy_antdiv_training_state(rtwdev);
@@ -5864,8 +6648,6 @@ void rtw89_phy_antdiv_work(struct work_struct *work)
rtw89_phy_antdiv_decision_state(rtwdev);
rtw89_phy_antdiv_set_ant(rtwdev);
}
-
- mutex_unlock(&rtwdev->mutex);
}
void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev)
@@ -5886,19 +6668,34 @@ void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev)
return;
antdiv->training_count = 0;
- ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->antdiv_work, 0);
+ wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->antdiv_work, 0);
+}
+
+static void __rtw89_phy_env_monitor_init(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
+{
+ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
+ "BB-%d env_monitor init\n", bb->phy_idx);
+
+ rtw89_phy_ccx_top_setting_init(rtwdev, bb);
+ rtw89_phy_ifs_clm_setting_init(rtwdev, bb);
}
static void rtw89_phy_env_monitor_init(struct rtw89_dev *rtwdev)
{
- rtw89_phy_ccx_top_setting_init(rtwdev);
- rtw89_phy_ifs_clm_setting_init(rtwdev);
+ struct rtw89_bb_ctx *bb;
+
+ rtw89_for_each_capab_bb(rtwdev, bb)
+ __rtw89_phy_env_monitor_init(rtwdev, bb);
}
-static void rtw89_phy_edcca_init(struct rtw89_dev *rtwdev)
+static void __rtw89_phy_edcca_init(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs;
- struct rtw89_edcca_bak *edcca_bak = &rtwdev->hal.edcca_bak;
+ struct rtw89_edcca_bak *edcca_bak = &bb->edcca_bak;
+
+ rtw89_debug(rtwdev, RTW89_DBG_EDCCA, "BB-%d edcca init\n", bb->phy_idx);
memset(edcca_bak, 0, sizeof(*edcca_bak));
@@ -5914,8 +6711,16 @@ static void rtw89_phy_edcca_init(struct rtw89_dev *rtwdev)
rtw89_phy_set_phy_regs(rtwdev, R_DFS_FFT_CG, B_DFS_FFT_EN, 1);
}
- rtw89_phy_write32_mask(rtwdev, edcca_regs->tx_collision_t2r_st,
- edcca_regs->tx_collision_t2r_st_mask, 0x29);
+ rtw89_phy_write32_idx(rtwdev, edcca_regs->tx_collision_t2r_st,
+ edcca_regs->tx_collision_t2r_st_mask, 0x29, bb->phy_idx);
+}
+
+static void rtw89_phy_edcca_init(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_bb_ctx *bb;
+
+ rtw89_for_each_capab_bb(rtwdev, bb)
+ __rtw89_phy_edcca_init(rtwdev, bb);
}
void rtw89_phy_dm_init(struct rtw89_dev *rtwdev)
@@ -5944,17 +6749,33 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev)
rtw89_chip_cfg_txrx_path(rtwdev);
}
-void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
+void rtw89_phy_dm_reinit(struct rtw89_dev *rtwdev)
+{
+ rtw89_phy_env_monitor_init(rtwdev);
+ rtw89_physts_parsing_init(rtwdev);
+}
+
+void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_reg_def *bss_clr_vld = &chip->bss_clr_vld;
- enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
+ enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
+ struct ieee80211_bss_conf *bss_conf;
u8 bss_color;
- if (!vif->bss_conf.he_support || !vif->cfg.assoc)
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ if (!bss_conf->he_support || !vif->cfg.assoc) {
+ rcu_read_unlock();
return;
+ }
- bss_color = vif->bss_conf.he_bss_color.color;
+ bss_color = bss_conf->he_bss_color.color;
+
+ rcu_read_unlock();
rtw89_phy_write32_idx(rtwdev, bss_clr_vld->addr, bss_clr_vld->mask, 0x1,
phy_idx);
@@ -5964,6 +6785,74 @@ void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif
vif->cfg.aid, phy_idx);
}
+static bool rfk_chan_validate_desc(const struct rtw89_rfk_chan_desc *desc)
+{
+ return desc->ch != 0;
+}
+
+static bool rfk_chan_is_equivalent(const struct rtw89_rfk_chan_desc *desc,
+ const struct rtw89_chan *chan)
+{
+ if (!rfk_chan_validate_desc(desc))
+ return false;
+
+ if (desc->ch != chan->channel)
+ return false;
+
+ if (desc->has_band && desc->band != chan->band_type)
+ return false;
+
+ if (desc->has_bw && desc->bw != chan->band_width)
+ return false;
+
+ return true;
+}
+
+struct rfk_chan_iter_data {
+ const struct rtw89_rfk_chan_desc desc;
+ unsigned int found;
+};
+
+static int rfk_chan_iter_search(const struct rtw89_chan *chan, void *data)
+{
+ struct rfk_chan_iter_data *iter_data = data;
+
+ if (rfk_chan_is_equivalent(&iter_data->desc, chan))
+ iter_data->found++;
+
+ return 0;
+}
+
+u8 rtw89_rfk_chan_lookup(struct rtw89_dev *rtwdev,
+ const struct rtw89_rfk_chan_desc *desc, u8 desc_nr,
+ const struct rtw89_chan *target_chan)
+{
+ int sel = -1;
+ u8 i;
+
+ for (i = 0; i < desc_nr; i++) {
+ struct rfk_chan_iter_data iter_data = {
+ .desc = desc[i],
+ };
+
+ if (rfk_chan_is_equivalent(&desc[i], target_chan))
+ return i;
+
+ rtw89_iterate_entity_chan(rtwdev, rfk_chan_iter_search, &iter_data);
+ if (!iter_data.found && sel == -1)
+ sel = i;
+ }
+
+ if (sel == -1) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "no idle rfk entry; force replace the first\n");
+ sel = 0;
+ }
+
+ return sel;
+}
+EXPORT_SYMBOL(rtw89_rfk_chan_lookup);
+
static void
_rfk_write_rf(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def)
{
@@ -6194,44 +7083,46 @@ void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx,
}
EXPORT_SYMBOL(rtw89_decode_chan_idx);
-void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, bool scan)
+void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb, bool scan)
{
const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs;
- struct rtw89_edcca_bak *edcca_bak = &rtwdev->hal.edcca_bak;
+ struct rtw89_edcca_bak *edcca_bak = &bb->edcca_bak;
if (scan) {
edcca_bak->a =
- rtw89_phy_read32_mask(rtwdev, edcca_regs->edcca_level,
- edcca_regs->edcca_mask);
+ rtw89_phy_read32_idx(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_mask, bb->phy_idx);
edcca_bak->p =
- rtw89_phy_read32_mask(rtwdev, edcca_regs->edcca_level,
- edcca_regs->edcca_p_mask);
+ rtw89_phy_read32_idx(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_p_mask, bb->phy_idx);
edcca_bak->ppdu =
- rtw89_phy_read32_mask(rtwdev, edcca_regs->ppdu_level,
- edcca_regs->ppdu_mask);
-
- rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level,
- edcca_regs->edcca_mask, EDCCA_MAX);
- rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level,
- edcca_regs->edcca_p_mask, EDCCA_MAX);
- rtw89_phy_write32_mask(rtwdev, edcca_regs->ppdu_level,
- edcca_regs->ppdu_mask, EDCCA_MAX);
+ rtw89_phy_read32_idx(rtwdev, edcca_regs->ppdu_level,
+ edcca_regs->ppdu_mask, bb->phy_idx);
+
+ rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_mask, EDCCA_MAX, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_p_mask, EDCCA_MAX, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, edcca_regs->ppdu_level,
+ edcca_regs->ppdu_mask, EDCCA_MAX, bb->phy_idx);
} else {
- rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level,
- edcca_regs->edcca_mask,
- edcca_bak->a);
- rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level,
- edcca_regs->edcca_p_mask,
- edcca_bak->p);
- rtw89_phy_write32_mask(rtwdev, edcca_regs->ppdu_level,
- edcca_regs->ppdu_mask,
- edcca_bak->ppdu);
+ rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_mask,
+ edcca_bak->a, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_p_mask,
+ edcca_bak->p, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, edcca_regs->ppdu_level,
+ edcca_regs->ppdu_mask,
+ edcca_bak->ppdu, bb->phy_idx);
}
}
-static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev)
+static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
{
const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs;
+ const struct rtw89_edcca_p_regs *edcca_p_regs;
bool flag_fb, flag_p20, flag_s20, flag_s40, flag_s80;
s8 pwdb_fb, pwdb_p20, pwdb_s20, pwdb_s40, pwdb_s80;
u8 path, per20_bitmap;
@@ -6241,13 +7132,18 @@ static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev)
if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_EDCCA))
return;
+ if (bb->phy_idx == RTW89_PHY_1)
+ edcca_p_regs = &edcca_regs->p[RTW89_PHY_1];
+ else
+ edcca_p_regs = &edcca_regs->p[RTW89_PHY_0];
+
if (rtwdev->chip->chip_id == RTL8922A)
rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be,
edcca_regs->rpt_sel_be_mask, 0);
- rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel,
- edcca_regs->rpt_sel_mask, 0);
- tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_b);
+ rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel,
+ edcca_p_regs->rpt_sel_mask, 0);
+ tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b);
path = u32_get_bits(tmp, B_EDCCA_RPT_B_PATH_MASK);
flag_s80 = u32_get_bits(tmp, B_EDCCA_RPT_B_S80);
flag_s40 = u32_get_bits(tmp, B_EDCCA_RPT_B_S40);
@@ -6258,19 +7154,19 @@ static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev)
pwdb_p20 = u32_get_bits(tmp, MASKBYTE2);
pwdb_fb = u32_get_bits(tmp, MASKBYTE3);
- rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel,
- edcca_regs->rpt_sel_mask, 4);
- tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_b);
+ rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel,
+ edcca_p_regs->rpt_sel_mask, 4);
+ tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b);
pwdb_s80 = u32_get_bits(tmp, MASKBYTE1);
pwdb_s40 = u32_get_bits(tmp, MASKBYTE2);
- per20_bitmap = rtw89_phy_read32_mask(rtwdev, edcca_regs->rpt_a,
+ per20_bitmap = rtw89_phy_read32_mask(rtwdev, edcca_p_regs->rpt_a,
MASKBYTE0);
if (rtwdev->chip->chip_id == RTL8922A) {
rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be,
edcca_regs->rpt_sel_be_mask, 4);
- tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_b);
+ tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b);
pwdb[0] = u32_get_bits(tmp, MASKBYTE3);
pwdb[1] = u32_get_bits(tmp, MASKBYTE2);
pwdb[2] = u32_get_bits(tmp, MASKBYTE1);
@@ -6278,33 +7174,33 @@ static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev)
rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be,
edcca_regs->rpt_sel_be_mask, 5);
- tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_b);
+ tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b);
pwdb[4] = u32_get_bits(tmp, MASKBYTE3);
pwdb[5] = u32_get_bits(tmp, MASKBYTE2);
pwdb[6] = u32_get_bits(tmp, MASKBYTE1);
pwdb[7] = u32_get_bits(tmp, MASKBYTE0);
} else {
- rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel,
- edcca_regs->rpt_sel_mask, 0);
- tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_a);
+ rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel,
+ edcca_p_regs->rpt_sel_mask, 0);
+ tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a);
pwdb[0] = u32_get_bits(tmp, MASKBYTE3);
pwdb[1] = u32_get_bits(tmp, MASKBYTE2);
- rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel,
- edcca_regs->rpt_sel_mask, 1);
- tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_a);
+ rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel,
+ edcca_p_regs->rpt_sel_mask, 1);
+ tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a);
pwdb[2] = u32_get_bits(tmp, MASKBYTE3);
pwdb[3] = u32_get_bits(tmp, MASKBYTE2);
- rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel,
- edcca_regs->rpt_sel_mask, 2);
- tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_a);
+ rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel,
+ edcca_p_regs->rpt_sel_mask, 2);
+ tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a);
pwdb[4] = u32_get_bits(tmp, MASKBYTE3);
pwdb[5] = u32_get_bits(tmp, MASKBYTE2);
- rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel,
- edcca_regs->rpt_sel_mask, 3);
- tmp = rtw89_phy_read32(rtwdev, edcca_regs->rpt_a);
+ rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel,
+ edcca_p_regs->rpt_sel_mask, 3);
+ tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a);
pwdb[6] = u32_get_bits(tmp, MASKBYTE3);
pwdb[7] = u32_get_bits(tmp, MASKBYTE2);
}
@@ -6326,9 +7222,10 @@ static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev)
pwdb_fb, pwdb_p20, pwdb_s20, pwdb_s40, pwdb_s80);
}
-static u8 rtw89_phy_edcca_get_thre_by_rssi(struct rtw89_dev *rtwdev)
+static u8 rtw89_phy_edcca_get_thre_by_rssi(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb)
{
- struct rtw89_phy_ch_info *ch_info = &rtwdev->ch_info;
+ struct rtw89_phy_ch_info *ch_info = &bb->ch_info;
bool is_linked = rtwdev->total_sta_assoc > 0;
u8 rssi_min = ch_info->rssi_min >> 1;
u8 edcca_thre;
@@ -6344,13 +7241,13 @@ static u8 rtw89_phy_edcca_get_thre_by_rssi(struct rtw89_dev *rtwdev)
return edcca_thre;
}
-void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev)
+void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
{
const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs;
- struct rtw89_edcca_bak *edcca_bak = &rtwdev->hal.edcca_bak;
+ struct rtw89_edcca_bak *edcca_bak = &bb->edcca_bak;
u8 th;
- th = rtw89_phy_edcca_get_thre_by_rssi(rtwdev);
+ th = rtw89_phy_edcca_get_thre_by_rssi(rtwdev, bb);
if (th == edcca_bak->th_old)
return;
@@ -6359,23 +7256,33 @@ void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_EDCCA,
"[EDCCA]: Normal Mode, EDCCA_th = %d\n", th);
- rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level,
- edcca_regs->edcca_mask, th);
- rtw89_phy_write32_mask(rtwdev, edcca_regs->edcca_level,
- edcca_regs->edcca_p_mask, th);
- rtw89_phy_write32_mask(rtwdev, edcca_regs->ppdu_level,
- edcca_regs->ppdu_mask, th);
+ rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_mask, th, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level,
+ edcca_regs->edcca_p_mask, th, bb->phy_idx);
+ rtw89_phy_write32_idx(rtwdev, edcca_regs->ppdu_level,
+ edcca_regs->ppdu_mask, th, bb->phy_idx);
+}
+
+static
+void __rtw89_phy_edcca_track(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
+{
+ rtw89_debug(rtwdev, RTW89_DBG_EDCCA, "BB-%d edcca track\n", bb->phy_idx);
+
+ rtw89_phy_edcca_thre_calc(rtwdev, bb);
+ rtw89_phy_edcca_log(rtwdev, bb);
}
void rtw89_phy_edcca_track(struct rtw89_dev *rtwdev)
{
struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_bb_ctx *bb;
if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DYNAMIC_EDCCA))
return;
- rtw89_phy_edcca_thre_calc(rtwdev);
- rtw89_phy_edcca_log(rtwdev);
+ rtw89_for_each_active_bb(rtwdev, bb)
+ __rtw89_phy_edcca_track(rtwdev, bb);
}
enum rtw89_rf_path_bit rtw89_phy_get_kpath(struct rtw89_dev *rtwdev,
@@ -6398,10 +7305,8 @@ enum rtw89_rf_path_bit rtw89_phy_get_kpath(struct rtw89_dev *rtwdev,
return RF_D;
case MLO_0_PLUS_2_1RF:
case MLO_2_PLUS_0_1RF:
- if (phy_idx == RTW89_PHY_0)
- return RF_AB;
- else
- return RF_AB;
+ /* for both PHY 0/1 */
+ return RF_AB;
case MLO_0_PLUS_2_2RF:
case MLO_2_PLUS_0_2RF:
case MLO_2_PLUS_2_2RF:
diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h
index 082231ebbee5..5b451f1cfaac 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.h
+++ b/drivers/net/wireless/realtek/rtw89/phy.h
@@ -51,13 +51,17 @@
#define RA_MASK_EHT_2SS_RATES GENMASK_ULL(43, 28)
#define RA_MASK_EHT_3SS_RATES GENMASK_ULL(59, 44)
#define RA_MASK_EHT_4SS_RATES GENMASK_ULL(62, 60)
+#define RA_MASK_EHT_1SS_MCS0_11 GENMASK_ULL(23, 12)
+#define RA_MASK_EHT_2SS_MCS0_11 GENMASK_ULL(39, 28)
+#define RA_MASK_EHT_3SS_MCS0_11 GENMASK_ULL(55, 44)
+#define RA_MASK_EHT_4SS_MCS0_11 GENMASK_ULL(62, 60)
#define RA_MASK_EHT_RATES GENMASK_ULL(62, 12)
#define CFO_TRK_ENABLE_TH (2 << 2)
#define CFO_TRK_STOP_TH_4 (30 << 2)
#define CFO_TRK_STOP_TH_3 (20 << 2)
#define CFO_TRK_STOP_TH_2 (10 << 2)
-#define CFO_TRK_STOP_TH_1 (00 << 2)
+#define CFO_TRK_STOP_TH_1 (03 << 2)
#define CFO_TRK_STOP_TH (2 << 2)
#define CFO_SW_COMP_FINE_TUNE (2 << 2)
#define CFO_PERIOD_CNT 15
@@ -129,6 +133,7 @@
#define EDCCA_HL_DIFF_NORMAL 8
#define RSSI_UNIT_CONVER 110
#define EDCCA_UNIT_CONVER 128
+#define EDCCA_PWROFST_DEFAULT 18
enum rtw89_phy_c2h_ra_func {
RTW89_PHY_C2H_FUNC_STS_RPT,
@@ -150,6 +155,7 @@ enum rtw89_phy_c2h_rfk_log_func {
enum rtw89_phy_c2h_rfk_report_func {
RTW89_PHY_C2H_RFK_REPORT_FUNC_STATE = 0,
+ RTW89_PHY_C2H_RFK_LOG_TAS_PWR = 6,
};
enum rtw89_phy_c2h_dm_func {
@@ -158,6 +164,7 @@ enum rtw89_phy_c2h_dm_func {
RTW89_PHY_C2H_DM_FUNC_SIGB,
RTW89_PHY_C2H_DM_FUNC_LOWRT_RTY,
RTW89_PHY_C2H_DM_FUNC_MCC_DIG,
+ RTW89_PHY_C2H_DM_FUNC_FW_SCAN = 0xc,
RTW89_PHY_C2H_DM_FUNC_NUM,
};
@@ -714,6 +721,19 @@ enum rtw89_phy_gain_band_be rtw89_subband_to_gain_band_be(enum rtw89_subband sub
}
}
+struct rtw89_rfk_chan_desc {
+ /* desc is valid iff ch is non-zero */
+ u8 ch;
+
+ /* To avoid us from extending old chip code every time, each new
+ * field must be defined along with a bool flag in positivte way.
+ */
+ bool has_band;
+ u8 band;
+ bool has_bw;
+ u8 bw;
+};
+
enum rtw89_rfk_flag {
RTW89_RFK_F_WRF = 0,
RTW89_RFK_F_WM = 1,
@@ -799,8 +819,13 @@ void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev,
enum rtw89_rf_path rf_path,
void *extra_data);
void rtw89_phy_dm_init(struct rtw89_dev *rtwdev);
+void rtw89_phy_dm_reinit(struct rtw89_dev *rtwdev);
void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
u32 data, enum rtw89_phy_idx phy_idx);
+void rtw89_phy_write32_idx_set(struct rtw89_dev *rtwdev, u32 addr, u32 bits,
+ enum rtw89_phy_idx phy_idx);
+void rtw89_phy_write32_idx_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bits,
+ enum rtw89_phy_idx phy_idx);
u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
enum rtw89_phy_idx phy_idx);
s8 *rtw89_phy_raw_byr_seek(struct rtw89_dev *rtwdev,
@@ -808,6 +833,11 @@ s8 *rtw89_phy_raw_byr_seek(struct rtw89_dev *rtwdev,
const struct rtw89_rate_desc *desc);
s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band, u8 bw,
const struct rtw89_rate_desc *rate_desc);
+void rtw89_phy_ant_gain_init(struct rtw89_dev *rtwdev);
+s16 rtw89_phy_ant_gain_pwr_offset(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan);
+int rtw89_print_ant_gain(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
+ const struct rtw89_chan *chan);
void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev,
const struct rtw89_txpwr_table *tbl);
s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
@@ -878,10 +908,55 @@ void rtw89_phy_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
phy->set_txpwr_limit_ru(rtwdev, chan, phy_idx);
}
-void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta);
+static inline s8 rtw89_phy_txpwr_rf_to_bb(struct rtw89_dev *rtwdev, s8 txpwr_rf)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+
+ return txpwr_rf << (chip->txpwr_factor_bb - chip->txpwr_factor_rf);
+}
+
+static inline s8 rtw89_phy_txpwr_bb_to_rf(struct rtw89_dev *rtwdev, s8 txpwr_bb)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+
+ return txpwr_bb >> (chip->txpwr_factor_bb - chip->txpwr_factor_rf);
+}
+
+static inline s8 rtw89_phy_txpwr_rf_to_mac(struct rtw89_dev *rtwdev, s8 txpwr_rf)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+
+ return txpwr_rf >> (chip->txpwr_factor_rf - chip->txpwr_factor_mac);
+}
+
+static inline s8 rtw89_phy_txpwr_dbm_to_mac(struct rtw89_dev *rtwdev, s8 dbm)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+
+ return clamp_t(s16, dbm << chip->txpwr_factor_mac, -64, 63);
+}
+
+static inline s16 rtw89_phy_txpwr_mac_to_rf(struct rtw89_dev *rtwdev, s8 txpwr_mac)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+
+ return txpwr_mac << (chip->txpwr_factor_rf - chip->txpwr_factor_mac);
+}
+
+static inline s16 rtw89_phy_txpwr_mac_to_bb(struct rtw89_dev *rtwdev, s8 txpwr_mac)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+
+ return txpwr_mac << (chip->txpwr_factor_bb - chip->txpwr_factor_mac);
+}
+
+void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link);
void rtw89_phy_ra_update(struct rtw89_dev *rtwdev);
-void rtw89_phy_ra_updata_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta,
+void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta,
u32 changed);
+void rtw89_phy_ra_update_sta_link(struct rtw89_dev *rtwdev,
+ struct rtw89_sta_link *rtwsta_link,
+ u32 changed);
void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
const struct cfg80211_bitrate_mask *mask);
@@ -893,23 +968,29 @@ int rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev *rtwdev,
unsigned int ms);
int rtw89_phy_rfk_tssi_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan,
enum rtw89_tssi_mode tssi_mode,
unsigned int ms);
int rtw89_phy_rfk_iqk_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan,
unsigned int ms);
int rtw89_phy_rfk_dpk_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan,
unsigned int ms);
int rtw89_phy_rfk_txgapk_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan,
unsigned int ms);
int rtw89_phy_rfk_dack_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan,
unsigned int ms);
int rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
- unsigned int ms);
+ const struct rtw89_chan *chan,
+ bool is_chl_k, unsigned int ms);
void rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy,
const struct rtw89_chan *chan,
@@ -919,35 +1000,40 @@ void rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
struct rtw89_h2c_rf_tssi *h2c);
void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev);
-void rtw89_phy_cfo_track_work(struct work_struct *work);
+void rtw89_phy_cfo_track_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val,
struct rtw89_rx_phy_ppdu *phy_ppdu);
void rtw89_phy_stat_track(struct rtw89_dev *rtwdev);
void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev);
void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
u32 val);
-void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev);
+void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb);
void rtw89_phy_dig(struct rtw89_dev *rtwdev);
void rtw89_phy_tx_path_div_track(struct rtw89_dev *rtwdev);
void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu);
void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev);
-void rtw89_phy_antdiv_work(struct work_struct *work);
-void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
+void rtw89_phy_antdiv_work(struct wiphy *wiphy, struct wiphy_work *work);
+void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev,
enum rtw89_mac_idx mac_idx,
enum rtw89_tssi_bandedge_cfg bandedge_cfg);
-void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev);
u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band);
void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx,
u8 *ch, enum nl80211_band *band);
-void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, bool scan);
+void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev,
+ struct rtw89_bb_ctx *bb, bool scan);
void rtw89_phy_edcca_track(struct rtw89_dev *rtwdev);
-void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev);
+void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb);
enum rtw89_rf_path_bit rtw89_phy_get_kpath(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx);
enum rtw89_rf_path rtw89_phy_get_syn_sel(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx);
+u8 rtw89_rfk_chan_lookup(struct rtw89_dev *rtwdev,
+ const struct rtw89_rfk_chan_desc *desc, u8 desc_nr,
+ const struct rtw89_chan *target_chan);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/phy_be.c b/drivers/net/wireless/realtek/rtw89/phy_be.c
index be0148f2b96f..d321cf1fc485 100644
--- a/drivers/net/wireless/realtek/rtw89/phy_be.c
+++ b/drivers/net/wireless/realtek/rtw89/phy_be.c
@@ -362,7 +362,7 @@ static void rtw89_phy_bb_wrap_force_cr_init(struct rtw89_dev *rtwdev,
rtw89_write32_mask(rtwdev, addr, B_BE_PWR_FORCE_RU_ENON, 0);
rtw89_write32_mask(rtwdev, addr, B_BE_PWR_FORCE_RU_ON, 0);
addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_FORCE_MACID, mac_idx);
- rtw89_write32_mask(rtwdev, addr, B_BE_PWR_FORCE_MACID_ON, 0);
+ rtw89_write32_mask(rtwdev, addr, B_BE_PWR_FORCE_MACID_ALL, 0);
addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_COEX_CTRL, mac_idx);
rtw89_write32_mask(rtwdev, addr, B_BE_PWR_FORCE_COEX_ON, 0);
addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_RATE_CTRL, mac_idx);
@@ -381,16 +381,40 @@ static void rtw89_phy_bb_wrap_ftm_init(struct rtw89_dev *rtwdev,
rtw89_write32_mask(rtwdev, addr, 0x7, 0);
}
-static void rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev)
+static void rtw89_phy_bb_wrap_ul_pwr(struct rtw89_dev *rtwdev)
{
- enum rtw89_mac_idx mac_idx = RTW89_MAC_0;
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
+ u8 mac_idx;
+ u32 addr;
+
+ if (chip_id != RTL8922A)
+ return;
+
+ for (mac_idx = 0; mac_idx < RTW89_MAC_NUM; mac_idx++) {
+ addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_RSSI_TARGET_LMT, mac_idx);
+ rtw89_write32(rtwdev, addr, 0x0201FE00);
+ addr = rtw89_mac_reg_by_idx(rtwdev, R_BE_PWR_TH, mac_idx);
+ rtw89_write32(rtwdev, addr, 0x00FFEC7E);
+ }
+}
+static void __rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev,
+ enum rtw89_mac_idx mac_idx)
+{
rtw89_phy_bb_wrap_pwr_by_macid_init(rtwdev);
rtw89_phy_bb_wrap_tx_path_by_macid_init(rtwdev);
rtw89_phy_bb_wrap_listen_path_en_init(rtwdev);
rtw89_phy_bb_wrap_force_cr_init(rtwdev, mac_idx);
rtw89_phy_bb_wrap_ftm_init(rtwdev, mac_idx);
rtw89_phy_bb_wrap_tpu_set_all(rtwdev, mac_idx);
+ rtw89_phy_bb_wrap_ul_pwr(rtwdev);
+}
+
+static void rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev)
+{
+ __rtw89_phy_bb_wrap_init_be(rtwdev, RTW89_MAC_0);
+ if (rtwdev->dbcc_en)
+ __rtw89_phy_bb_wrap_init_be(rtwdev, RTW89_MAC_1);
}
static void rtw89_phy_ch_info_init_be(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c
index 31290d8cb7f7..8e4fe73e7d77 100644
--- a/drivers/net/wireless/realtek/rtw89/ps.c
+++ b/drivers/net/wireless/realtek/rtw89/ps.c
@@ -8,6 +8,7 @@
#include "debug.h"
#include "fw.h"
#include "mac.h"
+#include "phy.h"
#include "ps.h"
#include "reg.h"
#include "util.h"
@@ -55,17 +56,15 @@ static void rtw89_ps_power_mode_change_with_hci(struct rtw89_dev *rtwdev,
static void rtw89_ps_power_mode_change(struct rtw89_dev *rtwdev, bool enter)
{
- if (rtwdev->chip->low_power_hci_modes & BIT(rtwdev->ps_mode))
+ if (rtwdev->chip->low_power_hci_modes & BIT(rtwdev->ps_mode) &&
+ !test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags))
rtw89_ps_power_mode_change_with_hci(rtwdev, enter);
else
rtw89_mac_power_mode_change(rtwdev, enter);
}
-void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev)
{
- if (rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)
- return;
-
if (!rtwdev->ps_mode)
return;
@@ -84,23 +83,24 @@ void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
rtw89_ps_power_mode_change(rtwdev, false);
}
-static void __rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void __rtw89_enter_lps_link(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_lps_parm lps_param = {
- .macid = rtwvif->mac_id,
+ .macid = rtwvif_link->mac_id,
.psmode = RTW89_MAC_AX_PS_MODE_LEGACY,
.lastrpwm = RTW89_LAST_RPWM_PS,
};
rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_FW_CTRL);
rtw89_fw_h2c_lps_parm(rtwdev, &lps_param);
- rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif);
}
-static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, u8 mac_id)
+static void __rtw89_leave_lps(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_lps_parm lps_param = {
- .macid = mac_id,
+ .macid = rtwvif_link->mac_id,
.psmode = RTW89_MAC_AX_PS_MODE_ACTIVE,
.lastrpwm = RTW89_LAST_RPWM_ACTIVE,
};
@@ -108,11 +108,12 @@ static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, u8 mac_id)
rtw89_fw_h2c_lps_parm(rtwdev, &lps_param);
rtw89_fw_leave_lps_check(rtwdev, 0);
rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON);
+ rtw89_chip_digital_pwr_comp(rtwdev, rtwvif_link->phy_idx);
}
void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
{
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
__rtw89_leave_ps_mode(rtwdev);
}
@@ -120,43 +121,66 @@ void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
bool ps_mode)
{
- lockdep_assert_held(&rtwdev->mutex);
+ struct rtw89_vif_link *rtwvif_link;
+ bool can_ps_mode = true;
+ unsigned int link_id;
+
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (test_and_set_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags))
return;
- __rtw89_enter_lps(rtwdev, rtwvif);
- if (ps_mode)
- __rtw89_enter_ps_mode(rtwdev, rtwvif);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ __rtw89_enter_lps_link(rtwdev, rtwvif_link);
+
+ if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)
+ can_ps_mode = false;
+ }
+
+ if (RTW89_CHK_FW_FEATURE(LPS_CH_INFO, &rtwdev->fw))
+ rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif);
+ else
+ rtw89_fw_h2c_lps_ml_cmn_info(rtwdev, rtwvif);
+
+ if (ps_mode && can_ps_mode)
+ __rtw89_enter_ps_mode(rtwdev);
}
-static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION &&
- rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT)
+ if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION &&
+ rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT)
return;
- __rtw89_leave_lps(rtwdev, rtwvif->mac_id);
+ __rtw89_leave_lps(rtwdev, rtwvif_link);
}
void rtw89_leave_lps(struct rtw89_dev *rtwdev)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (!test_and_clear_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags))
return;
__rtw89_leave_ps_mode(rtwdev);
+ rtw89_phy_dm_reinit(rtwdev);
+
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_leave_lps_vif(rtwdev, rtwvif);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_leave_lps_vif(rtwdev, rtwvif_link);
}
void rtw89_enter_ips(struct rtw89_dev *rtwdev)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
set_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags);
@@ -164,14 +188,17 @@ void rtw89_enter_ips(struct rtw89_dev *rtwdev)
return;
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_mac_vif_deinit(rtwdev, rtwvif);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_mac_vif_deinit(rtwdev, rtwvif_link);
rtw89_core_stop(rtwdev);
}
void rtw89_leave_ips(struct rtw89_dev *rtwdev)
{
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
int ret;
if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
@@ -184,7 +211,8 @@ void rtw89_leave_ips(struct rtw89_dev *rtwdev)
rtw89_set_channel(rtwdev);
rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_mac_vif_init(rtwdev, rtwvif);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_mac_vif_init(rtwdev, rtwvif_link);
clear_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags);
}
@@ -195,48 +223,50 @@ void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl)
rtw89_leave_lps(rtwdev);
}
-static void rtw89_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
+static void rtw89_tsf32_toggle(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
enum rtw89_p2pps_action act)
{
if (act == RTW89_P2P_ACT_UPDATE || act == RTW89_P2P_ACT_REMOVE)
return;
if (act == RTW89_P2P_ACT_INIT)
- rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif, true);
+ rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif_link, true);
else if (act == RTW89_P2P_ACT_TERMINATE)
- rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif, false);
+ rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif_link, false);
}
static void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif)
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
enum rtw89_p2pps_action act;
u8 noa_id;
- if (rtwvif->last_noa_nr == 0)
+ if (rtwvif_link->last_noa_nr == 0)
return;
- for (noa_id = 0; noa_id < rtwvif->last_noa_nr; noa_id++) {
- if (noa_id == rtwvif->last_noa_nr - 1)
+ for (noa_id = 0; noa_id < rtwvif_link->last_noa_nr; noa_id++) {
+ if (noa_id == rtwvif_link->last_noa_nr - 1)
act = RTW89_P2P_ACT_TERMINATE;
else
act = RTW89_P2P_ACT_REMOVE;
- rtw89_tsf32_toggle(rtwdev, rtwvif, act);
- rtw89_fw_h2c_p2p_act(rtwdev, vif, NULL, act, noa_id);
+ rtw89_tsf32_toggle(rtwdev, rtwvif_link, act);
+ rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, bss_conf,
+ NULL, act, noa_id);
}
}
static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev,
- struct ieee80211_vif *vif)
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct ieee80211_p2p_noa_desc *desc;
enum rtw89_p2pps_action act;
u8 noa_id;
for (noa_id = 0; noa_id < RTW89_P2P_MAX_NOA_NUM; noa_id++) {
- desc = &vif->bss_conf.p2p_noa_attr.desc[noa_id];
+ desc = &bss_conf->p2p_noa_attr.desc[noa_id];
if (!desc->count || !desc->duration)
break;
@@ -244,16 +274,19 @@ static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev,
act = RTW89_P2P_ACT_INIT;
else
act = RTW89_P2P_ACT_UPDATE;
- rtw89_tsf32_toggle(rtwdev, rtwvif, act);
- rtw89_fw_h2c_p2p_act(rtwdev, vif, desc, act, noa_id);
+ rtw89_tsf32_toggle(rtwdev, rtwvif_link, act);
+ rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, bss_conf,
+ desc, act, noa_id);
}
- rtwvif->last_noa_nr = noa_id;
+ rtwvif_link->last_noa_nr = noa_id;
}
-void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
+void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf)
{
- rtw89_p2p_disable_all_noa(rtwdev, vif);
- rtw89_p2p_update_noa(rtwdev, vif);
+ rtw89_p2p_disable_all_noa(rtwdev, rtwvif_link, bss_conf);
+ rtw89_p2p_update_noa(rtwdev, rtwvif_link, bss_conf);
}
void rtw89_recalc_lps(struct rtw89_dev *rtwdev)
@@ -289,9 +322,9 @@ disable_lps:
rtwdev->lps_enabled = false;
}
-void rtw89_p2p_noa_renew(struct rtw89_vif *rtwvif)
+void rtw89_p2p_noa_renew(struct rtw89_vif_link *rtwvif_link)
{
- struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa;
+ struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa;
struct rtw89_p2p_noa_ie *ie = &setter->ie;
struct rtw89_p2p_ie_head *p2p_head = &ie->p2p_head;
struct rtw89_noa_attr_head *noa_head = &ie->noa_head;
@@ -316,10 +349,10 @@ void rtw89_p2p_noa_renew(struct rtw89_vif *rtwvif)
noa_head->oppps_ctwindow = 0;
}
-void rtw89_p2p_noa_append(struct rtw89_vif *rtwvif,
+void rtw89_p2p_noa_append(struct rtw89_vif_link *rtwvif_link,
const struct ieee80211_p2p_noa_desc *desc)
{
- struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa;
+ struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa;
struct rtw89_p2p_noa_ie *ie = &setter->ie;
struct rtw89_p2p_ie_head *p2p_head = &ie->p2p_head;
struct rtw89_noa_attr_head *noa_head = &ie->noa_head;
@@ -336,9 +369,9 @@ void rtw89_p2p_noa_append(struct rtw89_vif *rtwvif,
ie->noa_desc[setter->noa_count++] = *desc;
}
-u8 rtw89_p2p_noa_fetch(struct rtw89_vif *rtwvif, void **data)
+u8 rtw89_p2p_noa_fetch(struct rtw89_vif_link *rtwvif_link, void **data)
{
- struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa;
+ struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa;
struct rtw89_p2p_noa_ie *ie = &setter->ie;
void *tail;
@@ -349,3 +382,150 @@ u8 rtw89_p2p_noa_fetch(struct rtw89_vif *rtwvif, void **data)
tail = ie->noa_desc + setter->noa_count;
return tail - *data;
}
+
+static void rtw89_ps_noa_once_set_work(struct wiphy *wiphy, struct wiphy_work *work)
+{
+ struct rtw89_ps_noa_once_handler *noa_once =
+ container_of(work, struct rtw89_ps_noa_once_handler, set_work.work);
+
+ lockdep_assert_wiphy(wiphy);
+
+ noa_once->in_duration = true;
+}
+
+static void rtw89_ps_noa_once_clr_work(struct wiphy *wiphy, struct wiphy_work *work)
+{
+ struct rtw89_ps_noa_once_handler *noa_once =
+ container_of(work, struct rtw89_ps_noa_once_handler, clr_work.work);
+ struct rtw89_vif_link *rtwvif_link =
+ container_of(noa_once, struct rtw89_vif_link, noa_once);
+ struct rtw89_dev *rtwdev = rtwvif_link->rtwvif->rtwdev;
+
+ lockdep_assert_wiphy(wiphy);
+
+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
+ noa_once->in_duration = false;
+}
+
+void rtw89_p2p_noa_once_init(struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_ps_noa_once_handler *noa_once = &rtwvif_link->noa_once;
+
+ noa_once->in_duration = false;
+ noa_once->tsf_begin = 0;
+ noa_once->tsf_end = 0;
+
+ wiphy_delayed_work_init(&noa_once->set_work, rtw89_ps_noa_once_set_work);
+ wiphy_delayed_work_init(&noa_once->clr_work, rtw89_ps_noa_once_clr_work);
+}
+
+static void rtw89_p2p_noa_once_cancel(struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_ps_noa_once_handler *noa_once = &rtwvif_link->noa_once;
+ struct rtw89_dev *rtwdev = rtwvif_link->rtwvif->rtwdev;
+ struct wiphy *wiphy = rtwdev->hw->wiphy;
+
+ wiphy_delayed_work_cancel(wiphy, &noa_once->set_work);
+ wiphy_delayed_work_cancel(wiphy, &noa_once->clr_work);
+}
+
+void rtw89_p2p_noa_once_deinit(struct rtw89_vif_link *rtwvif_link)
+{
+ rtw89_p2p_noa_once_cancel(rtwvif_link);
+ rtw89_p2p_noa_once_init(rtwvif_link);
+}
+
+void rtw89_p2p_noa_once_recalc(struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_ps_noa_once_handler *noa_once = &rtwvif_link->noa_once;
+ struct rtw89_dev *rtwdev = rtwvif_link->rtwvif->rtwdev;
+ const struct ieee80211_p2p_noa_desc *noa_desc;
+ struct wiphy *wiphy = rtwdev->hw->wiphy;
+ struct ieee80211_bss_conf *bss_conf;
+ u64 tsf_begin = U64_MAX, tsf_end;
+ u64 set_delay_us = 0;
+ u64 clr_delay_us = 0;
+ u32 start_time;
+ u32 interval;
+ u32 duration;
+ u64 tsf;
+ int ret;
+ int i;
+
+ lockdep_assert_wiphy(wiphy);
+
+ ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
+ if (ret) {
+ rtw89_warn(rtwdev, "%s: failed to get tsf\n", __func__);
+ return;
+ }
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
+ for (i = 0; i < ARRAY_SIZE(bss_conf->p2p_noa_attr.desc); i++) {
+ bool first = tsf_begin == U64_MAX;
+ u64 tmp;
+
+ noa_desc = &bss_conf->p2p_noa_attr.desc[i];
+ if (noa_desc->count == 0 || noa_desc->count == 255)
+ continue;
+
+ start_time = le32_to_cpu(noa_desc->start_time);
+ interval = le32_to_cpu(noa_desc->interval);
+ duration = le32_to_cpu(noa_desc->duration);
+
+ if (unlikely(duration == 0 ||
+ (noa_desc->count > 1 && interval == 0)))
+ continue;
+
+ tmp = start_time + interval * (noa_desc->count - 1) + duration;
+ tmp = (tsf & GENMASK_ULL(63, 32)) + tmp;
+ if (unlikely(tmp <= tsf))
+ continue;
+ tsf_end = first ? tmp : max(tsf_end, tmp);
+
+ tmp = (tsf & GENMASK_ULL(63, 32)) | start_time;
+ tsf_begin = first ? tmp : min(tsf_begin, tmp);
+ }
+
+ rcu_read_unlock();
+
+ if (tsf_begin == U64_MAX)
+ return;
+
+ rtw89_p2p_noa_once_cancel(rtwvif_link);
+
+ if (noa_once->tsf_end > tsf) {
+ tsf_begin = min(tsf_begin, noa_once->tsf_begin);
+ tsf_end = max(tsf_end, noa_once->tsf_end);
+ }
+
+ clr_delay_us = min_t(u64, tsf_end - tsf, UINT_MAX);
+
+ if (tsf_begin <= tsf) {
+ noa_once->in_duration = true;
+ goto out;
+ }
+
+ set_delay_us = tsf_begin - tsf;
+ if (unlikely(set_delay_us > UINT_MAX)) {
+ rtw89_warn(rtwdev, "%s: unhandled begin\n", __func__);
+ set_delay_us = 0;
+ clr_delay_us = 0;
+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
+ noa_once->in_duration = false;
+ }
+
+out:
+ if (set_delay_us)
+ wiphy_delayed_work_queue(wiphy, &noa_once->set_work,
+ usecs_to_jiffies(set_delay_us));
+ if (clr_delay_us)
+ wiphy_delayed_work_queue(wiphy, &noa_once->clr_work,
+ usecs_to_jiffies(clr_delay_us));
+
+ noa_once->tsf_begin = tsf_begin;
+ noa_once->tsf_end = tsf_end;
+}
diff --git a/drivers/net/wireless/realtek/rtw89/ps.h b/drivers/net/wireless/realtek/rtw89/ps.h
index 54486e4550b6..b2c43d44820d 100644
--- a/drivers/net/wireless/realtek/rtw89/ps.h
+++ b/drivers/net/wireless/realtek/rtw89/ps.h
@@ -9,17 +9,22 @@ void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
bool ps_mode);
void rtw89_leave_lps(struct rtw89_dev *rtwdev);
void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev);
-void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
+void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev);
void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev);
void rtw89_enter_ips(struct rtw89_dev *rtwdev);
void rtw89_leave_ips(struct rtw89_dev *rtwdev);
void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl);
-void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
+void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ struct ieee80211_bss_conf *bss_conf);
void rtw89_recalc_lps(struct rtw89_dev *rtwdev);
-void rtw89_p2p_noa_renew(struct rtw89_vif *rtwvif);
-void rtw89_p2p_noa_append(struct rtw89_vif *rtwvif,
+void rtw89_p2p_noa_renew(struct rtw89_vif_link *rtwvif_link);
+void rtw89_p2p_noa_append(struct rtw89_vif_link *rtwvif_link,
const struct ieee80211_p2p_noa_desc *desc);
-u8 rtw89_p2p_noa_fetch(struct rtw89_vif *rtwvif, void **data);
+u8 rtw89_p2p_noa_fetch(struct rtw89_vif_link *rtwvif_link, void **data);
+void rtw89_p2p_noa_once_init(struct rtw89_vif_link *rtwvif_link);
+void rtw89_p2p_noa_once_deinit(struct rtw89_vif_link *rtwvif_link);
+void rtw89_p2p_noa_once_recalc(struct rtw89_vif_link *rtwvif_link);
static inline void rtw89_leave_ips_by_hwflags(struct rtw89_dev *rtwdev)
{
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index 72e448e91b6f..f05c81ae5869 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -107,6 +107,15 @@
#define B_AX_DBG_SEL0_16BIT BIT(11)
#define B_AX_DBG_SEL0 GENMASK(7, 0)
+#define R_AX_GPIO_EXT_CTRL 0x0060
+#define B_AX_GPIO_MOD_15_TO_8_MASK GENMASK(31, 24)
+#define B_AX_GPIO_MOD_9 BIT(25)
+#define B_AX_GPIO_IO_SEL_15_TO_8_MASK GENMASK(23, 16)
+#define B_AX_GPIO_IO_SEL_9 BIT(17)
+#define B_AX_GPIO_OUT_15_TO_8_MASK GENMASK(15, 8)
+#define B_AX_GPIO_IN_15_TO_8_MASK GENMASK(7, 0)
+#define B_AX_GPIO_IN_9 BIT(1)
+
#define R_AX_SYS_SDIO_CTRL 0x0070
#define B_AX_PCIE_DIS_L2_CTRL_LDO_HCI BIT(15)
#define B_AX_PCIE_DIS_WLSUS_AFT_PDN BIT(14)
@@ -187,6 +196,8 @@
#define R_AX_HALT_C2H 0x016C
#define R_AX_WCPU_FW_CTRL 0x01E0
+#define B_AX_IDMEM_SHARE_MODE_RECORD_MASK GENMASK(27, 24)
+#define B_AX_IDMEM_SHARE_MODE_RECORD_VALID BIT(23)
#define B_AX_WCPU_FWDL_STS_MASK GENMASK(7, 5)
#define B_AX_FWDL_PATH_RDY BIT(2)
#define B_AX_H2C_PATH_RDY BIT(1)
@@ -235,6 +246,9 @@
#define R_AX_SPSANA_ON_CTRL1 0x0224
+#define R_AX_SPS_ANA_ON_CTRL2 0x0228
+#define RTL8852B_RFE_05_SPS_ANA 0x4A82
+
#define R_AX_WLAN_XTAL_SI_CTRL 0x0270
#define B_AX_WL_XTAL_SI_CMD_POLL BIT(31)
#define B_AX_BT_XTAL_SI_ERR_FLAG BIT(30)
@@ -264,6 +278,9 @@
#define R_AX_GPIO0_7_FUNC_SEL 0x02D0
+#define R_AX_GPIO8_15_FUNC_SEL 0x02D4
+#define B_AX_PINMUX_GPIO9_FUNC_SEL_MASK GENMASK(7, 4)
+
#define R_AX_EECS_EESK_FUNC_SEL 0x02D8
#define B_AX_PINMUX_EESK_FUNC_SEL_MASK GENMASK(7, 4)
@@ -308,6 +325,9 @@
#define B_AX_S1_LDO2PWRCUT_F BIT(23)
#define B_AX_S0_LDO_VSEL_F_MASK GENMASK(22, 21)
+#define R_AX_DBG_WOW 0x0504
+#define B_AX_DBG_WOW_CPU_IO_RX_EN BIT(8)
+
#define R_AX_SEC_CTRL 0x0C00
#define B_AX_SEC_IDMEM_SIZE_CONFIG_MASK GENMASK(17, 16)
@@ -700,6 +720,14 @@
B_AX_HDT_CHANNEL_DMA_ERR_INT_EN | \
B_AX_HDT_TOTAL_LEN_ERR_INT_EN | \
B_AX_HDT_DMA_PROCESS_ERR_INT_EN)
+#define B_AX_HOST_DISP_IMR_SET_V01 (B_AX_HDT_CHANNEL_DIFF_ERR_INT_EN | \
+ B_AX_HDT_PAYLOAD_OVERFLOW_INT_EN | \
+ B_AX_HDT_PAYLOAD_UNDERFLOW_INT_EN | \
+ B_AX_HDT_CHANNEL_DMA_ERR_INT_EN | \
+ B_AX_HDT_TOTAL_LEN_ERR_INT_EN | \
+ B_AX_HDT_DMA_PROCESS_ERR_INT_EN | \
+ B_AX_HDT_RX_WRITE_OVERFLOW_INT_EN | \
+ B_AX_HDT_RX_WRITE_UNDERFLOW_INT_EN)
#define B_AX_HR_WRFF_UNDERFLOW_ERR_INT_EN BIT(31)
#define B_AX_HR_WRFF_OVERFLOW_ERR_INT_EN BIT(30)
@@ -1090,6 +1118,7 @@
#define B_AX_WDE_BUFMGN_FRZTMR_MODE BIT(0)
#define R_AX_WDE_ERR_IMR 0x8C38
+#define B_AX_WDE_DATCHN_UAPG_ERR_INT_EN BIT(30)
#define B_AX_WDE_DATCHN_RRDY_ERR_INT_EN BIT(27)
#define B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN BIT(26)
#define B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN BIT(25)
@@ -1129,6 +1158,29 @@
B_AX_WDE_DATCHN_ARBT_ERR_INT_EN | \
B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN | \
B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN)
+#define B_AX_WDE_IMR_CLR_V01 (B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN | \
+ B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN | \
+ B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \
+ B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN | \
+ B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \
+ B_AX_WDE_GETNPG_STRPG_ERR_INT_EN | \
+ B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN | \
+ B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN | \
+ B_AX_WDE_QUE_CMDTYPE_ERR_INT_EN | \
+ B_AX_WDE_QUE_DSTQUEID_ERR_INT_EN | \
+ B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN | \
+ B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \
+ B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \
+ B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN | \
+ B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN | \
+ B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN | \
+ B_AX_WDE_DATCHN_ARBT_ERR_INT_EN | \
+ B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN | \
+ B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN | \
+ B_AX_WDE_DATCHN_RRDY_ERR_INT_EN | \
+ B_AX_WDE_DATCHN_ADRERR_ERR_INT_EN | \
+ B_AX_WDE_DATCHN_CAMREQ_ERR_INT_EN | \
+ B_AX_WDE_DATCHN_UAPG_ERR_INT_EN)
#define B_AX_WDE_IMR_SET (B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN | \
B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN | \
B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \
@@ -1148,6 +1200,28 @@
B_AX_WDE_DATCHN_ARBT_ERR_INT_EN | \
B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN | \
B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN)
+#define B_AX_WDE_IMR_SET_V01 (B_AX_WDE_BUFREQ_QTAID_ERR_INT_EN | \
+ B_AX_WDE_BUFREQ_UNAVAL_ERR_INT_EN | \
+ B_AX_WDE_BUFRTN_INVLD_PKTID_ERR_INT_EN | \
+ B_AX_WDE_BUFRTN_SIZE_ERR_INT_EN | \
+ B_AX_WDE_BUFREQ_SRCHTAILPG_ERR_INT_EN | \
+ B_AX_WDE_GETNPG_STRPG_ERR_INT_EN | \
+ B_AX_WDE_GETNPG_PGOFST_ERR_INT_EN | \
+ B_AX_WDE_BUFMGN_FRZTO_ERR_INT_EN | \
+ B_AX_WDE_QUE_CMDTYPE_ERR_INT_EN | \
+ B_AX_WDE_QUE_DSTQUEID_ERR_INT_EN | \
+ B_AX_WDE_QUE_SRCQUEID_ERR_INT_EN | \
+ B_AX_WDE_ENQ_PKTCNT_OVRF_ERR_INT_EN | \
+ B_AX_WDE_ENQ_PKTCNT_NVAL_ERR_INT_EN | \
+ B_AX_WDE_PREPKTLLT_AD_ERR_INT_EN | \
+ B_AX_WDE_NXTPKTLL_AD_ERR_INT_EN | \
+ B_AX_WDE_QUEMGN_FRZTO_ERR_INT_EN | \
+ B_AX_WDE_DATCHN_ARBT_ERR_INT_EN | \
+ B_AX_WDE_DATCHN_NULLPG_ERR_INT_EN | \
+ B_AX_WDE_DATCHN_FRZTO_ERR_INT_EN | \
+ B_AX_WDE_DATCHN_RRDY_ERR_INT_EN | \
+ B_AX_WDE_DATCHN_ADRERR_ERR_INT_EN | \
+ B_AX_WDE_DATCHN_CAMREQ_ERR_INT_EN)
#define B_AX_WDE_DATCHN_CAMREQ_ERR_INT_EN BIT(29)
#define B_AX_WDE_DATCHN_ADRERR_ERR_INT_EN BIT(28)
@@ -1891,7 +1965,6 @@
B_AX_B0_IMR_ERR_USRCTL_NOINIT | \
B_AX_B0_IMR_ERR_CMDPSR_1STCMDERR | \
B_AX_B0_IMR_ERR_CMDPSR_CMDTYPE | \
- B_AX_B0_IMR_ERR_CMDPSR_FRZTO | \
B_AX_B0_IMR_ERR_CMDPSR_TBLSZ | \
B_AX_B0_IMR_ERR_MPDUINFO_RECFG | \
B_AX_B0_IMR_ERR_MPDUIF_DATAERR | \
@@ -2435,6 +2508,10 @@
#define B_AX_RTS_TXTIME_TH_MASK GENMASK(15, 8)
#define B_AX_RTS_LEN_TH_MASK GENMASK(7, 0)
+#define R_AX_AGG_LEN_VHT_0 0xC618
+#define R_AX_AGG_LEN_VHT_0_C1 0xE618
+#define B_AX_AMPDU_MAX_LEN_VHT_MASK GENMASK(19, 0)
+
#define S_AX_CTS2S_TH_SEC_256B 1
#define R_AX_SIFS_SETTING 0xC624
#define R_AX_SIFS_SETTING_C1 0xE624
@@ -3093,7 +3170,9 @@
B_AX_OFDM_CCA_TIMEOUT_INT_EN | \
B_AX_DATA_ON_TIMEOUT_INT_EN | \
B_AX_STS_ON_TIMEOUT_INT_EN | \
- B_AX_CSI_ON_TIMEOUT_INT_EN)
+ B_AX_CSI_ON_TIMEOUT_INT_EN | \
+ B_AX_PHYINTF_TIMEOUT_THR_MSAK)
+#define B_AX_PHYINFO_IMR_SET (B_AX_PHY_TXON_TIMEOUT_INT_EN | 0x7)
#define R_AX_PHYINFO_ERR_ISR 0xCCFC
#define R_AX_PHYINFO_ERR_ISR_C1 0xECFC
@@ -3167,6 +3246,8 @@
#define R_AX_DLK_PROTECT_CTL_C1 0xEE02
#define B_AX_RX_DLK_CCA_TIME_MASK GENMASK(15, 8)
#define B_AX_RX_DLK_DATA_TIME_MASK GENMASK(7, 4)
+#define B_AX_RX_DLK_RST_EN BIT(1)
+#define B_AX_RX_DLK_INT_EN BIT(0)
#define R_AX_PLCP_HDR_FLTR 0xCE04
#define R_AX_PLCP_HDR_FLTR_C1 0xEE04
@@ -3847,6 +3928,15 @@
#define R_BE_EFUSE_CTRL_1_V1 0x0034
#define B_BE_EF_DATA_MASK GENMASK(31, 0)
+#define R_BE_GPIO_EXT_CTRL 0x0060
+#define B_BE_GPIO_MOD_15_TO_8_MASK GENMASK(31, 24)
+#define B_BE_GPIO_MOD_9 BIT(25)
+#define B_BE_GPIO_IO_SEL_15_TO_8_MASK GENMASK(23, 16)
+#define B_BE_GPIO_IO_SEL_9 BIT(17)
+#define B_BE_GPIO_OUT_15_TO_8_MASK GENMASK(15, 8)
+#define B_BE_GPIO_IN_15_TO_8_MASK GENMASK(7, 0)
+#define B_BE_GPIO_IN_9 BIT(1)
+
#define R_BE_WL_BT_PWR_CTRL 0x0068
#define B_BE_ISO_BD2PP BIT(31)
#define B_BE_LDOV12B_EN BIT(30)
@@ -4292,6 +4382,9 @@
#define B_BE_REG_CK40M_EN BIT(1)
#define B_BE_REG_CK640M_EN BIT(0)
+#define R_BE_GPIO8_15_FUNC_SEL 0x02D4
+#define B_BE_PINMUX_GPIO9_FUNC_SEL_MASK GENMASK(7, 4)
+
#define R_BE_WLAN_XTAL_SI_CTRL 0x0270
#define B_BE_WL_XTAL_SI_CMD_POLL BIT(31)
#define B_BE_WL_XTAL_SI_CHIPID_MASK GENMASK(30, 28)
@@ -4311,6 +4404,8 @@
#define R_BE_WLCPU_PORT_PC 0x03FC
+#define R_BE_DBG_WOW 0x0504
+
#define R_BE_DCPU_PLATFORM_ENABLE 0x0888
#define B_BE_DCPU_SYM_DPLT_MEM_MUX_EN BIT(10)
#define B_BE_DCPU_WARM_EN BIT(9)
@@ -5955,6 +6050,9 @@
#define R_BE_WP_PAGE_INFO1 0xB7AC
#define B_BE_WP_AVAL_PG_MASK GENMASK(28, 16)
+#define R_BE_LTPC_T0_PATH0 0xBA28
+#define R_BE_LTPC_T0_PATH1 0xBB28
+
#define R_BE_CMAC_SHARE_FUNC_EN 0x0E000
#define B_BE_CMAC_SHARE_CRPRT BIT(31)
#define B_BE_CMAC_SHARE_EN BIT(30)
@@ -6520,6 +6618,13 @@
#define B_BE_RTS_LIMIT_IN_OFDM6 BIT(1)
#define B_BE_CHECK_CCK_EN BIT(0)
+#define R_BE_TXCNT 0x1082C
+#define R_BE_TXCNT_C1 0x1482C
+#define B_BE_ADD_TXCNT_BY BIT(31)
+#define B_BE_TOTAL_TC_OPT BIT(30)
+#define B_BE_S_TXCNT_LMT_MASK GENMASK(29, 24)
+#define B_BE_L_TXCNT_LMT_MASK GENMASK(21, 16)
+
#define R_BE_MBSSID_DROP_0 0x1083C
#define R_BE_MBSSID_DROP_0_C1 0x1483C
#define B_BE_GI_LTF_FB_SEL BIT(30)
@@ -6997,6 +7102,10 @@
#define B_BE_MACLBK_RDY_NUM_MASK GENMASK(7, 3)
#define B_BE_MACLBK_EN BIT(0)
+#define R_BE_CLIENT_OM_CTRL 0x11040
+#define R_BE_CLIENT_OM_CTRL_C1 0x15040
+#define B_BE_TRIG_DIS_EHTTB BIT(24)
+
#define R_BE_WMAC_NAV_CTL 0x11080
#define R_BE_WMAC_NAV_CTL_C1 0x15080
#define B_BE_WMAC_NAV_UPPER_EN BIT(26)
@@ -7349,6 +7458,10 @@
#define B_BE_CSIPRT_HESU_AID_EN BIT(25)
#define B_BE_CSIPRT_VHTSU_AID_EN BIT(24)
+#define R_BE_DRV_INFO_OPTION 0x11470
+#define R_BE_DRV_INFO_OPTION_C1 0x15470
+#define B_BE_DRV_INFO_PHYRPT_EN BIT(0)
+
#define R_BE_RX_ERR_ISR 0x114F4
#define R_BE_RX_ERR_ISR_C1 0x154F4
#define B_BE_RX_ERR_TRIG_ACT_TO BIT(9)
@@ -7488,7 +7601,15 @@
#define B_BE_PWR_FORCE_RU_ON BIT(18)
#define B_BE_PWR_FORCE_RU_ENON BIT(28)
#define R_BE_PWR_FORCE_MACID 0x11A48
-#define B_BE_PWR_FORCE_MACID_ON BIT(9)
+#define B_BE_PWR_FORCE_MACID_DBM_ON BIT(9)
+#define B_BE_PWR_FORCE_MACID_DBM_VAL GENMASK(17, 10)
+#define B_BE_PWR_FORCE_MACID_EN_VAL BIT(18)
+#define B_BE_PWR_FORCE_MACID_EN_ON BIT(19)
+#define B_BE_PWR_FORCE_MACID_ALL \
+ (B_BE_PWR_FORCE_MACID_DBM_ON | \
+ B_BE_PWR_FORCE_MACID_DBM_VAL | \
+ B_BE_PWR_FORCE_MACID_EN_VAL | \
+ B_BE_PWR_FORCE_MACID_EN_ON)
#define R_BE_PWR_REG_CTRL 0x11A50
#define B_BE_PWR_BT_EN BIT(23)
@@ -7497,6 +7618,9 @@
#define B_BE_PWR_BT_VAL GENMASK(8, 0)
#define B_BE_PWR_FORCE_COEX_ON GENMASK(29, 27)
+#define R_BE_PWR_TH 0x11A78
+#define R_BE_PWR_RSSI_TARGET_LMT 0x11A84
+
#define R_BE_PWR_OFST_SW 0x11AE8
#define B_BE_PWR_OFST_SW_DB GENMASK(27, 24)
@@ -7806,6 +7930,8 @@
#define B_UPD_P0_EN BIT(31)
#define R_EMLSR 0x0044
#define B_EMLSR_PARM GENMASK(27, 12)
+#define R_CHK_LPS_STAT 0x0058
+#define B_CHK_LPS_STAT BIT(0)
#define R_SPOOF_CG 0x00B4
#define B_SPOOF_CG_EN BIT(17)
#define R_CHINFO_SEG 0x00B4
@@ -7822,6 +7948,7 @@
#define B_ANAPAR_PW15_H2 GENMASK(27, 26)
#define R_ANAPAR 0x032C
#define B_ANAPAR_15 GENMASK(31, 16)
+#define B_ANAPAR_EN1 BIT(31)
#define B_ANAPAR_ADCCLK BIT(30)
#define B_ANAPAR_FLTRST BIT(22)
#define B_ANAPAR_CRXBB GENMASK(18, 16)
@@ -7863,10 +7990,12 @@
#define R_RXCCA_BE1 0x0520
#define B_RXCCA_BE1_DIS BIT(0)
#define R_UPD_CLK_ADC 0x0700
+#define B_UPD_GEN_ON BIT(27)
#define B_UPD_CLK_ADC_VAL GENMASK(26, 25)
#define B_UPD_CLK_ADC_ON BIT(24)
#define B_ENABLE_CCK BIT(5)
#define R_RSTB_ASYNC 0x0704
+#define B_RSTB_ASYNC_BW80 GENMASK(9, 8)
#define B_RSTB_ASYNC_ALL BIT(1)
#define R_P0_ANT_SW 0x0728
#define B_P0_HW_ANTSW_DIS_BY_GNT_BT BIT(12)
@@ -7930,6 +8059,8 @@
#define B_MEASUREMENT_TRIG_MSK BIT(2)
#define B_CCX_TRIG_OPT_MSK BIT(1)
#define B_CCX_EN_MSK BIT(0)
+#define R_FAHM 0x0C1C
+#define B_RXTD_CKEN BIT(2)
#define R_IFS_COUNTER 0x0C28
#define B_IFS_CLM_PERIOD_MSK GENMASK(31, 16)
#define B_IFS_CLM_COUNTER_UNIT_MSK GENMASK(15, 14)
@@ -7963,6 +8094,7 @@
#define B_IQK_DPK_RST BIT(0)
#define R_TX_COLLISION_T2R_ST 0x0C70
#define B_TX_COLLISION_T2R_ST_M GENMASK(25, 20)
+#define B_TXRX_FORCE_VAL GENMASK(9, 0)
#define R_TXGATING 0x0C74
#define B_TXGATING_EN BIT(4)
#define R_TXRFC 0x0C7C
@@ -8023,6 +8155,7 @@
#define B_P0_RFMODE_FTM_RX GENMASK(11, 0)
#define R_P0_NRBW 0x12B8
#define B_P0_NRBW_DBG BIT(30)
+#define B_P0_NRBW_RSTB BIT(28)
#define R_S0_RXDC 0x12D4
#define B_S0_RXDC_I GENMASK(25, 16)
#define B_S0_RXDC_Q GENMASK(31, 26)
@@ -8043,6 +8176,8 @@
#define B_EDCCA_RPT_B_S40 BIT(4)
#define B_EDCCA_RPT_B_S80 BIT(3)
#define B_EDCCA_RPT_B_PATH_MASK GENMASK(2, 1)
+#define R_EDCCA_RPT_P1_A 0x1740
+#define R_EDCCA_RPT_P1_B 0x1744
#define R_SWSI_V1 0x174C
#define B_SWSI_W_BUSY_V1 BIT(24)
#define B_SWSI_R_BUSY_V1 BIT(25)
@@ -8104,8 +8239,11 @@
#define R_S0_ADDCK 0x1E00
#define B_S0_ADDCK_I GENMASK(9, 0)
#define B_S0_ADDCK_Q GENMASK(19, 10)
+#define R_TXCKEN_FORCE 0x2008
+#define B_TXCKEN_FORCE_ALL GENMASK(24, 0)
#define R_EDCCA_RPT_SEL 0x20CC
#define B_EDCCA_RPT_SEL_MSK GENMASK(2, 0)
+#define B_EDCCA_RPT_SEL_P1_MSK GENMASK(5, 3)
#define R_ADC_FIFO 0x20fc
#define B_ADC_FIFO_RST GENMASK(31, 24)
#define B_ADC_FIFO_RXK GENMASK(31, 16)
@@ -8175,6 +8313,8 @@
#define B_P1_EN_SOUND_WO_NDP BIT(1)
#define R_EDCCA_RPT_A_BE 0x2E38
#define R_EDCCA_RPT_B_BE 0x2E3C
+#define R_EDCCA_RPT_P1_A_BE 0x2E40
+#define R_EDCCA_RPT_P1_B_BE 0x2E44
#define R_S1_HW_SI_DIS 0x3200
#define B_S1_HW_SI_DIS_W_R_TRIG GENMASK(30, 28)
#define R_P1_RXCK 0x32A0
@@ -8259,6 +8399,7 @@
#define R_DCFO_COMP_S0 0x448C
#define B_DCFO_COMP_S0_MSK GENMASK(11, 0)
#define R_DCFO_WEIGHT 0x4490
+#define B_DAC_CLK_IDX BIT(31)
#define B_DCFO_WEIGHT_MSK GENMASK(27, 24)
#define R_DCFO_OPT 0x4494
#define B_DCFO_OPT_EN BIT(29)
@@ -8374,6 +8515,7 @@
#define B_CDD_EVM_CHK_EN BIT(0)
#define R_PATH0_BAND_SEL_V1 0x4738
#define B_PATH0_BAND_SEL_MSK_V1 BIT(17)
+#define B_PATH0_BAND_NRBW_EN_V1 BIT(16)
#define R_PATH0_BT_SHARE_V1 0x4738
#define B_PATH0_BT_SHARE_V1 BIT(19)
#define R_PATH0_BTG_PATH_V1 0x4738
@@ -8417,6 +8559,7 @@
#define B_PATH1_G_TIA1_LNA6_OP1DB_V1 GENMASK(15, 8)
#define R_PATH1_BAND_SEL_V1 0x4AA4
#define B_PATH1_BAND_SEL_MSK_V1 BIT(17)
+#define B_PATH1_BAND_NRBW_EN_V1 BIT(16)
#define R_PATH1_BT_SHARE_V1 0x4AA4
#define B_PATH1_BT_SHARE_V1 BIT(19)
#define R_PATH1_BTG_PATH_V1 0x4AA4
@@ -8437,6 +8580,8 @@
#define B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1 BIT(30)
#define B_SEG0R_PD_SPATIAL_REUSE_EN_MSK BIT(29)
#define B_SEG0R_PD_LOWER_BOUND_MSK GENMASK(10, 6)
+#define R_PWOFST 0x488C
+#define B_PWOFST GENMASK(21, 17)
#define R_2P4G_BAND 0x4970
#define B_2P4G_BAND_SEL BIT(1)
#define R_FC0_BW 0x4974
@@ -8600,8 +8745,10 @@
#define B_DPD_GDIS BIT(13)
#define B_IQK_RFC_ON BIT(1)
#define R_TXPWRB 0x56CC
+#define R_P1_TXPWRB 0x76CC
#define B_TXPWRB_ON BIT(28)
#define B_TXPWRB_VAL GENMASK(27, 19)
+#define B_TXPWRB_MAX GENMASK(8, 0)
#define R_DPD_OFT_EN 0x5800
#define B_DPD_OFT_EN BIT(28)
#define B_DPD_TSSI_CW GENMASK(26, 18)
@@ -8617,6 +8764,8 @@
#define B_P0_TMETER GENMASK(15, 10)
#define B_P0_TMETER_DIS BIT(16)
#define B_P0_TMETER_TRK BIT(24)
+#define R_P0_ADCFF_EN 0x58C8
+#define B_P0_ADCFF_EN BIT(24)
#define R_P1_TSSIC 0x7814
#define B_P1_TSSIC_BYPASS BIT(11)
#define R_P0_TSSI_TRK 0x5818
@@ -8628,7 +8777,9 @@
#define B_P0_TSSI_EN BIT(31)
#define B_P0_TSSI_AVG GENMASK(15, 12)
#define R_P0_RFCTM 0x5864
+#define B_P0_CLKG_FORCE GENMASK(31, 30)
#define B_P0_RFCTM_EN BIT(29)
+#define B_P0_GOT_TXRX GENMASK(28, 27)
#define B_P0_RFCTM_VAL GENMASK(25, 20)
#define R_P0_RFCTM_RDY BIT(26)
#define R_P0_TRSW 0x5868
@@ -8661,12 +8812,14 @@
#define B_P0_RFM_BT_EN BIT(5)
#define B_P0_RFM_OUT GENMASK(4, 0)
#define R_P0_PATH_RST 0x58AC
+#define B_P0_PATH_RST BIT(27)
#define R_P0_TXDPD 0x58D4
#define B_P0_TXDPD GENMASK(31, 28)
#define R_P0_TXPW_RSTB 0x58DC
#define B_P0_TXPW_RSTB_MANON BIT(30)
#define B_P0_TXPW_RSTB_TSSI BIT(31)
#define R_P0_TSSI_MV_AVG 0x58E4
+#define B_P0_TXPW_RSTB GENMASK(28, 27)
#define B_P0_TSSI_MV_MIX GENMASK(19, 11)
#define B_P0_TSSI_MV_AVG GENMASK(13, 11)
#define B_P0_TSSI_MV_CLR BIT(14)
@@ -8791,6 +8944,10 @@
#define B_P1_TSSI_ALIM2 GENMASK(29, 0)
#define R_P1_TSSI_ADC_CLK 0x766c
#define B_P1_TSSI_ADC_CLK GENMASK(17, 16)
+#define R_P1_TXAGC_TH 0x7800
+#define B_P1_TXAGC_MAXMIN GENMASK(15, 0)
+#define R_P1_TXPW_FORCE 0x780C
+#define B_P1_TXPW_RDY BIT(15)
#define R_P1_TSSIC 0x7814
#define B_P1_TSSIC_BYPASS BIT(11)
#define R_P1_TMETER 0x7810
@@ -8806,14 +8963,20 @@
#define B_P1_TSSI_EN BIT(31)
#define B_P1_TSSI_AVG GENMASK(15, 12)
#define R_P1_RFCTM 0x7864
+#define B_P1_CLKG_FORCE GENMASK(31, 30)
+#define B_P1_GOT_TXRX GENMASK(28, 27)
#define R_P1_RFCTM_RDY BIT(26)
#define B_P1_RFCTM_VAL GENMASK(25, 20)
#define B_P1_RFCTM_DEL GENMASK(19, 11)
#define R_P1_PATH_RST 0x78AC
+#define B_P1_PATH_RST BIT(27)
+#define R_P1_ADCFF_EN 0x78C8
+#define B_P1_ADCFF_EN BIT(24)
#define R_P1_TXPW_RSTB 0x78DC
#define B_P1_TXPW_RSTB_MANON BIT(30)
#define B_P1_TXPW_RSTB_TSSI BIT(31)
#define R_P1_TSSI_MV_AVG 0x78E4
+#define B_P1_TXPW_RSTB GENMASK(28, 27)
#define B_P1_TSSI_MV_MIX GENMASK(19, 11)
#define B_P1_TSSI_MV_AVG GENMASK(13, 11)
#define B_P1_TSSI_MV_CLR BIT(14)
@@ -8998,6 +9161,7 @@
#define R_IQRSN 0x8220
#define B_IQRSN_K1 BIT(28)
#define B_IQRSN_K2 BIT(16)
+#define R_DPD_CH0B 0x82BC
#define R_RXCFIR_P0C0 0x8D40
#define R_RXCFIR_P0C1 0x8D84
#define R_RXCFIR_P0C2 0x8DC8
@@ -9031,15 +9195,28 @@
#define B_IQKINF2_FCNT GENMASK(23, 16)
#define B_IQKINF2_KCNT GENMASK(15, 8)
#define B_IQKINF2_NCTLV GENMASK(7, 0)
+#define R_TXAGC_REF_DBM_RF1_P0 0xBC04
+#define B_TXAGC_OFDM_REF_DBM_RF1_P0 GENMASK(10, 2)
+#define B_TXAGC_CCK_REF_DBM_RF1_P0 GENMASK(19, 11)
+#define R_TSSI_K_RF1_P0 0xBC28
+#define B_TSSI_K_OFDM_RF1_P0 GENMASK(9, 0)
+#define R_TXAGC_REF_DBM_RF1_P1 0xBD04
+#define B_TXAGC_OFDM_REF_DBM_RF1_P1 GENMASK(10, 2)
+#define B_TXAGC_CCK_REF_DBM_RF1_P1 GENMASK(19, 11)
+#define R_TSSI_K_RF1_P1 0xBD28
+#define B_TSSI_K_OFDM_RF1_P1 GENMASK(9, 0)
+#define R_RFK_ST 0xBFF8
#define R_DCOF0 0xC000
#define B_DCOF0_RST BIT(17)
#define B_DCOF0_V GENMASK(4, 1)
#define R_DCOF1 0xC004
+#define B_DCOF1_VAL GENMASK(31, 20)
#define B_DCOF1_RST BIT(17)
#define B_DCOF1_S BIT(0)
#define R_DCOF8 0xC020
#define B_DCOF8_V GENMASK(4, 1)
#define R_DCOF9 0xC024
+#define B_DCOF9_VAL GENMASK(31, 20)
#define B_DCOF9_RST BIT(17)
#define R_DACK_S0P0 0xC040
#define B_DACK_S0P0_OK BIT(31)
@@ -9090,6 +9267,7 @@
#define R_ADCMOD 0xC0E8
#define B_ADCMOD_LP GENMASK(31, 16)
#define R_DCIM 0xC0EC
+#define B_DCIM_RC GENMASK(23, 16)
#define B_DCIM_FR GENMASK(14, 13)
#define R_ADDCK0D 0xC0F0
#define B_ADDCK0D_VAL2 GENMASK(31, 26)
@@ -9112,11 +9290,18 @@
#define B_ADDCKR0_DC GENMASK(15, 4)
#define B_ADDCKR0_A1 GENMASK(9, 0)
#define R_DACK10 0xC100
+#define B_DACK10_RST BIT(17)
#define B_DACK10 GENMASK(4, 1)
#define R_DACK1_K 0xc104
+#define B_DACK1_VAL GENMASK(31, 20)
+#define B_DACK1_RST BIT(17)
#define B_DACK1_EN BIT(0)
#define R_DACK11 0xC120
#define B_DACK11 GENMASK(4, 1)
+#define R_DACK2_K 0xC124
+#define B_DACK2_VAL GENMASK(31, 20)
+#define B_DACK2_RST BIT(17)
+#define B_DACK2_EN BIT(0)
#define R_DACK_S1P0 0xC140
#define B_DACK_S1P0_OK BIT(31)
#define R_DACK_BIAS10 0xC148
@@ -9165,6 +9350,11 @@
#define B_DACKN0_V GENMASK(21, 14)
#define R_DACKN1_CTL 0xC224
#define B_DACKN1_V GENMASK(21, 14)
+#define B_DACKN1_ON BIT(0)
+#define R_DACKN2_CTL 0xC238
+#define B_DACKN2_ON BIT(0)
+#define R_DACKN3_CTL 0xC24C
+#define B_DACKN3_ON BIT(0)
#define R_GAIN_MAP0 0xE44C
#define B_GAIN_MAP0_EN BIT(0)
#define R_GAIN_MAP1 0xE54C
@@ -9180,20 +9370,25 @@
#define R_TSSI_PWR_P0 0xE610
#define R_TSSI_PWR_P1 0xE710
#define B_TSSI_CONT_EN BIT(3)
+#define R_P0_TXPWRB_BE 0xE61C
+#define R_P1_TXPWRB_BE 0xE71C
+#define B_TXPWRB_MAX_BE GENMASK(20, 12)
#define R_TSSI_MAP_OFST_P0 0xE620
#define R_TSSI_MAP_OFST_P1 0xE720
#define B_TSSI_MAP_OFST_OFDM GENMASK(17, 9)
#define B_TSSI_MAP_OFST_CCK GENMASK(26, 18)
-#define R_TXAGC_REF0_P0 0xE628
-#define R_TXAGC_REF0_P1 0xE728
-#define B_TXAGC_REF0_OFDM_DBM GENMASK(8, 0)
-#define B_TXAGC_REF0_CCK_DBM GENMASK(17, 9)
-#define B_TXAGC_REF0_OFDM_CW GENMASK(26, 18)
-#define R_TXAGC_REF1_P0 0xE62C
-#define R_TXAGC_REF1_P1 0xE72C
-#define B_TXAGC_REF1_CCK_CW GENMASK(8, 0)
+#define R_TXAGC_REF_DBM_P0 0xE628
+#define B_TXAGC_OFDM_REF_DBM_P0 GENMASK(8, 0)
+#define B_TXAGC_CCK_REF_DBM_P0 GENMASK(17, 9)
+#define R_TSSI_K_P0 0xE6A0
+#define B_TSSI_K_OFDM_P0 GENMASK(29, 20)
#define R_TXPWR_RSTB 0xE70C
#define B_TXPWR_RSTB BIT(16)
+#define R_TXAGC_REF_DBM_P1 0xE728
+#define B_TXAGC_OFDM_REF_DBM_P1 GENMASK(8, 0)
+#define B_TXAGC_CCK_REF_DBM_P1 GENMASK(17, 9)
+#define R_TSSI_K_P1 0xE7A0
+#define B_TSSI_K_OFDM_P1 GENMASK(29, 20)
/* WiFi CPU local domain */
#define R_AX_WDT_CTRL 0x0040
diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c
index d0857ef60ea6..3ad14cab1f58 100644
--- a/drivers/net/wireless/realtek/rtw89/regd.c
+++ b/drivers/net/wireless/realtek/rtw89/regd.c
@@ -7,254 +7,266 @@
#include "ps.h"
#include "util.h"
-#define COUNTRY_REGD(_alpha2, _txpwr_regd...) \
- {.alpha2 = (_alpha2), \
- .txpwr_regd = {_txpwr_regd}, \
+static
+void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+
+#define COUNTRY_REGD(_alpha2, _rule_2ghz, _rule_5ghz, _rule_6ghz, _fmap) \
+ { \
+ .alpha2 = _alpha2, \
+ .txpwr_regd[RTW89_BAND_2G] = _rule_2ghz, \
+ .txpwr_regd[RTW89_BAND_5G] = _rule_5ghz, \
+ .txpwr_regd[RTW89_BAND_6G] = _rule_6ghz, \
+ .func_bitmap = { _fmap, }, \
}
+static_assert(BITS_PER_TYPE(unsigned long) >= NUM_OF_RTW89_REGD_FUNC);
+
static const struct rtw89_regd rtw89_ww_regd =
- COUNTRY_REGD("00", RTW89_WW, RTW89_WW, RTW89_WW);
+ COUNTRY_REGD("00", RTW89_WW, RTW89_WW, RTW89_WW, 0x0);
static const struct rtw89_regd rtw89_regd_map[] = {
- COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC),
- COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("CL", RTW89_CHILE, RTW89_CHILE, RTW89_CHILE),
- COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("CR", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("EC", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("SV", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("HN", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC),
- COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("UY", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("VE", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("PR", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("DO", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("AT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("BE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("CY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("CZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("DK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("EE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("FI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("FR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("DE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("GR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("HU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("IS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("IE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("IT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("LV", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("LI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("LT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("LU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("MT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("MC", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("NL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("NO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("PL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("PT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("SK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("SI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("ES", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("SE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("CH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("GB", RTW89_UK, RTW89_UK, RTW89_UK),
- COUNTRY_REGD("AL", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("AZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("BH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("BA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("BG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("HR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("EG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("GH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("IQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("IL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("JO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("KZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("LB", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("LS", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("MK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("MZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("NA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("NG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("OM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("QA", RTW89_QATAR, RTW89_QATAR, RTW89_QATAR),
- COUNTRY_REGD("RO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("RU", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("SA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("SN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("ME", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("ZA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("UA", RTW89_UKRAINE, RTW89_UKRAINE, RTW89_UKRAINE),
- COUNTRY_REGD("AE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("YE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("ZW", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("BD", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("KH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("CN", RTW89_CN, RTW89_CN, RTW89_CN),
- COUNTRY_REGD("HK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("IN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC, RTW89_KCC),
- COUNTRY_REGD("MY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("PK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("PH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("SG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("LK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC, RTW89_ETSI),
- COUNTRY_REGD("TH", RTW89_ETSI, RTW89_ETSI, RTW89_THAILAND),
- COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA),
- COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA),
- COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("CA", RTW89_IC, RTW89_IC, RTW89_IC),
- COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK, RTW89_MKK),
- COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("TN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("DZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("AD", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("AO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("AI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("AQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("AM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("BY", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("BZ", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("BJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("BT", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("BW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("BV", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("IO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("BN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("BF", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("MM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("CM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("CV", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("CF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("TD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("CX", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
- COUNTRY_REGD("CC", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
- COUNTRY_REGD("KM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("CG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("CD", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("CK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("DJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("ER", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("ET", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("FK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("FO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("FJ", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("GF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("PF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("TF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("GA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("GM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("GE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("GI", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("GG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("GW", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("GY", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("HM", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
- COUNTRY_REGD("VA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("IM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("JE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("KI", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("XK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("LA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("LR", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("LY", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("MO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("MG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("MW", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("MV", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("ML", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("MH", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("MQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("MR", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("MU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("MS", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("NR", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("NP", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("NC", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("NE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("NU", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
- COUNTRY_REGD("NF", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
- COUNTRY_REGD("MP", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("PW", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("RE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("RW", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("SH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("PM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("VC", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("WS", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("SM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("ST", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("SL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("SB", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("SO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("GS", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("SJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("SZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("TJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("TZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("TG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("TK", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
- COUNTRY_REGD("TO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("TM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("TC", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("TV", RTW89_ETSI, RTW89_NA, RTW89_NA),
- COUNTRY_REGD("UG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("VI", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("VU", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("WF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("EH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("ZM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("IR", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("PS", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
+ COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC, 0x0),
+ COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("CL", RTW89_CHILE, RTW89_CHILE, RTW89_CHILE, 0x0),
+ COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("CR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("EC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("SV", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("HN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC, 0x0),
+ COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x1),
+ COUNTRY_REGD("UY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("VE", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("PR", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("DO", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("AT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("BE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("CY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("CZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("DK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("EE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("FI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("FR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("DE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("GR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("HU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("IS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("IE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("IT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("LV", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("LI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("LT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("LU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("MT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("MC", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("NL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("NO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("PL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("PT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("SK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("SI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("ES", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("SE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("CH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("GB", RTW89_UK, RTW89_UK, RTW89_UK, 0x0),
+ COUNTRY_REGD("AL", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("AZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("BH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("BA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("BG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("HR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("EG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("GH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("IQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("IL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("JO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("KZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("LB", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("LS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("MK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("MZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("NA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("NG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("OM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("QA", RTW89_QATAR, RTW89_QATAR, RTW89_QATAR, 0x0),
+ COUNTRY_REGD("RO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
+ COUNTRY_REGD("RU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("SA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("SN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("ME", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("ZA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("UA", RTW89_UKRAINE, RTW89_UKRAINE, RTW89_UKRAINE, 0x0),
+ COUNTRY_REGD("AE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("YE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("ZW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("BD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("KH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("CN", RTW89_CN, RTW89_CN, RTW89_CN, 0x0),
+ COUNTRY_REGD("HK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("IN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC, RTW89_KCC, 0x1),
+ COUNTRY_REGD("MY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("PK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("PH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("SG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("LK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("TH", RTW89_THAILAND, RTW89_THAILAND, RTW89_THAILAND, 0x0),
+ COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA, 0x0),
+ COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA, 0x0),
+ COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("CA", RTW89_IC, RTW89_IC, RTW89_IC, 0x1),
+ COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK, RTW89_MKK, 0x0),
+ COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("TN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("DZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("AD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("AO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("AI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("AQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("AM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("BY", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("BZ", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("BJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("BT", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("BW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("BV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("IO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("BN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("BF", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("MM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("CM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("CV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("CF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("TD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("CX", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
+ COUNTRY_REGD("CC", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
+ COUNTRY_REGD("KM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("CG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("CD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("CK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("DJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("ER", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("ET", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("FK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("FO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("FJ", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("GF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("PF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("TF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("GA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("GM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("GE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("GI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("GG", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("GW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("GY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("HM", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
+ COUNTRY_REGD("VA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("IM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("JE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("KI", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("XK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("LA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("LR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("LY", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("MO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("MG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("MW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("MV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("ML", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("MH", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("MQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("MR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("MU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("MS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("NR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("NP", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("NC", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("NE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("NU", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
+ COUNTRY_REGD("NF", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
+ COUNTRY_REGD("MP", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("PW", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("RE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("RW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("SH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("PM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("VC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("WS", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("SM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("ST", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
+ COUNTRY_REGD("SL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("SB", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("SO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("GS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("SJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("SZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("TJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("TZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("TG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("TK", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
+ COUNTRY_REGD("TO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("TM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("TC", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("TV", RTW89_ETSI, RTW89_NA, RTW89_NA, 0x0),
+ COUNTRY_REGD("UG", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("VI", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
+ COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
+ COUNTRY_REGD("VU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("WF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("EH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("ZM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("CU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("IR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("SY", RTW89_ETSI, RTW89_NA, RTW89_NA, 0x0),
+ COUNTRY_REGD("SD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
+ COUNTRY_REGD("PS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
};
static const char rtw89_alpha2_list_eu[][3] = {
@@ -292,13 +304,16 @@ static const char rtw89_alpha2_list_eu[][3] = {
"RO",
};
-static const struct rtw89_regd *rtw89_regd_find_reg_by_name(const char *alpha2)
+static const struct rtw89_regd *rtw89_regd_find_reg_by_name(struct rtw89_dev *rtwdev,
+ const char *alpha2)
{
+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ const struct rtw89_regd_ctrl *regd_ctrl = &regulatory->ctrl;
u32 i;
- for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) {
- if (!memcmp(rtw89_regd_map[i].alpha2, alpha2, 2))
- return &rtw89_regd_map[i];
+ for (i = 0; i < regd_ctrl->nr; i++) {
+ if (!memcmp(regd_ctrl->map[i].alpha2, alpha2, 2))
+ return &regd_ctrl->map[i];
}
return &rtw89_ww_regd;
@@ -309,22 +324,25 @@ static bool rtw89_regd_is_ww(const struct rtw89_regd *regd)
return regd == &rtw89_ww_regd;
}
-static u8 rtw89_regd_get_index(const struct rtw89_regd *regd)
+static u8 rtw89_regd_get_index(struct rtw89_dev *rtwdev, const struct rtw89_regd *regd)
{
+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ const struct rtw89_regd_ctrl *regd_ctrl = &regulatory->ctrl;
+
BUILD_BUG_ON(ARRAY_SIZE(rtw89_regd_map) > RTW89_REGD_MAX_COUNTRY_NUM);
if (rtw89_regd_is_ww(regd))
return RTW89_REGD_MAX_COUNTRY_NUM;
- return regd - rtw89_regd_map;
+ return regd - regd_ctrl->map;
}
-static u8 rtw89_regd_get_index_by_name(const char *alpha2)
+static u8 rtw89_regd_get_index_by_name(struct rtw89_dev *rtwdev, const char *alpha2)
{
const struct rtw89_regd *regd;
- regd = rtw89_regd_find_reg_by_name(alpha2);
- return rtw89_regd_get_index(regd);
+ regd = rtw89_regd_find_reg_by_name(rtwdev, alpha2);
+ return rtw89_regd_get_index(rtwdev, regd);
}
#define rtw89_debug_regd(_dev, _regd, _desc, _argv...) \
@@ -341,51 +359,61 @@ do { \
static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev,
struct wiphy *wiphy)
{
+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ const struct rtw89_regd_ctrl *regd_ctrl = &regulatory->ctrl;
const struct rtw89_chip_info *chip = rtwdev->chip;
- bool regd_allow_unii_4 = chip->support_unii4;
struct ieee80211_supported_band *sband;
struct rtw89_acpi_dsm_result res = {};
+ bool enable_by_fcc;
+ bool enable_by_ic;
int ret;
u8 val;
+ int i;
- if (!chip->support_unii4)
- goto bottom;
+ sband = wiphy->bands[NL80211_BAND_5GHZ];
+ if (!sband)
+ return;
+
+ if (!chip->support_unii4) {
+ sband->n_channels -= RTW89_5GHZ_UNII4_CHANNEL_NUM;
+ return;
+ }
+
+ bitmap_fill(regulatory->block_unii4, RTW89_REGD_MAX_COUNTRY_NUM);
- ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_59G_EN, &res);
+ ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_UNII4_SUP, &res);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"acpi: cannot eval unii 4: %d\n", ret);
+ enable_by_fcc = true;
+ enable_by_ic = false;
goto bottom;
}
val = res.u.value;
+ enable_by_fcc = u8_get_bits(val, RTW89_ACPI_CONF_UNII4_FCC);
+ enable_by_ic = u8_get_bits(val, RTW89_ACPI_CONF_UNII4_IC);
rtw89_debug(rtwdev, RTW89_DBG_REGD,
- "acpi: eval if allow unii 4: %d\n", val);
-
- switch (val) {
- case 0:
- regd_allow_unii_4 = false;
- break;
- case 1:
- regd_allow_unii_4 = true;
- break;
- default:
- break;
- }
+ "acpi: eval if allow unii-4: 0x%x\n", val);
bottom:
- rtw89_debug(rtwdev, RTW89_DBG_REGD, "regd: allow unii 4: %d\n",
- regd_allow_unii_4);
-
- if (regd_allow_unii_4)
- return;
-
- sband = wiphy->bands[NL80211_BAND_5GHZ];
- if (!sband)
- return;
+ for (i = 0; i < regd_ctrl->nr; i++) {
+ const struct rtw89_regd *regd = &regd_ctrl->map[i];
- sband->n_channels -= 3;
+ switch (regd->txpwr_regd[RTW89_BAND_5G]) {
+ case RTW89_FCC:
+ if (enable_by_fcc)
+ clear_bit(i, regulatory->block_unii4);
+ break;
+ case RTW89_IC:
+ if (enable_by_ic)
+ clear_bit(i, regulatory->block_unii4);
+ break;
+ default:
+ break;
+ }
+ }
}
static void __rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev, bool block,
@@ -394,7 +422,7 @@ static void __rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev, bool block,
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
u8 index;
- index = rtw89_regd_get_index_by_name(alpha2);
+ index = rtw89_regd_get_index_by_name(rtwdev, alpha2);
if (index == RTW89_REGD_MAX_COUNTRY_NUM) {
rtw89_debug(rtwdev, RTW89_DBG_REGD, "%s: unknown alpha2 %c%c\n",
__func__, alpha2[0], alpha2[1]);
@@ -459,6 +487,52 @@ out:
kfree(ptr);
}
+static void rtw89_regd_setup_policy_6ghz_sp(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ const struct rtw89_regd_ctrl *regd_ctrl = &regulatory->ctrl;
+ const struct rtw89_acpi_policy_6ghz_sp *ptr;
+ struct rtw89_acpi_dsm_result res = {};
+ bool enable_by_us;
+ int ret;
+ int i;
+
+ ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP, &res);
+ if (ret) {
+ rtw89_debug(rtwdev, RTW89_DBG_REGD,
+ "acpi: cannot eval policy 6ghz-sp: %d\n", ret);
+ return;
+ }
+
+ ptr = res.u.policy_6ghz_sp;
+
+ switch (ptr->override) {
+ default:
+ rtw89_debug(rtwdev, RTW89_DBG_REGD,
+ "%s: unknown override case: %d\n", __func__,
+ ptr->override);
+ fallthrough;
+ case 0:
+ goto out;
+ case 1:
+ break;
+ }
+
+ bitmap_fill(regulatory->block_6ghz_sp, RTW89_REGD_MAX_COUNTRY_NUM);
+
+ enable_by_us = u8_get_bits(ptr->conf, RTW89_ACPI_CONF_6GHZ_SP_US);
+
+ for (i = 0; i < regd_ctrl->nr; i++) {
+ const struct rtw89_regd *tmp = &regd_ctrl->map[i];
+
+ if (enable_by_us && memcmp(tmp->alpha2, "US", 2) == 0)
+ clear_bit(i, regulatory->block_6ghz_sp);
+ }
+
+out:
+ kfree(ptr);
+}
+
static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
@@ -501,6 +575,7 @@ bottom:
if (regd_allow_6ghz) {
rtw89_regd_setup_policy_6ghz(rtwdev);
+ rtw89_regd_setup_policy_6ghz_sp(rtwdev);
return;
}
@@ -513,10 +588,56 @@ bottom:
kfree(sband);
}
+#define RTW89_DEF_REGD_STR(regd) \
+ [RTW89_ ## regd] = #regd
+
+static const char * const rtw89_regd_string[] = {
+ RTW89_DEF_REGD_STR(WW),
+ RTW89_DEF_REGD_STR(ETSI),
+ RTW89_DEF_REGD_STR(FCC),
+ RTW89_DEF_REGD_STR(MKK),
+ RTW89_DEF_REGD_STR(NA),
+ RTW89_DEF_REGD_STR(IC),
+ RTW89_DEF_REGD_STR(KCC),
+ RTW89_DEF_REGD_STR(ACMA),
+ RTW89_DEF_REGD_STR(NCC),
+ RTW89_DEF_REGD_STR(MEXICO),
+ RTW89_DEF_REGD_STR(CHILE),
+ RTW89_DEF_REGD_STR(UKRAINE),
+ RTW89_DEF_REGD_STR(CN),
+ RTW89_DEF_REGD_STR(QATAR),
+ RTW89_DEF_REGD_STR(UK),
+ RTW89_DEF_REGD_STR(THAILAND),
+};
+
+static_assert(ARRAY_SIZE(rtw89_regd_string) == RTW89_REGD_NUM);
+
+const char *rtw89_regd_get_string(enum rtw89_regulation_type regd)
+{
+ if (regd < 0 || regd >= RTW89_REGD_NUM)
+ return "(unknown)";
+
+ return rtw89_regd_string[regd];
+}
+
int rtw89_regd_setup(struct rtw89_dev *rtwdev)
{
+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
+ const struct rtw89_regd_data *regd_data = elm_info->regd;
struct wiphy *wiphy = rtwdev->hw->wiphy;
+ if (regd_data) {
+ regulatory->ctrl.nr = regd_data->nr;
+ regulatory->ctrl.map = regd_data->map;
+ } else {
+ regulatory->ctrl.nr = ARRAY_SIZE(rtw89_regd_map);
+ regulatory->ctrl.map = rtw89_regd_map;
+ }
+
+ regulatory->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
+ regulatory->txpwr_uk_follow_etsi = true;
+
if (!wiphy)
return -EINVAL;
@@ -527,21 +648,16 @@ int rtw89_regd_setup(struct rtw89_dev *rtwdev)
return 0;
}
-int rtw89_regd_init(struct rtw89_dev *rtwdev,
- void (*reg_notifier)(struct wiphy *wiphy,
- struct regulatory_request *request))
+int rtw89_regd_init_hint(struct rtw89_dev *rtwdev)
{
- struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_regd *chip_regd;
struct wiphy *wiphy = rtwdev->hw->wiphy;
int ret;
- regulatory->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
-
if (!wiphy)
return -EINVAL;
- chip_regd = rtw89_regd_find_reg_by_name(rtwdev->efuse.country_code);
+ chip_regd = rtw89_regd_find_reg_by_name(rtwdev, rtwdev->efuse.country_code);
if (!rtw89_regd_is_ww(chip_regd)) {
rtwdev->regulatory.regd = chip_regd;
/* Ignore country ie if there is a country domain programmed in chip */
@@ -562,24 +678,73 @@ int rtw89_regd_init(struct rtw89_dev *rtwdev,
return 0;
}
-static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev,
- struct wiphy *wiphy)
+static void rtw89_regd_apply_policy_unii4(struct rtw89_dev *rtwdev,
+ struct wiphy *wiphy)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_regd *regd = regulatory->regd;
struct ieee80211_supported_band *sband;
u8 index;
int i;
- index = rtw89_regd_get_index(regd);
- if (index == RTW89_REGD_MAX_COUNTRY_NUM)
+ sband = wiphy->bands[NL80211_BAND_5GHZ];
+ if (!sband)
return;
- if (!test_bit(index, regulatory->block_6ghz))
+ if (!chip->support_unii4)
return;
+ index = rtw89_regd_get_index(rtwdev, regd);
+ if (index != RTW89_REGD_MAX_COUNTRY_NUM &&
+ !test_bit(index, regulatory->block_unii4))
+ return;
+
+ rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c unii-4 is blocked by policy\n",
+ regd->alpha2[0], regd->alpha2[1]);
+
+ for (i = RTW89_5GHZ_UNII4_START_INDEX; i < sband->n_channels; i++)
+ sband->channels[i].flags |= IEEE80211_CHAN_DISABLED;
+}
+
+static bool regd_is_6ghz_blocked(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ const struct rtw89_regd *regd = regulatory->regd;
+ u8 index;
+
+ index = rtw89_regd_get_index(rtwdev, regd);
+ if (index != RTW89_REGD_MAX_COUNTRY_NUM &&
+ !test_bit(index, regulatory->block_6ghz))
+ return false;
+
rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is blocked by policy\n",
regd->alpha2[0], regd->alpha2[1]);
+ return true;
+}
+
+static bool regd_is_6ghz_not_applicable(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ const struct rtw89_regd *regd = regulatory->regd;
+
+ if (regd->txpwr_regd[RTW89_BAND_6G] != RTW89_NA)
+ return false;
+
+ rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is N/A in regd map\n",
+ regd->alpha2[0], regd->alpha2[1]);
+ return true;
+}
+
+static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev,
+ struct wiphy *wiphy)
+{
+ struct ieee80211_supported_band *sband;
+ int i;
+
+ if (!regd_is_6ghz_blocked(rtwdev) &&
+ !regd_is_6ghz_not_applicable(rtwdev))
+ return;
sband = wiphy->bands[NL80211_BAND_6GHZ];
if (!sband)
@@ -589,11 +754,47 @@ static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev,
sband->channels[i].flags |= IEEE80211_CHAN_DISABLED;
}
+static void rtw89_regd_apply_policy_tas(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ const struct rtw89_regd *regd = regulatory->regd;
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+ u8 tas_country;
+
+ if (!tas->enable)
+ return;
+
+ if (memcmp("US", regd->alpha2, 2) == 0)
+ tas_country = RTW89_ACPI_CONF_TAS_US;
+ else if (memcmp("CA", regd->alpha2, 2) == 0)
+ tas_country = RTW89_ACPI_CONF_TAS_CA;
+ else if (memcmp("KR", regd->alpha2, 2) == 0)
+ tas_country = RTW89_ACPI_CONF_TAS_KR;
+ else
+ tas_country = RTW89_ACPI_CONF_TAS_OTHERS;
+
+ tas->block_regd = !(tas->enabled_countries & tas_country &&
+ test_bit(RTW89_REGD_FUNC_TAS, regd->func_bitmap));
+}
+
+static void rtw89_regd_apply_policy_ant_gain(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ const struct rtw89_regd *regd = regulatory->regd;
+
+ if (!chip->support_ant_gain)
+ return;
+
+ ant_gain->block_country = !test_bit(RTW89_REGD_FUNC_DAG, regd->func_bitmap);
+}
+
static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev,
struct wiphy *wiphy,
struct regulatory_request *request)
{
- rtwdev->regulatory.regd = rtw89_regd_find_reg_by_name(request->alpha2);
+ rtwdev->regulatory.regd = rtw89_regd_find_reg_by_name(rtwdev, request->alpha2);
/* This notification might be set from the system of distros,
* and it does not expect the regulatory will be modified by
* connecting to an AP (i.e. country ie).
@@ -604,15 +805,19 @@ static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev,
else
wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE;
+ rtw89_regd_apply_policy_unii4(rtwdev, wiphy);
rtw89_regd_apply_policy_6ghz(rtwdev, wiphy);
+ rtw89_regd_apply_policy_tas(rtwdev);
+ rtw89_regd_apply_policy_ant_gain(rtwdev);
}
+static
void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request)
{
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct rtw89_dev *rtwdev = hw->priv;
- mutex_lock(&rtwdev->mutex);
+ wiphy_lock(wiphy);
rtw89_leave_ps_mode(rtwdev);
if (wiphy->regd) {
@@ -628,68 +833,272 @@ void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request
rtw89_core_set_chip_txpwr(rtwdev);
exit:
- mutex_unlock(&rtwdev->mutex);
+ wiphy_unlock(wiphy);
+}
+
+/* Maximum Transmit Power field (@raw) can be EIRP or PSD.
+ * Both units are 0.5 dB-based. Return a constraint in dB.
+ */
+static s8 tpe_get_constraint(s8 raw)
+{
+ const u8 hw_deviation = 3; /* unit: 0.5 dB */
+ const u8 antenna_gain = 10; /* unit: 0.5 dB */
+ const u8 array_gain = 6; /* unit: 0.5 dB */
+ const u8 offset = hw_deviation + antenna_gain + array_gain;
+
+ return (raw - offset) / 2;
+}
+
+static void tpe_intersect_constraint(struct rtw89_reg_6ghz_tpe *tpe, s8 cstr)
+{
+ if (tpe->valid) {
+ tpe->constraint = min(tpe->constraint, cstr);
+ return;
+ }
+
+ tpe->constraint = cstr;
+ tpe->valid = true;
}
-static void __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev)
+static void tpe_deal_with_eirp(struct rtw89_reg_6ghz_tpe *tpe,
+ const struct ieee80211_parsed_tpe_eirp *eirp)
+{
+ unsigned int i;
+ s8 cstr;
+
+ if (!eirp->valid)
+ return;
+
+ for (i = 0; i < eirp->count; i++) {
+ cstr = tpe_get_constraint(eirp->power[i]);
+ tpe_intersect_constraint(tpe, cstr);
+ }
+}
+
+static s8 tpe_convert_psd_to_eirp(s8 psd)
+{
+ static const unsigned int mlog20 = 1301;
+
+ return psd + 10 * mlog20 / 1000;
+}
+
+static void tpe_deal_with_psd(struct rtw89_reg_6ghz_tpe *tpe,
+ const struct ieee80211_parsed_tpe_psd *psd)
+{
+ unsigned int i;
+ s8 cstr_psd;
+ s8 cstr;
+
+ if (!psd->valid)
+ return;
+
+ for (i = 0; i < psd->count; i++) {
+ cstr_psd = tpe_get_constraint(psd->power[i]);
+ cstr = tpe_convert_psd_to_eirp(cstr_psd);
+ tpe_intersect_constraint(tpe, cstr);
+ }
+}
+
+static void rtw89_calculate_tpe(struct rtw89_dev *rtwdev,
+ struct rtw89_reg_6ghz_tpe *result_tpe,
+ const struct ieee80211_parsed_tpe *parsed_tpe)
+{
+ static const u8 category = IEEE80211_TPE_CAT_6GHZ_DEFAULT;
+
+ tpe_deal_with_eirp(result_tpe, &parsed_tpe->max_local[category]);
+ tpe_deal_with_eirp(result_tpe, &parsed_tpe->max_reg_client[category]);
+ tpe_deal_with_psd(result_tpe, &parsed_tpe->psd_local[category]);
+ tpe_deal_with_psd(result_tpe, &parsed_tpe->psd_reg_client[category]);
+}
+
+static bool __rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ struct rtw89_reg_6ghz_tpe new = {};
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_vif *rtwvif;
+ unsigned int link_id;
+ bool changed = false;
+
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+ const struct rtw89_reg_6ghz_tpe *tmp;
+ const struct rtw89_chan *chan;
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
+ if (chan->band_type != RTW89_BAND_6G)
+ continue;
+
+ tmp = &rtwvif_link->reg_6ghz_tpe;
+ if (!tmp->valid)
+ continue;
+
+ tpe_intersect_constraint(&new, tmp->constraint);
+ }
+ }
+
+ if (memcmp(&regulatory->reg_6ghz_tpe, &new,
+ sizeof(regulatory->reg_6ghz_tpe)) != 0)
+ changed = true;
+
+ if (changed) {
+ if (new.valid)
+ rtw89_debug(rtwdev, RTW89_DBG_REGD,
+ "recalc 6 GHz reg TPE to %d dBm\n",
+ new.constraint);
+ else
+ rtw89_debug(rtwdev, RTW89_DBG_REGD,
+ "recalc 6 GHz reg TPE to none\n");
+
+ regulatory->reg_6ghz_tpe = new;
+ }
+
+ return changed;
+}
+
+static int rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link, bool active,
+ unsigned int *changed)
+{
+ struct rtw89_reg_6ghz_tpe *tpe = &rtwvif_link->reg_6ghz_tpe;
+ struct ieee80211_bss_conf *bss_conf;
+
+ memset(tpe, 0, sizeof(*tpe));
+
+ if (!active || rtwvif_link->reg_6ghz_power != RTW89_REG_6GHZ_POWER_STD)
+ goto bottom;
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ rtw89_calculate_tpe(rtwdev, tpe, &bss_conf->tpe);
+
+ rcu_read_unlock();
+
+ if (!tpe->valid)
+ goto bottom;
+
+ if (tpe->constraint < RTW89_MIN_VALID_POWER_CONSTRAINT) {
+ rtw89_err(rtwdev,
+ "%s: constraint %d dBm is less than min valid val\n",
+ __func__, tpe->constraint);
+
+ tpe->valid = false;
+ return -EINVAL;
+ }
+
+bottom:
+ *changed += __rtw89_reg_6ghz_tpe_recalc(rtwdev);
+ return 0;
+}
+
+static bool __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ const struct rtw89_regd *regd = regulatory->regd;
enum rtw89_reg_6ghz_power sel;
const struct rtw89_chan *chan;
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
+ unsigned int link_id;
int count = 0;
+ u8 index;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
- chan = rtw89_chan_get(rtwdev, rtwvif->sub_entity_idx);
- if (chan->band_type != RTW89_BAND_6G)
- continue;
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
+ if (chan->band_type != RTW89_BAND_6G)
+ continue;
- if (count != 0 && rtwvif->reg_6ghz_power == sel)
- continue;
+ if (count != 0 && rtwvif_link->reg_6ghz_power == sel)
+ continue;
- sel = rtwvif->reg_6ghz_power;
- count++;
+ sel = rtwvif_link->reg_6ghz_power;
+ count++;
+ }
}
if (count != 1)
sel = RTW89_REG_6GHZ_POWER_DFLT;
+ if (sel == RTW89_REG_6GHZ_POWER_STD) {
+ index = rtw89_regd_get_index(rtwdev, regd);
+ if (index == RTW89_REGD_MAX_COUNTRY_NUM ||
+ test_bit(index, regulatory->block_6ghz_sp)) {
+ rtw89_debug(rtwdev, RTW89_DBG_REGD,
+ "%c%c 6 GHz SP is blocked by policy\n",
+ regd->alpha2[0], regd->alpha2[1]);
+ sel = RTW89_REG_6GHZ_POWER_DFLT;
+ }
+ }
+
if (regulatory->reg_6ghz_power == sel)
- return;
+ return false;
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"recalc 6 GHz reg power type to %d\n", sel);
regulatory->reg_6ghz_power = sel;
-
- rtw89_core_set_chip_txpwr(rtwdev);
+ return true;
}
-void rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif, bool active)
+static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link, bool active,
+ unsigned int *changed)
{
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_bss_conf *bss_conf;
+
+ rcu_read_lock();
- lockdep_assert_held(&rtwdev->mutex);
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
if (active) {
- switch (vif->bss_conf.power_type) {
+ switch (bss_conf->power_type) {
case IEEE80211_REG_VLP_AP:
- rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP;
+ rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP;
break;
case IEEE80211_REG_LPI_AP:
- rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_LPI;
+ rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_LPI;
break;
case IEEE80211_REG_SP_AP:
- rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_STD;
+ rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_STD;
break;
default:
- rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
+ rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
break;
}
} else {
- rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
+ rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
}
- __rtw89_reg_6ghz_power_recalc(rtwdev);
+ rcu_read_unlock();
+
+ *changed += __rtw89_reg_6ghz_power_recalc(rtwdev);
+ return 0;
+}
+
+int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+ bool active)
+{
+ unsigned int changed = 0;
+ int ret;
+
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ /* The result of reg_6ghz_tpe may depend on reg_6ghz_power type,
+ * so must do reg_6ghz_tpe_recalc() after reg_6ghz_power_recalc().
+ */
+
+ ret = rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif_link, active, &changed);
+ if (ret)
+ return ret;
+
+ ret = rtw89_reg_6ghz_tpe_recalc(rtwdev, rtwvif_link, active, &changed);
+ if (ret)
+ return ret;
+
+ if (changed)
+ rtw89_core_set_chip_txpwr(rtwdev);
+
+ return 0;
}
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
index 51d3e61eaa1d..fafa200a9c8d 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
@@ -105,6 +105,10 @@ static const u32 rtw8851b_c2h_regs[RTW89_C2HREG_MAX] = {
R_AX_C2HREG_DATA3
};
+static const u32 rtw8851b_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = {
+ R_AX_C2HREG_DATA3 + 3, R_AX_C2HREG_DATA3 + 3,
+};
+
static const struct rtw89_page_regs rtw8851b_page_regs = {
.hci_fc_ctrl = R_AX_HCI_FC_CTRL,
.ch_page_ctrl = R_AX_CH_PAGE_CTRL,
@@ -181,6 +185,15 @@ static const struct rtw89_rrsr_cfgs rtw8851b_rrsr_cfgs = {
.rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2},
};
+static const struct rtw89_rfkill_regs rtw8851b_rfkill_regs = {
+ .pinmux = {R_AX_GPIO8_15_FUNC_SEL,
+ B_AX_PINMUX_GPIO9_FUNC_SEL_MASK,
+ 0xf},
+ .mode = {R_AX_GPIO_EXT_CTRL + 2,
+ (B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16,
+ 0x0},
+};
+
static const struct rtw89_dig_regs rtw8851b_dig_regs = {
.seg0_pd_reg = R_SEG0R_PD_V1,
.pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
@@ -211,10 +224,17 @@ static const struct rtw89_edcca_regs rtw8851b_edcca_regs = {
.edcca_p_mask = B_EDCCA_LVL_MSK1,
.ppdu_level = R_SEG0R_EDCCA_LVL_V1,
.ppdu_mask = B_EDCCA_LVL_MSK3,
- .rpt_a = R_EDCCA_RPT_A,
- .rpt_b = R_EDCCA_RPT_B,
- .rpt_sel = R_EDCCA_RPT_SEL,
- .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ .p = {{
+ .rpt_a = R_EDCCA_RPT_A,
+ .rpt_b = R_EDCCA_RPT_B,
+ .rpt_sel = R_EDCCA_RPT_SEL,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ }, {
+ .rpt_a = R_EDCCA_RPT_P1_A,
+ .rpt_b = R_EDCCA_RPT_P1_B,
+ .rpt_sel = R_EDCCA_RPT_SEL,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK,
+ }},
.tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
.tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
};
@@ -269,7 +289,7 @@ static int rtw8851b_pwr_on_func(struct rtw89_dev *rtwdev)
{
u32 val32;
u8 val8;
- u32 ret;
+ int ret;
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN |
B_AX_AFSM_PCIE_SUS_EN);
@@ -388,7 +408,7 @@ static void rtw8851b_patch_swr_pfm2pwm(struct rtw89_dev *rtwdev)
static int rtw8851b_pwr_off_func(struct rtw89_dev *rtwdev)
{
u32 val32;
- u32 ret;
+ int ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
XTAL_SI_RFC2RF);
@@ -1574,28 +1594,40 @@ static void rtw8851b_rfk_init(struct rtw89_dev *rtwdev)
rtw8851b_aack(rtwdev);
rtw8851b_rck(rtwdev);
rtw8851b_dack(rtwdev);
- rtw8851b_rx_dck(rtwdev, RTW89_PHY_0);
+ rtw8851b_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0);
}
-static void rtw8851b_rfk_channel(struct rtw89_dev *rtwdev)
+static void rtw8851b_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
+ enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
+ enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
- rtw8851b_rx_dck(rtwdev, phy_idx);
- rtw8851b_iqk(rtwdev, phy_idx);
- rtw8851b_tssi(rtwdev, phy_idx, true);
- rtw8851b_dpk(rtwdev, phy_idx);
+ rtw89_btc_ntfy_conn_rfk(rtwdev, true);
+
+ rtw8851b_rx_dck(rtwdev, phy_idx, chanctx_idx);
+ rtw8851b_iqk(rtwdev, phy_idx, chanctx_idx);
+ rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
+ rtw8851b_tssi(rtwdev, phy_idx, true, chanctx_idx);
+ rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
+ rtw8851b_dpk(rtwdev, phy_idx, chanctx_idx);
+
+ rtw89_btc_ntfy_conn_rfk(rtwdev, false);
}
static void rtw8851b_rfk_band_changed(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx)
+ enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan)
{
- rtw8851b_tssi_scan(rtwdev, phy_idx);
+ rtw8851b_tssi_scan(rtwdev, phy_idx, chan);
}
-static void rtw8851b_rfk_scan(struct rtw89_dev *rtwdev, bool start)
+static void rtw8851b_rfk_scan(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ bool start)
{
- rtw8851b_wifi_scan_notify(rtwdev, start, RTW89_PHY_0);
+ rtw8851b_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx,
+ rtwvif_link->chanctx_idx);
}
static void rtw8851b_rfk_track(struct rtw89_dev *rtwdev)
@@ -1797,7 +1829,7 @@ rtw8851b_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
static void rtw8851b_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en,
enum rtw89_phy_idx phy_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
rtw89_phy_write_reg3_tbl(rtwdev, en ? &rtw8851b_btc_preagc_en_defs_tbl :
&rtw8851b_btc_preagc_dis_defs_tbl);
@@ -1820,7 +1852,7 @@ static void rtw8851b_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en,
static void rtw8851b_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en,
enum rtw89_phy_idx phy_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
if (en) {
rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
@@ -1865,7 +1897,7 @@ static void rtw8851b_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en,
static void rtw8851b_bb_ctrl_rx_path(struct rtw89_dev *rtwdev,
enum rtw89_rf_path_bit rx_path)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
u32 rst_mask0;
if (rx_path == RF_A) {
@@ -2279,7 +2311,8 @@ static void rtw8851b_query_ppdu(struct rtw89_dev *rtwdev,
u8 path;
u8 *rx_power = phy_ppdu->rssi;
- status->signal = RTW89_RSSI_RAW_TO_DBM(rx_power[RF_PATH_A]);
+ if (!status->signal)
+ status->signal = RTW89_RSSI_RAW_TO_DBM(rx_power[RF_PATH_A]);
for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
status->chains |= BIT(path);
@@ -2320,6 +2353,7 @@ static int rtw8851b_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
u8 wl_rfc_s1;
int ret;
+ rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
@@ -2370,9 +2404,12 @@ static const struct rtw89_chip_ops rtw8851b_chip_ops = {
.get_thermal = rtw8851b_get_thermal,
.ctrl_btg_bt_rx = rtw8851b_ctrl_btg_bt_rx,
.query_ppdu = rtw8851b_query_ppdu,
+ .convert_rpl_to_rssi = NULL,
+ .phy_rpt_to_rssi = NULL,
.ctrl_nbtg_bt_tx = rtw8851b_ctrl_nbtg_bt_tx,
.cfg_txrx_path = rtw8851b_bb_cfg_txrx_path,
.set_txpwr_ul_tb_offset = rtw8851b_set_txpwr_ul_tb_offset,
+ .digital_pwr_comp = NULL,
.pwr_on_func = rtw8851b_pwr_on_func,
.pwr_off_func = rtw8851b_pwr_off_func,
.query_rxdesc = rtw89_core_query_rxdesc,
@@ -2386,6 +2423,7 @@ static const struct rtw89_chip_ops rtw8851b_chip_ops = {
.h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl,
.h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl,
.h2c_ampdu_cmac_tbl = NULL,
+ .h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl,
.h2c_default_dmac_tbl = NULL,
.h2c_update_beacon = rtw89_fw_h2c_update_beacon,
.h2c_ba_cam = rtw89_fw_h2c_ba_cam,
@@ -2421,6 +2459,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.try_ce_fw = true,
.bbmcu_nr = 0,
.needed_fw_elms = 0,
+ .fw_blacklist = NULL,
.fifo_size = 196608,
.small_fifo_size = true,
.dle_scc_rsvd_size = 98304,
@@ -2432,6 +2471,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.wde_qempty_acq_grpnum = 4,
.wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000},
+ .thermal_th = {0x32, 0x35},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
.bb_table = &rtw89_8851b_phy_bb_table,
@@ -2441,21 +2481,32 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.nctl_post_table = &rtw8851b_nctl_post_defs_tbl,
.dflt_parms = &rtw89_8851b_dflt_parms,
.rfe_parms_conf = rtw89_8851b_rfe_parms_conf,
+ .txpwr_factor_bb = 3,
.txpwr_factor_rf = 2,
.txpwr_factor_mac = 1,
.dig_table = NULL,
.dig_regs = &rtw8851b_dig_regs,
.tssi_dbw_table = NULL,
+ .support_macid_num = RTW89_MAX_MAC_ID_NUM,
+ .support_link_num = 0,
.support_chanctx_num = 0,
+ .support_rnr = false,
.support_bands = BIT(NL80211_BAND_2GHZ) |
BIT(NL80211_BAND_5GHZ),
.support_bandwidths = BIT(NL80211_CHAN_WIDTH_20) |
BIT(NL80211_CHAN_WIDTH_40) |
BIT(NL80211_CHAN_WIDTH_80),
.support_unii4 = true,
+ .support_ant_gain = false,
+ .support_tas = false,
+ .support_sar_by_ant = false,
.ul_tb_waveform_ctrl = true,
.ul_tb_pwr_diff = false,
+ .rx_freq_frome_ie = true,
.hw_sec_hdr = false,
+ .hw_mgmt_tx_encrypt = false,
+ .hw_tkip_crypto = false,
+ .hw_mlo_bmc_crypto = false,
.rf_path_num = 1,
.tx_nss = 1,
.rx_nss = 1,
@@ -2506,7 +2557,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8},
.c2h_regs = rtw8851b_c2h_regs,
.page_regs = &rtw8851b_page_regs,
- .wow_reason_reg = R_AX_C2HREG_DATA3 + 3,
+ .wow_reason_reg = rtw8851b_wow_wakeup_regs,
.cfo_src_fd = true,
.cfo_hw_comp = true,
.dcfo_comp = &rtw8851b_dcfo_comp,
@@ -2517,6 +2568,8 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.rrsr_cfgs = &rtw8851b_rrsr_cfgs,
.bss_clr_vld = {R_BSS_CLR_MAP_V1, B_BSS_CLR_MAP_VLD0},
.bss_clr_map_reg = R_BSS_CLR_MAP_V1,
+ .rfkill_init = &rtw8851b_rfkill_regs,
+ .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9},
.dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) |
BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) |
BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI),
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c
index a221f94627f5..f72b3ac6f149 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c
@@ -521,9 +521,10 @@ static void _dac_cal(struct rtw89_dev *rtwdev, bool force)
}
static void _rx_dck_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path, bool is_afe)
+ enum rtw89_rf_path path, bool is_afe,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RX_DCK] ==== S%d RX DCK (%s / CH%d / %s / by %s)====\n", path,
@@ -574,7 +575,8 @@ static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 rf
_rxbb_ofst_swap(rtwdev, path, rf_mode);
}
-static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe)
+static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe,
+ enum rtw89_chanctx_idx chanctx_idx)
{
u32 rf_reg5;
u8 path;
@@ -584,7 +586,7 @@ static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_af
0x2, rtwdev->hal.cv);
for (path = 0; path < RF_PATH_NUM_8851B; path++) {
- _rx_dck_info(rtwdev, phy, path, is_afe);
+ _rx_dck_info(rtwdev, phy, path, is_afe, chanctx_idx);
rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK);
@@ -1481,9 +1483,9 @@ static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev,
}
static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- u8 path)
+ u8 path, enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u8 idx = 0;
@@ -1586,10 +1588,11 @@ static void _iqk_init(struct rtw89_dev *rtwdev)
}
static void _doiqk(struct rtw89_dev *rtwdev, bool force,
- enum rtw89_phy_idx phy_idx, u8 path)
+ enum rtw89_phy_idx phy_idx, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx);
u32 backup_rf_val[RTW8851B_IQK_SS][BACKUP_RF_REGS_NR];
u32 backup_bb_val[BACKUP_BB_REGS_NR];
@@ -1602,7 +1605,7 @@ static void _doiqk(struct rtw89_dev *rtwdev, bool force,
iqk_info->version = RTW8851B_IQK_VER;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version);
- _iqk_get_ch_info(rtwdev, phy_idx, path);
+ _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx);
_rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]);
_rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path);
@@ -1618,9 +1621,10 @@ static void _doiqk(struct rtw89_dev *rtwdev, bool force,
BTC_WRFK_ONESHOT_STOP);
}
-static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force)
+static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ bool force, enum rtw89_chanctx_idx chanctx_idx)
{
- _doiqk(rtwdev, force, phy_idx, RF_PATH_A);
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx);
}
static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, const u32 *reg,
@@ -1746,9 +1750,9 @@ static void _dpk_init(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
}
static void _dpk_information(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
u8 kidx = dpk->cur_idx[path];
@@ -2195,7 +2199,7 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
if (dgain > 0x5fc || dgain < 0x556) {
_dpk_one_shot(rtwdev, phy, path, D_SYNC);
- dgain = _dpk_dgain_read(rtwdev);
+ _dpk_dgain_read(rtwdev);
}
if (agc_cnt == 0) {
@@ -2449,7 +2453,8 @@ _error:
}
static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
- enum rtw89_phy_idx phy, u8 kpath)
+ enum rtw89_phy_idx phy, u8 kpath,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
u32 kip_bkup[RF_PATH_NUM_8851B][DPK_KIP_REG_NUM_8851B] = {};
@@ -2465,7 +2470,7 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
continue;
_dpk_bkup_kip(rtwdev, dpk_kip_reg, kip_bkup, path);
_dpk_bkup_rf(rtwdev, dpk_rf_reg, rf_bkup, path);
- _dpk_information(rtwdev, phy, path);
+ _dpk_information(rtwdev, phy, path, chanctx_idx);
_dpk_init(rtwdev, path);
if (rtwdev->is_tssi_mode[path])
@@ -2505,13 +2510,14 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
_dpk_kip_pwr_clk_onoff(rtwdev, false);
}
-static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force)
+static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force,
+ enum rtw89_chanctx_idx chanctx_idx)
{
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[DPK] ****** 8851B DPK Start (Ver: 0x%x, Cv: %d) ******\n",
DPK_VER_8851B, rtwdev->hal.cv);
- _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy));
+ _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy), chanctx_idx);
}
static void _dpk_track(struct rtw89_dev *rtwdev)
@@ -2617,9 +2623,8 @@ static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
}
static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_sys_defs_tbl);
@@ -2650,7 +2655,7 @@ static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
#define RTW8851B_TSSI_GET_VAL(ptr, idx) \
({ \
@@ -2664,7 +2669,6 @@ static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx ph
__val; \
})
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u8 subband = chan->subband_type;
const s8 *thm_up_a = NULL;
@@ -2755,9 +2759,8 @@ static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx
}
static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
@@ -2766,9 +2769,9 @@ static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy
}
static void _tssi_alignment_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path, bool all)
+ enum rtw89_rf_path path, bool all,
+ const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
@@ -2944,10 +2947,9 @@ static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch)
}
static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u32 gidx, gidx_1st, gidx_2nd;
u8 ch = chan->channel;
s8 de_1st;
@@ -2980,10 +2982,9 @@ static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u32 tgidx, tgidx_1st, tgidx_2nd;
u8 ch = chan->channel;
s8 tde_1st;
@@ -3017,10 +3018,10 @@ static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx ph
return val;
}
-static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u8 gidx;
s8 ofdm_de;
@@ -3033,7 +3034,7 @@ static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx p
for (i = RF_PATH_A; i < RTW8851B_TSSI_PATH_NR; i++) {
gidx = _tssi_get_cck_group(rtwdev, ch);
- trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i);
+ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan);
val = tssi_info->tssi_cck[i][gidx] + trim_de;
rtw89_debug(rtwdev, RTW89_DBG_TSSI,
@@ -3049,8 +3050,8 @@ static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx p
rtw89_phy_read32_mask(rtwdev, _tssi_de_cck_long[i],
_TSSI_DE_MASK));
- ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i);
- trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i);
+ ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i, chan);
+ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan);
val = ofdm_de + trim_de;
rtw89_debug(rtwdev, RTW89_DBG_TSSI,
@@ -3096,10 +3097,10 @@ static void _tssi_alimentk_dump_result(struct rtw89_dev *rtwdev, enum rtw89_rf_p
}
static void _tssi_alimentk_done(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy, enum rtw89_rf_path path)
+ enum rtw89_phy_idx phy, enum rtw89_rf_path path,
+ const struct rtw89_chan *chan)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 channel = chan->channel;
u8 band;
@@ -3255,9 +3256,10 @@ void rtw8851b_dack(struct rtw89_dev *rtwdev)
_dac_cal(rtwdev, false);
}
-void rtw8851b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+void rtw8851b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx);
u32 tx_en;
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START);
@@ -3265,30 +3267,32 @@ void rtw8851b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
_wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx));
_iqk_init(rtwdev);
- _iqk(rtwdev, phy_idx, false);
+ _iqk(rtwdev, phy_idx, false, chanctx_idx);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP);
}
-void rtw8851b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+void rtw8851b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx);
u32 tx_en;
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START);
rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
_wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx));
- _rx_dck(rtwdev, phy_idx, false);
+ _rx_dck(rtwdev, phy_idx, false, chanctx_idx);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP);
}
-void rtw8851b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+void rtw8851b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx);
u32 tx_en;
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START);
@@ -3297,7 +3301,7 @@ void rtw8851b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
rtwdev->dpk.is_dpk_enable = true;
rtwdev->dpk.is_dpk_reload_en = false;
- _dpk(rtwdev, phy_idx, false);
+ _dpk(rtwdev, phy_idx, false, chanctx_idx);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP);
@@ -3308,9 +3312,11 @@ void rtw8851b_dpk_track(struct rtw89_dev *rtwdev)
_dpk_track(rtwdev);
}
-void rtw8851b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en)
+void rtw8851b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ bool hwtx_en, enum rtw89_chanctx_idx chanctx_idx)
{
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_A);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_A, chanctx_idx);
u8 i;
rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", __func__, phy);
@@ -3319,26 +3325,26 @@ void rtw8851b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_e
_tssi_disable(rtwdev, phy);
for (i = RF_PATH_A; i < RF_PATH_NUM_8851B; i++) {
- _tssi_set_sys(rtwdev, phy, i);
+ _tssi_set_sys(rtwdev, phy, i, chan);
_tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i);
_tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i);
_tssi_set_dck(rtwdev, phy, i);
- _tssi_set_tmeter_tbl(rtwdev, phy, i);
+ _tssi_set_tmeter_tbl(rtwdev, phy, i, chan);
_tssi_set_dac_gain_tbl(rtwdev, phy, i);
- _tssi_slope_cal_org(rtwdev, phy, i);
- _tssi_alignment_default(rtwdev, phy, i, true);
+ _tssi_slope_cal_org(rtwdev, phy, i, chan);
+ _tssi_alignment_default(rtwdev, phy, i, true, chan);
_tssi_set_tssi_slope(rtwdev, phy, i);
}
_tssi_enable(rtwdev, phy);
- _tssi_set_efuse_to_de(rtwdev, phy);
+ _tssi_set_efuse_to_de(rtwdev, phy, chan);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP);
}
-void rtw8851b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+void rtw8851b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 channel = chan->channel;
u32 i;
@@ -3348,20 +3354,21 @@ void rtw8851b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
_tssi_disable(rtwdev, phy);
for (i = RF_PATH_A; i < RF_PATH_NUM_8851B; i++) {
- _tssi_set_sys(rtwdev, phy, i);
- _tssi_set_tmeter_tbl(rtwdev, phy, i);
- _tssi_slope_cal_org(rtwdev, phy, i);
- _tssi_alignment_default(rtwdev, phy, i, true);
+ _tssi_set_sys(rtwdev, phy, i, chan);
+ _tssi_set_tmeter_tbl(rtwdev, phy, i, chan);
+ _tssi_slope_cal_org(rtwdev, phy, i, chan);
+ _tssi_alignment_default(rtwdev, phy, i, true, chan);
}
_tssi_enable(rtwdev, phy);
- _tssi_set_efuse_to_de(rtwdev, phy);
+ _tssi_set_efuse_to_de(rtwdev, phy, chan);
}
static void rtw8851b_tssi_default_txagc(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy, bool enable)
+ enum rtw89_phy_idx phy, bool enable,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
u8 channel = chan->channel;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "======> %s ch=%d\n",
@@ -3379,7 +3386,7 @@ static void rtw8851b_tssi_default_txagc(struct rtw89_dev *rtwdev,
rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0);
rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1);
- _tssi_alimentk_done(rtwdev, phy, RF_PATH_A);
+ _tssi_alimentk_done(rtwdev, phy, RF_PATH_A, chan);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"======>%s 2 SCAN_END Set 0x5818[7:0]=0x%x\n",
@@ -3391,12 +3398,13 @@ static void rtw8851b_tssi_default_txagc(struct rtw89_dev *rtwdev,
}
void rtw8851b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
- enum rtw89_phy_idx phy_idx)
+ enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
{
if (scan_start)
- rtw8851b_tssi_default_txagc(rtwdev, phy_idx, true);
+ rtw8851b_tssi_default_txagc(rtwdev, phy_idx, true, chanctx_idx);
else
- rtw8851b_tssi_default_txagc(rtwdev, phy_idx, false);
+ rtw8851b_tssi_default_txagc(rtwdev, phy_idx, false, chanctx_idx);
}
static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h
index b66a23d6d367..ea7df628256b 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.h
@@ -12,15 +12,21 @@ void rtw8851b_lck_init(struct rtw89_dev *rtwdev);
void rtw8851b_lck_track(struct rtw89_dev *rtwdev);
void rtw8851b_rck(struct rtw89_dev *rtwdev);
void rtw8851b_dack(struct rtw89_dev *rtwdev);
-void rtw8851b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
-void rtw8851b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
+void rtw8851b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
+void rtw8851b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
void rtw8851b_dpk_init(struct rtw89_dev *rtwdev);
-void rtw8851b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
+void rtw8851b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
void rtw8851b_dpk_track(struct rtw89_dev *rtwdev);
-void rtw8851b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en);
-void rtw8851b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
+void rtw8851b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ bool hwtx_en, enum rtw89_chanctx_idx chanctx_idx);
+void rtw8851b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan);
void rtw8851b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
- enum rtw89_phy_idx phy_idx);
+ enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851be.c b/drivers/net/wireless/realtek/rtw89/rtw8851be.c
index ca1374a71727..5810af825242 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851be.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851be.c
@@ -27,6 +27,7 @@ static const struct rtw89_pci_info rtw8851b_pci_info = {
.io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS,
.rx_ring_eq_is_full = false,
.check_rx_tag = false,
+ .no_rxbd_fs = false,
.init_cfg_reg = R_AX_PCIE_INIT_CFG1,
.txhci_en_bit = B_AX_TXHCI_EN,
@@ -46,6 +47,7 @@ static const struct rtw89_pci_info rtw8851b_pci_info = {
.rpwm_addr = R_AX_PCIE_HRPWM,
.cpwm_addr = R_AX_CPWM,
.mit_addr = R_AX_INT_MIT_RX,
+ .wp_sel_addr = 0,
.tx_dma_ch_mask = BIT(RTW89_TXCH_ACH4) | BIT(RTW89_TXCH_ACH5) |
BIT(RTW89_TXCH_ACH6) | BIT(RTW89_TXCH_ACH7) |
BIT(RTW89_TXCH_CH10) | BIT(RTW89_TXCH_CH11),
@@ -59,10 +61,14 @@ static const struct rtw89_pci_info rtw8851b_pci_info = {
.enable_intr = rtw89_pci_enable_intr,
.disable_intr = rtw89_pci_disable_intr,
.recognize_intrs = rtw89_pci_recognize_intrs,
+
+ .ssid_quirks = NULL,
};
static const struct rtw89_driver_info rtw89_8851be_info = {
.chip = &rtw8851b_chip_info,
+ .variant = NULL,
+ .quirks = NULL,
.bus = {
.pci = &rtw8851b_pci_info,
},
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 2deadec715cf..cd5987fc52d7 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -337,6 +337,11 @@ static const struct rtw89_pwr_cfg rtw8852a_pwroff[] = {
PWR_INTF_MSK_PCIE,
PWR_BASE_MAC,
PWR_CMD_WRITE, BIT(0), 0},
+ {0x0092,
+ PWR_CV_MSK_ALL,
+ PWR_INTF_MSK_PCIE,
+ PWR_BASE_MAC,
+ PWR_CMD_WRITE, BIT(4), BIT(4)},
{0x0005,
PWR_CV_MSK_ALL,
PWR_INTF_MSK_PCIE,
@@ -398,6 +403,10 @@ static const u32 rtw8852a_c2h_regs[RTW89_C2HREG_MAX] = {
R_AX_C2HREG_DATA3
};
+static const u32 rtw8852a_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = {
+ R_AX_C2HREG_DATA3 + 3, R_AX_C2HREG_DATA3 + 3,
+};
+
static const struct rtw89_page_regs rtw8852a_page_regs = {
.hci_fc_ctrl = R_AX_HCI_FC_CTRL,
.ch_page_ctrl = R_AX_CH_PAGE_CTRL,
@@ -474,6 +483,15 @@ static const struct rtw89_rrsr_cfgs rtw8852a_rrsr_cfgs = {
.rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2},
};
+static const struct rtw89_rfkill_regs rtw8852a_rfkill_regs = {
+ .pinmux = {R_AX_GPIO8_15_FUNC_SEL,
+ B_AX_PINMUX_GPIO9_FUNC_SEL_MASK,
+ 0xf},
+ .mode = {R_AX_GPIO_EXT_CTRL + 2,
+ (B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16,
+ 0x0},
+};
+
static const struct rtw89_dig_regs rtw8852a_dig_regs = {
.seg0_pd_reg = R_SEG0R_PD,
.pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
@@ -504,10 +522,17 @@ static const struct rtw89_edcca_regs rtw8852a_edcca_regs = {
.edcca_p_mask = B_EDCCA_LVL_MSK1,
.ppdu_level = R_SEG0R_EDCCA_LVL,
.ppdu_mask = B_EDCCA_LVL_MSK3,
- .rpt_a = R_EDCCA_RPT_A,
- .rpt_b = R_EDCCA_RPT_B,
- .rpt_sel = R_EDCCA_RPT_SEL,
- .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ .p = {{
+ .rpt_a = R_EDCCA_RPT_A,
+ .rpt_b = R_EDCCA_RPT_B,
+ .rpt_sel = R_EDCCA_RPT_SEL,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ }, {
+ .rpt_a = R_EDCCA_RPT_P1_A,
+ .rpt_b = R_EDCCA_RPT_P1_B,
+ .rpt_sel = R_EDCCA_RPT_SEL,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK,
+ }},
.tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
.tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
};
@@ -1328,29 +1353,40 @@ static void rtw8852a_rfk_init(struct rtw89_dev *rtwdev)
rtwdev->is_tssi_mode[RF_PATH_B] = false;
rtw8852a_rck(rtwdev);
- rtw8852a_dack(rtwdev);
- rtw8852a_rx_dck(rtwdev, RTW89_PHY_0, true);
+ rtw8852a_dack(rtwdev, RTW89_CHANCTX_0);
+ rtw8852a_rx_dck(rtwdev, RTW89_PHY_0, true, RTW89_CHANCTX_0);
}
-static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev)
+static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
+ enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
+ enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
+
+ rtw89_btc_ntfy_conn_rfk(rtwdev, true);
+
+ rtw8852a_rx_dck(rtwdev, phy_idx, true, chanctx_idx);
+ rtw8852a_iqk(rtwdev, phy_idx, chanctx_idx);
+ rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
+ rtw8852a_tssi(rtwdev, phy_idx, chanctx_idx);
+ rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
+ rtw8852a_dpk(rtwdev, phy_idx, chanctx_idx);
- rtw8852a_rx_dck(rtwdev, phy_idx, true);
- rtw8852a_iqk(rtwdev, phy_idx);
- rtw8852a_tssi(rtwdev, phy_idx);
- rtw8852a_dpk(rtwdev, phy_idx);
+ rtw89_btc_ntfy_conn_rfk(rtwdev, false);
}
static void rtw8852a_rfk_band_changed(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx)
+ enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan)
{
- rtw8852a_tssi_scan(rtwdev, phy_idx);
+ rtw8852a_tssi_scan(rtwdev, phy_idx, chan);
}
-static void rtw8852a_rfk_scan(struct rtw89_dev *rtwdev, bool start)
+static void rtw8852a_rfk_scan(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ bool start)
{
- rtw8852a_wifi_scan_notify(rtwdev, start, RTW89_PHY_0);
+ rtw8852a_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx);
}
static void rtw8852a_rfk_track(struct rtw89_dev *rtwdev)
@@ -1530,10 +1566,8 @@ static void rtw8852a_start_pmac_tx(struct rtw89_dev *rtwdev,
void rtw8852a_bb_set_pmac_tx(struct rtw89_dev *rtwdev,
struct rtw8852a_bb_pmac_info *tx_info,
- enum rtw89_phy_idx idx)
+ enum rtw89_phy_idx idx, const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
-
if (!tx_info->en_pmac_tx) {
rtw8852a_stop_pmac_tx(rtwdev, tx_info, idx);
rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0, idx);
@@ -1555,7 +1589,7 @@ void rtw8852a_bb_set_pmac_tx(struct rtw89_dev *rtwdev,
void rtw8852a_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable,
u16 tx_cnt, u16 period, u16 tx_time,
- enum rtw89_phy_idx idx)
+ enum rtw89_phy_idx idx, const struct rtw89_chan *chan)
{
struct rtw8852a_bb_pmac_info tx_info = {0};
@@ -1565,7 +1599,7 @@ void rtw8852a_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable,
tx_info.tx_cnt = tx_cnt;
tx_info.period = period;
tx_info.tx_time = tx_time;
- rtw8852a_bb_set_pmac_tx(rtwdev, &tx_info, idx);
+ rtw8852a_bb_set_pmac_tx(rtwdev, &tx_info, idx, chan);
}
void rtw8852a_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm,
@@ -2047,7 +2081,9 @@ static void rtw8852a_query_ppdu(struct rtw89_dev *rtwdev,
u8 path;
u8 *rx_power = phy_ppdu->rssi;
- status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A], rx_power[RF_PATH_B]));
+ if (!status->signal)
+ status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A],
+ rx_power[RF_PATH_B]));
for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
status->chains |= BIT(path);
status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]);
@@ -2094,9 +2130,12 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
.get_thermal = rtw8852a_get_thermal,
.ctrl_btg_bt_rx = rtw8852a_ctrl_btg_bt_rx,
.query_ppdu = rtw8852a_query_ppdu,
+ .convert_rpl_to_rssi = NULL,
+ .phy_rpt_to_rssi = NULL,
.ctrl_nbtg_bt_tx = rtw8852a_ctrl_nbtg_bt_tx,
.cfg_txrx_path = NULL,
.set_txpwr_ul_tb_offset = rtw8852a_set_txpwr_ul_tb_offset,
+ .digital_pwr_comp = NULL,
.pwr_on_func = NULL,
.pwr_off_func = NULL,
.query_rxdesc = rtw89_core_query_rxdesc,
@@ -2110,6 +2149,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
.h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl,
.h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl,
.h2c_ampdu_cmac_tbl = NULL,
+ .h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl,
.h2c_default_dmac_tbl = NULL,
.h2c_update_beacon = rtw89_fw_h2c_update_beacon,
.h2c_ba_cam = rtw89_fw_h2c_ba_cam,
@@ -2136,6 +2176,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.try_ce_fw = false,
.bbmcu_nr = 0,
.needed_fw_elms = 0,
+ .fw_blacklist = NULL,
.fifo_size = 458752,
.small_fifo_size = false,
.dle_scc_rsvd_size = 0,
@@ -2147,6 +2188,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.wde_qempty_acq_grpnum = 16,
.wde_qempty_mgq_grpsel = 16,
.rf_base_addr = {0xc000, 0xd000},
+ .thermal_th = {0x32, 0x35},
.pwr_on_seq = pwr_on_seq_8852a,
.pwr_off_seq = pwr_off_seq_8852a,
.bb_table = &rtw89_8852a_phy_bb_table,
@@ -2157,21 +2199,32 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.nctl_post_table = NULL,
.dflt_parms = &rtw89_8852a_dflt_parms,
.rfe_parms_conf = NULL,
+ .txpwr_factor_bb = 3,
.txpwr_factor_rf = 2,
.txpwr_factor_mac = 1,
.dig_table = &rtw89_8852a_phy_dig_table,
.dig_regs = &rtw8852a_dig_regs,
.tssi_dbw_table = NULL,
+ .support_macid_num = RTW89_MAX_MAC_ID_NUM,
+ .support_link_num = 0,
.support_chanctx_num = 1,
+ .support_rnr = false,
.support_bands = BIT(NL80211_BAND_2GHZ) |
BIT(NL80211_BAND_5GHZ),
.support_bandwidths = BIT(NL80211_CHAN_WIDTH_20) |
BIT(NL80211_CHAN_WIDTH_40) |
BIT(NL80211_CHAN_WIDTH_80),
.support_unii4 = false,
+ .support_ant_gain = false,
+ .support_tas = false,
+ .support_sar_by_ant = false,
.ul_tb_waveform_ctrl = false,
.ul_tb_pwr_diff = false,
+ .rx_freq_frome_ie = true,
.hw_sec_hdr = false,
+ .hw_mgmt_tx_encrypt = false,
+ .hw_tkip_crypto = false,
+ .hw_mlo_bmc_crypto = false,
.rf_path_num = 2,
.tx_nss = 2,
.rx_nss = 2,
@@ -2223,7 +2276,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.c2h_regs = rtw8852a_c2h_regs,
.c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8},
.page_regs = &rtw8852a_page_regs,
- .wow_reason_reg = R_AX_C2HREG_DATA3 + 3,
+ .wow_reason_reg = rtw8852a_wow_wakeup_regs,
.cfo_src_fd = false,
.cfo_hw_comp = false,
.dcfo_comp = &rtw8852a_dcfo_comp,
@@ -2234,6 +2287,8 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.rrsr_cfgs = &rtw8852a_rrsr_cfgs,
.bss_clr_vld = {R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0},
.bss_clr_map_reg = R_BSS_CLR_MAP,
+ .rfkill_init = &rtw8852a_rfkill_regs,
+ .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9},
.dma_ch_mask = 0,
.edcca_regs = &rtw8852a_edcca_regs,
#ifdef CONFIG_PM
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.h b/drivers/net/wireless/realtek/rtw89/rtw8852a.h
index ea82fed7b7be..d6c1acd09238 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.h
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.h
@@ -97,10 +97,10 @@ extern const struct rtw89_chip_info rtw8852a_chip_info;
void rtw8852a_bb_set_plcp_tx(struct rtw89_dev *rtwdev);
void rtw8852a_bb_set_pmac_tx(struct rtw89_dev *rtwdev,
struct rtw8852a_bb_pmac_info *tx_info,
- enum rtw89_phy_idx idx);
+ enum rtw89_phy_idx idx, const struct rtw89_chan *chan);
void rtw8852a_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable,
u16 tx_cnt, u16 period, u16 tx_time,
- enum rtw89_phy_idx idx);
+ enum rtw89_phy_idx idx, const struct rtw89_chan *chan);
void rtw8852a_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm,
enum rtw89_phy_idx idx);
void rtw8852a_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
index d86429e4a35f..9db8713ac99b 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
@@ -493,11 +493,12 @@ static void _dack(struct rtw89_dev *rtwdev)
_dack_s1(rtwdev);
}
-static void _dac_cal(struct rtw89_dev *rtwdev, bool force)
+static void _dac_cal(struct rtw89_dev *rtwdev, bool force,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_dack_info *dack = &rtwdev->dack;
u32 rf0_0, rf1_0;
- u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, RF_AB);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, RF_AB, chanctx_idx);
dack->dack_done = false;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK b\n");
@@ -799,12 +800,13 @@ static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path, u8 ktype)
}
static bool _iqk_one_shot(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx, u8 path, u8 ktype)
+ enum rtw89_phy_idx phy_idx, u8 path, u8 ktype,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
bool fail = false;
u32 iqk_cmd = 0x0;
- u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy_idx, path);
+ u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy_idx, path, chanctx_idx);
u32 addr_rfc_ctl = 0x0;
if (path == RF_PATH_A)
@@ -888,7 +890,8 @@ static bool _iqk_one_shot(struct rtw89_dev *rtwdev,
}
static bool _rxk_group_sel(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx, u8 path)
+ enum rtw89_phy_idx phy_idx, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
static const u32 rxgn_a[4] = {0x18C, 0x1A0, 0x28C, 0x2A0};
@@ -927,7 +930,7 @@ static bool _rxk_group_sel(struct rtw89_dev *rtwdev,
rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, gp);
rtw89_phy_write32_mask(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN, 0x1);
rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP);
- fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK);
+ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK, chanctx_idx);
rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(16 + gp + path * 4), fail);
}
@@ -952,7 +955,8 @@ static bool _rxk_group_sel(struct rtw89_dev *rtwdev,
}
static bool _iqk_nbrxk(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx, u8 path)
+ enum rtw89_phy_idx phy_idx, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u8 group = 0x0;
@@ -991,7 +995,7 @@ static bool _iqk_nbrxk(struct rtw89_dev *rtwdev,
B_CFIR_LUT_GP, group);
rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN);
rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP);
- fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK);
+ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK, chanctx_idx);
switch (iqk_info->iqk_band[path]) {
case RTW89_BAND_2G:
@@ -1040,7 +1044,8 @@ static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path)
}
static bool _txk_group_sel(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx, u8 path)
+ enum rtw89_phy_idx phy_idx, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
static const u32 a_txgain[4] = {0xE466, 0x646D, 0xE4E2, 0x64ED};
static const u32 g_txgain[4] = {0x60e8, 0x60f0, 0x61e8, 0x61ED};
@@ -1083,7 +1088,7 @@ static bool _txk_group_sel(struct rtw89_dev *rtwdev,
rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
B_CFIR_LUT_GP, gp);
rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP);
- fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK);
+ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK, chanctx_idx);
rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(8 + gp + path * 4), fail);
}
@@ -1098,7 +1103,8 @@ static bool _txk_group_sel(struct rtw89_dev *rtwdev,
}
static bool _iqk_nbtxk(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx, u8 path)
+ enum rtw89_phy_idx phy_idx, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u8 group = 0x2;
@@ -1131,7 +1137,7 @@ static bool _iqk_nbtxk(struct rtw89_dev *rtwdev,
rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, group);
rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt);
rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP);
- fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK);
+ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK, chanctx_idx);
if (!fail) {
tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD);
iqk_info->nb_txcfir[path] = tmp | 0x2;
@@ -1179,7 +1185,8 @@ static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path)
}
static bool _iqk_lok(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx, u8 path)
+ enum rtw89_phy_idx phy_idx, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u32 rf0 = 0x0;
@@ -1210,11 +1217,11 @@ static bool _iqk_lok(struct rtw89_dev *rtwdev,
rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN);
rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP);
rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt);
- tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_COARSE);
+ tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_COARSE, chanctx_idx);
iqk_info->lok_cor_fail[0][path] = tmp;
fsleep(10);
rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt);
- tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_FINE);
+ tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_FINE, chanctx_idx);
iqk_info->lok_fin_fail[0][path] = tmp;
fail = _lok_finetune_check(rtwdev, path);
return fail;
@@ -1321,7 +1328,8 @@ static void _iqk_info_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
}
static
-void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
+void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
bool lok_is_fail = false;
@@ -1333,30 +1341,35 @@ void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
for (i = 0; i < 3; i++) {
_lok_res_table(rtwdev, path, ibias++);
_iqk_txk_setting(rtwdev, path);
- lok_is_fail = _iqk_lok(rtwdev, phy_idx, path);
+ lok_is_fail = _iqk_lok(rtwdev, phy_idx, path, chanctx_idx);
if (!lok_is_fail)
break;
}
if (iqk_info->is_nbiqk)
- iqk_info->iqk_tx_fail[0][path] = _iqk_nbtxk(rtwdev, phy_idx, path);
+ iqk_info->iqk_tx_fail[0][path] = _iqk_nbtxk(rtwdev, phy_idx, path,
+ chanctx_idx);
else
- iqk_info->iqk_tx_fail[0][path] = _txk_group_sel(rtwdev, phy_idx, path);
+ iqk_info->iqk_tx_fail[0][path] = _txk_group_sel(rtwdev, phy_idx, path,
+ chanctx_idx);
_iqk_rxclk_setting(rtwdev, path);
_iqk_rxk_setting(rtwdev, path);
if (iqk_info->is_nbiqk || rtwdev->dbcc_en || iqk_info->iqk_band[path] == RTW89_BAND_2G)
- iqk_info->iqk_rx_fail[0][path] = _iqk_nbrxk(rtwdev, phy_idx, path);
+ iqk_info->iqk_rx_fail[0][path] = _iqk_nbrxk(rtwdev, phy_idx, path,
+ chanctx_idx);
else
- iqk_info->iqk_rx_fail[0][path] = _rxk_group_sel(rtwdev, phy_idx, path);
+ iqk_info->iqk_rx_fail[0][path] = _rxk_group_sel(rtwdev, phy_idx, path,
+ chanctx_idx);
_iqk_info_iqk(rtwdev, phy_idx, path);
}
static void _iqk_get_ch_info(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy, u8 path)
+ enum rtw89_phy_idx phy, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
u32 reg_rf18 = 0x0, reg_35c = 0x0;
u8 idx = 0;
u8 get_empty_table = false;
@@ -1413,9 +1426,9 @@ static void _iqk_get_ch_info(struct rtw89_dev *rtwdev,
}
static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
- u8 path)
+ u8 path, enum rtw89_chanctx_idx chanctx_idx)
{
- _iqk_by_path(rtwdev, phy_idx, path);
+ _iqk_by_path(rtwdev, phy_idx, path, chanctx_idx);
}
static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path)
@@ -1513,7 +1526,8 @@ static void _iqk_macbb_setting(struct rtw89_dev *rtwdev,
rtw89_rfk_parser(rtwdev, tbl);
}
-static void _iqk_dbcc(struct rtw89_dev *rtwdev, u8 path)
+static void _iqk_dbcc(struct rtw89_dev *rtwdev, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u8 phy_idx = 0x0;
@@ -1525,10 +1539,10 @@ static void _iqk_dbcc(struct rtw89_dev *rtwdev, u8 path)
else
phy_idx = RTW89_PHY_1;
- _iqk_get_ch_info(rtwdev, phy_idx, path);
+ _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx);
_iqk_macbb_setting(rtwdev, phy_idx, path);
_iqk_preset(rtwdev, path);
- _iqk_start_iqk(rtwdev, phy_idx, path);
+ _iqk_start_iqk(rtwdev, phy_idx, path, chanctx_idx);
_iqk_restore(rtwdev, path);
_iqk_afebb_restore(rtwdev, phy_idx, path);
}
@@ -1607,12 +1621,13 @@ static void _iqk_init(struct rtw89_dev *rtwdev)
}
static void _doiqk(struct rtw89_dev *rtwdev, bool force,
- enum rtw89_phy_idx phy_idx, u8 path)
+ enum rtw89_phy_idx phy_idx, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u32 backup_bb_val[BACKUP_BB_REGS_NR];
u32 backup_rf_val[RTW8852A_IQK_SS][BACKUP_RF_REGS_NR];
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START);
@@ -1622,12 +1637,12 @@ static void _doiqk(struct rtw89_dev *rtwdev, bool force,
iqk_info->version = RTW8852A_IQK_VER;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version);
- _iqk_get_ch_info(rtwdev, phy_idx, path);
+ _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx);
_rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]);
_rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path);
_iqk_macbb_setting(rtwdev, phy_idx, path);
_iqk_preset(rtwdev, path);
- _iqk_start_iqk(rtwdev, phy_idx, path);
+ _iqk_start_iqk(rtwdev, phy_idx, path, chanctx_idx);
_iqk_restore(rtwdev, path);
_iqk_afebb_restore(rtwdev, phy_idx, path);
_rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]);
@@ -1635,18 +1650,19 @@ static void _doiqk(struct rtw89_dev *rtwdev, bool force,
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP);
}
-static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force)
+static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force,
+ enum rtw89_chanctx_idx chanctx_idx)
{
switch (_kpath(rtwdev, phy_idx)) {
case RF_A:
- _doiqk(rtwdev, force, phy_idx, RF_PATH_A);
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx);
break;
case RF_B:
- _doiqk(rtwdev, force, phy_idx, RF_PATH_B);
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx);
break;
case RF_AB:
- _doiqk(rtwdev, force, phy_idx, RF_PATH_A);
- _doiqk(rtwdev, force, phy_idx, RF_PATH_B);
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx);
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx);
break;
default:
break;
@@ -1656,9 +1672,10 @@ static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool forc
#define RXDCK_VER_8852A 0xe
static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path, bool is_afe)
+ enum rtw89_rf_path path, bool is_afe,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy, path);
+ u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy, path, chanctx_idx);
u32 ori_val;
rtw89_debug(rtwdev, RTW89_DBG_RFK,
@@ -1704,7 +1721,7 @@ static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- bool is_afe)
+ bool is_afe, enum rtw89_chanctx_idx chanctx_idx)
{
u8 path, kpath, dck_tune;
u32 rf_reg5;
@@ -1732,7 +1749,7 @@ static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0);
rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX);
- _set_rx_dck(rtwdev, phy, path, is_afe);
+ _set_rx_dck(rtwdev, phy, path, is_afe, chanctx_idx);
rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, dck_tune);
rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5);
@@ -1800,9 +1817,10 @@ static void _dpk_reload_kip(struct rtw89_dev *rtwdev, u32 *reg,
}
static u8 _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path, enum rtw8852a_dpk_id id)
+ enum rtw89_rf_path path, enum rtw8852a_dpk_id id,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy, path);
+ u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy, path, chanctx_idx);
u16 dpk_cmd = 0x0;
u32 val;
int ret;
@@ -1841,18 +1859,19 @@ static u8 _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
static void _dpk_rx_dck(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_EN_TIA_IDA, 0x3);
- _set_rx_dck(rtwdev, phy, path, false);
+ _set_rx_dck(rtwdev, phy, path, false, chanctx_idx);
}
static void _dpk_information(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
u8 kidx = dpk->cur_idx[path];
dpk->bp[path][kidx].band = chan->band_type;
@@ -1967,7 +1986,8 @@ static void _dpk_kip_restore(struct rtw89_dev *rtwdev,
static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
u8 cur_rxbb;
@@ -1997,7 +2017,7 @@ static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev,
rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11);
- _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK);
+ _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK, chanctx_idx);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d LBK RXIQC = 0x%x\n", path,
rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD));
@@ -2186,10 +2206,11 @@ static bool _dpk_sync_check(struct rtw89_dev *rtwdev,
}
static bool _dpk_sync(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path, u8 kidx)
+ enum rtw89_rf_path path, u8 kidx,
+ enum rtw89_chanctx_idx chanctx_idx)
{
_dpk_tpg_sel(rtwdev, path, kidx);
- _dpk_one_shot(rtwdev, phy, path, SYNC);
+ _dpk_one_shot(rtwdev, phy, path, SYNC, chanctx_idx);
return _dpk_sync_check(rtwdev, path); /*1= fail*/
}
@@ -2242,10 +2263,10 @@ static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev)
static void _dpk_gainloss(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy, enum rtw89_rf_path path,
- u8 kidx)
+ u8 kidx, enum rtw89_chanctx_idx chanctx_idx)
{
_dpk_table_select(rtwdev, path, kidx, 1);
- _dpk_one_shot(rtwdev, phy, path, GAIN_LOSS);
+ _dpk_one_shot(rtwdev, phy, path, GAIN_LOSS, chanctx_idx);
}
#define DPK_TXAGC_LOWER 0x2e
@@ -2322,7 +2343,7 @@ static u8 _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check)
static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path, u8 kidx, u8 init_txagc,
- bool loss_only)
+ bool loss_only, enum rtw89_chanctx_idx chanctx_idx)
{
#define DPK_AGC_ADJ_LMT 6
#define DPK_DGAIN_UPPER 1922
@@ -2330,7 +2351,7 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
#define DPK_RXBB_UPPER 0x1f
#define DPK_RXBB_LOWER 0
#define DPK_GL_CRIT 7
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
u8 tmp_txagc, tmp_rxbb = 0, tmp_gl_idx = 0;
u8 agc_cnt = 0;
bool limited_rxbb = false;
@@ -2344,7 +2365,7 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
do {
switch (step) {
case DPK_AGC_STEP_SYNC_DGAIN:
- if (_dpk_sync(rtwdev, phy, path, kidx)) {
+ if (_dpk_sync(rtwdev, phy, path, kidx, chanctx_idx)) {
tmp_txagc = DPK_TXAGC_INVAL;
goout = true;
break;
@@ -2380,7 +2401,8 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
if (chan->band_width < RTW89_CHANNEL_WIDTH_80)
_dpk_bypass_rxcfir(rtwdev, path, true);
else
- _dpk_lbk_rxiqk(rtwdev, phy, path);
+ _dpk_lbk_rxiqk(rtwdev, phy, path,
+ chanctx_idx);
}
if (dgain > DPK_DGAIN_UPPER || dgain < DPK_DGAIN_LOWER)
step = DPK_AGC_STEP_SYNC_DGAIN;
@@ -2391,7 +2413,7 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
break;
case DPK_AGC_STEP_GAIN_LOSS_IDX:
- _dpk_gainloss(rtwdev, phy, path, kidx);
+ _dpk_gainloss(rtwdev, phy, path, kidx, chanctx_idx);
tmp_gl_idx = _dpk_gainloss_read(rtwdev);
if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true)) ||
@@ -2475,11 +2497,12 @@ static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order)
}
static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path, u8 kidx, u8 gain)
+ enum rtw89_rf_path path, u8 kidx, u8 gain,
+ enum rtw89_chanctx_idx chanctx_idx)
{
_dpk_set_mdpd_para(rtwdev, 0x0);
_dpk_table_select(rtwdev, path, kidx, 1);
- _dpk_one_shot(rtwdev, phy, path, MDPK_IDL);
+ _dpk_one_shot(rtwdev, phy, path, MDPK_IDL, chanctx_idx);
}
static void _dpk_fill_result(struct rtw89_dev *rtwdev,
@@ -2518,10 +2541,10 @@ static void _dpk_fill_result(struct rtw89_dev *rtwdev,
}
static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
bool is_reload = false;
u8 idx, cur_band, cur_ch;
@@ -2545,7 +2568,8 @@ static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path, u8 gain)
+ enum rtw89_rf_path path, u8 gain,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
u8 txagc = 0, kidx = dpk->cur_idx[path];
@@ -2558,16 +2582,16 @@ static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
_rf_direct_cntrl(rtwdev, path, false);
txagc = _dpk_set_tx_pwr(rtwdev, gain, path);
_dpk_rf_setting(rtwdev, gain, path, kidx);
- _dpk_rx_dck(rtwdev, phy, path);
+ _dpk_rx_dck(rtwdev, phy, path, chanctx_idx);
_dpk_kip_setting(rtwdev, path, kidx);
_dpk_manual_txcfir(rtwdev, path, true);
- txagc = _dpk_agc(rtwdev, phy, path, kidx, txagc, false);
+ txagc = _dpk_agc(rtwdev, phy, path, kidx, txagc, false, chanctx_idx);
if (txagc == DPK_TXAGC_INVAL)
is_fail = true;
_dpk_get_thermal(rtwdev, kidx, path);
- _dpk_idl_mpa(rtwdev, phy, path, kidx, gain);
+ _dpk_idl_mpa(rtwdev, phy, path, kidx, gain, chanctx_idx);
rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX);
_dpk_fill_result(rtwdev, path, kidx, gain, txagc);
_dpk_manual_txcfir(rtwdev, path, false);
@@ -2584,7 +2608,8 @@ static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
- enum rtw89_phy_idx phy, u8 kpath)
+ enum rtw89_phy_idx phy, u8 kpath,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
u32 backup_bb_val[BACKUP_BB_REGS_NR];
@@ -2599,7 +2624,8 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
if (!(kpath & BIT(path)))
continue;
- reloaded[path] = _dpk_reload_check(rtwdev, phy, path);
+ reloaded[path] = _dpk_reload_check(rtwdev, phy, path,
+ chanctx_idx);
if (!reloaded[path] && dpk->bp[path][0].ch != 0)
dpk->cur_idx[path] = !dpk->cur_idx[path];
else
@@ -2624,7 +2650,7 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
_dpk_tssi_pause(rtwdev, path, true);
_dpk_bkup_kip(rtwdev, kip_reg, kip_bkup, path);
_rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path);
- _dpk_information(rtwdev, phy, path);
+ _dpk_information(rtwdev, phy, path, chanctx_idx);
}
_dpk_bb_afe_setting(rtwdev, phy, path, kpath);
@@ -2633,7 +2659,7 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
if (!(kpath & BIT(path)) || reloaded[path])
continue;
- is_fail = _dpk_main(rtwdev, phy, path, 1);
+ is_fail = _dpk_main(rtwdev, phy, path, 1, chanctx_idx);
_dpk_onoff(rtwdev, path, is_fail);
}
@@ -2652,10 +2678,11 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
}
}
-static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_fem_info *fem = &rtwdev->fem;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
if (fem->epa_2g && chan->band_type == RTW89_BAND_2G) {
rtw89_debug(rtwdev, RTW89_DBG_RFK,
@@ -2682,17 +2709,19 @@ static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
}
}
-static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force)
+static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ bool force, enum rtw89_chanctx_idx chanctx_idx)
{
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[DPK] ****** DPK Start (Ver: 0x%x, Cv: %d, RF_para: %d) ******\n",
RTW8852A_DPK_VER, rtwdev->hal.cv,
RTW8852A_RF_REL_VERSION);
- if (_dpk_bypass_check(rtwdev, phy))
+ if (_dpk_bypass_check(rtwdev, phy, chanctx_idx))
_dpk_force_bypass(rtwdev, phy);
else
- _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy));
+ _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy),
+ chanctx_idx);
}
static void _dpk_onoff(struct rtw89_dev *rtwdev,
@@ -2815,9 +2844,8 @@ static void _dpk_track(struct rtw89_dev *rtwdev)
}
static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
if (band == RTW89_BAND_2G)
@@ -2826,9 +2854,9 @@ static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXA, 0x1);
}
-static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_sys_defs_tbl);
@@ -2838,9 +2866,9 @@ static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
}
static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path,
+ const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
@@ -2869,7 +2897,7 @@ static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
#define __get_val(ptr, idx) \
({ \
@@ -2883,7 +2911,6 @@ static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx ph
__val; \
})
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u8 subband = chan->subband_type;
const s8 *thm_up_a = NULL;
@@ -3076,9 +3103,8 @@ static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev,
}
static void _tssi_pak(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 subband = chan->subband_type;
switch (subband) {
@@ -3252,10 +3278,9 @@ static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch)
}
static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u32 gidx, gidx_1st, gidx_2nd;
s8 de_1st = 0;
@@ -3290,10 +3315,9 @@ static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u32 tgidx, tgidx_1st, tgidx_2nd;
s8 tde_1st = 0;
@@ -3328,11 +3352,10 @@ static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev,
}
static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy)
+ enum rtw89_phy_idx phy, const struct rtw89_chan *chan)
{
#define __DE_MASK 0x003ff000
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
static const u32 r_cck_long[RF_PATH_NUM_8852A] = {0x5858, 0x7858};
static const u32 r_cck_short[RF_PATH_NUM_8852A] = {0x5860, 0x7860};
static const u32 r_mcs_20m[RF_PATH_NUM_8852A] = {0x5838, 0x7838};
@@ -3352,7 +3375,7 @@ static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev,
for (i = 0; i < RF_PATH_NUM_8852A; i++) {
gidx = _tssi_get_cck_group(rtwdev, ch);
- trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i);
+ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan);
val = tssi_info->tssi_cck[i][gidx] + trim_de;
rtw89_debug(rtwdev, RTW89_DBG_TSSI,
@@ -3368,8 +3391,8 @@ static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev,
rtw89_phy_read32_mask(rtwdev, r_cck_long[i],
__DE_MASK));
- ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i);
- trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i);
+ ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i, chan);
+ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan);
val = ofdm_de + trim_de;
rtw89_debug(rtwdev, RTW89_DBG_TSSI,
@@ -3458,10 +3481,10 @@ static void _tssi_track(struct rtw89_dev *rtwdev)
}
}
-static void _tssi_high_power(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+static void _tssi_high_power(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel, ch_tmp;
u8 bw = chan->band_width;
u8 band = chan->band_type;
@@ -3497,24 +3520,25 @@ static void _tssi_high_power(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
}
static void _tssi_hw_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- u8 path, s16 pwr_dbm, u8 enable)
+ u8 path, s16 pwr_dbm, u8 enable, const struct rtw89_chan *chan)
{
rtw8852a_bb_set_plcp_tx(rtwdev);
rtw8852a_bb_cfg_tx_path(rtwdev, path);
rtw8852a_bb_set_power(rtwdev, pwr_dbm, phy);
- rtw8852a_bb_set_pmac_pkt_tx(rtwdev, enable, 20, 5000, 0, phy);
+ rtw8852a_bb_set_pmac_pkt_tx(rtwdev, enable, 20, 5000, 0, phy, chan);
}
-static void _tssi_pre_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+static void _tssi_pre_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
const struct rtw89_chip_info *mac_reg = rtwdev->chip;
u8 ch = chan->channel, ch_tmp;
u8 bw = chan->band_width;
u8 band = chan->band_type;
u32 tx_en;
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy, 0, chanctx_idx);
s8 power;
s16 xdbm;
u32 i, tx_counter = 0;
@@ -3546,9 +3570,9 @@ static void _tssi_pre_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
_wait_rx_mode(rtwdev, _kpath(rtwdev, phy));
tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
- _tssi_hw_tx(rtwdev, phy, RF_PATH_AB, xdbm, true);
+ _tssi_hw_tx(rtwdev, phy, RF_PATH_AB, xdbm, true, chan);
mdelay(15);
- _tssi_hw_tx(rtwdev, phy, RF_PATH_AB, xdbm, false);
+ _tssi_hw_tx(rtwdev, phy, RF_PATH_AB, xdbm, false, chan);
tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD) -
tx_counter;
@@ -3600,19 +3624,21 @@ void rtw8852a_rck(struct rtw89_dev *rtwdev)
_rck(rtwdev, path);
}
-void rtw8852a_dack(struct rtw89_dev *rtwdev)
+void rtw8852a_dack(struct rtw89_dev *rtwdev,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0, chanctx_idx);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START);
- _dac_cal(rtwdev, false);
+ _dac_cal(rtwdev, false, chanctx_idx);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP);
}
-void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
{
u32 tx_en;
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START);
rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
@@ -3620,34 +3646,35 @@ void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
_iqk_init(rtwdev);
if (rtwdev->dbcc_en)
- _iqk_dbcc(rtwdev, phy_idx);
+ _iqk_dbcc(rtwdev, phy_idx, chanctx_idx);
else
- _iqk(rtwdev, phy_idx, false);
+ _iqk(rtwdev, phy_idx, false, chanctx_idx);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP);
}
void rtw8852a_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
- bool is_afe)
+ bool is_afe, enum rtw89_chanctx_idx chanctx_idx)
{
u32 tx_en;
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START);
rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
_wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx));
- _rx_dck(rtwdev, phy_idx, is_afe);
+ _rx_dck(rtwdev, phy_idx, is_afe, chanctx_idx);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP);
}
-void rtw8852a_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+void rtw8852a_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
{
u32 tx_en;
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START);
rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
@@ -3655,7 +3682,7 @@ void rtw8852a_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
rtwdev->dpk.is_dpk_enable = true;
rtwdev->dpk.is_dpk_reload_en = false;
- _dpk(rtwdev, phy_idx, false);
+ _dpk(rtwdev, phy_idx, false, chanctx_idx);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP);
@@ -3666,8 +3693,10 @@ void rtw8852a_dpk_track(struct rtw89_dev *rtwdev)
_dpk_track(rtwdev);
}
-void rtw8852a_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+void rtw8852a_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_chanctx_idx chanctx_idx)
{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
u8 i;
rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n",
@@ -3676,26 +3705,27 @@ void rtw8852a_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
_tssi_disable(rtwdev, phy);
for (i = RF_PATH_A; i < RF_PATH_NUM_8852A; i++) {
- _tssi_rf_setting(rtwdev, phy, i);
- _tssi_set_sys(rtwdev, phy);
- _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i);
+ _tssi_rf_setting(rtwdev, phy, i, chan);
+ _tssi_set_sys(rtwdev, phy, chan);
+ _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i, chan);
_tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i);
_tssi_set_dck(rtwdev, phy, i);
- _tssi_set_tmeter_tbl(rtwdev, phy, i);
+ _tssi_set_tmeter_tbl(rtwdev, phy, i, chan);
_tssi_set_dac_gain_tbl(rtwdev, phy, i);
_tssi_slope_cal_org(rtwdev, phy, i);
_tssi_set_rf_gap_tbl(rtwdev, phy, i);
_tssi_set_slope(rtwdev, phy, i);
- _tssi_pak(rtwdev, phy, i);
+ _tssi_pak(rtwdev, phy, i, chan);
}
_tssi_enable(rtwdev, phy);
- _tssi_set_efuse_to_de(rtwdev, phy);
- _tssi_high_power(rtwdev, phy);
- _tssi_pre_tx(rtwdev, phy);
+ _tssi_set_efuse_to_de(rtwdev, phy, chan);
+ _tssi_high_power(rtwdev, phy, chan);
+ _tssi_pre_tx(rtwdev, phy, chanctx_idx);
}
-void rtw8852a_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+void rtw8852a_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan)
{
u8 i;
@@ -3710,14 +3740,14 @@ void rtw8852a_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
_tssi_disable(rtwdev, phy);
for (i = RF_PATH_A; i < RF_PATH_NUM_8852A; i++) {
- _tssi_rf_setting(rtwdev, phy, i);
- _tssi_set_sys(rtwdev, phy);
- _tssi_set_tmeter_tbl(rtwdev, phy, i);
- _tssi_pak(rtwdev, phy, i);
+ _tssi_rf_setting(rtwdev, phy, i, chan);
+ _tssi_set_sys(rtwdev, phy, chan);
+ _tssi_set_tmeter_tbl(rtwdev, phy, i, chan);
+ _tssi_pak(rtwdev, phy, i, chan);
}
_tssi_enable(rtwdev, phy);
- _tssi_set_efuse_to_de(rtwdev, phy);
+ _tssi_set_efuse_to_de(rtwdev, phy, chan);
}
void rtw8852a_tssi_track(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h
index fa058ccc8616..8761f2cc9359 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h
@@ -8,14 +8,19 @@
#include "core.h"
void rtw8852a_rck(struct rtw89_dev *rtwdev);
-void rtw8852a_dack(struct rtw89_dev *rtwdev);
-void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
+void rtw8852a_dack(struct rtw89_dev *rtwdev,
+ enum rtw89_chanctx_idx chanctx_idx);
+void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
void rtw8852a_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
- bool is_afe);
-void rtw8852a_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
+ bool is_afe, enum rtw89_chanctx_idx chanctx_idx);
+void rtw8852a_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
void rtw8852a_dpk_track(struct rtw89_dev *rtwdev);
-void rtw8852a_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
-void rtw8852a_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
+void rtw8852a_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_chanctx_idx chanctx_idx);
+void rtw8852a_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan);
void rtw8852a_tssi_track(struct rtw89_dev *rtwdev);
void rtw8852a_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
enum rtw89_phy_idx phy_idx);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c
index 7c6ffedb77e2..2037713e3952 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c
@@ -27,6 +27,7 @@ static const struct rtw89_pci_info rtw8852a_pci_info = {
.io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS,
.rx_ring_eq_is_full = false,
.check_rx_tag = false,
+ .no_rxbd_fs = false,
.init_cfg_reg = R_AX_PCIE_INIT_CFG1,
.txhci_en_bit = B_AX_TXHCI_EN,
@@ -46,6 +47,7 @@ static const struct rtw89_pci_info rtw8852a_pci_info = {
.rpwm_addr = R_AX_PCIE_HRPWM,
.cpwm_addr = R_AX_CPWM,
.mit_addr = R_AX_INT_MIT_RX,
+ .wp_sel_addr = 0,
.tx_dma_ch_mask = 0,
.bd_idx_addr_low_power = NULL,
.dma_addr_set = &rtw89_pci_ch_dma_addr_set,
@@ -57,10 +59,14 @@ static const struct rtw89_pci_info rtw8852a_pci_info = {
.enable_intr = rtw89_pci_enable_intr,
.disable_intr = rtw89_pci_disable_intr,
.recognize_intrs = rtw89_pci_recognize_intrs,
+
+ .ssid_quirks = NULL,
};
static const struct rtw89_driver_info rtw89_8852ae_info = {
.chip = &rtw8852a_chip_info,
+ .variant = NULL,
+ .quirks = NULL,
.bus = {
.pci = &rtw8852a_pci_info,
},
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
index d025c4135e1c..dacdb384de2c 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
@@ -8,6 +8,7 @@
#include "phy.h"
#include "reg.h"
#include "rtw8852b.h"
+#include "rtw8852b_common.h"
#include "rtw8852b_rfk.h"
#include "rtw8852b_table.h"
#include "txrx.h"
@@ -65,167 +66,6 @@ static const struct rtw89_dle_mem rtw8852b_dle_mem_pcie[] = {
NULL},
};
-static const struct rtw89_reg3_def rtw8852b_pmac_ht20_mcs7_tbl[] = {
- {0x4580, 0x0000ffff, 0x0},
- {0x4580, 0xffff0000, 0x0},
- {0x4584, 0x0000ffff, 0x0},
- {0x4584, 0xffff0000, 0x0},
- {0x4580, 0x0000ffff, 0x1},
- {0x4578, 0x00ffffff, 0x2018b},
- {0x4570, 0x03ffffff, 0x7},
- {0x4574, 0x03ffffff, 0x32407},
- {0x45b8, 0x00000010, 0x0},
- {0x45b8, 0x00000100, 0x0},
- {0x45b8, 0x00000080, 0x0},
- {0x45b8, 0x00000008, 0x0},
- {0x45a0, 0x0000ff00, 0x0},
- {0x45a0, 0xff000000, 0x1},
- {0x45a4, 0x0000ff00, 0x2},
- {0x45a4, 0xff000000, 0x3},
- {0x45b8, 0x00000020, 0x0},
- {0x4568, 0xe0000000, 0x0},
- {0x45b8, 0x00000002, 0x1},
- {0x456c, 0xe0000000, 0x0},
- {0x45b4, 0x00006000, 0x0},
- {0x45b4, 0x00001800, 0x1},
- {0x45b8, 0x00000040, 0x0},
- {0x45b8, 0x00000004, 0x0},
- {0x45b8, 0x00000200, 0x0},
- {0x4598, 0xf8000000, 0x0},
- {0x45b8, 0x00100000, 0x0},
- {0x45a8, 0x00000fc0, 0x0},
- {0x45b8, 0x00200000, 0x0},
- {0x45b0, 0x00000038, 0x0},
- {0x45b0, 0x000001c0, 0x0},
- {0x45a0, 0x000000ff, 0x0},
- {0x45b8, 0x00400000, 0x0},
- {0x4590, 0x000007ff, 0x0},
- {0x45b0, 0x00000e00, 0x0},
- {0x45ac, 0x0000001f, 0x0},
- {0x45b8, 0x00800000, 0x0},
- {0x45a8, 0x0003f000, 0x0},
- {0x45b8, 0x01000000, 0x0},
- {0x45b0, 0x00007000, 0x0},
- {0x45b0, 0x00038000, 0x0},
- {0x45a0, 0x00ff0000, 0x0},
- {0x45b8, 0x02000000, 0x0},
- {0x4590, 0x003ff800, 0x0},
- {0x45b0, 0x001c0000, 0x0},
- {0x45ac, 0x000003e0, 0x0},
- {0x45b8, 0x04000000, 0x0},
- {0x45a8, 0x00fc0000, 0x0},
- {0x45b8, 0x08000000, 0x0},
- {0x45b0, 0x00e00000, 0x0},
- {0x45b0, 0x07000000, 0x0},
- {0x45a4, 0x000000ff, 0x0},
- {0x45b8, 0x10000000, 0x0},
- {0x4594, 0x000007ff, 0x0},
- {0x45b0, 0x38000000, 0x0},
- {0x45ac, 0x00007c00, 0x0},
- {0x45b8, 0x20000000, 0x0},
- {0x45a8, 0x3f000000, 0x0},
- {0x45b8, 0x40000000, 0x0},
- {0x45b4, 0x00000007, 0x0},
- {0x45b4, 0x00000038, 0x0},
- {0x45a4, 0x00ff0000, 0x0},
- {0x45b8, 0x80000000, 0x0},
- {0x4594, 0x003ff800, 0x0},
- {0x45b4, 0x000001c0, 0x0},
- {0x4598, 0xf8000000, 0x0},
- {0x45b8, 0x00100000, 0x0},
- {0x45a8, 0x00000fc0, 0x7},
- {0x45b8, 0x00200000, 0x0},
- {0x45b0, 0x00000038, 0x0},
- {0x45b0, 0x000001c0, 0x0},
- {0x45a0, 0x000000ff, 0x0},
- {0x45b4, 0x06000000, 0x0},
- {0x45b0, 0x00000007, 0x0},
- {0x45b8, 0x00080000, 0x0},
- {0x45a8, 0x0000003f, 0x0},
- {0x457c, 0xffe00000, 0x1},
- {0x4530, 0xffffffff, 0x0},
- {0x4588, 0x00003fff, 0x0},
- {0x4598, 0x000001ff, 0x0},
- {0x4534, 0xffffffff, 0x0},
- {0x4538, 0xffffffff, 0x0},
- {0x453c, 0xffffffff, 0x0},
- {0x4588, 0x0fffc000, 0x0},
- {0x4598, 0x0003fe00, 0x0},
- {0x4540, 0xffffffff, 0x0},
- {0x4544, 0xffffffff, 0x0},
- {0x4548, 0xffffffff, 0x0},
- {0x458c, 0x00003fff, 0x0},
- {0x4598, 0x07fc0000, 0x0},
- {0x454c, 0xffffffff, 0x0},
- {0x4550, 0xffffffff, 0x0},
- {0x4554, 0xffffffff, 0x0},
- {0x458c, 0x0fffc000, 0x0},
- {0x459c, 0x000001ff, 0x0},
- {0x4558, 0xffffffff, 0x0},
- {0x455c, 0xffffffff, 0x0},
- {0x4530, 0xffffffff, 0x4e790001},
- {0x4588, 0x00003fff, 0x0},
- {0x4598, 0x000001ff, 0x1},
- {0x4534, 0xffffffff, 0x0},
- {0x4538, 0xffffffff, 0x4b},
- {0x45ac, 0x38000000, 0x7},
- {0x4588, 0xf0000000, 0x0},
- {0x459c, 0x7e000000, 0x0},
- {0x45b8, 0x00040000, 0x0},
- {0x45b8, 0x00020000, 0x0},
- {0x4590, 0xffc00000, 0x0},
- {0x45b8, 0x00004000, 0x0},
- {0x4578, 0xff000000, 0x0},
- {0x45b8, 0x00000400, 0x0},
- {0x45b8, 0x00000800, 0x0},
- {0x45b8, 0x00001000, 0x0},
- {0x45b8, 0x00002000, 0x0},
- {0x45b4, 0x00018000, 0x0},
- {0x45ac, 0x07800000, 0x0},
- {0x45b4, 0x00000600, 0x2},
- {0x459c, 0x0001fe00, 0x80},
- {0x45ac, 0x00078000, 0x3},
- {0x459c, 0x01fe0000, 0x1},
-};
-
-static const struct rtw89_reg3_def rtw8852b_btc_preagc_en_defs[] = {
- {0x46D0, GENMASK(1, 0), 0x3},
- {0x4790, GENMASK(1, 0), 0x3},
- {0x4AD4, GENMASK(31, 0), 0xf},
- {0x4AE0, GENMASK(31, 0), 0xf},
- {0x4688, GENMASK(31, 24), 0x80},
- {0x476C, GENMASK(31, 24), 0x80},
- {0x4694, GENMASK(7, 0), 0x80},
- {0x4694, GENMASK(15, 8), 0x80},
- {0x4778, GENMASK(7, 0), 0x80},
- {0x4778, GENMASK(15, 8), 0x80},
- {0x4AE4, GENMASK(23, 0), 0x780D1E},
- {0x4AEC, GENMASK(23, 0), 0x780D1E},
- {0x469C, GENMASK(31, 26), 0x34},
- {0x49F0, GENMASK(31, 26), 0x34},
-};
-
-static DECLARE_PHY_REG3_TBL(rtw8852b_btc_preagc_en_defs);
-
-static const struct rtw89_reg3_def rtw8852b_btc_preagc_dis_defs[] = {
- {0x46D0, GENMASK(1, 0), 0x0},
- {0x4790, GENMASK(1, 0), 0x0},
- {0x4AD4, GENMASK(31, 0), 0x60},
- {0x4AE0, GENMASK(31, 0), 0x60},
- {0x4688, GENMASK(31, 24), 0x1a},
- {0x476C, GENMASK(31, 24), 0x1a},
- {0x4694, GENMASK(7, 0), 0x2a},
- {0x4694, GENMASK(15, 8), 0x2a},
- {0x4778, GENMASK(7, 0), 0x2a},
- {0x4778, GENMASK(15, 8), 0x2a},
- {0x4AE4, GENMASK(23, 0), 0x79E99E},
- {0x4AEC, GENMASK(23, 0), 0x79E99E},
- {0x469C, GENMASK(31, 26), 0x26},
- {0x49F0, GENMASK(31, 26), 0x26},
-};
-
-static DECLARE_PHY_REG3_TBL(rtw8852b_btc_preagc_dis_defs);
-
static const u32 rtw8852b_h2c_regs[RTW89_H2CREG_MAX] = {
R_AX_H2CREG_DATA0, R_AX_H2CREG_DATA1, R_AX_H2CREG_DATA2,
R_AX_H2CREG_DATA3
@@ -236,6 +76,10 @@ static const u32 rtw8852b_c2h_regs[RTW89_C2HREG_MAX] = {
R_AX_C2HREG_DATA3
};
+static const u32 rtw8852b_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = {
+ R_AX_C2HREG_DATA3 + 3, R_AX_C2HREG_DATA3 + 3,
+};
+
static const struct rtw89_page_regs rtw8852b_page_regs = {
.hci_fc_ctrl = R_AX_HCI_FC_CTRL,
.ch_page_ctrl = R_AX_CH_PAGE_CTRL,
@@ -306,6 +150,15 @@ static const struct rtw89_rrsr_cfgs rtw8852b_rrsr_cfgs = {
.rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2},
};
+static const struct rtw89_rfkill_regs rtw8852b_rfkill_regs = {
+ .pinmux = {R_AX_GPIO8_15_FUNC_SEL,
+ B_AX_PINMUX_GPIO9_FUNC_SEL_MASK,
+ 0xf},
+ .mode = {R_AX_GPIO_EXT_CTRL + 2,
+ (B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16,
+ 0x0},
+};
+
static const struct rtw89_dig_regs rtw8852b_dig_regs = {
.seg0_pd_reg = R_SEG0R_PD_V1,
.pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
@@ -336,10 +189,17 @@ static const struct rtw89_edcca_regs rtw8852b_edcca_regs = {
.edcca_p_mask = B_EDCCA_LVL_MSK1,
.ppdu_level = R_SEG0R_EDCCA_LVL_V1,
.ppdu_mask = B_EDCCA_LVL_MSK3,
- .rpt_a = R_EDCCA_RPT_A,
- .rpt_b = R_EDCCA_RPT_B,
- .rpt_sel = R_EDCCA_RPT_SEL,
- .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ .p = {{
+ .rpt_a = R_EDCCA_RPT_A,
+ .rpt_b = R_EDCCA_RPT_B,
+ .rpt_sel = R_EDCCA_RPT_SEL,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ }, {
+ .rpt_a = R_EDCCA_RPT_P1_A,
+ .rpt_b = R_EDCCA_RPT_P1_B,
+ .rpt_sel = R_EDCCA_RPT_SEL,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK,
+ }},
.tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
.tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
};
@@ -390,10 +250,20 @@ static const struct rtw89_btc_fbtc_mreg rtw89_btc_8852b_mon_reg[] = {
static const u8 rtw89_btc_8852b_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {70, 60, 50, 40};
static const u8 rtw89_btc_8852b_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20};
+static void rtw8852b_pwr_sps_ana(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_efuse *efuse = &rtwdev->efuse;
+
+ if (efuse->rfe_type == 0x5)
+ rtw89_write16(rtwdev, R_AX_SPS_ANA_ON_CTRL2, RTL8852B_RFE_05_SPS_ANA);
+}
+
static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev)
{
u32 val32;
- u32 ret;
+ int ret;
+
+ rtw8852b_pwr_sps_ana(rtwdev);
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN |
B_AX_AFSM_PCIE_SUS_EN);
@@ -520,7 +390,9 @@ func_en:
static int rtw8852b_pwr_off_func(struct rtw89_dev *rtwdev)
{
u32 val32;
- u32 ret;
+ int ret;
+
+ rtw8852b_pwr_sps_ana(rtwdev);
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
XTAL_SI_RFC2RF);
@@ -550,6 +422,7 @@ static int rtw8852b_pwr_off_func(struct rtw89_dev *rtwdev)
return ret;
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
+ rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB);
rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3);
@@ -578,806 +451,6 @@ static int rtw8852b_pwr_off_func(struct rtw89_dev *rtwdev)
return 0;
}
-static void rtw8852be_efuse_parsing(struct rtw89_efuse *efuse,
- struct rtw8852b_efuse *map)
-{
- ether_addr_copy(efuse->addr, map->e.mac_addr);
- efuse->rfe_type = map->rfe_type;
- efuse->xtal_cap = map->xtal_k;
-}
-
-static void rtw8852b_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
- struct rtw8852b_efuse *map)
-{
- struct rtw89_tssi_info *tssi = &rtwdev->tssi;
- struct rtw8852b_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi};
- u8 i, j;
-
- tssi->thermal[RF_PATH_A] = map->path_a_therm;
- tssi->thermal[RF_PATH_B] = map->path_b_therm;
-
- for (i = 0; i < RF_PATH_NUM_8852B; i++) {
- memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi,
- sizeof(ofst[i]->cck_tssi));
-
- for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++)
- rtw89_debug(rtwdev, RTW89_DBG_TSSI,
- "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n",
- i, j, tssi->tssi_cck[i][j]);
-
- memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi,
- sizeof(ofst[i]->bw40_tssi));
- memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM,
- ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g));
-
- for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++)
- rtw89_debug(rtwdev, RTW89_DBG_TSSI,
- "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n",
- i, j, tssi->tssi_mcs[i][j]);
- }
-}
-
-static bool _decode_efuse_gain(u8 data, s8 *high, s8 *low)
-{
- if (high)
- *high = sign_extend32(FIELD_GET(GENMASK(7, 4), data), 3);
- if (low)
- *low = sign_extend32(FIELD_GET(GENMASK(3, 0), data), 3);
-
- return data != 0xff;
-}
-
-static void rtw8852b_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev,
- struct rtw8852b_efuse *map)
-{
- struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
- bool valid = false;
-
- valid |= _decode_efuse_gain(map->rx_gain_2g_cck,
- &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_CCK],
- &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_CCK]);
- valid |= _decode_efuse_gain(map->rx_gain_2g_ofdm,
- &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_OFDM],
- &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_OFDM]);
- valid |= _decode_efuse_gain(map->rx_gain_5g_low,
- &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_LOW],
- &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_LOW]);
- valid |= _decode_efuse_gain(map->rx_gain_5g_mid,
- &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_MID],
- &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_MID]);
- valid |= _decode_efuse_gain(map->rx_gain_5g_high,
- &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_HIGH],
- &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_HIGH]);
-
- gain->offset_valid = valid;
-}
-
-static int rtw8852b_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
- enum rtw89_efuse_block block)
-{
- struct rtw89_efuse *efuse = &rtwdev->efuse;
- struct rtw8852b_efuse *map;
-
- map = (struct rtw8852b_efuse *)log_map;
-
- efuse->country_code[0] = map->country_code[0];
- efuse->country_code[1] = map->country_code[1];
- rtw8852b_efuse_parsing_tssi(rtwdev, map);
- rtw8852b_efuse_parsing_gain_offset(rtwdev, map);
-
- switch (rtwdev->hci.type) {
- case RTW89_HCI_TYPE_PCIE:
- rtw8852be_efuse_parsing(efuse, map);
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type);
-
- return 0;
-}
-
-static void rtw8852b_phycap_parsing_power_cal(struct rtw89_dev *rtwdev, u8 *phycap_map)
-{
-#define PWR_K_CHK_OFFSET 0x5E9
-#define PWR_K_CHK_VALUE 0xAA
- u32 offset = PWR_K_CHK_OFFSET - rtwdev->chip->phycap_addr;
-
- if (phycap_map[offset] == PWR_K_CHK_VALUE)
- rtwdev->efuse.power_k_valid = true;
-}
-
-static void rtw8852b_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map)
-{
- struct rtw89_tssi_info *tssi = &rtwdev->tssi;
- static const u32 tssi_trim_addr[RF_PATH_NUM_8852B] = {0x5D6, 0x5AB};
- u32 addr = rtwdev->chip->phycap_addr;
- bool pg = false;
- u32 ofst;
- u8 i, j;
-
- for (i = 0; i < RF_PATH_NUM_8852B; i++) {
- for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) {
- /* addrs are in decreasing order */
- ofst = tssi_trim_addr[i] - addr - j;
- tssi->tssi_trim[i][j] = phycap_map[ofst];
-
- if (phycap_map[ofst] != 0xff)
- pg = true;
- }
- }
-
- if (!pg) {
- memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim));
- rtw89_debug(rtwdev, RTW89_DBG_TSSI,
- "[TSSI][TRIM] no PG, set all trim info to 0\n");
- }
-
- for (i = 0; i < RF_PATH_NUM_8852B; i++)
- for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++)
- rtw89_debug(rtwdev, RTW89_DBG_TSSI,
- "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n",
- i, j, tssi->tssi_trim[i][j],
- tssi_trim_addr[i] - j);
-}
-
-static void rtw8852b_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev,
- u8 *phycap_map)
-{
- struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
- static const u32 thm_trim_addr[RF_PATH_NUM_8852B] = {0x5DF, 0x5DC};
- u32 addr = rtwdev->chip->phycap_addr;
- u8 i;
-
- for (i = 0; i < RF_PATH_NUM_8852B; i++) {
- info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr];
-
- rtw89_debug(rtwdev, RTW89_DBG_RFK,
- "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n",
- i, info->thermal_trim[i]);
-
- if (info->thermal_trim[i] != 0xff)
- info->pg_thermal_trim = true;
- }
-}
-
-static void rtw8852b_thermal_trim(struct rtw89_dev *rtwdev)
-{
-#define __thm_setting(raw) \
-({ \
- u8 __v = (raw); \
- ((__v & 0x1) << 3) | ((__v & 0x1f) >> 1); \
-})
- struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
- u8 i, val;
-
- if (!info->pg_thermal_trim) {
- rtw89_debug(rtwdev, RTW89_DBG_RFK,
- "[THERMAL][TRIM] no PG, do nothing\n");
-
- return;
- }
-
- for (i = 0; i < RF_PATH_NUM_8852B; i++) {
- val = __thm_setting(info->thermal_trim[i]);
- rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val);
-
- rtw89_debug(rtwdev, RTW89_DBG_RFK,
- "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n",
- i, val);
- }
-#undef __thm_setting
-}
-
-static void rtw8852b_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev,
- u8 *phycap_map)
-{
- struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
- static const u32 pabias_trim_addr[RF_PATH_NUM_8852B] = {0x5DE, 0x5DB};
- u32 addr = rtwdev->chip->phycap_addr;
- u8 i;
-
- for (i = 0; i < RF_PATH_NUM_8852B; i++) {
- info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr];
-
- rtw89_debug(rtwdev, RTW89_DBG_RFK,
- "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n",
- i, info->pa_bias_trim[i]);
-
- if (info->pa_bias_trim[i] != 0xff)
- info->pg_pa_bias_trim = true;
- }
-}
-
-static void rtw8852b_pa_bias_trim(struct rtw89_dev *rtwdev)
-{
- struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
- u8 pabias_2g, pabias_5g;
- u8 i;
-
- if (!info->pg_pa_bias_trim) {
- rtw89_debug(rtwdev, RTW89_DBG_RFK,
- "[PA_BIAS][TRIM] no PG, do nothing\n");
-
- return;
- }
-
- for (i = 0; i < RF_PATH_NUM_8852B; i++) {
- pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]);
- pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]);
-
- rtw89_debug(rtwdev, RTW89_DBG_RFK,
- "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n",
- i, pabias_2g, pabias_5g);
-
- rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g);
- rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g);
- }
-}
-
-static void rtw8852b_phycap_parsing_gain_comp(struct rtw89_dev *rtwdev, u8 *phycap_map)
-{
- static const u32 comp_addrs[][RTW89_SUBBAND_2GHZ_5GHZ_NR] = {
- {0x5BB, 0x5BA, 0, 0x5B9, 0x5B8},
- {0x590, 0x58F, 0, 0x58E, 0x58D},
- };
- struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
- u32 phycap_addr = rtwdev->chip->phycap_addr;
- bool valid = false;
- int path, i;
- u8 data;
-
- for (path = 0; path < 2; path++)
- for (i = 0; i < RTW89_SUBBAND_2GHZ_5GHZ_NR; i++) {
- if (comp_addrs[path][i] == 0)
- continue;
-
- data = phycap_map[comp_addrs[path][i] - phycap_addr];
- valid |= _decode_efuse_gain(data, NULL,
- &gain->comp[path][i]);
- }
-
- gain->comp_valid = valid;
-}
-
-static int rtw8852b_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map)
-{
- rtw8852b_phycap_parsing_power_cal(rtwdev, phycap_map);
- rtw8852b_phycap_parsing_tssi(rtwdev, phycap_map);
- rtw8852b_phycap_parsing_thermal_trim(rtwdev, phycap_map);
- rtw8852b_phycap_parsing_pa_bias_trim(rtwdev, phycap_map);
- rtw8852b_phycap_parsing_gain_comp(rtwdev, phycap_map);
-
- return 0;
-}
-
-static void rtw8852b_power_trim(struct rtw89_dev *rtwdev)
-{
- rtw8852b_thermal_trim(rtwdev);
- rtw8852b_pa_bias_trim(rtwdev);
-}
-
-static void rtw8852b_set_channel_mac(struct rtw89_dev *rtwdev,
- const struct rtw89_chan *chan,
- u8 mac_idx)
-{
- u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_AX_WMAC_RFMOD, mac_idx);
- u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, mac_idx);
- u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXRATE_CHK, mac_idx);
- u8 txsc20 = 0, txsc40 = 0;
-
- switch (chan->band_width) {
- case RTW89_CHANNEL_WIDTH_80:
- txsc40 = rtw89_phy_get_txsc(rtwdev, chan, RTW89_CHANNEL_WIDTH_40);
- fallthrough;
- case RTW89_CHANNEL_WIDTH_40:
- txsc20 = rtw89_phy_get_txsc(rtwdev, chan, RTW89_CHANNEL_WIDTH_20);
- break;
- default:
- break;
- }
-
- switch (chan->band_width) {
- case RTW89_CHANNEL_WIDTH_80:
- rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(1));
- rtw89_write32(rtwdev, sub_carr, txsc20 | (txsc40 << 4));
- break;
- case RTW89_CHANNEL_WIDTH_40:
- rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(0));
- rtw89_write32(rtwdev, sub_carr, txsc20);
- break;
- case RTW89_CHANNEL_WIDTH_20:
- rtw89_write8_clr(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK);
- rtw89_write32(rtwdev, sub_carr, 0);
- break;
- default:
- break;
- }
-
- if (chan->channel > 14) {
- rtw89_write8_clr(rtwdev, chk_rate, B_AX_BAND_MODE);
- rtw89_write8_set(rtwdev, chk_rate,
- B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6);
- } else {
- rtw89_write8_set(rtwdev, chk_rate, B_AX_BAND_MODE);
- rtw89_write8_clr(rtwdev, chk_rate,
- B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6);
- }
-}
-
-static const u32 rtw8852b_sco_barker_threshold[14] = {
- 0x1cfea, 0x1d0e1, 0x1d1d7, 0x1d2cd, 0x1d3c3, 0x1d4b9, 0x1d5b0, 0x1d6a6,
- 0x1d79c, 0x1d892, 0x1d988, 0x1da7f, 0x1db75, 0x1ddc4
-};
-
-static const u32 rtw8852b_sco_cck_threshold[14] = {
- 0x27de3, 0x27f35, 0x28088, 0x281da, 0x2832d, 0x2847f, 0x285d2, 0x28724,
- 0x28877, 0x289c9, 0x28b1c, 0x28c6e, 0x28dc1, 0x290ed
-};
-
-static void rtw8852b_ctrl_sco_cck(struct rtw89_dev *rtwdev, u8 primary_ch)
-{
- u8 ch_element = primary_ch - 1;
-
- rtw89_phy_write32_mask(rtwdev, R_RXSCOBC, B_RXSCOBC_TH,
- rtw8852b_sco_barker_threshold[ch_element]);
- rtw89_phy_write32_mask(rtwdev, R_RXSCOCCK, B_RXSCOCCK_TH,
- rtw8852b_sco_cck_threshold[ch_element]);
-}
-
-static u8 rtw8852b_sco_mapping(u8 central_ch)
-{
- if (central_ch == 1)
- return 109;
- else if (central_ch >= 2 && central_ch <= 6)
- return 108;
- else if (central_ch >= 7 && central_ch <= 10)
- return 107;
- else if (central_ch >= 11 && central_ch <= 14)
- return 106;
- else if (central_ch == 36 || central_ch == 38)
- return 51;
- else if (central_ch >= 40 && central_ch <= 58)
- return 50;
- else if (central_ch >= 60 && central_ch <= 64)
- return 49;
- else if (central_ch == 100 || central_ch == 102)
- return 48;
- else if (central_ch >= 104 && central_ch <= 126)
- return 47;
- else if (central_ch >= 128 && central_ch <= 151)
- return 46;
- else if (central_ch >= 153 && central_ch <= 177)
- return 45;
- else
- return 0;
-}
-
-struct rtw8852b_bb_gain {
- u32 gain_g[BB_PATH_NUM_8852B];
- u32 gain_a[BB_PATH_NUM_8852B];
- u32 gain_mask;
-};
-
-static const struct rtw8852b_bb_gain bb_gain_lna[LNA_GAIN_NUM] = {
- { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740},
- .gain_mask = 0x00ff0000 },
- { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740},
- .gain_mask = 0xff000000 },
- { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
- .gain_mask = 0x000000ff },
- { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
- .gain_mask = 0x0000ff00 },
- { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
- .gain_mask = 0x00ff0000 },
- { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
- .gain_mask = 0xff000000 },
- { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
- .gain_mask = 0x000000ff },
-};
-
-static const struct rtw8852b_bb_gain bb_gain_tia[TIA_GAIN_NUM] = {
- { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
- .gain_mask = 0x00ff0000 },
- { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
- .gain_mask = 0xff000000 },
-};
-
-static void rtw8852b_set_gain_error(struct rtw89_dev *rtwdev,
- enum rtw89_subband subband,
- enum rtw89_rf_path path)
-{
- const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax;
- u8 gain_band = rtw89_subband_to_bb_gain_band(subband);
- s32 val;
- u32 reg;
- u32 mask;
- int i;
-
- for (i = 0; i < LNA_GAIN_NUM; i++) {
- if (subband == RTW89_CH_2G)
- reg = bb_gain_lna[i].gain_g[path];
- else
- reg = bb_gain_lna[i].gain_a[path];
-
- mask = bb_gain_lna[i].gain_mask;
- val = gain->lna_gain[gain_band][path][i];
- rtw89_phy_write32_mask(rtwdev, reg, mask, val);
- }
-
- for (i = 0; i < TIA_GAIN_NUM; i++) {
- if (subband == RTW89_CH_2G)
- reg = bb_gain_tia[i].gain_g[path];
- else
- reg = bb_gain_tia[i].gain_a[path];
-
- mask = bb_gain_tia[i].gain_mask;
- val = gain->tia_gain[gain_band][path][i];
- rtw89_phy_write32_mask(rtwdev, reg, mask, val);
- }
-}
-
-static void rtw8852b_set_gain_offset(struct rtw89_dev *rtwdev,
- enum rtw89_subband subband,
- enum rtw89_phy_idx phy_idx)
-{
- static const u32 gain_err_addr[2] = {R_P0_AGC_RSVD, R_P1_AGC_RSVD};
- static const u32 rssi_ofst_addr[2] = {R_PATH0_G_TIA1_LNA6_OP1DB_V1,
- R_PATH1_G_TIA1_LNA6_OP1DB_V1};
- struct rtw89_hal *hal = &rtwdev->hal;
- struct rtw89_phy_efuse_gain *efuse_gain = &rtwdev->efuse_gain;
- enum rtw89_gain_offset gain_ofdm_band;
- s32 offset_a, offset_b;
- s32 offset_ofdm, offset_cck;
- s32 tmp;
- u8 path;
-
- if (!efuse_gain->comp_valid)
- goto next;
-
- for (path = RF_PATH_A; path < BB_PATH_NUM_8852B; path++) {
- tmp = efuse_gain->comp[path][subband];
- tmp = clamp_t(s32, tmp << 2, S8_MIN, S8_MAX);
- rtw89_phy_write32_mask(rtwdev, gain_err_addr[path], MASKBYTE0, tmp);
- }
-
-next:
- if (!efuse_gain->offset_valid)
- return;
-
- gain_ofdm_band = rtw89_subband_to_gain_offset_band_of_ofdm(subband);
-
- offset_a = -efuse_gain->offset[RF_PATH_A][gain_ofdm_band];
- offset_b = -efuse_gain->offset[RF_PATH_B][gain_ofdm_band];
-
- tmp = -((offset_a << 2) + (efuse_gain->offset_base[RTW89_PHY_0] >> 2));
- tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX);
- rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[RF_PATH_A], B_PATH0_R_G_OFST_MASK, tmp);
-
- tmp = -((offset_b << 2) + (efuse_gain->offset_base[RTW89_PHY_0] >> 2));
- tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX);
- rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[RF_PATH_B], B_PATH0_R_G_OFST_MASK, tmp);
-
- if (hal->antenna_rx == RF_B) {
- offset_ofdm = -efuse_gain->offset[RF_PATH_B][gain_ofdm_band];
- offset_cck = -efuse_gain->offset[RF_PATH_B][0];
- } else {
- offset_ofdm = -efuse_gain->offset[RF_PATH_A][gain_ofdm_band];
- offset_cck = -efuse_gain->offset[RF_PATH_A][0];
- }
-
- tmp = (offset_ofdm << 4) + efuse_gain->offset_base[RTW89_PHY_0];
- tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX);
- rtw89_phy_write32_idx(rtwdev, R_P0_RPL1, B_P0_RPL1_BIAS_MASK, tmp, phy_idx);
-
- tmp = (offset_ofdm << 4) + efuse_gain->rssi_base[RTW89_PHY_0];
- tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX);
- rtw89_phy_write32_idx(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK, tmp, phy_idx);
-
- if (subband == RTW89_CH_2G) {
- tmp = (offset_cck << 3) + (efuse_gain->offset_base[RTW89_PHY_0] >> 1);
- tmp = clamp_t(s32, tmp, S8_MIN >> 1, S8_MAX >> 1);
- rtw89_phy_write32_mask(rtwdev, R_RX_RPL_OFST,
- B_RX_RPL_OFST_CCK_MASK, tmp);
- }
-}
-
-static
-void rtw8852b_set_rxsc_rpl_comp(struct rtw89_dev *rtwdev, enum rtw89_subband subband)
-{
- const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax;
- u8 band = rtw89_subband_to_bb_gain_band(subband);
- u32 val;
-
- val = FIELD_PREP(B_P0_RPL1_20_MASK, (gain->rpl_ofst_20[band][RF_PATH_A] +
- gain->rpl_ofst_20[band][RF_PATH_B]) / 2) |
- FIELD_PREP(B_P0_RPL1_40_MASK, (gain->rpl_ofst_40[band][RF_PATH_A][0] +
- gain->rpl_ofst_40[band][RF_PATH_B][0]) / 2) |
- FIELD_PREP(B_P0_RPL1_41_MASK, (gain->rpl_ofst_40[band][RF_PATH_A][1] +
- gain->rpl_ofst_40[band][RF_PATH_B][1]) / 2);
- val >>= B_P0_RPL1_SHIFT;
- rtw89_phy_write32_mask(rtwdev, R_P0_RPL1, B_P0_RPL1_MASK, val);
- rtw89_phy_write32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_MASK, val);
-
- val = FIELD_PREP(B_P0_RTL2_42_MASK, (gain->rpl_ofst_40[band][RF_PATH_A][2] +
- gain->rpl_ofst_40[band][RF_PATH_B][2]) / 2) |
- FIELD_PREP(B_P0_RTL2_80_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][0] +
- gain->rpl_ofst_80[band][RF_PATH_B][0]) / 2) |
- FIELD_PREP(B_P0_RTL2_81_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][1] +
- gain->rpl_ofst_80[band][RF_PATH_B][1]) / 2) |
- FIELD_PREP(B_P0_RTL2_8A_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][10] +
- gain->rpl_ofst_80[band][RF_PATH_B][10]) / 2);
- rtw89_phy_write32(rtwdev, R_P0_RPL2, val);
- rtw89_phy_write32(rtwdev, R_P1_RPL2, val);
-
- val = FIELD_PREP(B_P0_RTL3_82_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][2] +
- gain->rpl_ofst_80[band][RF_PATH_B][2]) / 2) |
- FIELD_PREP(B_P0_RTL3_83_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][3] +
- gain->rpl_ofst_80[band][RF_PATH_B][3]) / 2) |
- FIELD_PREP(B_P0_RTL3_84_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][4] +
- gain->rpl_ofst_80[band][RF_PATH_B][4]) / 2) |
- FIELD_PREP(B_P0_RTL3_89_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][9] +
- gain->rpl_ofst_80[band][RF_PATH_B][9]) / 2);
- rtw89_phy_write32(rtwdev, R_P0_RPL3, val);
- rtw89_phy_write32(rtwdev, R_P1_RPL3, val);
-}
-
-static void rtw8852b_ctrl_ch(struct rtw89_dev *rtwdev,
- const struct rtw89_chan *chan,
- enum rtw89_phy_idx phy_idx)
-{
- u8 central_ch = chan->channel;
- u8 subband = chan->subband_type;
- u8 sco_comp;
- bool is_2g = central_ch <= 14;
-
- /* Path A */
- if (is_2g)
- rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1,
- B_PATH0_BAND_SEL_MSK_V1, 1, phy_idx);
- else
- rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1,
- B_PATH0_BAND_SEL_MSK_V1, 0, phy_idx);
-
- /* Path B */
- if (is_2g)
- rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1,
- B_PATH1_BAND_SEL_MSK_V1, 1, phy_idx);
- else
- rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1,
- B_PATH1_BAND_SEL_MSK_V1, 0, phy_idx);
-
- /* SCO compensate FC setting */
- sco_comp = rtw8852b_sco_mapping(central_ch);
- rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_INV, sco_comp, phy_idx);
-
- if (chan->band_type == RTW89_BAND_6G)
- return;
-
- /* CCK parameters */
- if (central_ch == 14) {
- rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, 0x3b13ff);
- rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, 0x1c42de);
- rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfdb0ad);
- rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, 0xf60f6e);
- rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, 0xfd8f92);
- rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0x2d011);
- rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0x1c02c);
- rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, 0xfff00a);
- } else {
- rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, 0x3d23ff);
- rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, 0x29b354);
- rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfc1c8);
- rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, 0xfdb053);
- rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, 0xf86f9a);
- rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0xfaef92);
- rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0xfe5fcc);
- rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, 0xffdff5);
- }
-
- rtw8852b_set_gain_error(rtwdev, subband, RF_PATH_A);
- rtw8852b_set_gain_error(rtwdev, subband, RF_PATH_B);
- rtw8852b_set_gain_offset(rtwdev, subband, phy_idx);
- rtw8852b_set_rxsc_rpl_comp(rtwdev, subband);
-}
-
-static void rtw8852b_bw_setting(struct rtw89_dev *rtwdev, u8 bw, u8 path)
-{
- static const u32 adc_sel[2] = {0xC0EC, 0xC1EC};
- static const u32 wbadc_sel[2] = {0xC0E4, 0xC1E4};
-
- switch (bw) {
- case RTW89_CHANNEL_WIDTH_5:
- rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x1);
- rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x0);
- break;
- case RTW89_CHANNEL_WIDTH_10:
- rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x2);
- rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x1);
- break;
- case RTW89_CHANNEL_WIDTH_20:
- rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0);
- rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2);
- break;
- case RTW89_CHANNEL_WIDTH_40:
- rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0);
- rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2);
- break;
- case RTW89_CHANNEL_WIDTH_80:
- rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0);
- rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2);
- break;
- default:
- rtw89_warn(rtwdev, "Fail to set ADC\n");
- }
-}
-
-static void rtw8852b_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw,
- enum rtw89_phy_idx phy_idx)
-{
- u32 rx_path_0;
-
- switch (bw) {
- case RTW89_CHANNEL_WIDTH_5:
- rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x1, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx);
-
- /*Set RF mode at 3 */
- rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX,
- B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX,
- B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
- break;
- case RTW89_CHANNEL_WIDTH_10:
- rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x2, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx);
-
- /*Set RF mode at 3 */
- rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX,
- B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX,
- B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
- break;
- case RTW89_CHANNEL_WIDTH_20:
- rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx);
-
- /*Set RF mode at 3 */
- rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX,
- B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX,
- B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
- break;
- case RTW89_CHANNEL_WIDTH_40:
- rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x1, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH,
- pri_ch, phy_idx);
-
- /*Set RF mode at 3 */
- rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX,
- B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX,
- B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
- /*CCK primary channel */
- if (pri_ch == RTW89_SC_20_UPPER)
- rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 1);
- else
- rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 0);
-
- break;
- case RTW89_CHANNEL_WIDTH_80:
- rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x2, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH,
- pri_ch, phy_idx);
-
- /*Set RF mode at A */
- rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX,
- B_P0_RFMODE_ORI_RX_ALL, 0xaaa, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX,
- B_P1_RFMODE_ORI_RX_ALL, 0xaaa, phy_idx);
- break;
- default:
- rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw,
- pri_ch);
- }
-
- rtw8852b_bw_setting(rtwdev, bw, RF_PATH_A);
- rtw8852b_bw_setting(rtwdev, bw, RF_PATH_B);
-
- rx_path_0 = rtw89_phy_read32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0,
- phy_idx);
- if (rx_path_0 == 0x1)
- rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX,
- B_P1_RFMODE_ORI_RX_ALL, 0x111, phy_idx);
- else if (rx_path_0 == 0x2)
- rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX,
- B_P0_RFMODE_ORI_RX_ALL, 0x111, phy_idx);
-}
-
-static void rtw8852b_ctrl_cck_en(struct rtw89_dev *rtwdev, bool cck_en)
-{
- if (cck_en) {
- rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 1);
- rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0);
- } else {
- rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 0);
- rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 1);
- }
-}
-
-static void rtw8852b_5m_mask(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan,
- enum rtw89_phy_idx phy_idx)
-{
- u8 pri_ch = chan->pri_ch_idx;
- bool mask_5m_low;
- bool mask_5m_en;
-
- switch (chan->band_width) {
- case RTW89_CHANNEL_WIDTH_40:
- /* Prich=1: Mask 5M High, Prich=2: Mask 5M Low */
- mask_5m_en = true;
- mask_5m_low = pri_ch == RTW89_SC_20_LOWER;
- break;
- case RTW89_CHANNEL_WIDTH_80:
- /* Prich=3: Mask 5M High, Prich=4: Mask 5M Low, Else: Disable */
- mask_5m_en = pri_ch == RTW89_SC_20_UPMOST ||
- pri_ch == RTW89_SC_20_LOWEST;
- mask_5m_low = pri_ch == RTW89_SC_20_LOWEST;
- break;
- default:
- mask_5m_en = false;
- break;
- }
-
- if (!mask_5m_en) {
- rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_EN, 0x0);
- rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT_V1,
- B_ASSIGN_SBD_OPT_EN_V1, 0x0, phy_idx);
- return;
- }
-
- if (mask_5m_low) {
- rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_TH, 0x4);
- rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x1);
- rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB2, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB0, 0x1);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_TH, 0x4);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_EN, 0x1);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB2, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB0, 0x1);
- } else {
- rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_TH, 0x4);
- rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x1);
- rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB2, 0x1);
- rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB0, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_TH, 0x4);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_EN, 0x1);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB2, 0x1);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB0, 0x0);
- }
- rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT_V1,
- B_ASSIGN_SBD_OPT_EN_V1, 0x1, phy_idx);
-}
-
-static void rtw8852b_bb_reset_all(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
-{
- rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx);
- fsleep(1);
- rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx);
- rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx);
-}
-
static void rtw8852b_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band,
enum rtw89_phy_idx phy_idx, bool en)
{
@@ -1409,87 +482,20 @@ static void rtw8852b_bb_reset(struct rtw89_dev *rtwdev,
rtw89_phy_write32_set(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN);
rtw89_phy_write32_set(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON);
rtw89_phy_write32_set(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN);
- rtw8852b_bb_reset_all(rtwdev, phy_idx);
+ rtw8852bx_bb_reset_all(rtwdev, phy_idx);
rtw89_phy_write32_clr(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON);
rtw89_phy_write32_clr(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN);
rtw89_phy_write32_clr(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON);
rtw89_phy_write32_clr(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN);
}
-static void rtw8852b_bb_macid_ctrl_init(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx)
-{
- u32 addr;
-
- for (addr = R_AX_PWR_MACID_LMT_TABLE0;
- addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4)
- rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0);
-}
-
-static void rtw8852b_bb_sethw(struct rtw89_dev *rtwdev)
-{
- struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
-
- rtw89_phy_write32_clr(rtwdev, R_P0_EN_SOUND_WO_NDP, B_P0_EN_SOUND_WO_NDP);
- rtw89_phy_write32_clr(rtwdev, R_P1_EN_SOUND_WO_NDP, B_P1_EN_SOUND_WO_NDP);
-
- rtw8852b_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0);
-
- /* read these registers after loading BB parameters */
- gain->offset_base[RTW89_PHY_0] =
- rtw89_phy_read32_mask(rtwdev, R_P0_RPL1, B_P0_RPL1_BIAS_MASK);
- gain->rssi_base[RTW89_PHY_0] =
- rtw89_phy_read32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK);
-}
-
-static void rtw8852b_bb_set_pop(struct rtw89_dev *rtwdev)
-{
- if (rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR)
- rtw89_phy_write32_clr(rtwdev, R_PKT_CTRL, B_PKT_POP_EN);
-}
-
-static void rtw8852b_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan,
- enum rtw89_phy_idx phy_idx)
-{
- bool cck_en = chan->channel <= 14;
- u8 pri_ch_idx = chan->pri_ch_idx;
- u8 band = chan->band_type, chan_idx;
-
- if (cck_en)
- rtw8852b_ctrl_sco_cck(rtwdev, chan->primary_channel);
-
- rtw8852b_ctrl_ch(rtwdev, chan, phy_idx);
- rtw8852b_ctrl_bw(rtwdev, pri_ch_idx, chan->band_width, phy_idx);
- rtw8852b_ctrl_cck_en(rtwdev, cck_en);
- if (chan->band_type == RTW89_BAND_5G) {
- rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
- B_PATH0_BT_SHARE_V1, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1,
- B_PATH0_BTG_PATH_V1, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1,
- B_PATH1_BT_SHARE_V1, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1,
- B_PATH1_BTG_PATH_V1, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1,
- B_BT_DYN_DC_EST_EN_MSK, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x0);
- }
- chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band);
- rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx);
- rtw8852b_5m_mask(rtwdev, chan, phy_idx);
- rtw8852b_bb_set_pop(rtwdev);
- rtw8852b_bb_reset_all(rtwdev, phy_idx);
-}
-
static void rtw8852b_set_channel(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_mac_idx mac_idx,
enum rtw89_phy_idx phy_idx)
{
- rtw8852b_set_channel_mac(rtwdev, chan, mac_idx);
- rtw8852b_set_channel_bb(rtwdev, chan, phy_idx);
+ rtw8852bx_set_channel_mac(rtwdev, chan, mac_idx);
+ rtw8852bx_set_channel_bb(rtwdev, chan, phy_idx);
rtw8852b_set_channel_rf(rtwdev, chan, phy_idx);
}
@@ -1559,29 +565,41 @@ static void rtw8852b_rfk_init(struct rtw89_dev *rtwdev)
rtw8852b_dpk_init(rtwdev);
rtw8852b_rck(rtwdev);
- rtw8852b_dack(rtwdev);
- rtw8852b_rx_dck(rtwdev, RTW89_PHY_0);
+ rtw8852b_dack(rtwdev, RTW89_CHANCTX_0);
+ rtw8852b_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0);
}
-static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev)
+static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
+ enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
+ enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
+
+ rtw89_btc_ntfy_conn_rfk(rtwdev, true);
- rtw8852b_rx_dck(rtwdev, phy_idx);
- rtw8852b_iqk(rtwdev, phy_idx);
- rtw8852b_tssi(rtwdev, phy_idx, true);
- rtw8852b_dpk(rtwdev, phy_idx);
+ rtw8852b_rx_dck(rtwdev, phy_idx, chanctx_idx);
+ rtw8852b_iqk(rtwdev, phy_idx, chanctx_idx);
+ rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
+ rtw8852b_tssi(rtwdev, phy_idx, true, chanctx_idx);
+ rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
+ rtw8852b_dpk(rtwdev, phy_idx, chanctx_idx);
+
+ rtw89_btc_ntfy_conn_rfk(rtwdev, false);
}
static void rtw8852b_rfk_band_changed(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx)
+ enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan)
{
- rtw8852b_tssi_scan(rtwdev, phy_idx);
+ rtw8852b_tssi_scan(rtwdev, phy_idx, chan);
}
-static void rtw8852b_rfk_scan(struct rtw89_dev *rtwdev, bool start)
+static void rtw8852b_rfk_scan(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ bool start)
{
- rtw8852b_wifi_scan_notify(rtwdev, start, RTW89_PHY_0);
+ rtw8852b_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx,
+ rtwvif_link->chanctx_idx);
}
static void rtw8852b_rfk_track(struct rtw89_dev *rtwdev)
@@ -1589,540 +607,6 @@ static void rtw8852b_rfk_track(struct rtw89_dev *rtwdev)
rtw8852b_dpk_track(rtwdev);
}
-static u32 rtw8852b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx, s16 ref)
-{
- const u16 tssi_16dbm_cw = 0x12c;
- const u8 base_cw_0db = 0x27;
- const s8 ofst_int = 0;
- s16 pwr_s10_3;
- s16 rf_pwr_cw;
- u16 bb_pwr_cw;
- u32 pwr_cw;
- u32 tssi_ofst_cw;
-
- pwr_s10_3 = (ref << 1) + (s16)(ofst_int) + (s16)(base_cw_0db << 3);
- bb_pwr_cw = FIELD_GET(GENMASK(2, 0), pwr_s10_3);
- rf_pwr_cw = FIELD_GET(GENMASK(8, 3), pwr_s10_3);
- rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63);
- pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw;
-
- tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3));
- rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
- "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n",
- tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw);
-
- return FIELD_PREP(B_DPD_TSSI_CW, tssi_ofst_cw) |
- FIELD_PREP(B_DPD_PWR_CW, pwr_cw) |
- FIELD_PREP(B_DPD_REF, ref);
-}
-
-static void rtw8852b_set_txpwr_ref(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx)
-{
- static const u32 addr[RF_PATH_NUM_8852B] = {0x5800, 0x7800};
- const u32 mask = B_DPD_TSSI_CW | B_DPD_PWR_CW | B_DPD_REF;
- const u8 ofst_ofdm = 0x4;
- const u8 ofst_cck = 0x8;
- const s16 ref_ofdm = 0;
- const s16 ref_cck = 0;
- u32 val;
- u8 i;
-
- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n");
-
- rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL,
- B_AX_PWR_REF, 0x0);
-
- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n");
- val = rtw8852b_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm);
-
- for (i = 0; i < RF_PATH_NUM_8852B; i++)
- rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val,
- phy_idx);
-
- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n");
- val = rtw8852b_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck);
-
- for (i = 0; i < RF_PATH_NUM_8852B; i++)
- rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val,
- phy_idx);
-}
-
-static void rtw8852b_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev,
- const struct rtw89_chan *chan,
- u8 tx_shape_idx,
- enum rtw89_phy_idx phy_idx)
-{
-#define __DFIR_CFG_ADDR(i) (R_TXFIR0 + ((i) << 2))
-#define __DFIR_CFG_MASK 0xffffffff
-#define __DFIR_CFG_NR 8
-#define __DECL_DFIR_PARAM(_name, _val...) \
- static const u32 param_ ## _name[] = {_val}; \
- static_assert(ARRAY_SIZE(param_ ## _name) == __DFIR_CFG_NR)
-
- __DECL_DFIR_PARAM(flat,
- 0x023D23FF, 0x0029B354, 0x000FC1C8, 0x00FDB053,
- 0x00F86F9A, 0x06FAEF92, 0x00FE5FCC, 0x00FFDFF5);
- __DECL_DFIR_PARAM(sharp,
- 0x023D83FF, 0x002C636A, 0x0013F204, 0x00008090,
- 0x00F87FB0, 0x06F99F83, 0x00FDBFBA, 0x00003FF5);
- __DECL_DFIR_PARAM(sharp_14,
- 0x023B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E,
- 0x00FD8F92, 0x0602D011, 0x0001C02C, 0x00FFF00A);
- u8 ch = chan->channel;
- const u32 *param;
- u32 addr;
- int i;
-
- if (ch > 14) {
- rtw89_warn(rtwdev,
- "set tx shape dfir by unknown ch: %d on 2G\n", ch);
- return;
- }
-
- if (ch == 14)
- param = param_sharp_14;
- else
- param = tx_shape_idx == 0 ? param_flat : param_sharp;
-
- for (i = 0; i < __DFIR_CFG_NR; i++) {
- addr = __DFIR_CFG_ADDR(i);
- rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
- "set tx shape dfir: 0x%x: 0x%x\n", addr, param[i]);
- rtw89_phy_write32_idx(rtwdev, addr, __DFIR_CFG_MASK, param[i],
- phy_idx);
- }
-
-#undef __DECL_DFIR_PARAM
-#undef __DFIR_CFG_NR
-#undef __DFIR_CFG_MASK
-#undef __DECL_CFG_ADDR
-}
-
-static void rtw8852b_set_tx_shape(struct rtw89_dev *rtwdev,
- const struct rtw89_chan *chan,
- enum rtw89_phy_idx phy_idx)
-{
- const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
- u8 band = chan->band_type;
- u8 regd = rtw89_regd_get(rtwdev, band);
- u8 tx_shape_cck = (*rfe_parms->tx_shape.lmt)[band][RTW89_RS_CCK][regd];
- u8 tx_shape_ofdm = (*rfe_parms->tx_shape.lmt)[band][RTW89_RS_OFDM][regd];
-
- if (band == RTW89_BAND_2G)
- rtw8852b_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx);
-
- rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG,
- tx_shape_ofdm);
-}
-
-static void rtw8852b_set_txpwr(struct rtw89_dev *rtwdev,
- const struct rtw89_chan *chan,
- enum rtw89_phy_idx phy_idx)
-{
- rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx);
- rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx);
- rtw8852b_set_tx_shape(rtwdev, chan, phy_idx);
- rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx);
- rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
-}
-
-static void rtw8852b_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx)
-{
- rtw8852b_set_txpwr_ref(rtwdev, phy_idx);
-}
-
-static
-void rtw8852b_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
- s8 pw_ofst, enum rtw89_mac_idx mac_idx)
-{
- u32 reg;
-
- if (pw_ofst < -16 || pw_ofst > 15) {
- rtw89_warn(rtwdev, "[ULTB] Err pwr_offset=%d\n", pw_ofst);
- return;
- }
-
- reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_CTRL, mac_idx);
- rtw89_write32_set(rtwdev, reg, B_AX_PWR_UL_TB_CTRL_EN);
-
- reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, mac_idx);
- rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, pw_ofst);
-
- pw_ofst = max_t(s8, pw_ofst - 3, -16);
- reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, mac_idx);
- rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_MASK, pw_ofst);
-}
-
-static int
-rtw8852b_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
-{
- int ret;
-
- ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, 0x07763333);
- if (ret)
- return ret;
-
- ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, 0x01ebf000);
- if (ret)
- return ret;
-
- ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, 0x0002f8ff);
- if (ret)
- return ret;
-
- rtw8852b_set_txpwr_ul_tb_offset(rtwdev, 0, phy_idx == RTW89_PHY_1 ?
- RTW89_MAC_1 : RTW89_MAC_0);
-
- return 0;
-}
-
-void rtw8852b_bb_set_plcp_tx(struct rtw89_dev *rtwdev)
-{
- const struct rtw89_reg3_def *def = rtw8852b_pmac_ht20_mcs7_tbl;
- u8 i;
-
- for (i = 0; i < ARRAY_SIZE(rtw8852b_pmac_ht20_mcs7_tbl); i++, def++)
- rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data);
-}
-
-static void rtw8852b_stop_pmac_tx(struct rtw89_dev *rtwdev,
- struct rtw8852b_bb_pmac_info *tx_info,
- enum rtw89_phy_idx idx)
-{
- rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC Stop Tx");
- if (tx_info->mode == CONT_TX)
- rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_CTX_EN, 0, idx);
- else if (tx_info->mode == PKTS_TX)
- rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_PTX_EN, 0, idx);
-}
-
-static void rtw8852b_start_pmac_tx(struct rtw89_dev *rtwdev,
- struct rtw8852b_bb_pmac_info *tx_info,
- enum rtw89_phy_idx idx)
-{
- enum rtw8852b_pmac_mode mode = tx_info->mode;
- u32 pkt_cnt = tx_info->tx_cnt;
- u16 period = tx_info->period;
-
- if (mode == CONT_TX && !tx_info->is_cck) {
- rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_CTX_EN, 1, idx);
- rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CTx Start");
- } else if (mode == PKTS_TX) {
- rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_PTX_EN, 1, idx);
- rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD,
- B_PMAC_TX_PRD_MSK, period, idx);
- rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CNT, B_PMAC_TX_CNT_MSK,
- pkt_cnt, idx);
- rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC PTx Start");
- }
-
- rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CTRL, B_PMAC_TXEN_DIS, 1, idx);
- rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CTRL, B_PMAC_TXEN_DIS, 0, idx);
-}
-
-void rtw8852b_bb_set_pmac_tx(struct rtw89_dev *rtwdev,
- struct rtw8852b_bb_pmac_info *tx_info,
- enum rtw89_phy_idx idx)
-{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
-
- if (!tx_info->en_pmac_tx) {
- rtw8852b_stop_pmac_tx(rtwdev, tx_info, idx);
- rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0, idx);
- if (chan->band_type == RTW89_BAND_2G)
- rtw89_phy_write32_clr(rtwdev, R_RXCCA, B_RXCCA_DIS);
- return;
- }
-
- rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC Tx Enable");
-
- rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_TXEN, 1, idx);
- rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_RXEN, 1, idx);
- rtw89_phy_write32_idx(rtwdev, R_PMAC_RX_CFG1, B_PMAC_OPT1_MSK, 0x3f, idx);
- rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, idx);
- rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 1, idx);
- rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS);
- rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, idx);
-
- rtw8852b_start_pmac_tx(rtwdev, tx_info, idx);
-}
-
-void rtw8852b_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable,
- u16 tx_cnt, u16 period, u16 tx_time,
- enum rtw89_phy_idx idx)
-{
- struct rtw8852b_bb_pmac_info tx_info = {0};
-
- tx_info.en_pmac_tx = enable;
- tx_info.is_cck = 0;
- tx_info.mode = PKTS_TX;
- tx_info.tx_cnt = tx_cnt;
- tx_info.period = period;
- tx_info.tx_time = tx_time;
-
- rtw8852b_bb_set_pmac_tx(rtwdev, &tx_info, idx);
-}
-
-void rtw8852b_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm,
- enum rtw89_phy_idx idx)
-{
- rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CFG Tx PWR = %d", pwr_dbm);
-
- rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 1, idx);
- rtw89_phy_write32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, pwr_dbm, idx);
-}
-
-void rtw8852b_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path)
-{
- rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 7, RTW89_PHY_0);
-
- rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CFG Tx Path = %d", tx_path);
-
- if (tx_path == RF_PATH_A) {
- rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 1);
- rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0);
- } else if (tx_path == RF_PATH_B) {
- rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 2);
- rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0);
- } else if (tx_path == RF_PATH_AB) {
- rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 3);
- rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 4);
- } else {
- rtw89_debug(rtwdev, RTW89_DBG_TSSI, "Error Tx Path");
- }
-}
-
-void rtw8852b_bb_tx_mode_switch(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx idx, u8 mode)
-{
- if (mode != 0)
- return;
-
- rtw89_debug(rtwdev, RTW89_DBG_TSSI, "Tx mode switch");
-
- rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_TXEN, 0, idx);
- rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_RXEN, 0, idx);
- rtw89_phy_write32_idx(rtwdev, R_PMAC_RX_CFG1, B_PMAC_OPT1_MSK, 0, idx);
- rtw89_phy_write32_idx(rtwdev, R_PMAC_RXMOD, B_PMAC_RXMOD_MSK, 0, idx);
- rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_DPD_EN, 0, idx);
- rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, idx);
- rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 0, idx);
-}
-
-void rtw8852b_bb_backup_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx,
- struct rtw8852b_bb_tssi_bak *bak)
-{
- s32 tmp;
-
- bak->tx_path = rtw89_phy_read32_idx(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, idx);
- bak->rx_path = rtw89_phy_read32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, idx);
- bak->p0_rfmode = rtw89_phy_read32_idx(rtwdev, R_P0_RFMODE, MASKDWORD, idx);
- bak->p0_rfmode_ftm = rtw89_phy_read32_idx(rtwdev, R_P0_RFMODE_FTM_RX, MASKDWORD, idx);
- bak->p1_rfmode = rtw89_phy_read32_idx(rtwdev, R_P1_RFMODE, MASKDWORD, idx);
- bak->p1_rfmode_ftm = rtw89_phy_read32_idx(rtwdev, R_P1_RFMODE_FTM_RX, MASKDWORD, idx);
- tmp = rtw89_phy_read32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, idx);
- bak->tx_pwr = sign_extend32(tmp, 8);
-}
-
-void rtw8852b_bb_restore_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx,
- const struct rtw8852b_bb_tssi_bak *bak)
-{
- rtw89_phy_write32_idx(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, bak->tx_path, idx);
- if (bak->tx_path == RF_AB)
- rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0x4);
- else
- rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0x0);
- rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, bak->rx_path, idx);
- rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 1, idx);
- rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE, MASKDWORD, bak->p0_rfmode, idx);
- rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_FTM_RX, MASKDWORD, bak->p0_rfmode_ftm, idx);
- rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE, MASKDWORD, bak->p1_rfmode, idx);
- rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_FTM_RX, MASKDWORD, bak->p1_rfmode_ftm, idx);
- rtw89_phy_write32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, bak->tx_pwr, idx);
-}
-
-static void rtw8852b_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en,
- enum rtw89_phy_idx phy_idx)
-{
- rtw89_phy_write_reg3_tbl(rtwdev, en ? &rtw8852b_btc_preagc_en_defs_tbl :
- &rtw8852b_btc_preagc_dis_defs_tbl);
-}
-
-static void rtw8852b_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en,
- enum rtw89_phy_idx phy_idx)
-{
- if (en) {
- rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
- B_PATH0_BT_SHARE_V1, 0x1);
- rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1,
- B_PATH0_BTG_PATH_V1, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
- B_PATH1_G_LNA6_OP1DB_V1, 0x20);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
- B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x30);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1,
- B_PATH1_BT_SHARE_V1, 0x1);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1,
- B_PATH1_BTG_PATH_V1, 0x1);
- rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x1);
- rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x2);
- rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1,
- B_BT_DYN_DC_EST_EN_MSK, 0x1);
- rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x1);
- } else {
- rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
- B_PATH0_BT_SHARE_V1, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1,
- B_PATH0_BTG_PATH_V1, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
- B_PATH1_G_LNA6_OP1DB_V1, 0x1a);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
- B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x2a);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1,
- B_PATH1_BT_SHARE_V1, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1,
- B_PATH1_BTG_PATH_V1, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xc);
- rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x0);
- rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1,
- B_BT_DYN_DC_EST_EN_MSK, 0x1);
- rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x0);
- }
-}
-
-void rtw8852b_bb_ctrl_rx_path(struct rtw89_dev *rtwdev,
- enum rtw89_rf_path_bit rx_path)
-{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
- u32 rst_mask0;
- u32 rst_mask1;
-
- if (rx_path == RF_A) {
- rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, 1);
- rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG0, 1);
- rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG1, 1);
- rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0);
- rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0);
- rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 4);
- rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
- rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0);
- } else if (rx_path == RF_B) {
- rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, 2);
- rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG0, 2);
- rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG1, 2);
- rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0);
- rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0);
- rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 4);
- rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
- rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0);
- } else if (rx_path == RF_AB) {
- rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, 3);
- rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG0, 3);
- rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG1, 3);
- rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 1);
- rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 1);
- rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 4);
- rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1);
- rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1);
- }
-
- rtw8852b_set_gain_offset(rtwdev, chan->subband_type, RTW89_PHY_0);
-
- if (chan->band_type == RTW89_BAND_2G &&
- (rx_path == RF_B || rx_path == RF_AB))
- rtw8852b_ctrl_btg_bt_rx(rtwdev, true, RTW89_PHY_0);
- else
- rtw8852b_ctrl_btg_bt_rx(rtwdev, false, RTW89_PHY_0);
-
- rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI;
- rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI;
- if (rx_path == RF_A) {
- rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1);
- rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3);
- } else {
- rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 1);
- rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 3);
- }
-}
-
-static void rtw8852b_bb_ctrl_rf_mode_rx_path(struct rtw89_dev *rtwdev,
- enum rtw89_rf_path_bit rx_path)
-{
- if (rx_path == RF_A) {
- rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE,
- B_P0_RFMODE_ORI_TXRX_FTM_TX, 0x1233312);
- rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE_FTM_RX,
- B_P0_RFMODE_FTM_RX, 0x333);
- rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE,
- B_P1_RFMODE_ORI_TXRX_FTM_TX, 0x1111111);
- rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE_FTM_RX,
- B_P1_RFMODE_FTM_RX, 0x111);
- } else if (rx_path == RF_B) {
- rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE,
- B_P0_RFMODE_ORI_TXRX_FTM_TX, 0x1111111);
- rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE_FTM_RX,
- B_P0_RFMODE_FTM_RX, 0x111);
- rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE,
- B_P1_RFMODE_ORI_TXRX_FTM_TX, 0x1233312);
- rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE_FTM_RX,
- B_P1_RFMODE_FTM_RX, 0x333);
- } else if (rx_path == RF_AB) {
- rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE,
- B_P0_RFMODE_ORI_TXRX_FTM_TX, 0x1233312);
- rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE_FTM_RX,
- B_P0_RFMODE_FTM_RX, 0x333);
- rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE,
- B_P1_RFMODE_ORI_TXRX_FTM_TX, 0x1233312);
- rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE_FTM_RX,
- B_P1_RFMODE_FTM_RX, 0x333);
- }
-}
-
-static void rtw8852b_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
-{
- struct rtw89_hal *hal = &rtwdev->hal;
- enum rtw89_rf_path_bit rx_path = hal->antenna_rx ? hal->antenna_rx : RF_AB;
-
- rtw8852b_bb_ctrl_rx_path(rtwdev, rx_path);
- rtw8852b_bb_ctrl_rf_mode_rx_path(rtwdev, rx_path);
-
- if (rtwdev->hal.rx_nss == 1) {
- rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0);
- rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0);
- rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
- rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0);
- } else {
- rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 1);
- rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 1);
- rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1);
- rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1);
- }
-
- rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0x0, RTW89_PHY_0);
-}
-
-static u8 rtw8852b_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
-{
- if (rtwdev->is_tssi_mode[rf_path]) {
- u32 addr = 0x1c10 + (rf_path << 13);
-
- return rtw89_phy_read32_mask(rtwdev, addr, 0x3F000000);
- }
-
- rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
- rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0);
- rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
-
- fsleep(200);
-
- return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL);
-}
-
static void rtw8852b_btc_set_rfe(struct rtw89_dev *rtwdev)
{
const struct rtw89_btc_ver *ver = rtwdev->btc.ver;
@@ -2177,86 +661,6 @@ static void rtw8852b_btc_set_rfe(struct rtw89_dev *rtwdev)
}
}
-static
-void rtw8852b_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val)
-{
- rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x20000);
- rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, group);
- rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val);
- rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0);
-}
-
-static void rtw8852b_btc_init_cfg(struct rtw89_dev *rtwdev)
-{
- struct rtw89_btc *btc = &rtwdev->btc;
- const struct rtw89_chip_info *chip = rtwdev->chip;
- const struct rtw89_mac_ax_coex coex_params = {
- .pta_mode = RTW89_MAC_AX_COEX_RTK_MODE,
- .direction = RTW89_MAC_AX_COEX_INNER,
- };
-
- /* PTA init */
- rtw89_mac_coex_init(rtwdev, &coex_params);
-
- /* set WL Tx response = Hi-Pri */
- chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true);
- chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true);
-
- /* set rf gnt debug off */
- rtw89_write_rf(rtwdev, RF_PATH_A, RR_WLSEL, RFREG_MASK, 0x0);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_WLSEL, RFREG_MASK, 0x0);
-
- /* set WL Tx thru in TRX mask table if GNT_WL = 0 && BT_S1 = ss group */
- if (btc->ant_type == BTC_ANT_SHARED) {
- rtw8852b_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff);
- rtw8852b_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_SS_GROUP, 0x5ff);
- /* set path-A(S0) Tx/Rx no-mask if GNT_WL=0 && BT_S1=tx group */
- rtw8852b_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff);
- rtw8852b_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_TX_GROUP, 0x55f);
- } else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */
- rtw8852b_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_SS_GROUP, 0x5df);
- rtw8852b_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_SS_GROUP, 0x5df);
- rtw8852b_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff);
- rtw8852b_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_TX_GROUP, 0x5ff);
- }
-
- /* set PTA break table */
- rtw89_write32(rtwdev, R_BTC_BREAK_TABLE, BTC_BREAK_PARAM);
-
- /* enable BT counter 0xda40[16,2] = 2b'11 */
- rtw89_write32_set(rtwdev, R_AX_CSR_MODE, B_AX_BT_CNT_RST | B_AX_STATIS_BT_EN);
- btc->cx.wl.status.map.init_ok = true;
-}
-
-static
-void rtw8852b_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state)
-{
- u32 bitmap;
- u32 reg;
-
- switch (map) {
- case BTC_PRI_MASK_TX_RESP:
- reg = R_BTC_BT_COEX_MSK_TABLE;
- bitmap = B_BTC_PRI_MASK_TX_RESP_V1;
- break;
- case BTC_PRI_MASK_BEACON:
- reg = R_AX_WL_PRI_MSK;
- bitmap = B_AX_PTA_WL_PRI_MASK_BCNQ;
- break;
- case BTC_PRI_MASK_RX_CCK:
- reg = R_BTC_BT_COEX_MSK_TABLE;
- bitmap = B_BTC_PRI_MASK_RXCCK_V1;
- break;
- default:
- return;
- }
-
- if (state)
- rtw89_write32_set(rtwdev, reg, bitmap);
- else
- rtw89_write32_clr(rtwdev, reg, bitmap);
-}
-
union rtw8852b_btc_wl_txpwr_ctrl {
u32 txpwr_val;
struct {
@@ -2324,185 +728,19 @@ do { \
#undef __write_ctrl
}
-static
-s8 rtw8852b_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
-{
- /* +6 for compensate offset */
- return clamp_t(s8, val + 6, -100, 0) + 100;
-}
-
-static
-void rtw8852b_btc_update_bt_cnt(struct rtw89_dev *rtwdev)
-{
- /* Feature move to firmware */
-}
-
-static void rtw8852b_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state)
-{
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x31);
-
- /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */
- if (state)
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x179);
- else
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x20);
-
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
-}
-
-static void rtw8852b_btc_set_wl_lna2(struct rtw89_dev *rtwdev, u8 level)
-{
- switch (level) {
- case 0: /* default */
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
- break;
- case 1: /* Fix LNA2=5 */
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5);
- rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
- break;
- }
-}
-
-static void rtw8852b_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level)
-{
- struct rtw89_btc *btc = &rtwdev->btc;
-
- switch (level) {
- case 0: /* original */
- default:
- rtw8852b_ctrl_nbtg_bt_tx(rtwdev, false, RTW89_PHY_0);
- btc->dm.wl_lna2 = 0;
- break;
- case 1: /* for FDD free-run */
- rtw8852b_ctrl_nbtg_bt_tx(rtwdev, true, RTW89_PHY_0);
- btc->dm.wl_lna2 = 0;
- break;
- case 2: /* for BTG Co-Rx*/
- rtw8852b_ctrl_nbtg_bt_tx(rtwdev, false, RTW89_PHY_0);
- btc->dm.wl_lna2 = 1;
- break;
- }
-
- rtw8852b_btc_set_wl_lna2(rtwdev, btc->dm.wl_lna2);
-}
-
-static void rtw8852b_fill_freq_with_ppdu(struct rtw89_dev *rtwdev,
- struct rtw89_rx_phy_ppdu *phy_ppdu,
- struct ieee80211_rx_status *status)
-{
- u16 chan = phy_ppdu->chan_idx;
- enum nl80211_band band;
- u8 ch;
-
- if (chan == 0)
- return;
-
- rtw89_decode_chan_idx(rtwdev, chan, &ch, &band);
- status->freq = ieee80211_channel_to_frequency(ch, band);
- status->band = band;
-}
-
-static void rtw8852b_query_ppdu(struct rtw89_dev *rtwdev,
- struct rtw89_rx_phy_ppdu *phy_ppdu,
- struct ieee80211_rx_status *status)
-{
- u8 path;
- u8 *rx_power = phy_ppdu->rssi;
-
- status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A], rx_power[RF_PATH_B]));
- for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
- status->chains |= BIT(path);
- status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]);
- }
- if (phy_ppdu->valid)
- rtw8852b_fill_freq_with_ppdu(rtwdev, phy_ppdu, status);
-}
-
-static int rtw8852b_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
-{
- int ret;
-
- rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN,
- B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
- rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_REG_ZCDC_H_MASK, 0x1);
- rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
- rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
- rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
-
- ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xC7,
- FULL_BIT_MASK);
- if (ret)
- return ret;
-
- ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xC7,
- FULL_BIT_MASK);
- if (ret)
- return ret;
-
- rtw89_write8(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_XYN_CYCLE);
-
- return 0;
-}
-
-static int rtw8852b_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
-{
- u8 wl_rfc_s0;
- u8 wl_rfc_s1;
- int ret;
-
- rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
- B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
-
- ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, &wl_rfc_s0);
- if (ret)
- return ret;
- wl_rfc_s0 &= ~XTAL_SI_RF00S_EN;
- ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, wl_rfc_s0,
- FULL_BIT_MASK);
- if (ret)
- return ret;
-
- ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, &wl_rfc_s1);
- if (ret)
- return ret;
- wl_rfc_s1 &= ~XTAL_SI_RF10S_EN;
- ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, wl_rfc_s1,
- FULL_BIT_MASK);
- return ret;
-}
-
static const struct rtw89_chip_ops rtw8852b_chip_ops = {
- .enable_bb_rf = rtw8852b_mac_enable_bb_rf,
- .disable_bb_rf = rtw8852b_mac_disable_bb_rf,
+ .enable_bb_rf = rtw8852bx_mac_enable_bb_rf,
+ .disable_bb_rf = rtw8852bx_mac_disable_bb_rf,
.bb_preinit = NULL,
.bb_postinit = NULL,
.bb_reset = rtw8852b_bb_reset,
- .bb_sethw = rtw8852b_bb_sethw,
+ .bb_sethw = rtw8852bx_bb_sethw,
.read_rf = rtw89_phy_read_rf_v1,
.write_rf = rtw89_phy_write_rf_v1,
.set_channel = rtw8852b_set_channel,
.set_channel_help = rtw8852b_set_channel_help,
- .read_efuse = rtw8852b_read_efuse,
- .read_phycap = rtw8852b_read_phycap,
+ .read_efuse = rtw8852bx_read_efuse,
+ .read_phycap = rtw8852bx_read_phycap,
.fem_setup = NULL,
.rfe_gpio = NULL,
.rfk_hw_init = NULL,
@@ -2512,16 +750,19 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
.rfk_band_changed = rtw8852b_rfk_band_changed,
.rfk_scan = rtw8852b_rfk_scan,
.rfk_track = rtw8852b_rfk_track,
- .power_trim = rtw8852b_power_trim,
- .set_txpwr = rtw8852b_set_txpwr,
- .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl,
- .init_txpwr_unit = rtw8852b_init_txpwr_unit,
- .get_thermal = rtw8852b_get_thermal,
- .ctrl_btg_bt_rx = rtw8852b_ctrl_btg_bt_rx,
- .query_ppdu = rtw8852b_query_ppdu,
- .ctrl_nbtg_bt_tx = rtw8852b_ctrl_nbtg_bt_tx,
- .cfg_txrx_path = rtw8852b_bb_cfg_txrx_path,
- .set_txpwr_ul_tb_offset = rtw8852b_set_txpwr_ul_tb_offset,
+ .power_trim = rtw8852bx_power_trim,
+ .set_txpwr = rtw8852bx_set_txpwr,
+ .set_txpwr_ctrl = rtw8852bx_set_txpwr_ctrl,
+ .init_txpwr_unit = rtw8852bx_init_txpwr_unit,
+ .get_thermal = rtw8852bx_get_thermal,
+ .ctrl_btg_bt_rx = rtw8852bx_ctrl_btg_bt_rx,
+ .query_ppdu = rtw8852bx_query_ppdu,
+ .convert_rpl_to_rssi = rtw8852bx_convert_rpl_to_rssi,
+ .phy_rpt_to_rssi = NULL,
+ .ctrl_nbtg_bt_tx = rtw8852bx_ctrl_nbtg_bt_tx,
+ .cfg_txrx_path = rtw8852bx_bb_cfg_txrx_path,
+ .set_txpwr_ul_tb_offset = rtw8852bx_set_txpwr_ul_tb_offset,
+ .digital_pwr_comp = NULL,
.pwr_on_func = rtw8852b_pwr_on_func,
.pwr_off_func = rtw8852b_pwr_off_func,
.query_rxdesc = rtw89_core_query_rxdesc,
@@ -2535,18 +776,19 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
.h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl,
.h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl,
.h2c_ampdu_cmac_tbl = NULL,
+ .h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl,
.h2c_default_dmac_tbl = NULL,
.h2c_update_beacon = rtw89_fw_h2c_update_beacon,
.h2c_ba_cam = rtw89_fw_h2c_ba_cam,
.btc_set_rfe = rtw8852b_btc_set_rfe,
- .btc_init_cfg = rtw8852b_btc_init_cfg,
- .btc_set_wl_pri = rtw8852b_btc_set_wl_pri,
+ .btc_init_cfg = rtw8852bx_btc_init_cfg,
+ .btc_set_wl_pri = rtw8852bx_btc_set_wl_pri,
.btc_set_wl_txpwr_ctrl = rtw8852b_btc_set_wl_txpwr_ctrl,
- .btc_get_bt_rssi = rtw8852b_btc_get_bt_rssi,
- .btc_update_bt_cnt = rtw8852b_btc_update_bt_cnt,
- .btc_wl_s1_standby = rtw8852b_btc_wl_s1_standby,
- .btc_set_wl_rx_gain = rtw8852b_btc_set_wl_rx_gain,
+ .btc_get_bt_rssi = rtw8852bx_btc_get_bt_rssi,
+ .btc_update_bt_cnt = rtw8852bx_btc_update_bt_cnt,
+ .btc_wl_s1_standby = rtw8852bx_btc_wl_s1_standby,
+ .btc_set_wl_rx_gain = rtw8852bx_btc_set_wl_rx_gain,
.btc_set_policy = rtw89_btc_set_policy_v1,
};
@@ -2570,10 +812,11 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.try_ce_fw = true,
.bbmcu_nr = 0,
.needed_fw_elms = 0,
+ .fw_blacklist = &rtw89_fw_blacklist_default,
.fifo_size = 196608,
.small_fifo_size = true,
.dle_scc_rsvd_size = 98304,
- .max_amsdu_limit = 3500,
+ .max_amsdu_limit = 5000,
.dis_2g_40m_ul_ofdma = true,
.rsvd_ple_ofst = 0x2f800,
.hfc_param_ini = rtw8852b_hfc_param_ini_pcie,
@@ -2581,6 +824,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.wde_qempty_acq_grpnum = 4,
.wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000, 0xf000},
+ .thermal_th = {0x32, 0x35},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
.bb_table = &rtw89_8852b_phy_bb_table,
@@ -2591,21 +835,32 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.nctl_post_table = NULL,
.dflt_parms = &rtw89_8852b_dflt_parms,
.rfe_parms_conf = NULL,
+ .txpwr_factor_bb = 3,
.txpwr_factor_rf = 2,
.txpwr_factor_mac = 1,
.dig_table = NULL,
.dig_regs = &rtw8852b_dig_regs,
.tssi_dbw_table = NULL,
+ .support_macid_num = RTW89_MAX_MAC_ID_NUM,
+ .support_link_num = 0,
.support_chanctx_num = 0,
+ .support_rnr = false,
.support_bands = BIT(NL80211_BAND_2GHZ) |
BIT(NL80211_BAND_5GHZ),
.support_bandwidths = BIT(NL80211_CHAN_WIDTH_20) |
BIT(NL80211_CHAN_WIDTH_40) |
BIT(NL80211_CHAN_WIDTH_80),
.support_unii4 = true,
+ .support_ant_gain = true,
+ .support_tas = false,
+ .support_sar_by_ant = true,
.ul_tb_waveform_ctrl = true,
.ul_tb_pwr_diff = false,
+ .rx_freq_frome_ie = true,
.hw_sec_hdr = false,
+ .hw_mgmt_tx_encrypt = false,
+ .hw_tkip_crypto = false,
+ .hw_mlo_bmc_crypto = false,
.rf_path_num = 2,
.tx_nss = 2,
.rx_nss = 2,
@@ -2657,7 +912,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8},
.c2h_regs = rtw8852b_c2h_regs,
.page_regs = &rtw8852b_page_regs,
- .wow_reason_reg = R_AX_C2HREG_DATA3 + 3,
+ .wow_reason_reg = rtw8852b_wow_wakeup_regs,
.cfo_src_fd = true,
.cfo_hw_comp = true,
.dcfo_comp = &rtw8852b_dcfo_comp,
@@ -2668,6 +923,8 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.rrsr_cfgs = &rtw8852b_rrsr_cfgs,
.bss_clr_vld = {R_BSS_CLR_MAP_V1, B_BSS_CLR_MAP_VLD0},
.bss_clr_map_reg = R_BSS_CLR_MAP_V1,
+ .rfkill_init = &rtw8852b_rfkill_regs,
+ .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9},
.dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) |
BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) |
BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI),
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.h b/drivers/net/wireless/realtek/rtw89/rtw8852b.h
index 4f9b3d476879..5ec7180fd355 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.h
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.h
@@ -10,128 +10,6 @@
#define RF_PATH_NUM_8852B 2
#define BB_PATH_NUM_8852B 2
-enum rtw8852b_pmac_mode {
- NONE_TEST,
- PKTS_TX,
- PKTS_RX,
- CONT_TX
-};
-
-struct rtw8852b_u_efuse {
- u8 rsvd[0x88];
- u8 mac_addr[ETH_ALEN];
-};
-
-struct rtw8852b_e_efuse {
- u8 mac_addr[ETH_ALEN];
-};
-
-struct rtw8852b_tssi_offset {
- u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM];
- u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM];
- u8 rsvd[7];
- u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM];
-} __packed;
-
-struct rtw8852b_efuse {
- u8 rsvd[0x210];
- struct rtw8852b_tssi_offset path_a_tssi;
- u8 rsvd1[10];
- struct rtw8852b_tssi_offset path_b_tssi;
- u8 rsvd2[94];
- u8 channel_plan;
- u8 xtal_k;
- u8 rsvd3;
- u8 iqk_lck;
- u8 rsvd4[5];
- u8 reg_setting:2;
- u8 tx_diversity:1;
- u8 rx_diversity:2;
- u8 ac_mode:1;
- u8 module_type:2;
- u8 rsvd5;
- u8 shared_ant:1;
- u8 coex_type:3;
- u8 ant_iso:1;
- u8 radio_on_off:1;
- u8 rsvd6:2;
- u8 eeprom_version;
- u8 customer_id;
- u8 tx_bb_swing_2g;
- u8 tx_bb_swing_5g;
- u8 tx_cali_pwr_trk_mode;
- u8 trx_path_selection;
- u8 rfe_type;
- u8 country_code[2];
- u8 rsvd7[3];
- u8 path_a_therm;
- u8 path_b_therm;
- u8 rsvd8[2];
- u8 rx_gain_2g_ofdm;
- u8 rsvd9;
- u8 rx_gain_2g_cck;
- u8 rsvd10;
- u8 rx_gain_5g_low;
- u8 rsvd11;
- u8 rx_gain_5g_mid;
- u8 rsvd12;
- u8 rx_gain_5g_high;
- u8 rsvd13[35];
- u8 path_a_cck_pwr_idx[6];
- u8 path_a_bw40_1tx_pwr_idx[5];
- u8 path_a_ofdm_1tx_pwr_idx_diff:4;
- u8 path_a_bw20_1tx_pwr_idx_diff:4;
- u8 path_a_bw20_2tx_pwr_idx_diff:4;
- u8 path_a_bw40_2tx_pwr_idx_diff:4;
- u8 path_a_cck_2tx_pwr_idx_diff:4;
- u8 path_a_ofdm_2tx_pwr_idx_diff:4;
- u8 rsvd14[0xf2];
- union {
- struct rtw8852b_u_efuse u;
- struct rtw8852b_e_efuse e;
- };
-} __packed;
-
-struct rtw8852b_bb_pmac_info {
- u8 en_pmac_tx:1;
- u8 is_cck:1;
- u8 mode:3;
- u8 rsvd:3;
- u16 tx_cnt;
- u16 period;
- u16 tx_time;
- u8 duty_cycle;
-};
-
-struct rtw8852b_bb_tssi_bak {
- u8 tx_path;
- u8 rx_path;
- u32 p0_rfmode;
- u32 p0_rfmode_ftm;
- u32 p1_rfmode;
- u32 p1_rfmode_ftm;
- s16 tx_pwr; /* S9 */
-};
-
extern const struct rtw89_chip_info rtw8852b_chip_info;
-void rtw8852b_bb_set_plcp_tx(struct rtw89_dev *rtwdev);
-void rtw8852b_bb_set_pmac_tx(struct rtw89_dev *rtwdev,
- struct rtw8852b_bb_pmac_info *tx_info,
- enum rtw89_phy_idx idx);
-void rtw8852b_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable,
- u16 tx_cnt, u16 period, u16 tx_time,
- enum rtw89_phy_idx idx);
-void rtw8852b_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm,
- enum rtw89_phy_idx idx);
-void rtw8852b_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path);
-void rtw8852b_bb_ctrl_rx_path(struct rtw89_dev *rtwdev,
- enum rtw89_rf_path_bit rx_path);
-void rtw8852b_bb_tx_mode_switch(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx idx, u8 mode);
-void rtw8852b_bb_backup_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx,
- struct rtw8852b_bb_tssi_bak *bak);
-void rtw8852b_bb_restore_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx,
- const struct rtw8852b_bb_tssi_bak *bak);
-
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c
new file mode 100644
index 000000000000..0cf03f18cbb1
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c
@@ -0,0 +1,2104 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#include "coex.h"
+#include "debug.h"
+#include "mac.h"
+#include "phy.h"
+#include "reg.h"
+#include "rtw8852b_common.h"
+#include "sar.h"
+#include "util.h"
+
+static const struct rtw89_reg3_def rtw8852bx_pmac_ht20_mcs7_tbl[] = {
+ {0x4580, 0x0000ffff, 0x0},
+ {0x4580, 0xffff0000, 0x0},
+ {0x4584, 0x0000ffff, 0x0},
+ {0x4584, 0xffff0000, 0x0},
+ {0x4580, 0x0000ffff, 0x1},
+ {0x4578, 0x00ffffff, 0x2018b},
+ {0x4570, 0x03ffffff, 0x7},
+ {0x4574, 0x03ffffff, 0x32407},
+ {0x45b8, 0x00000010, 0x0},
+ {0x45b8, 0x00000100, 0x0},
+ {0x45b8, 0x00000080, 0x0},
+ {0x45b8, 0x00000008, 0x0},
+ {0x45a0, 0x0000ff00, 0x0},
+ {0x45a0, 0xff000000, 0x1},
+ {0x45a4, 0x0000ff00, 0x2},
+ {0x45a4, 0xff000000, 0x3},
+ {0x45b8, 0x00000020, 0x0},
+ {0x4568, 0xe0000000, 0x0},
+ {0x45b8, 0x00000002, 0x1},
+ {0x456c, 0xe0000000, 0x0},
+ {0x45b4, 0x00006000, 0x0},
+ {0x45b4, 0x00001800, 0x1},
+ {0x45b8, 0x00000040, 0x0},
+ {0x45b8, 0x00000004, 0x0},
+ {0x45b8, 0x00000200, 0x0},
+ {0x4598, 0xf8000000, 0x0},
+ {0x45b8, 0x00100000, 0x0},
+ {0x45a8, 0x00000fc0, 0x0},
+ {0x45b8, 0x00200000, 0x0},
+ {0x45b0, 0x00000038, 0x0},
+ {0x45b0, 0x000001c0, 0x0},
+ {0x45a0, 0x000000ff, 0x0},
+ {0x45b8, 0x00400000, 0x0},
+ {0x4590, 0x000007ff, 0x0},
+ {0x45b0, 0x00000e00, 0x0},
+ {0x45ac, 0x0000001f, 0x0},
+ {0x45b8, 0x00800000, 0x0},
+ {0x45a8, 0x0003f000, 0x0},
+ {0x45b8, 0x01000000, 0x0},
+ {0x45b0, 0x00007000, 0x0},
+ {0x45b0, 0x00038000, 0x0},
+ {0x45a0, 0x00ff0000, 0x0},
+ {0x45b8, 0x02000000, 0x0},
+ {0x4590, 0x003ff800, 0x0},
+ {0x45b0, 0x001c0000, 0x0},
+ {0x45ac, 0x000003e0, 0x0},
+ {0x45b8, 0x04000000, 0x0},
+ {0x45a8, 0x00fc0000, 0x0},
+ {0x45b8, 0x08000000, 0x0},
+ {0x45b0, 0x00e00000, 0x0},
+ {0x45b0, 0x07000000, 0x0},
+ {0x45a4, 0x000000ff, 0x0},
+ {0x45b8, 0x10000000, 0x0},
+ {0x4594, 0x000007ff, 0x0},
+ {0x45b0, 0x38000000, 0x0},
+ {0x45ac, 0x00007c00, 0x0},
+ {0x45b8, 0x20000000, 0x0},
+ {0x45a8, 0x3f000000, 0x0},
+ {0x45b8, 0x40000000, 0x0},
+ {0x45b4, 0x00000007, 0x0},
+ {0x45b4, 0x00000038, 0x0},
+ {0x45a4, 0x00ff0000, 0x0},
+ {0x45b8, 0x80000000, 0x0},
+ {0x4594, 0x003ff800, 0x0},
+ {0x45b4, 0x000001c0, 0x0},
+ {0x4598, 0xf8000000, 0x0},
+ {0x45b8, 0x00100000, 0x0},
+ {0x45a8, 0x00000fc0, 0x7},
+ {0x45b8, 0x00200000, 0x0},
+ {0x45b0, 0x00000038, 0x0},
+ {0x45b0, 0x000001c0, 0x0},
+ {0x45a0, 0x000000ff, 0x0},
+ {0x45b4, 0x06000000, 0x0},
+ {0x45b0, 0x00000007, 0x0},
+ {0x45b8, 0x00080000, 0x0},
+ {0x45a8, 0x0000003f, 0x0},
+ {0x457c, 0xffe00000, 0x1},
+ {0x4530, 0xffffffff, 0x0},
+ {0x4588, 0x00003fff, 0x0},
+ {0x4598, 0x000001ff, 0x0},
+ {0x4534, 0xffffffff, 0x0},
+ {0x4538, 0xffffffff, 0x0},
+ {0x453c, 0xffffffff, 0x0},
+ {0x4588, 0x0fffc000, 0x0},
+ {0x4598, 0x0003fe00, 0x0},
+ {0x4540, 0xffffffff, 0x0},
+ {0x4544, 0xffffffff, 0x0},
+ {0x4548, 0xffffffff, 0x0},
+ {0x458c, 0x00003fff, 0x0},
+ {0x4598, 0x07fc0000, 0x0},
+ {0x454c, 0xffffffff, 0x0},
+ {0x4550, 0xffffffff, 0x0},
+ {0x4554, 0xffffffff, 0x0},
+ {0x458c, 0x0fffc000, 0x0},
+ {0x459c, 0x000001ff, 0x0},
+ {0x4558, 0xffffffff, 0x0},
+ {0x455c, 0xffffffff, 0x0},
+ {0x4530, 0xffffffff, 0x4e790001},
+ {0x4588, 0x00003fff, 0x0},
+ {0x4598, 0x000001ff, 0x1},
+ {0x4534, 0xffffffff, 0x0},
+ {0x4538, 0xffffffff, 0x4b},
+ {0x45ac, 0x38000000, 0x7},
+ {0x4588, 0xf0000000, 0x0},
+ {0x459c, 0x7e000000, 0x0},
+ {0x45b8, 0x00040000, 0x0},
+ {0x45b8, 0x00020000, 0x0},
+ {0x4590, 0xffc00000, 0x0},
+ {0x45b8, 0x00004000, 0x0},
+ {0x4578, 0xff000000, 0x0},
+ {0x45b8, 0x00000400, 0x0},
+ {0x45b8, 0x00000800, 0x0},
+ {0x45b8, 0x00001000, 0x0},
+ {0x45b8, 0x00002000, 0x0},
+ {0x45b4, 0x00018000, 0x0},
+ {0x45ac, 0x07800000, 0x0},
+ {0x45b4, 0x00000600, 0x2},
+ {0x459c, 0x0001fe00, 0x80},
+ {0x45ac, 0x00078000, 0x3},
+ {0x459c, 0x01fe0000, 0x1},
+};
+
+static const struct rtw89_reg3_def rtw8852bx_btc_preagc_en_defs[] = {
+ {0x46D0, GENMASK(1, 0), 0x3},
+ {0x4790, GENMASK(1, 0), 0x3},
+ {0x4AD4, GENMASK(31, 0), 0xf},
+ {0x4AE0, GENMASK(31, 0), 0xf},
+ {0x4688, GENMASK(31, 24), 0x80},
+ {0x476C, GENMASK(31, 24), 0x80},
+ {0x4694, GENMASK(7, 0), 0x80},
+ {0x4694, GENMASK(15, 8), 0x80},
+ {0x4778, GENMASK(7, 0), 0x80},
+ {0x4778, GENMASK(15, 8), 0x80},
+ {0x4AE4, GENMASK(23, 0), 0x780D1E},
+ {0x4AEC, GENMASK(23, 0), 0x780D1E},
+ {0x469C, GENMASK(31, 26), 0x34},
+ {0x49F0, GENMASK(31, 26), 0x34},
+};
+
+static DECLARE_PHY_REG3_TBL(rtw8852bx_btc_preagc_en_defs);
+
+static const struct rtw89_reg3_def rtw8852bx_btc_preagc_dis_defs[] = {
+ {0x46D0, GENMASK(1, 0), 0x0},
+ {0x4790, GENMASK(1, 0), 0x0},
+ {0x4AD4, GENMASK(31, 0), 0x60},
+ {0x4AE0, GENMASK(31, 0), 0x60},
+ {0x4688, GENMASK(31, 24), 0x1a},
+ {0x476C, GENMASK(31, 24), 0x1a},
+ {0x4694, GENMASK(7, 0), 0x2a},
+ {0x4694, GENMASK(15, 8), 0x2a},
+ {0x4778, GENMASK(7, 0), 0x2a},
+ {0x4778, GENMASK(15, 8), 0x2a},
+ {0x4AE4, GENMASK(23, 0), 0x79E99E},
+ {0x4AEC, GENMASK(23, 0), 0x79E99E},
+ {0x469C, GENMASK(31, 26), 0x26},
+ {0x49F0, GENMASK(31, 26), 0x26},
+};
+
+static DECLARE_PHY_REG3_TBL(rtw8852bx_btc_preagc_dis_defs);
+
+static void rtw8852be_efuse_parsing(struct rtw89_efuse *efuse,
+ struct rtw8852bx_efuse *map)
+{
+ ether_addr_copy(efuse->addr, map->e.mac_addr);
+ efuse->rfe_type = map->rfe_type;
+ efuse->xtal_cap = map->xtal_k;
+}
+
+static void rtw8852bx_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
+ struct rtw8852bx_efuse *map)
+{
+ struct rtw89_tssi_info *tssi = &rtwdev->tssi;
+ struct rtw8852bx_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi};
+ u8 i, j;
+
+ tssi->thermal[RF_PATH_A] = map->path_a_therm;
+ tssi->thermal[RF_PATH_B] = map->path_b_therm;
+
+ for (i = 0; i < RF_PATH_NUM_8852BX; i++) {
+ memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi,
+ sizeof(ofst[i]->cck_tssi));
+
+ for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++)
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n",
+ i, j, tssi->tssi_cck[i][j]);
+
+ memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi,
+ sizeof(ofst[i]->bw40_tssi));
+ memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM,
+ ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g));
+
+ for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++)
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n",
+ i, j, tssi->tssi_mcs[i][j]);
+ }
+}
+
+static bool _decode_efuse_gain(u8 data, s8 *high, s8 *low)
+{
+ if (high)
+ *high = sign_extend32(FIELD_GET(GENMASK(7, 4), data), 3);
+ if (low)
+ *low = sign_extend32(FIELD_GET(GENMASK(3, 0), data), 3);
+
+ return data != 0xff;
+}
+
+static void rtw8852bx_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev,
+ struct rtw8852bx_efuse *map)
+{
+ struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
+ bool valid = false;
+
+ valid |= _decode_efuse_gain(map->rx_gain_2g_cck,
+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_CCK],
+ &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_CCK]);
+ valid |= _decode_efuse_gain(map->rx_gain_2g_ofdm,
+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_OFDM],
+ &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_OFDM]);
+ valid |= _decode_efuse_gain(map->rx_gain_5g_low,
+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_LOW],
+ &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_LOW]);
+ valid |= _decode_efuse_gain(map->rx_gain_5g_mid,
+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_MID],
+ &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_MID]);
+ valid |= _decode_efuse_gain(map->rx_gain_5g_high,
+ &gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_HIGH],
+ &gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_HIGH]);
+
+ gain->offset_valid = valid;
+}
+
+static int __rtw8852bx_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
+ enum rtw89_efuse_block block)
+{
+ struct rtw89_efuse *efuse = &rtwdev->efuse;
+ struct rtw8852bx_efuse *map;
+
+ map = (struct rtw8852bx_efuse *)log_map;
+
+ efuse->country_code[0] = map->country_code[0];
+ efuse->country_code[1] = map->country_code[1];
+ rtw8852bx_efuse_parsing_tssi(rtwdev, map);
+ rtw8852bx_efuse_parsing_gain_offset(rtwdev, map);
+
+ switch (rtwdev->hci.type) {
+ case RTW89_HCI_TYPE_PCIE:
+ rtw8852be_efuse_parsing(efuse, map);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type);
+
+ return 0;
+}
+
+static void rtw8852bx_phycap_parsing_power_cal(struct rtw89_dev *rtwdev, u8 *phycap_map)
+{
+#define PWR_K_CHK_OFFSET 0x5E9
+#define PWR_K_CHK_VALUE 0xAA
+ u32 offset = PWR_K_CHK_OFFSET - rtwdev->chip->phycap_addr;
+
+ if (phycap_map[offset] == PWR_K_CHK_VALUE)
+ rtwdev->efuse.power_k_valid = true;
+}
+
+static void rtw8852bx_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map)
+{
+ struct rtw89_tssi_info *tssi = &rtwdev->tssi;
+ static const u32 tssi_trim_addr[RF_PATH_NUM_8852BX] = {0x5D6, 0x5AB};
+ u32 addr = rtwdev->chip->phycap_addr;
+ bool pg = false;
+ u32 ofst;
+ u8 i, j;
+
+ for (i = 0; i < RF_PATH_NUM_8852BX; i++) {
+ for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) {
+ /* addrs are in decreasing order */
+ ofst = tssi_trim_addr[i] - addr - j;
+ tssi->tssi_trim[i][j] = phycap_map[ofst];
+
+ if (phycap_map[ofst] != 0xff)
+ pg = true;
+ }
+ }
+
+ if (!pg) {
+ memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim));
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI][TRIM] no PG, set all trim info to 0\n");
+ }
+
+ for (i = 0; i < RF_PATH_NUM_8852BX; i++)
+ for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++)
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n",
+ i, j, tssi->tssi_trim[i][j],
+ tssi_trim_addr[i] - j);
+}
+
+static void rtw8852bx_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev,
+ u8 *phycap_map)
+{
+ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
+ static const u32 thm_trim_addr[RF_PATH_NUM_8852BX] = {0x5DF, 0x5DC};
+ u32 addr = rtwdev->chip->phycap_addr;
+ u8 i;
+
+ for (i = 0; i < RF_PATH_NUM_8852BX; i++) {
+ info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr];
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n",
+ i, info->thermal_trim[i]);
+
+ if (info->thermal_trim[i] != 0xff)
+ info->pg_thermal_trim = true;
+ }
+}
+
+static void rtw8852bx_thermal_trim(struct rtw89_dev *rtwdev)
+{
+#define __thm_setting(raw) \
+({ \
+ u8 __v = (raw); \
+ ((__v & 0x1) << 3) | ((__v & 0x1f) >> 1); \
+})
+ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
+ u8 i, val;
+
+ if (!info->pg_thermal_trim) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[THERMAL][TRIM] no PG, do nothing\n");
+
+ return;
+ }
+
+ for (i = 0; i < RF_PATH_NUM_8852BX; i++) {
+ val = __thm_setting(info->thermal_trim[i]);
+ rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n",
+ i, val);
+ }
+#undef __thm_setting
+}
+
+static void rtw8852bx_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev,
+ u8 *phycap_map)
+{
+ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
+ static const u32 pabias_trim_addr[RF_PATH_NUM_8852BX] = {0x5DE, 0x5DB};
+ u32 addr = rtwdev->chip->phycap_addr;
+ u8 i;
+
+ for (i = 0; i < RF_PATH_NUM_8852BX; i++) {
+ info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr];
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n",
+ i, info->pa_bias_trim[i]);
+
+ if (info->pa_bias_trim[i] != 0xff)
+ info->pg_pa_bias_trim = true;
+ }
+}
+
+static void rtw8852bx_pa_bias_trim(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
+ u8 pabias_2g, pabias_5g;
+ u8 i;
+
+ if (!info->pg_pa_bias_trim) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[PA_BIAS][TRIM] no PG, do nothing\n");
+
+ return;
+ }
+
+ for (i = 0; i < RF_PATH_NUM_8852BX; i++) {
+ pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]);
+ pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n",
+ i, pabias_2g, pabias_5g);
+
+ rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g);
+ rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g);
+ }
+}
+
+static void rtw8852bx_phycap_parsing_gain_comp(struct rtw89_dev *rtwdev, u8 *phycap_map)
+{
+ static const u32 comp_addrs[][RTW89_SUBBAND_2GHZ_5GHZ_NR] = {
+ {0x5BB, 0x5BA, 0, 0x5B9, 0x5B8},
+ {0x590, 0x58F, 0, 0x58E, 0x58D},
+ };
+ struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
+ u32 phycap_addr = rtwdev->chip->phycap_addr;
+ bool valid = false;
+ int path, i;
+ u8 data;
+
+ for (path = 0; path < 2; path++)
+ for (i = 0; i < RTW89_SUBBAND_2GHZ_5GHZ_NR; i++) {
+ if (comp_addrs[path][i] == 0)
+ continue;
+
+ data = phycap_map[comp_addrs[path][i] - phycap_addr];
+ valid |= _decode_efuse_gain(data, NULL,
+ &gain->comp[path][i]);
+ }
+
+ gain->comp_valid = valid;
+}
+
+static int __rtw8852bx_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map)
+{
+ rtw8852bx_phycap_parsing_power_cal(rtwdev, phycap_map);
+ rtw8852bx_phycap_parsing_tssi(rtwdev, phycap_map);
+ rtw8852bx_phycap_parsing_thermal_trim(rtwdev, phycap_map);
+ rtw8852bx_phycap_parsing_pa_bias_trim(rtwdev, phycap_map);
+ rtw8852bx_phycap_parsing_gain_comp(rtwdev, phycap_map);
+
+ return 0;
+}
+
+static void __rtw8852bx_power_trim(struct rtw89_dev *rtwdev)
+{
+ rtw8852bx_thermal_trim(rtwdev);
+ rtw8852bx_pa_bias_trim(rtwdev);
+}
+
+static void __rtw8852bx_set_channel_mac(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ u8 mac_idx)
+{
+ u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_AX_WMAC_RFMOD, mac_idx);
+ u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, mac_idx);
+ u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXRATE_CHK, mac_idx);
+ u8 txsc20 = 0, txsc40 = 0;
+
+ switch (chan->band_width) {
+ case RTW89_CHANNEL_WIDTH_80:
+ txsc40 = rtw89_phy_get_txsc(rtwdev, chan, RTW89_CHANNEL_WIDTH_40);
+ fallthrough;
+ case RTW89_CHANNEL_WIDTH_40:
+ txsc20 = rtw89_phy_get_txsc(rtwdev, chan, RTW89_CHANNEL_WIDTH_20);
+ break;
+ default:
+ break;
+ }
+
+ switch (chan->band_width) {
+ case RTW89_CHANNEL_WIDTH_80:
+ rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(1));
+ rtw89_write32(rtwdev, sub_carr, txsc20 | (txsc40 << 4));
+ break;
+ case RTW89_CHANNEL_WIDTH_40:
+ rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(0));
+ rtw89_write32(rtwdev, sub_carr, txsc20);
+ break;
+ case RTW89_CHANNEL_WIDTH_20:
+ rtw89_write8_clr(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK);
+ rtw89_write32(rtwdev, sub_carr, 0);
+ break;
+ default:
+ break;
+ }
+
+ if (chan->channel > 14) {
+ rtw89_write8_clr(rtwdev, chk_rate, B_AX_BAND_MODE);
+ rtw89_write8_set(rtwdev, chk_rate,
+ B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6);
+ } else {
+ rtw89_write8_set(rtwdev, chk_rate, B_AX_BAND_MODE);
+ rtw89_write8_clr(rtwdev, chk_rate,
+ B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6);
+ }
+}
+
+static const u32 rtw8852bx_sco_barker_threshold[14] = {
+ 0x1cfea, 0x1d0e1, 0x1d1d7, 0x1d2cd, 0x1d3c3, 0x1d4b9, 0x1d5b0, 0x1d6a6,
+ 0x1d79c, 0x1d892, 0x1d988, 0x1da7f, 0x1db75, 0x1ddc4
+};
+
+static const u32 rtw8852bx_sco_cck_threshold[14] = {
+ 0x27de3, 0x27f35, 0x28088, 0x281da, 0x2832d, 0x2847f, 0x285d2, 0x28724,
+ 0x28877, 0x289c9, 0x28b1c, 0x28c6e, 0x28dc1, 0x290ed
+};
+
+static void rtw8852bx_ctrl_sco_cck(struct rtw89_dev *rtwdev, u8 primary_ch)
+{
+ u8 ch_element = primary_ch - 1;
+
+ rtw89_phy_write32_mask(rtwdev, R_RXSCOBC, B_RXSCOBC_TH,
+ rtw8852bx_sco_barker_threshold[ch_element]);
+ rtw89_phy_write32_mask(rtwdev, R_RXSCOCCK, B_RXSCOCCK_TH,
+ rtw8852bx_sco_cck_threshold[ch_element]);
+}
+
+static u8 rtw8852bx_sco_mapping(u8 central_ch)
+{
+ if (central_ch == 1)
+ return 109;
+ else if (central_ch >= 2 && central_ch <= 6)
+ return 108;
+ else if (central_ch >= 7 && central_ch <= 10)
+ return 107;
+ else if (central_ch >= 11 && central_ch <= 14)
+ return 106;
+ else if (central_ch == 36 || central_ch == 38)
+ return 51;
+ else if (central_ch >= 40 && central_ch <= 58)
+ return 50;
+ else if (central_ch >= 60 && central_ch <= 64)
+ return 49;
+ else if (central_ch == 100 || central_ch == 102)
+ return 48;
+ else if (central_ch >= 104 && central_ch <= 126)
+ return 47;
+ else if (central_ch >= 128 && central_ch <= 151)
+ return 46;
+ else if (central_ch >= 153 && central_ch <= 177)
+ return 45;
+ else
+ return 0;
+}
+
+struct rtw8852bx_bb_gain {
+ u32 gain_g[BB_PATH_NUM_8852BX];
+ u32 gain_a[BB_PATH_NUM_8852BX];
+ u32 gain_mask;
+};
+
+static const struct rtw8852bx_bb_gain bb_gain_lna[LNA_GAIN_NUM] = {
+ { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740},
+ .gain_mask = 0x00ff0000 },
+ { .gain_g = {0x4678, 0x475C}, .gain_a = {0x45DC, 0x4740},
+ .gain_mask = 0xff000000 },
+ { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
+ .gain_mask = 0x000000ff },
+ { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
+ .gain_mask = 0x0000ff00 },
+ { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
+ .gain_mask = 0x00ff0000 },
+ { .gain_g = {0x467C, 0x4760}, .gain_a = {0x4660, 0x4744},
+ .gain_mask = 0xff000000 },
+ { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
+ .gain_mask = 0x000000ff },
+};
+
+static const struct rtw8852bx_bb_gain bb_gain_tia[TIA_GAIN_NUM] = {
+ { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
+ .gain_mask = 0x00ff0000 },
+ { .gain_g = {0x4680, 0x4764}, .gain_a = {0x4664, 0x4748},
+ .gain_mask = 0xff000000 },
+};
+
+static void rtw8852bx_set_gain_error(struct rtw89_dev *rtwdev,
+ enum rtw89_subband subband,
+ enum rtw89_rf_path path)
+{
+ const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax;
+ u8 gain_band = rtw89_subband_to_bb_gain_band(subband);
+ s32 val;
+ u32 reg;
+ u32 mask;
+ int i;
+
+ for (i = 0; i < LNA_GAIN_NUM; i++) {
+ if (subband == RTW89_CH_2G)
+ reg = bb_gain_lna[i].gain_g[path];
+ else
+ reg = bb_gain_lna[i].gain_a[path];
+
+ mask = bb_gain_lna[i].gain_mask;
+ val = gain->lna_gain[gain_band][path][i];
+ rtw89_phy_write32_mask(rtwdev, reg, mask, val);
+ }
+
+ for (i = 0; i < TIA_GAIN_NUM; i++) {
+ if (subband == RTW89_CH_2G)
+ reg = bb_gain_tia[i].gain_g[path];
+ else
+ reg = bb_gain_tia[i].gain_a[path];
+
+ mask = bb_gain_tia[i].gain_mask;
+ val = gain->tia_gain[gain_band][path][i];
+ rtw89_phy_write32_mask(rtwdev, reg, mask, val);
+ }
+}
+
+static void rtw8852bt_ext_loss_avg_update(struct rtw89_dev *rtwdev,
+ s8 ext_loss_a, s8 ext_loss_b)
+{
+ s8 ext_loss_avg;
+ u64 linear;
+ u8 pwrofst;
+
+ if (ext_loss_a == ext_loss_b) {
+ ext_loss_avg = ext_loss_a;
+ } else {
+ linear = rtw89_db_to_linear(abs(ext_loss_a - ext_loss_b)) + 1;
+ linear /= 2;
+ ext_loss_avg = rtw89_linear_to_db(linear);
+ ext_loss_avg += min(ext_loss_a, ext_loss_b);
+ }
+
+ pwrofst = max(DIV_ROUND_CLOSEST(ext_loss_avg, 4) + 16, EDCCA_PWROFST_DEFAULT);
+
+ rtw89_phy_write32_mask(rtwdev, R_PWOFST, B_PWOFST, pwrofst);
+}
+
+static void rtw8852bx_set_gain_offset(struct rtw89_dev *rtwdev,
+ enum rtw89_subband subband,
+ enum rtw89_phy_idx phy_idx)
+{
+ static const u32 gain_err_addr[2] = {R_P0_AGC_RSVD, R_P1_AGC_RSVD};
+ static const u32 rssi_ofst_addr[2] = {R_PATH0_G_TIA1_LNA6_OP1DB_V1,
+ R_PATH1_G_TIA1_LNA6_OP1DB_V1};
+ struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_phy_efuse_gain *efuse_gain = &rtwdev->efuse_gain;
+ enum rtw89_gain_offset gain_ofdm_band;
+ s8 ext_loss_a = 0, ext_loss_b = 0;
+ s32 offset_a, offset_b;
+ s32 offset_ofdm, offset_cck;
+ s32 tmp;
+ u8 path;
+
+ if (!efuse_gain->comp_valid)
+ goto next;
+
+ for (path = RF_PATH_A; path < BB_PATH_NUM_8852BX; path++) {
+ tmp = efuse_gain->comp[path][subband];
+ tmp = clamp_t(s32, tmp << 2, S8_MIN, S8_MAX);
+ rtw89_phy_write32_mask(rtwdev, gain_err_addr[path], MASKBYTE0, tmp);
+ }
+
+next:
+ if (!efuse_gain->offset_valid)
+ goto ext_loss;
+
+ gain_ofdm_band = rtw89_subband_to_gain_offset_band_of_ofdm(subband);
+
+ offset_a = -efuse_gain->offset[RF_PATH_A][gain_ofdm_band];
+ offset_b = -efuse_gain->offset[RF_PATH_B][gain_ofdm_band];
+
+ tmp = -((offset_a << 2) + (efuse_gain->offset_base[RTW89_PHY_0] >> 2));
+ tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX);
+ rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[RF_PATH_A], B_PATH0_R_G_OFST_MASK, tmp);
+
+ tmp = -((offset_b << 2) + (efuse_gain->offset_base[RTW89_PHY_0] >> 2));
+ tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX);
+ rtw89_phy_write32_mask(rtwdev, rssi_ofst_addr[RF_PATH_B], B_PATH0_R_G_OFST_MASK, tmp);
+
+ if (hal->antenna_rx == RF_B) {
+ offset_ofdm = -efuse_gain->offset[RF_PATH_B][gain_ofdm_band];
+ offset_cck = -efuse_gain->offset[RF_PATH_B][0];
+ } else {
+ offset_ofdm = -efuse_gain->offset[RF_PATH_A][gain_ofdm_band];
+ offset_cck = -efuse_gain->offset[RF_PATH_A][0];
+ }
+
+ tmp = (offset_ofdm << 4) + efuse_gain->offset_base[RTW89_PHY_0];
+ tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX);
+ rtw89_phy_write32_idx(rtwdev, R_P0_RPL1, B_P0_RPL1_BIAS_MASK, tmp, phy_idx);
+
+ tmp = (offset_ofdm << 4) + efuse_gain->rssi_base[RTW89_PHY_0];
+ tmp = clamp_t(s32, tmp, S8_MIN, S8_MAX);
+ rtw89_phy_write32_idx(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK, tmp, phy_idx);
+
+ if (subband == RTW89_CH_2G) {
+ tmp = (offset_cck << 3) + (efuse_gain->offset_base[RTW89_PHY_0] >> 1);
+ tmp = clamp_t(s32, tmp, S8_MIN >> 1, S8_MAX >> 1);
+ rtw89_phy_write32_mask(rtwdev, R_RX_RPL_OFST,
+ B_RX_RPL_OFST_CCK_MASK, tmp);
+ }
+
+ ext_loss_a = (offset_a << 2) + (efuse_gain->offset_base[RTW89_PHY_0] >> 2);
+ ext_loss_b = (offset_b << 2) + (efuse_gain->offset_base[RTW89_PHY_0] >> 2);
+
+ext_loss:
+ if (rtwdev->chip->chip_id == RTL8852BT)
+ rtw8852bt_ext_loss_avg_update(rtwdev, ext_loss_a, ext_loss_b);
+}
+
+static
+void rtw8852bx_set_rxsc_rpl_comp(struct rtw89_dev *rtwdev, enum rtw89_subband subband)
+{
+ const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax;
+ u8 band = rtw89_subband_to_bb_gain_band(subband);
+ u32 val;
+
+ val = u32_encode_bits((gain->rpl_ofst_20[band][RF_PATH_A] +
+ gain->rpl_ofst_20[band][RF_PATH_B]) >> 1, B_P0_RPL1_20_MASK) |
+ u32_encode_bits((gain->rpl_ofst_40[band][RF_PATH_A][0] +
+ gain->rpl_ofst_40[band][RF_PATH_B][0]) >> 1, B_P0_RPL1_40_MASK) |
+ u32_encode_bits((gain->rpl_ofst_40[band][RF_PATH_A][1] +
+ gain->rpl_ofst_40[band][RF_PATH_B][1]) >> 1, B_P0_RPL1_41_MASK);
+ val >>= B_P0_RPL1_SHIFT;
+ rtw89_phy_write32_mask(rtwdev, R_P0_RPL1, B_P0_RPL1_MASK, val);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_MASK, val);
+
+ val = u32_encode_bits((gain->rpl_ofst_40[band][RF_PATH_A][2] +
+ gain->rpl_ofst_40[band][RF_PATH_B][2]) >> 1, B_P0_RTL2_42_MASK) |
+ u32_encode_bits((gain->rpl_ofst_80[band][RF_PATH_A][0] +
+ gain->rpl_ofst_80[band][RF_PATH_B][0]) >> 1, B_P0_RTL2_80_MASK) |
+ u32_encode_bits((gain->rpl_ofst_80[band][RF_PATH_A][1] +
+ gain->rpl_ofst_80[band][RF_PATH_B][1]) >> 1, B_P0_RTL2_81_MASK) |
+ u32_encode_bits((gain->rpl_ofst_80[band][RF_PATH_A][10] +
+ gain->rpl_ofst_80[band][RF_PATH_B][10]) >> 1, B_P0_RTL2_8A_MASK);
+ rtw89_phy_write32(rtwdev, R_P0_RPL2, val);
+ rtw89_phy_write32(rtwdev, R_P1_RPL2, val);
+
+ val = u32_encode_bits((gain->rpl_ofst_80[band][RF_PATH_A][2] +
+ gain->rpl_ofst_80[band][RF_PATH_B][2]) >> 1, B_P0_RTL3_82_MASK) |
+ u32_encode_bits((gain->rpl_ofst_80[band][RF_PATH_A][3] +
+ gain->rpl_ofst_80[band][RF_PATH_B][3]) >> 1, B_P0_RTL3_83_MASK) |
+ u32_encode_bits((gain->rpl_ofst_80[band][RF_PATH_A][4] +
+ gain->rpl_ofst_80[band][RF_PATH_B][4]) >> 1, B_P0_RTL3_84_MASK) |
+ u32_encode_bits((gain->rpl_ofst_80[band][RF_PATH_A][9] +
+ gain->rpl_ofst_80[band][RF_PATH_B][9]) >> 1, B_P0_RTL3_89_MASK);
+ rtw89_phy_write32(rtwdev, R_P0_RPL3, val);
+ rtw89_phy_write32(rtwdev, R_P1_RPL3, val);
+}
+
+static void rtw8852bx_ctrl_ch(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+{
+ u8 central_ch = chan->channel;
+ u8 subband = chan->subband_type;
+ u8 sco_comp;
+ bool is_2g = central_ch <= 14;
+
+ /* Path A */
+ if (is_2g)
+ rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1,
+ B_PATH0_BAND_SEL_MSK_V1, 1, phy_idx);
+ else
+ rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1,
+ B_PATH0_BAND_SEL_MSK_V1, 0, phy_idx);
+
+ /* Path B */
+ if (is_2g)
+ rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1,
+ B_PATH1_BAND_SEL_MSK_V1, 1, phy_idx);
+ else
+ rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1,
+ B_PATH1_BAND_SEL_MSK_V1, 0, phy_idx);
+
+ /* SCO compensate FC setting */
+ sco_comp = rtw8852bx_sco_mapping(central_ch);
+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_INV, sco_comp, phy_idx);
+
+ if (chan->band_type == RTW89_BAND_6G)
+ return;
+
+ /* CCK parameters */
+ if (central_ch == 14) {
+ rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, 0x3b13ff);
+ rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, 0x1c42de);
+ rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfdb0ad);
+ rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, 0xf60f6e);
+ rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, 0xfd8f92);
+ rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0x2d011);
+ rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0x1c02c);
+ rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, 0xfff00a);
+ } else {
+ rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, 0x3d23ff);
+ rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, 0x29b354);
+ rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfc1c8);
+ rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, 0xfdb053);
+ rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, 0xf86f9a);
+ rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0xfaef92);
+ rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0xfe5fcc);
+ rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, 0xffdff5);
+ }
+
+ rtw8852bx_set_gain_error(rtwdev, subband, RF_PATH_A);
+ rtw8852bx_set_gain_error(rtwdev, subband, RF_PATH_B);
+ rtw8852bx_set_gain_offset(rtwdev, subband, phy_idx);
+ rtw8852bx_set_rxsc_rpl_comp(rtwdev, subband);
+}
+
+static void rtw8852b_bw_setting(struct rtw89_dev *rtwdev, u8 bw, u8 path)
+{
+ static const u32 adc_sel[2] = {0xC0EC, 0xC1EC};
+ static const u32 wbadc_sel[2] = {0xC0E4, 0xC1E4};
+
+ switch (bw) {
+ case RTW89_CHANNEL_WIDTH_5:
+ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x1);
+ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x0);
+ break;
+ case RTW89_CHANNEL_WIDTH_10:
+ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x2);
+ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x1);
+ break;
+ case RTW89_CHANNEL_WIDTH_20:
+ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0);
+ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2);
+ break;
+ case RTW89_CHANNEL_WIDTH_40:
+ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0);
+ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2);
+ break;
+ case RTW89_CHANNEL_WIDTH_80:
+ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0);
+ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2);
+ break;
+ default:
+ rtw89_warn(rtwdev, "Fail to set ADC\n");
+ }
+}
+
+static
+void rtw8852bt_adc_cfg(struct rtw89_dev *rtwdev, u8 bw, u8 path)
+{
+ static const u32 rck_reset_count[2] = {0xC0E8, 0xC1E8};
+ static const u32 adc_op5_bw_sel[2] = {0xC0D8, 0xC1D8};
+ static const u32 adc_sample_td[2] = {0xC0D4, 0xC1D4};
+ static const u32 adc_rst_cycle[2] = {0xC0EC, 0xC1EC};
+ static const u32 decim_filter[2] = {0xC0EC, 0xC1EC};
+ static const u32 rck_offset[2] = {0xC0C4, 0xC1C4};
+ static const u32 rx_adc_clk[2] = {0x12A0, 0x32A0};
+ static const u32 wbadc_sel[2] = {0xC0E4, 0xC1E4};
+ static const u32 idac2_1[2] = {0xC0D4, 0xC1D4};
+ static const u32 idac2[2] = {0xC0D4, 0xC1D4};
+ static const u32 upd_clk_adc = {0x704};
+
+ if (rtwdev->chip->chip_id != RTL8852BT)
+ return;
+
+ rtw89_phy_write32_mask(rtwdev, idac2[path], B_P0_CFCH_CTL, 0x8);
+ rtw89_phy_write32_mask(rtwdev, rck_reset_count[path], B_ADCMOD_LP, 0x9);
+ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], B_WDADC_SEL, 0x2);
+ rtw89_phy_write32_mask(rtwdev, rx_adc_clk[path], B_P0_RXCK_ADJ, 0x49);
+ rtw89_phy_write32_mask(rtwdev, decim_filter[path], B_DCIM_FR, 0x0);
+
+ switch (bw) {
+ case RTW89_CHANNEL_WIDTH_5:
+ case RTW89_CHANNEL_WIDTH_10:
+ case RTW89_CHANNEL_WIDTH_20:
+ case RTW89_CHANNEL_WIDTH_40:
+ rtw89_phy_write32_mask(rtwdev, idac2_1[path], B_P0_CFCH_EN, 0x2);
+ rtw89_phy_write32_mask(rtwdev, adc_sample_td[path], B_P0_CFCH_BW0, 0x3);
+ rtw89_phy_write32_mask(rtwdev, adc_op5_bw_sel[path], B_P0_CFCH_BW1, 0xf);
+ rtw89_phy_write32_mask(rtwdev, rck_offset[path], B_DRCK_MUL, 0x0);
+ /* Tx TSSI ADC update */
+ rtw89_phy_write32_mask(rtwdev, upd_clk_adc, B_RSTB_ASYNC_BW80, 0);
+
+ if (rtwdev->efuse.rfe_type >= 51)
+ rtw89_phy_write32_mask(rtwdev, adc_rst_cycle[path], B_DCIM_RC, 0x2);
+ else
+ rtw89_phy_write32_mask(rtwdev, adc_rst_cycle[path], B_DCIM_RC, 0x3);
+ break;
+ case RTW89_CHANNEL_WIDTH_80:
+ rtw89_phy_write32_mask(rtwdev, idac2_1[path], B_P0_CFCH_EN, 0x2);
+ rtw89_phy_write32_mask(rtwdev, adc_sample_td[path], B_P0_CFCH_BW0, 0x2);
+ rtw89_phy_write32_mask(rtwdev, adc_op5_bw_sel[path], B_P0_CFCH_BW1, 0x8);
+ rtw89_phy_write32_mask(rtwdev, rck_offset[path], B_DRCK_MUL, 0x0);
+ rtw89_phy_write32_mask(rtwdev, adc_rst_cycle[path], B_DCIM_RC, 0x3);
+ /* Tx TSSI ADC update */
+ rtw89_phy_write32_mask(rtwdev, upd_clk_adc, B_RSTB_ASYNC_BW80, 1);
+ break;
+ case RTW89_CHANNEL_WIDTH_160:
+ rtw89_phy_write32_mask(rtwdev, idac2_1[path], B_P0_CFCH_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, adc_sample_td[path], B_P0_CFCH_BW0, 0x2);
+ rtw89_phy_write32_mask(rtwdev, adc_op5_bw_sel[path], B_P0_CFCH_BW1, 0x4);
+ rtw89_phy_write32_mask(rtwdev, rck_offset[path], B_DRCK_MUL, 0x6);
+ rtw89_phy_write32_mask(rtwdev, adc_rst_cycle[path], B_DCIM_RC, 0x3);
+ /* Tx TSSI ADC update */
+ rtw89_phy_write32_mask(rtwdev, upd_clk_adc, B_RSTB_ASYNC_BW80, 2);
+ break;
+ default:
+ rtw89_warn(rtwdev, "Fail to set ADC\n");
+ break;
+ }
+}
+
+static void rtw8852bx_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw,
+ enum rtw89_phy_idx phy_idx)
+{
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
+ u32 rx_path_0;
+
+ rx_path_0 = rtw89_phy_read32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, phy_idx);
+
+ switch (bw) {
+ case RTW89_CHANNEL_WIDTH_5:
+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x1, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx);
+
+ /*Set RF mode at 3 */
+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX,
+ B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX,
+ B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
+ if (chip_id == RTL8852BT) {
+ rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1,
+ B_PATH0_BAND_NRBW_EN_V1, 0x0, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1,
+ B_PATH1_BAND_NRBW_EN_V1, 0x0, phy_idx);
+ }
+ break;
+ case RTW89_CHANNEL_WIDTH_10:
+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x2, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx);
+
+ /*Set RF mode at 3 */
+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX,
+ B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX,
+ B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
+ if (chip_id == RTL8852BT) {
+ rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1,
+ B_PATH0_BAND_NRBW_EN_V1, 0x0, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1,
+ B_PATH1_BAND_NRBW_EN_V1, 0x0, phy_idx);
+ }
+ break;
+ case RTW89_CHANNEL_WIDTH_20:
+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x0, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH, 0x0, phy_idx);
+
+ /*Set RF mode at 3 */
+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX,
+ B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX,
+ B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
+ if (chip_id == RTL8852BT) {
+ rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1,
+ B_PATH0_BAND_NRBW_EN_V1, 0x1, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1,
+ B_PATH1_BAND_NRBW_EN_V1, 0x1, phy_idx);
+ }
+ break;
+ case RTW89_CHANNEL_WIDTH_40:
+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x1, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH,
+ pri_ch, phy_idx);
+
+ /*Set RF mode at 3 */
+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX,
+ B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX,
+ B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
+ /*CCK primary channel */
+ if (pri_ch == RTW89_SC_20_UPPER)
+ rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 1);
+ else
+ rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 0);
+
+ break;
+ case RTW89_CHANNEL_WIDTH_80:
+ rtw89_phy_write32_idx(rtwdev, R_FC0_BW_V1, B_FC0_BW_SET, 0x2, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_SBW, 0x0, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH,
+ pri_ch, phy_idx);
+
+ /*Set RF mode at 3 */
+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX,
+ B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX,
+ B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
+ break;
+ default:
+ rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw,
+ pri_ch);
+ }
+
+ if (chip_id == RTL8852B) {
+ rtw8852b_bw_setting(rtwdev, bw, RF_PATH_A);
+ rtw8852b_bw_setting(rtwdev, bw, RF_PATH_B);
+ } else if (chip_id == RTL8852BT) {
+ rtw8852bt_adc_cfg(rtwdev, bw, RF_PATH_A);
+ rtw8852bt_adc_cfg(rtwdev, bw, RF_PATH_B);
+ }
+
+ if (rx_path_0 == 0x1)
+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX,
+ B_P1_RFMODE_ORI_RX_ALL, 0x111, phy_idx);
+ else if (rx_path_0 == 0x2)
+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX,
+ B_P0_RFMODE_ORI_RX_ALL, 0x111, phy_idx);
+}
+
+static void rtw8852bx_ctrl_cck_en(struct rtw89_dev *rtwdev, bool cck_en)
+{
+ if (cck_en) {
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 1);
+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0);
+ } else {
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 0);
+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 1);
+ }
+}
+
+static void rtw8852bx_5m_mask(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+{
+ u8 pri_ch = chan->pri_ch_idx;
+ bool mask_5m_low;
+ bool mask_5m_en;
+
+ switch (chan->band_width) {
+ case RTW89_CHANNEL_WIDTH_40:
+ /* Prich=1: Mask 5M High, Prich=2: Mask 5M Low */
+ mask_5m_en = true;
+ mask_5m_low = pri_ch == RTW89_SC_20_LOWER;
+ break;
+ case RTW89_CHANNEL_WIDTH_80:
+ /* Prich=3: Mask 5M High, Prich=4: Mask 5M Low, Else: Disable */
+ mask_5m_en = pri_ch == RTW89_SC_20_UPMOST ||
+ pri_ch == RTW89_SC_20_LOWEST;
+ mask_5m_low = pri_ch == RTW89_SC_20_LOWEST;
+ break;
+ default:
+ mask_5m_en = false;
+ break;
+ }
+
+ if (!mask_5m_en) {
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_EN, 0x0);
+ rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT_V1,
+ B_ASSIGN_SBD_OPT_EN_V1, 0x0, phy_idx);
+ return;
+ }
+
+ if (mask_5m_low) {
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_TH, 0x4);
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB2, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB0, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_TH, 0x4);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB2, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB0, 0x1);
+ } else {
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_TH, 0x4);
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB2, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_5MDET_V1, B_PATH0_5MDET_SB0, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_TH, 0x4);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB2, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_5MDET_V1, B_PATH1_5MDET_SB0, 0x0);
+ }
+ rtw89_phy_write32_idx(rtwdev, R_ASSIGN_SBD_OPT_V1,
+ B_ASSIGN_SBD_OPT_EN_V1, 0x1, phy_idx);
+}
+
+static void __rtw8852bx_bb_reset_all(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+ rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx);
+ fsleep(1);
+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS, B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS, B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx);
+}
+
+static void rtw8852bx_bb_macid_ctrl_init(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
+{
+ u32 addr;
+
+ for (addr = R_AX_PWR_MACID_LMT_TABLE0;
+ addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4)
+ rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0);
+}
+
+static void __rtw8852bx_bb_sethw(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
+
+ rtw89_phy_write32_clr(rtwdev, R_P0_EN_SOUND_WO_NDP, B_P0_EN_SOUND_WO_NDP);
+ rtw89_phy_write32_clr(rtwdev, R_P1_EN_SOUND_WO_NDP, B_P1_EN_SOUND_WO_NDP);
+
+ rtw8852bx_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0);
+
+ /* read these registers after loading BB parameters */
+ gain->offset_base[RTW89_PHY_0] =
+ rtw89_phy_read32_mask(rtwdev, R_P0_RPL1, B_P0_RPL1_BIAS_MASK);
+ gain->rssi_base[RTW89_PHY_0] =
+ rtw89_phy_read32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK);
+}
+
+static void rtw8852bx_bb_set_pop(struct rtw89_dev *rtwdev)
+{
+ if (rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR)
+ rtw89_phy_write32_clr(rtwdev, R_PKT_CTRL, B_PKT_POP_EN);
+}
+
+static u32 rtw8852bt_spur_freq(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan)
+{
+ u8 center_chan = chan->channel;
+
+ switch (chan->band_type) {
+ case RTW89_BAND_5G:
+ if (center_chan == 151 || center_chan == 153 ||
+ center_chan == 155 || center_chan == 163)
+ return 5760;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+#define CARRIER_SPACING_312_5 312500 /* 312.5 kHz */
+#define CARRIER_SPACING_78_125 78125 /* 78.125 kHz */
+#define MAX_TONE_NUM 2048
+
+static void rtw8852bt_set_csi_tone_idx(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+{
+ s32 freq_diff, csi_idx, csi_tone_idx;
+ u32 spur_freq;
+
+ spur_freq = rtw8852bt_spur_freq(rtwdev, chan);
+ if (spur_freq == 0) {
+ rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN_V1, B_SEG0CSI_EN,
+ 0, phy_idx);
+ return;
+ }
+
+ freq_diff = (spur_freq - chan->freq) * 1000000;
+ csi_idx = s32_div_u32_round_closest(freq_diff, CARRIER_SPACING_78_125);
+ s32_div_u32_round_down(csi_idx, MAX_TONE_NUM, &csi_tone_idx);
+
+ rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_V1, B_SEG0CSI_IDX,
+ csi_tone_idx, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN_V1, B_SEG0CSI_EN, 1, phy_idx);
+}
+
+static
+void __rtw8852bx_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+{
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
+ bool cck_en = chan->channel <= 14;
+ u8 pri_ch_idx = chan->pri_ch_idx;
+ u8 band = chan->band_type, chan_idx;
+
+ if (cck_en)
+ rtw8852bx_ctrl_sco_cck(rtwdev, chan->primary_channel);
+
+ rtw8852bx_ctrl_ch(rtwdev, chan, phy_idx);
+ rtw8852bx_ctrl_bw(rtwdev, pri_ch_idx, chan->band_width, phy_idx);
+ rtw8852bx_ctrl_cck_en(rtwdev, cck_en);
+ if (chip_id == RTL8852BT)
+ rtw8852bt_set_csi_tone_idx(rtwdev, chan, phy_idx);
+ if (chip_id == RTL8852B && chan->band_type == RTW89_BAND_5G) {
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
+ B_PATH0_BT_SHARE_V1, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1,
+ B_PATH0_BTG_PATH_V1, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1,
+ B_PATH1_BT_SHARE_V1, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1,
+ B_PATH1_BTG_PATH_V1, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1,
+ B_BT_DYN_DC_EST_EN_MSK, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x0);
+ }
+ chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band);
+ rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx);
+ rtw8852bx_5m_mask(rtwdev, chan, phy_idx);
+ rtw8852bx_bb_set_pop(rtwdev);
+ __rtw8852bx_bb_reset_all(rtwdev, phy_idx);
+}
+
+static u32 rtw8852bx_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx,
+ s16 ref, u16 pwr_ofst_decrease)
+{
+ const u16 tssi_16dbm_cw = 0x12c;
+ const u8 base_cw_0db = 0x27;
+ s16 pwr_s10_3;
+ s16 rf_pwr_cw;
+ u16 bb_pwr_cw;
+ u32 pwr_cw;
+ u32 tssi_ofst_cw;
+
+ pwr_s10_3 = (ref << 1) + (s16)(base_cw_0db << 3) - pwr_ofst_decrease;
+ bb_pwr_cw = u16_get_bits(pwr_s10_3, GENMASK(2, 0));
+ rf_pwr_cw = u16_get_bits(pwr_s10_3, GENMASK(8, 3));
+ rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63);
+ pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw;
+
+ tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3)) -
+ pwr_ofst_decrease;
+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
+ "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n",
+ tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw);
+
+ return u32_encode_bits(tssi_ofst_cw, B_DPD_TSSI_CW) |
+ u32_encode_bits(pwr_cw, B_DPD_PWR_CW) |
+ u32_encode_bits(ref, B_DPD_REF);
+}
+
+/* @pwr_ofst (unit: 1/8 dBm): power of path A minus power of path B */
+static void rtw8852bx_set_txpwr_ref(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx, s16 pwr_ofst)
+{
+ static const u32 addr[RF_PATH_NUM_8852BX] = {0x5800, 0x7800};
+ const u32 mask = B_DPD_TSSI_CW | B_DPD_PWR_CW | B_DPD_REF;
+ u16 ofst_dec[RF_PATH_NUM_8852BX];
+ const u8 ofst_ofdm = 0x4;
+ const u8 ofst_cck = 0x8;
+ const s16 ref_ofdm = 0;
+ const s16 ref_cck = 0;
+ u32 val;
+ u8 i;
+
+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n");
+
+ rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL,
+ B_AX_PWR_REF, 0x0);
+
+ ofst_dec[RF_PATH_A] = pwr_ofst > 0 ? 0 : abs(pwr_ofst);
+ ofst_dec[RF_PATH_B] = pwr_ofst > 0 ? pwr_ofst : 0;
+
+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n");
+ for (i = 0; i < RF_PATH_NUM_8852BX; i++) {
+ val = rtw8852bx_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm, ofst_dec[i]);
+ rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val, phy_idx);
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n");
+ for (i = 0; i < RF_PATH_NUM_8852BX; i++) {
+ val = rtw8852bx_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck, ofst_dec[i]);
+ rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, phy_idx);
+ }
+}
+
+static void rtw8852bx_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ u8 tx_shape_idx,
+ enum rtw89_phy_idx phy_idx)
+{
+#define __DFIR_CFG_ADDR(i) (R_TXFIR0 + ((i) << 2))
+#define __DFIR_CFG_MASK 0xffffffff
+#define __DFIR_CFG_NR 8
+#define __DECL_DFIR_PARAM(_name, _val...) \
+ static const u32 param_ ## _name[] = {_val}; \
+ static_assert(ARRAY_SIZE(param_ ## _name) == __DFIR_CFG_NR)
+
+ __DECL_DFIR_PARAM(flat,
+ 0x023D23FF, 0x0029B354, 0x000FC1C8, 0x00FDB053,
+ 0x00F86F9A, 0x06FAEF92, 0x00FE5FCC, 0x00FFDFF5);
+ __DECL_DFIR_PARAM(sharp,
+ 0x023D83FF, 0x002C636A, 0x0013F204, 0x00008090,
+ 0x00F87FB0, 0x06F99F83, 0x00FDBFBA, 0x00003FF5);
+ __DECL_DFIR_PARAM(sharp_14,
+ 0x023B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E,
+ 0x00FD8F92, 0x0602D011, 0x0001C02C, 0x00FFF00A);
+ u8 ch = chan->channel;
+ const u32 *param;
+ u32 addr;
+ int i;
+
+ if (ch > 14) {
+ rtw89_warn(rtwdev,
+ "set tx shape dfir by unknown ch: %d on 2G\n", ch);
+ return;
+ }
+
+ if (ch == 14)
+ param = param_sharp_14;
+ else
+ param = tx_shape_idx == 0 ? param_flat : param_sharp;
+
+ for (i = 0; i < __DFIR_CFG_NR; i++) {
+ addr = __DFIR_CFG_ADDR(i);
+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
+ "set tx shape dfir: 0x%x: 0x%x\n", addr, param[i]);
+ rtw89_phy_write32_idx(rtwdev, addr, __DFIR_CFG_MASK, param[i],
+ phy_idx);
+ }
+
+#undef __DECL_DFIR_PARAM
+#undef __DFIR_CFG_NR
+#undef __DFIR_CFG_MASK
+#undef __DECL_CFG_ADDR
+}
+
+static void rtw8852bx_set_tx_shape(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+{
+ const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
+ u8 band = chan->band_type;
+ u8 regd = rtw89_regd_get(rtwdev, band);
+ u8 tx_shape_cck = (*rfe_parms->tx_shape.lmt)[band][RTW89_RS_CCK][regd];
+ u8 tx_shape_ofdm = (*rfe_parms->tx_shape.lmt)[band][RTW89_RS_OFDM][regd];
+
+ if (band == RTW89_BAND_2G)
+ rtw8852bx_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx);
+
+ rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG,
+ tx_shape_ofdm);
+}
+
+static s16 rtw8852bx_get_txpwr_sar_diff(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan)
+{
+ struct rtw89_sar_parm sar_parm = {
+ .center_freq = chan->freq,
+ .force_path = true,
+ };
+ s16 sar_bb_a, sar_bb_b;
+ s8 sar_mac;
+
+ sar_parm.path = RF_PATH_A;
+ sar_mac = rtw89_query_sar(rtwdev, &sar_parm);
+ sar_bb_a = rtw89_phy_txpwr_mac_to_bb(rtwdev, sar_mac);
+
+ sar_parm.path = RF_PATH_B;
+ sar_mac = rtw89_query_sar(rtwdev, &sar_parm);
+ sar_bb_b = rtw89_phy_txpwr_mac_to_bb(rtwdev, sar_mac);
+
+ return sar_bb_a - sar_bb_b;
+}
+
+static void rtw8852bx_set_txpwr_diff(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+{
+ s16 pwr_ofst;
+
+ pwr_ofst = rtw89_phy_ant_gain_pwr_offset(rtwdev, chan);
+ pwr_ofst += rtw8852bx_get_txpwr_sar_diff(rtwdev, chan);
+ rtw8852bx_set_txpwr_ref(rtwdev, phy_idx, pwr_ofst);
+}
+
+static void __rtw8852bx_set_txpwr(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+{
+ rtw89_phy_set_txpwr_byrate(rtwdev, chan, phy_idx);
+ rtw89_phy_set_txpwr_offset(rtwdev, chan, phy_idx);
+ rtw8852bx_set_tx_shape(rtwdev, chan, phy_idx);
+ rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx);
+ rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
+ rtw8852bx_set_txpwr_diff(rtwdev, chan, phy_idx);
+}
+
+static void __rtw8852bx_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
+{
+ rtw8852bx_set_txpwr_ref(rtwdev, phy_idx, 0);
+}
+
+static
+void __rtw8852bx_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
+ s8 pw_ofst, enum rtw89_mac_idx mac_idx)
+{
+ u32 reg;
+
+ if (pw_ofst < -16 || pw_ofst > 15) {
+ rtw89_warn(rtwdev, "[ULTB] Err pwr_offset=%d\n", pw_ofst);
+ return;
+ }
+
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_CTRL, mac_idx);
+ rtw89_write32_set(rtwdev, reg, B_AX_PWR_UL_TB_CTRL_EN);
+
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, mac_idx);
+ rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, pw_ofst);
+
+ pw_ofst = max_t(s8, pw_ofst - 3, -16);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, mac_idx);
+ rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_MASK, pw_ofst);
+}
+
+static int
+__rtw8852bx_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+ int ret;
+
+ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, 0x07763333);
+ if (ret)
+ return ret;
+
+ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, 0x01ebf000);
+ if (ret)
+ return ret;
+
+ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, 0x0002f8ff);
+ if (ret)
+ return ret;
+
+ rtw8852bx_set_txpwr_ul_tb_offset(rtwdev, 0, phy_idx == RTW89_PHY_1 ?
+ RTW89_MAC_1 : RTW89_MAC_0);
+
+ return 0;
+}
+
+static
+void __rtw8852bx_bb_set_plcp_tx(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_reg3_def *def = rtw8852bx_pmac_ht20_mcs7_tbl;
+ u8 i;
+
+ for (i = 0; i < ARRAY_SIZE(rtw8852bx_pmac_ht20_mcs7_tbl); i++, def++)
+ rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data);
+}
+
+static void rtw8852bx_stop_pmac_tx(struct rtw89_dev *rtwdev,
+ struct rtw8852bx_bb_pmac_info *tx_info,
+ enum rtw89_phy_idx idx)
+{
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC Stop Tx");
+ if (tx_info->mode == CONT_TX)
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_CTX_EN, 0, idx);
+ else if (tx_info->mode == PKTS_TX)
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_PTX_EN, 0, idx);
+}
+
+static void rtw8852bx_start_pmac_tx(struct rtw89_dev *rtwdev,
+ struct rtw8852bx_bb_pmac_info *tx_info,
+ enum rtw89_phy_idx idx)
+{
+ enum rtw8852bx_pmac_mode mode = tx_info->mode;
+ u32 pkt_cnt = tx_info->tx_cnt;
+ u16 period = tx_info->period;
+
+ if (mode == CONT_TX && !tx_info->is_cck) {
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_CTX_EN, 1, idx);
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CTx Start");
+ } else if (mode == PKTS_TX) {
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_PTX_EN, 1, idx);
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD,
+ B_PMAC_TX_PRD_MSK, period, idx);
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CNT, B_PMAC_TX_CNT_MSK,
+ pkt_cnt, idx);
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC PTx Start");
+ }
+
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CTRL, B_PMAC_TXEN_DIS, 1, idx);
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CTRL, B_PMAC_TXEN_DIS, 0, idx);
+}
+
+static
+void rtw8852bx_bb_set_pmac_tx(struct rtw89_dev *rtwdev,
+ struct rtw8852bx_bb_pmac_info *tx_info,
+ enum rtw89_phy_idx idx, const struct rtw89_chan *chan)
+{
+ if (!tx_info->en_pmac_tx) {
+ rtw8852bx_stop_pmac_tx(rtwdev, tx_info, idx);
+ rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0, idx);
+ if (chan->band_type == RTW89_BAND_2G)
+ rtw89_phy_write32_clr(rtwdev, R_RXCCA, B_RXCCA_DIS);
+ return;
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC Tx Enable");
+
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_TXEN, 1, idx);
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_RXEN, 1, idx);
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_RX_CFG1, B_PMAC_OPT1_MSK, 0x3f, idx);
+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, idx);
+ rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 1, idx);
+ rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS);
+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, idx);
+
+ rtw8852bx_start_pmac_tx(rtwdev, tx_info, idx);
+}
+
+static
+void __rtw8852bx_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable,
+ u16 tx_cnt, u16 period, u16 tx_time,
+ enum rtw89_phy_idx idx, const struct rtw89_chan *chan)
+{
+ struct rtw8852bx_bb_pmac_info tx_info = {0};
+
+ tx_info.en_pmac_tx = enable;
+ tx_info.is_cck = 0;
+ tx_info.mode = PKTS_TX;
+ tx_info.tx_cnt = tx_cnt;
+ tx_info.period = period;
+ tx_info.tx_time = tx_time;
+
+ rtw8852bx_bb_set_pmac_tx(rtwdev, &tx_info, idx, chan);
+}
+
+static
+void __rtw8852bx_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm,
+ enum rtw89_phy_idx idx)
+{
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CFG Tx PWR = %d", pwr_dbm);
+
+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 1, idx);
+ rtw89_phy_write32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, pwr_dbm, idx);
+}
+
+static
+void __rtw8852bx_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path)
+{
+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 7, RTW89_PHY_0);
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CFG Tx Path = %d", tx_path);
+
+ if (tx_path == RF_PATH_A) {
+ rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 1);
+ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0);
+ } else if (tx_path == RF_PATH_B) {
+ rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 2);
+ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0);
+ } else if (tx_path == RF_PATH_AB) {
+ rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 3);
+ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 4);
+ } else {
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "Error Tx Path");
+ }
+}
+
+static
+void __rtw8852bx_bb_tx_mode_switch(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx idx, u8 mode)
+{
+ if (mode != 0)
+ return;
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "Tx mode switch");
+
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_TXEN, 0, idx);
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_RXEN, 0, idx);
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_RX_CFG1, B_PMAC_OPT1_MSK, 0, idx);
+ rtw89_phy_write32_idx(rtwdev, R_PMAC_RXMOD, B_PMAC_RXMOD_MSK, 0, idx);
+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_DPD_EN, 0, idx);
+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, idx);
+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 0, idx);
+}
+
+static
+void __rtw8852bx_bb_backup_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx,
+ struct rtw8852bx_bb_tssi_bak *bak)
+{
+ s32 tmp;
+
+ bak->tx_path = rtw89_phy_read32_idx(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, idx);
+ bak->rx_path = rtw89_phy_read32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, idx);
+ bak->p0_rfmode = rtw89_phy_read32_idx(rtwdev, R_P0_RFMODE, MASKDWORD, idx);
+ bak->p0_rfmode_ftm = rtw89_phy_read32_idx(rtwdev, R_P0_RFMODE_FTM_RX, MASKDWORD, idx);
+ bak->p1_rfmode = rtw89_phy_read32_idx(rtwdev, R_P1_RFMODE, MASKDWORD, idx);
+ bak->p1_rfmode_ftm = rtw89_phy_read32_idx(rtwdev, R_P1_RFMODE_FTM_RX, MASKDWORD, idx);
+ tmp = rtw89_phy_read32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, idx);
+ bak->tx_pwr = sign_extend32(tmp, 8);
+}
+
+static
+void __rtw8852bx_bb_restore_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx,
+ const struct rtw8852bx_bb_tssi_bak *bak)
+{
+ rtw89_phy_write32_idx(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, bak->tx_path, idx);
+ if (bak->tx_path == RF_AB)
+ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0x4);
+ else
+ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 0x0);
+ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, bak->rx_path, idx);
+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 1, idx);
+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE, MASKDWORD, bak->p0_rfmode, idx);
+ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_FTM_RX, MASKDWORD, bak->p0_rfmode_ftm, idx);
+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE, MASKDWORD, bak->p1_rfmode, idx);
+ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_FTM_RX, MASKDWORD, bak->p1_rfmode_ftm, idx);
+ rtw89_phy_write32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, bak->tx_pwr, idx);
+}
+
+static void __rtw8852bx_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en,
+ enum rtw89_phy_idx phy_idx)
+{
+ rtw89_phy_write_reg3_tbl(rtwdev, en ? &rtw8852bx_btc_preagc_en_defs_tbl :
+ &rtw8852bx_btc_preagc_dis_defs_tbl);
+}
+
+static void __rtw8852bx_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en,
+ enum rtw89_phy_idx phy_idx)
+{
+ if (en) {
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
+ B_PATH0_BT_SHARE_V1, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1,
+ B_PATH0_BTG_PATH_V1, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
+ B_PATH1_G_LNA6_OP1DB_V1, 0x20);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
+ B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x30);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1,
+ B_PATH1_BT_SHARE_V1, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1,
+ B_PATH1_BTG_PATH_V1, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x2);
+ rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1,
+ B_BT_DYN_DC_EST_EN_MSK, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x1);
+ } else {
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BT_SHARE_V1,
+ B_PATH0_BT_SHARE_V1, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG_PATH_V1,
+ B_PATH0_BTG_PATH_V1, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_G_LNA6_OP1DB_V1,
+ B_PATH1_G_LNA6_OP1DB_V1, 0x1a);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_G_TIA0_LNA6_OP1DB_V1,
+ B_PATH1_G_TIA0_LNA6_OP1DB_V1, 0x2a);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BT_SHARE_V1,
+ B_PATH1_BT_SHARE_V1, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG_PATH_V1,
+ B_PATH1_BTG_PATH_V1, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xc);
+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_BT_SHARE, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_BT_SEG0, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_BT_DYN_DC_EST_EN_V1,
+ B_BT_DYN_DC_EST_EN_MSK, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x0);
+ }
+}
+
+static
+void __rtw8852bx_bb_ctrl_rx_path(struct rtw89_dev *rtwdev,
+ enum rtw89_rf_path_bit rx_path,
+ const struct rtw89_chan *chan)
+{
+ u32 rst_mask0;
+ u32 rst_mask1;
+
+ if (rx_path == RF_A) {
+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, 1);
+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG0, 1);
+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG1, 1);
+ rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0);
+ rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0);
+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 4);
+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0);
+ } else if (rx_path == RF_B) {
+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, 2);
+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG0, 2);
+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG1, 2);
+ rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0);
+ rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0);
+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 4);
+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0);
+ } else if (rx_path == RF_AB) {
+ rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, 3);
+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG0, 3);
+ rtw89_phy_write32_mask(rtwdev, R_FC0_BW_V1, B_ANT_RX_1RCCA_SEG1, 3);
+ rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 1);
+ rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 1);
+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 4);
+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1);
+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1);
+ }
+
+ rtw8852bx_set_gain_offset(rtwdev, chan->subband_type, RTW89_PHY_0);
+
+ if (chan->band_type == RTW89_BAND_2G &&
+ (rx_path == RF_B || rx_path == RF_AB))
+ rtw8852bx_ctrl_btg_bt_rx(rtwdev, true, RTW89_PHY_0);
+ else
+ rtw8852bx_ctrl_btg_bt_rx(rtwdev, false, RTW89_PHY_0);
+
+ rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI;
+ rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI;
+ if (rx_path == RF_A) {
+ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3);
+ } else {
+ rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 3);
+ }
+}
+
+static void rtw8852bx_bb_ctrl_rf_mode_rx_path(struct rtw89_dev *rtwdev,
+ enum rtw89_rf_path_bit rx_path)
+{
+ if (rx_path == RF_A) {
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE,
+ B_P0_RFMODE_ORI_TXRX_FTM_TX, 0x1233312);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE_FTM_RX,
+ B_P0_RFMODE_FTM_RX, 0x333);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE,
+ B_P1_RFMODE_ORI_TXRX_FTM_TX, 0x1111111);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE_FTM_RX,
+ B_P1_RFMODE_FTM_RX, 0x111);
+ } else if (rx_path == RF_B) {
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE,
+ B_P0_RFMODE_ORI_TXRX_FTM_TX, 0x1111111);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE_FTM_RX,
+ B_P0_RFMODE_FTM_RX, 0x111);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE,
+ B_P1_RFMODE_ORI_TXRX_FTM_TX, 0x1233312);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE_FTM_RX,
+ B_P1_RFMODE_FTM_RX, 0x333);
+ } else if (rx_path == RF_AB) {
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE,
+ B_P0_RFMODE_ORI_TXRX_FTM_TX, 0x1233312);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE_FTM_RX,
+ B_P0_RFMODE_FTM_RX, 0x333);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE,
+ B_P1_RFMODE_ORI_TXRX_FTM_TX, 0x1233312);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE_FTM_RX,
+ B_P1_RFMODE_FTM_RX, 0x333);
+ }
+}
+
+static void __rtw8852bx_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
+ enum rtw89_rf_path_bit rx_path = hal->antenna_rx ? hal->antenna_rx : RF_AB;
+
+ rtw8852bx_bb_ctrl_rx_path(rtwdev, rx_path, chan);
+ rtw8852bx_bb_ctrl_rf_mode_rx_path(rtwdev, rx_path);
+
+ if (rtwdev->hal.rx_nss == 1) {
+ rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0);
+ rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0);
+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0);
+ } else {
+ rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 1);
+ rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 1);
+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1);
+ rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1);
+ }
+
+ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0x0, RTW89_PHY_0);
+}
+
+static u8 __rtw8852bx_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
+{
+ if (rtwdev->is_tssi_mode[rf_path]) {
+ u32 addr = 0x1c10 + (rf_path << 13);
+
+ return rtw89_phy_read32_mask(rtwdev, addr, 0x3F000000);
+ }
+
+ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
+ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0);
+ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
+
+ fsleep(200);
+
+ return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL);
+}
+
+static
+void rtw8852bx_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val)
+{
+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x20000);
+ rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, group);
+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val);
+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0);
+}
+
+static void __rtw8852bx_btc_init_cfg(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ const struct rtw89_mac_ax_coex coex_params = {
+ .pta_mode = RTW89_MAC_AX_COEX_RTK_MODE,
+ .direction = RTW89_MAC_AX_COEX_INNER,
+ };
+
+ /* PTA init */
+ rtw89_mac_coex_init(rtwdev, &coex_params);
+
+ /* set WL Tx response = Hi-Pri */
+ chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true);
+ chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true);
+
+ /* set rf gnt debug off */
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_WLSEL, RFREG_MASK, 0x0);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_WLSEL, RFREG_MASK, 0x0);
+
+ /* set WL Tx thru in TRX mask table if GNT_WL = 0 && BT_S1 = ss group */
+ if (btc->ant_type == BTC_ANT_SHARED) {
+ rtw8852bx_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff);
+ rtw8852bx_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_SS_GROUP, 0x5ff);
+ /* set path-A(S0) Tx/Rx no-mask if GNT_WL=0 && BT_S1=tx group */
+ rtw8852bx_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff);
+ rtw8852bx_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_TX_GROUP, 0x55f);
+ } else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */
+ rtw8852bx_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_SS_GROUP, 0x5df);
+ rtw8852bx_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_SS_GROUP, 0x5df);
+ rtw8852bx_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff);
+ rtw8852bx_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_TX_GROUP, 0x5ff);
+ }
+
+ if (rtwdev->chip->chip_id == RTL8852BT) {
+ rtw8852bx_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_RX_GROUP, 0x5df);
+ rtw8852bx_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_RX_GROUP, 0x5df);
+ }
+
+ /* set PTA break table */
+ rtw89_write32(rtwdev, R_BTC_BREAK_TABLE, BTC_BREAK_PARAM);
+
+ /* enable BT counter 0xda40[16,2] = 2b'11 */
+ rtw89_write32_set(rtwdev, R_AX_CSR_MODE, B_AX_BT_CNT_RST | B_AX_STATIS_BT_EN);
+ btc->cx.wl.status.map.init_ok = true;
+}
+
+static
+void __rtw8852bx_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state)
+{
+ u32 bitmap;
+ u32 reg;
+
+ switch (map) {
+ case BTC_PRI_MASK_TX_RESP:
+ reg = R_BTC_BT_COEX_MSK_TABLE;
+ bitmap = B_BTC_PRI_MASK_TX_RESP_V1;
+ break;
+ case BTC_PRI_MASK_BEACON:
+ reg = R_AX_WL_PRI_MSK;
+ bitmap = B_AX_PTA_WL_PRI_MASK_BCNQ;
+ break;
+ case BTC_PRI_MASK_RX_CCK:
+ reg = R_BTC_BT_COEX_MSK_TABLE;
+ bitmap = B_BTC_PRI_MASK_RXCCK_V1;
+ break;
+ default:
+ return;
+ }
+
+ if (state)
+ rtw89_write32_set(rtwdev, reg, bitmap);
+ else
+ rtw89_write32_clr(rtwdev, reg, bitmap);
+}
+
+static
+s8 __rtw8852bx_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
+{
+ /* +6 for compensate offset */
+ return clamp_t(s8, val + 6, -100, 0) + 100;
+}
+
+static
+void __rtw8852bx_btc_update_bt_cnt(struct rtw89_dev *rtwdev)
+{
+ /* Feature move to firmware */
+}
+
+static void __rtw8852bx_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state)
+{
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x31);
+
+ /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */
+ if (state)
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x179);
+ else
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x20);
+
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
+}
+
+static void rtw8852bx_btc_set_wl_lna2(struct rtw89_dev *rtwdev, u8 level)
+{
+ switch (level) {
+ case 0: /* default */
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
+ break;
+ case 1: /* Fix LNA2=5 */
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
+ break;
+ }
+}
+
+static void __rtw8852bx_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+
+ switch (level) {
+ case 0: /* original */
+ default:
+ rtw8852bx_ctrl_nbtg_bt_tx(rtwdev, false, RTW89_PHY_0);
+ btc->dm.wl_lna2 = 0;
+ break;
+ case 1: /* for FDD free-run */
+ rtw8852bx_ctrl_nbtg_bt_tx(rtwdev, true, RTW89_PHY_0);
+ btc->dm.wl_lna2 = 0;
+ break;
+ case 2: /* for BTG Co-Rx*/
+ rtw8852bx_ctrl_nbtg_bt_tx(rtwdev, false, RTW89_PHY_0);
+ btc->dm.wl_lna2 = 1;
+ break;
+ }
+
+ rtw8852bx_btc_set_wl_lna2(rtwdev, btc->dm.wl_lna2);
+}
+
+static void rtw8852bx_fill_freq_with_ppdu(struct rtw89_dev *rtwdev,
+ struct rtw89_rx_phy_ppdu *phy_ppdu,
+ struct ieee80211_rx_status *status)
+{
+ u16 chan = phy_ppdu->chan_idx;
+ enum nl80211_band band;
+ u8 ch;
+
+ if (chan == 0)
+ return;
+
+ rtw89_decode_chan_idx(rtwdev, chan, &ch, &band);
+ status->freq = ieee80211_channel_to_frequency(ch, band);
+ status->band = band;
+}
+
+static void __rtw8852bx_query_ppdu(struct rtw89_dev *rtwdev,
+ struct rtw89_rx_phy_ppdu *phy_ppdu,
+ struct ieee80211_rx_status *status)
+{
+ u8 path;
+ u8 *rx_power = phy_ppdu->rssi;
+
+ if (!status->signal)
+ status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A],
+ rx_power[RF_PATH_B]));
+ for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
+ status->chains |= BIT(path);
+ status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]);
+ }
+ if (phy_ppdu->valid)
+ rtw8852bx_fill_freq_with_ppdu(rtwdev, phy_ppdu, status);
+}
+
+static void __rtw8852bx_convert_rpl_to_rssi(struct rtw89_dev *rtwdev,
+ struct rtw89_rx_phy_ppdu *phy_ppdu)
+{
+ u8 delta = phy_ppdu->rpl_avg - phy_ppdu->rssi_avg;
+ u8 *rssi = phy_ppdu->rssi;
+ u8 i;
+
+ for (i = 0; i < RF_PATH_NUM_8852BX; i++)
+ rssi[i] += delta;
+
+ phy_ppdu->rssi_avg = phy_ppdu->rpl_avg;
+}
+
+static int __rtw8852bx_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
+{
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
+ u32 val32;
+ int ret;
+
+ rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN,
+ B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_REG_ZCDC_H_MASK, 0x1);
+ rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
+ rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
+ rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
+
+ if (chip_id == RTL8852BT) {
+ val32 = rtw89_read32(rtwdev, R_AX_AFE_OFF_CTRL1);
+ val32 = u32_replace_bits(val32, 0x1, B_AX_S0_LDO_VSEL_F_MASK);
+ val32 = u32_replace_bits(val32, 0x1, B_AX_S1_LDO_VSEL_F_MASK);
+ rtw89_write32(rtwdev, R_AX_AFE_OFF_CTRL1, val32);
+ }
+
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xC7,
+ FULL_BIT_MASK);
+ if (ret)
+ return ret;
+
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xC7,
+ FULL_BIT_MASK);
+ if (ret)
+ return ret;
+
+ rtw89_write8(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_XYN_CYCLE);
+
+ return 0;
+}
+
+static int __rtw8852bx_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
+{
+ u8 wl_rfc_s0;
+ u8 wl_rfc_s1;
+ int ret;
+
+ rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
+ rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
+ B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
+
+ ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, &wl_rfc_s0);
+ if (ret)
+ return ret;
+ wl_rfc_s0 &= ~XTAL_SI_RF00S_EN;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, wl_rfc_s0,
+ FULL_BIT_MASK);
+ if (ret)
+ return ret;
+
+ ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, &wl_rfc_s1);
+ if (ret)
+ return ret;
+ wl_rfc_s1 &= ~XTAL_SI_RF10S_EN;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, wl_rfc_s1,
+ FULL_BIT_MASK);
+ return ret;
+}
+
+const struct rtw8852bx_info rtw8852bx_info = {
+ .mac_enable_bb_rf = __rtw8852bx_mac_enable_bb_rf,
+ .mac_disable_bb_rf = __rtw8852bx_mac_disable_bb_rf,
+ .bb_sethw = __rtw8852bx_bb_sethw,
+ .bb_reset_all = __rtw8852bx_bb_reset_all,
+ .bb_cfg_txrx_path = __rtw8852bx_bb_cfg_txrx_path,
+ .bb_cfg_tx_path = __rtw8852bx_bb_cfg_tx_path,
+ .bb_ctrl_rx_path = __rtw8852bx_bb_ctrl_rx_path,
+ .bb_set_plcp_tx = __rtw8852bx_bb_set_plcp_tx,
+ .bb_set_power = __rtw8852bx_bb_set_power,
+ .bb_set_pmac_pkt_tx = __rtw8852bx_bb_set_pmac_pkt_tx,
+ .bb_backup_tssi = __rtw8852bx_bb_backup_tssi,
+ .bb_restore_tssi = __rtw8852bx_bb_restore_tssi,
+ .bb_tx_mode_switch = __rtw8852bx_bb_tx_mode_switch,
+ .set_channel_mac = __rtw8852bx_set_channel_mac,
+ .set_channel_bb = __rtw8852bx_set_channel_bb,
+ .ctrl_nbtg_bt_tx = __rtw8852bx_ctrl_nbtg_bt_tx,
+ .ctrl_btg_bt_rx = __rtw8852bx_ctrl_btg_bt_rx,
+ .query_ppdu = __rtw8852bx_query_ppdu,
+ .convert_rpl_to_rssi = __rtw8852bx_convert_rpl_to_rssi,
+ .read_efuse = __rtw8852bx_read_efuse,
+ .read_phycap = __rtw8852bx_read_phycap,
+ .power_trim = __rtw8852bx_power_trim,
+ .set_txpwr = __rtw8852bx_set_txpwr,
+ .set_txpwr_ctrl = __rtw8852bx_set_txpwr_ctrl,
+ .init_txpwr_unit = __rtw8852bx_init_txpwr_unit,
+ .set_txpwr_ul_tb_offset = __rtw8852bx_set_txpwr_ul_tb_offset,
+ .get_thermal = __rtw8852bx_get_thermal,
+ .adc_cfg = rtw8852bt_adc_cfg,
+ .btc_init_cfg = __rtw8852bx_btc_init_cfg,
+ .btc_set_wl_pri = __rtw8852bx_btc_set_wl_pri,
+ .btc_get_bt_rssi = __rtw8852bx_btc_get_bt_rssi,
+ .btc_update_bt_cnt = __rtw8852bx_btc_update_bt_cnt,
+ .btc_wl_s1_standby = __rtw8852bx_btc_wl_s1_standby,
+ .btc_set_wl_rx_gain = __rtw8852bx_btc_set_wl_rx_gain,
+};
+EXPORT_SYMBOL(rtw8852bx_info);
+
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852B common routines");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_common.h b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.h
new file mode 100644
index 000000000000..3dce5422f41e
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.h
@@ -0,0 +1,400 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#ifndef __RTW89_8852BX_H__
+#define __RTW89_8852BX_H__
+
+#include "core.h"
+
+#define RF_PATH_NUM_8852BX 2
+#define BB_PATH_NUM_8852BX 2
+
+enum rtw8852bx_pmac_mode {
+ NONE_TEST,
+ PKTS_TX,
+ PKTS_RX,
+ CONT_TX
+};
+
+struct rtw8852bx_u_efuse {
+ u8 rsvd[0x88];
+ u8 mac_addr[ETH_ALEN];
+};
+
+struct rtw8852bx_e_efuse {
+ u8 mac_addr[ETH_ALEN];
+};
+
+struct rtw8852bx_tssi_offset {
+ u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM];
+ u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM];
+ u8 rsvd[7];
+ u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM];
+} __packed;
+
+struct rtw8852bx_efuse {
+ u8 rsvd[0x210];
+ struct rtw8852bx_tssi_offset path_a_tssi;
+ u8 rsvd1[10];
+ struct rtw8852bx_tssi_offset path_b_tssi;
+ u8 rsvd2[94];
+ u8 channel_plan;
+ u8 xtal_k;
+ u8 rsvd3;
+ u8 iqk_lck;
+ u8 rsvd4[5];
+ u8 reg_setting:2;
+ u8 tx_diversity:1;
+ u8 rx_diversity:2;
+ u8 ac_mode:1;
+ u8 module_type:2;
+ u8 rsvd5;
+ u8 shared_ant:1;
+ u8 coex_type:3;
+ u8 ant_iso:1;
+ u8 radio_on_off:1;
+ u8 rsvd6:2;
+ u8 eeprom_version;
+ u8 customer_id;
+ u8 tx_bb_swing_2g;
+ u8 tx_bb_swing_5g;
+ u8 tx_cali_pwr_trk_mode;
+ u8 trx_path_selection;
+ u8 rfe_type;
+ u8 country_code[2];
+ u8 rsvd7[3];
+ u8 path_a_therm;
+ u8 path_b_therm;
+ u8 rsvd8[2];
+ u8 rx_gain_2g_ofdm;
+ u8 rsvd9;
+ u8 rx_gain_2g_cck;
+ u8 rsvd10;
+ u8 rx_gain_5g_low;
+ u8 rsvd11;
+ u8 rx_gain_5g_mid;
+ u8 rsvd12;
+ u8 rx_gain_5g_high;
+ u8 rsvd13[35];
+ u8 path_a_cck_pwr_idx[6];
+ u8 path_a_bw40_1tx_pwr_idx[5];
+ u8 path_a_ofdm_1tx_pwr_idx_diff:4;
+ u8 path_a_bw20_1tx_pwr_idx_diff:4;
+ u8 path_a_bw20_2tx_pwr_idx_diff:4;
+ u8 path_a_bw40_2tx_pwr_idx_diff:4;
+ u8 path_a_cck_2tx_pwr_idx_diff:4;
+ u8 path_a_ofdm_2tx_pwr_idx_diff:4;
+ u8 rsvd14[0xf2];
+ union {
+ struct rtw8852bx_u_efuse u;
+ struct rtw8852bx_e_efuse e;
+ };
+} __packed;
+
+struct rtw8852bx_bb_pmac_info {
+ u8 en_pmac_tx:1;
+ u8 is_cck:1;
+ u8 mode:3;
+ u8 rsvd:3;
+ u16 tx_cnt;
+ u16 period;
+ u16 tx_time;
+ u8 duty_cycle;
+};
+
+struct rtw8852bx_bb_tssi_bak {
+ u8 tx_path;
+ u8 rx_path;
+ u32 p0_rfmode;
+ u32 p0_rfmode_ftm;
+ u32 p1_rfmode;
+ u32 p1_rfmode_ftm;
+ s16 tx_pwr; /* S9 */
+};
+
+struct rtw8852bx_info {
+ int (*mac_enable_bb_rf)(struct rtw89_dev *rtwdev);
+ int (*mac_disable_bb_rf)(struct rtw89_dev *rtwdev);
+ void (*bb_sethw)(struct rtw89_dev *rtwdev);
+ void (*bb_reset_all)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
+ void (*bb_cfg_txrx_path)(struct rtw89_dev *rtwdev);
+ void (*bb_cfg_tx_path)(struct rtw89_dev *rtwdev, u8 tx_path);
+ void (*bb_ctrl_rx_path)(struct rtw89_dev *rtwdev,
+ enum rtw89_rf_path_bit rx_path,
+ const struct rtw89_chan *chan);
+ void (*bb_set_plcp_tx)(struct rtw89_dev *rtwdev);
+ void (*bb_set_power)(struct rtw89_dev *rtwdev, s16 pwr_dbm,
+ enum rtw89_phy_idx idx);
+ void (*bb_set_pmac_pkt_tx)(struct rtw89_dev *rtwdev, u8 enable,
+ u16 tx_cnt, u16 period, u16 tx_time,
+ enum rtw89_phy_idx idx, const struct rtw89_chan *chan);
+ void (*bb_backup_tssi)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx,
+ struct rtw8852bx_bb_tssi_bak *bak);
+ void (*bb_restore_tssi)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx,
+ const struct rtw8852bx_bb_tssi_bak *bak);
+ void (*bb_tx_mode_switch)(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx idx, u8 mode);
+ void (*set_channel_mac)(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan, u8 mac_idx);
+ void (*set_channel_bb)(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx);
+ void (*ctrl_nbtg_bt_tx)(struct rtw89_dev *rtwdev, bool en,
+ enum rtw89_phy_idx phy_idx);
+ void (*ctrl_btg_bt_rx)(struct rtw89_dev *rtwdev, bool en,
+ enum rtw89_phy_idx phy_idx);
+ void (*query_ppdu)(struct rtw89_dev *rtwdev,
+ struct rtw89_rx_phy_ppdu *phy_ppdu,
+ struct ieee80211_rx_status *status);
+ void (*convert_rpl_to_rssi)(struct rtw89_dev *rtwdev,
+ struct rtw89_rx_phy_ppdu *phy_ppdu);
+ int (*read_efuse)(struct rtw89_dev *rtwdev, u8 *log_map,
+ enum rtw89_efuse_block block);
+ int (*read_phycap)(struct rtw89_dev *rtwdev, u8 *phycap_map);
+ void (*power_trim)(struct rtw89_dev *rtwdev);
+ void (*set_txpwr)(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx);
+ void (*set_txpwr_ctrl)(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx);
+ int (*init_txpwr_unit)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
+ void (*set_txpwr_ul_tb_offset)(struct rtw89_dev *rtwdev,
+ s8 pw_ofst, enum rtw89_mac_idx mac_idx);
+ u8 (*get_thermal)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path);
+ void (*adc_cfg)(struct rtw89_dev *rtwdev, u8 bw, u8 path);
+ void (*btc_init_cfg)(struct rtw89_dev *rtwdev);
+ void (*btc_set_wl_pri)(struct rtw89_dev *rtwdev, u8 map, bool state);
+ s8 (*btc_get_bt_rssi)(struct rtw89_dev *rtwdev, s8 val);
+ void (*btc_update_bt_cnt)(struct rtw89_dev *rtwdev);
+ void (*btc_wl_s1_standby)(struct rtw89_dev *rtwdev, bool state);
+ void (*btc_set_wl_rx_gain)(struct rtw89_dev *rtwdev, u32 level);
+};
+
+extern const struct rtw8852bx_info rtw8852bx_info;
+
+static inline
+int rtw8852bx_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
+{
+ return rtw8852bx_info.mac_enable_bb_rf(rtwdev);
+}
+
+static inline
+int rtw8852bx_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
+{
+ return rtw8852bx_info.mac_disable_bb_rf(rtwdev);
+}
+
+static inline
+void rtw8852bx_bb_sethw(struct rtw89_dev *rtwdev)
+{
+ rtw8852bx_info.bb_sethw(rtwdev);
+}
+
+static inline
+void rtw8852bx_bb_reset_all(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+ rtw8852bx_info.bb_reset_all(rtwdev, phy_idx);
+}
+
+static inline
+void rtw8852bx_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
+{
+ rtw8852bx_info.bb_cfg_txrx_path(rtwdev);
+}
+
+static inline
+void rtw8852bx_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path)
+{
+ rtw8852bx_info.bb_cfg_tx_path(rtwdev, tx_path);
+}
+
+static inline
+void rtw8852bx_bb_ctrl_rx_path(struct rtw89_dev *rtwdev,
+ enum rtw89_rf_path_bit rx_path,
+ const struct rtw89_chan *chan)
+{
+ rtw8852bx_info.bb_ctrl_rx_path(rtwdev, rx_path, chan);
+}
+
+static inline
+void rtw8852bx_bb_set_plcp_tx(struct rtw89_dev *rtwdev)
+{
+ rtw8852bx_info.bb_set_plcp_tx(rtwdev);
+}
+
+static inline
+void rtw8852bx_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm,
+ enum rtw89_phy_idx idx)
+{
+ rtw8852bx_info.bb_set_power(rtwdev, pwr_dbm, idx);
+}
+
+static inline
+void rtw8852bx_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable,
+ u16 tx_cnt, u16 period, u16 tx_time,
+ enum rtw89_phy_idx idx, const struct rtw89_chan *chan)
+{
+ rtw8852bx_info.bb_set_pmac_pkt_tx(rtwdev, enable, tx_cnt, period, tx_time, idx,
+ chan);
+}
+
+static inline
+void rtw8852bx_bb_backup_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx,
+ struct rtw8852bx_bb_tssi_bak *bak)
+{
+ rtw8852bx_info.bb_backup_tssi(rtwdev, idx, bak);
+}
+
+static inline
+void rtw8852bx_bb_restore_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx,
+ const struct rtw8852bx_bb_tssi_bak *bak)
+{
+ rtw8852bx_info.bb_restore_tssi(rtwdev, idx, bak);
+}
+
+static inline
+void rtw8852bx_bb_tx_mode_switch(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx idx, u8 mode)
+{
+ rtw8852bx_info.bb_tx_mode_switch(rtwdev, idx, mode);
+}
+
+static inline
+void rtw8852bx_set_channel_mac(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan, u8 mac_idx)
+{
+ rtw8852bx_info.set_channel_mac(rtwdev, chan, mac_idx);
+}
+
+static inline
+void rtw8852bx_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+{
+ rtw8852bx_info.set_channel_bb(rtwdev, chan, phy_idx);
+}
+
+static inline
+void rtw8852bx_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en,
+ enum rtw89_phy_idx phy_idx)
+{
+ rtw8852bx_info.ctrl_nbtg_bt_tx(rtwdev, en, phy_idx);
+}
+
+static inline
+void rtw8852bx_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en,
+ enum rtw89_phy_idx phy_idx)
+{
+ rtw8852bx_info.ctrl_btg_bt_rx(rtwdev, en, phy_idx);
+}
+
+static inline
+void rtw8852bx_query_ppdu(struct rtw89_dev *rtwdev,
+ struct rtw89_rx_phy_ppdu *phy_ppdu,
+ struct ieee80211_rx_status *status)
+{
+ rtw8852bx_info.query_ppdu(rtwdev, phy_ppdu, status);
+}
+
+static inline
+void rtw8852bx_convert_rpl_to_rssi(struct rtw89_dev *rtwdev,
+ struct rtw89_rx_phy_ppdu *phy_ppdu)
+{
+ rtw8852bx_info.convert_rpl_to_rssi(rtwdev, phy_ppdu);
+}
+
+static inline
+int rtw8852bx_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
+ enum rtw89_efuse_block block)
+{
+ return rtw8852bx_info.read_efuse(rtwdev, log_map, block);
+}
+
+static inline
+int rtw8852bx_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map)
+{
+ return rtw8852bx_info.read_phycap(rtwdev, phycap_map);
+}
+
+static inline
+void rtw8852bx_power_trim(struct rtw89_dev *rtwdev)
+{
+ rtw8852bx_info.power_trim(rtwdev);
+}
+
+static inline
+void rtw8852bx_set_txpwr(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+{
+ rtw8852bx_info.set_txpwr(rtwdev, chan, phy_idx);
+}
+
+static inline
+void rtw8852bx_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
+{
+ rtw8852bx_info.set_txpwr_ctrl(rtwdev, phy_idx);
+}
+
+static inline
+int rtw8852bx_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+ return rtw8852bx_info.init_txpwr_unit(rtwdev, phy_idx);
+}
+
+static inline
+void rtw8852bx_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
+ s8 pw_ofst, enum rtw89_mac_idx mac_idx)
+{
+ rtw8852bx_info.set_txpwr_ul_tb_offset(rtwdev, pw_ofst, mac_idx);
+}
+
+static inline
+u8 rtw8852bx_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
+{
+ return rtw8852bx_info.get_thermal(rtwdev, rf_path);
+}
+
+static inline
+void rtw8852bx_adc_cfg(struct rtw89_dev *rtwdev, u8 bw, u8 path)
+{
+ rtw8852bx_info.adc_cfg(rtwdev, bw, path);
+}
+
+static inline
+void rtw8852bx_btc_init_cfg(struct rtw89_dev *rtwdev)
+{
+ rtw8852bx_info.btc_init_cfg(rtwdev);
+}
+
+static inline
+void rtw8852bx_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state)
+{
+ rtw8852bx_info.btc_set_wl_pri(rtwdev, map, state);
+}
+
+static inline
+s8 rtw8852bx_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
+{
+ return rtw8852bx_info.btc_get_bt_rssi(rtwdev, val);
+}
+
+static inline
+void rtw8852bx_btc_update_bt_cnt(struct rtw89_dev *rtwdev)
+{
+ rtw8852bx_info.btc_update_bt_cnt(rtwdev);
+}
+
+static inline
+void rtw8852bx_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state)
+{
+ rtw8852bx_info.btc_wl_s1_standby(rtwdev, state);
+}
+
+static inline
+void rtw8852bx_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level)
+{
+ rtw8852bx_info.btc_set_wl_rx_gain(rtwdev, level);
+}
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c
index 259df67836a0..fbf82d42687b 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c
@@ -8,6 +8,7 @@
#include "phy.h"
#include "reg.h"
#include "rtw8852b.h"
+#include "rtw8852b_common.h"
#include "rtw8852b_rfk.h"
#include "rtw8852b_rfk_table.h"
#include "rtw8852b_table.h"
@@ -20,7 +21,7 @@
#define RTW8852B_RF_REL_VERSION 34
#define RTW8852B_DPK_VER 0x0d
#define RTW8852B_DPK_RF_PATH 2
-#define RTW8852B_DPK_KIP_REG_NUM 2
+#define RTW8852B_DPK_KIP_REG_NUM 3
#define _TSSI_DE_MASK GENMASK(21, 12)
#define ADDC_T_AVG 100
@@ -1381,9 +1382,10 @@ static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u
_iqk_info_iqk(rtwdev, phy_idx, path);
}
-static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 path)
+static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u32 reg_rf18;
u32 reg_35c;
@@ -1607,12 +1609,13 @@ static void _tmac_tx_pause(struct rtw89_dev *rtwdev, enum rtw89_phy_idx band_idx
}
static void _doiqk(struct rtw89_dev *rtwdev, bool force,
- enum rtw89_phy_idx phy_idx, u8 path)
+ enum rtw89_phy_idx phy_idx, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u32 backup_bb_val[BACKUP_BB_REGS_NR];
u32 backup_rf_val[RTW8852B_IQK_SS][BACKUP_RF_REGS_NR];
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START);
@@ -1622,7 +1625,7 @@ static void _doiqk(struct rtw89_dev *rtwdev, bool force,
iqk_info->version = RTW8852B_IQK_VER;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version);
- _iqk_get_ch_info(rtwdev, phy_idx, path);
+ _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx);
_rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]);
_rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path);
@@ -1637,20 +1640,21 @@ static void _doiqk(struct rtw89_dev *rtwdev, bool force,
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP);
}
-static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force)
+static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force,
+ enum rtw89_chanctx_idx chanctx_idx)
{
u8 kpath = _kpath(rtwdev, phy_idx);
switch (kpath) {
case RF_A:
- _doiqk(rtwdev, force, phy_idx, RF_PATH_A);
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx);
break;
case RF_B:
- _doiqk(rtwdev, force, phy_idx, RF_PATH_B);
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx);
break;
case RF_AB:
- _doiqk(rtwdev, force, phy_idx, RF_PATH_A);
- _doiqk(rtwdev, force, phy_idx, RF_PATH_B);
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx);
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx);
break;
default:
break;
@@ -1760,9 +1764,9 @@ static void _dpk_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
static void _dpk_information(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
u8 kidx = dpk->cur_idx[path];
@@ -1785,9 +1789,10 @@ static void _dpk_information(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy,
- enum rtw89_rf_path path, u8 kpath)
+ enum rtw89_rf_path path, u8 kpath,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
rtw89_rfk_parser(rtwdev, &rtw8852b_dpk_afe_defs_tbl);
@@ -1802,9 +1807,10 @@ static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev,
static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy,
- enum rtw89_rf_path path, u8 kpath)
+ enum rtw89_rf_path path, u8 kpath,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
rtw89_rfk_parser(rtwdev, &rtw8852b_dpk_afe_restore_defs_tbl);
@@ -2216,9 +2222,9 @@ static bool _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check)
static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path, u8 kidx, u8 init_txagc,
- bool loss_only)
+ bool loss_only, enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
u8 step = DPK_AGC_STEP_SYNC_DGAIN;
u8 tmp_txagc, tmp_rxbb = 0, tmp_gl_idx = 0;
u8 goout = 0, agc_cnt = 0, limited_rxbb = 0;
@@ -2415,9 +2421,9 @@ static void _dpk_fill_result(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
bool is_reload = false;
u8 idx, cur_band, cur_ch;
@@ -2442,7 +2448,8 @@ static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path, u8 gain)
+ enum rtw89_rf_path path, u8 gain,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
u8 txagc = 0x38, kidx = dpk->cur_idx[path];
@@ -2463,7 +2470,7 @@ static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
_dpk_kip_set_rxagc(rtwdev, phy, path);
_dpk_table_select(rtwdev, path, kidx, gain);
- txagc = _dpk_agc(rtwdev, phy, path, kidx, txagc, false);
+ txagc = _dpk_agc(rtwdev, phy, path, kidx, txagc, false, chanctx_idx);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Adjust txagc = 0x%x\n", txagc);
if (txagc == 0xff) {
@@ -2490,7 +2497,8 @@ static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
- enum rtw89_phy_idx phy, u8 kpath)
+ enum rtw89_phy_idx phy, u8 kpath,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120};
@@ -2502,7 +2510,8 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
if (dpk->is_dpk_reload_en) {
for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) {
- reloaded[path] = _dpk_reload_check(rtwdev, phy, path);
+ reloaded[path] = _dpk_reload_check(rtwdev, phy, path,
+ chanctx_idx);
if (!reloaded[path] && dpk->bp[path][0].ch)
dpk->cur_idx[path] = !dpk->cur_idx[path];
else
@@ -2518,19 +2527,19 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) {
_dpk_bkup_kip(rtwdev, kip_reg, kip_bkup, path);
_rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path);
- _dpk_information(rtwdev, phy, path);
+ _dpk_information(rtwdev, phy, path, chanctx_idx);
if (rtwdev->is_tssi_mode[path])
_dpk_tssi_pause(rtwdev, path, true);
}
- _dpk_bb_afe_setting(rtwdev, phy, path, kpath);
+ _dpk_bb_afe_setting(rtwdev, phy, path, kpath, chanctx_idx);
for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) {
- is_fail = _dpk_main(rtwdev, phy, path, 1);
+ is_fail = _dpk_main(rtwdev, phy, path, 1, chanctx_idx);
_dpk_onoff(rtwdev, path, is_fail);
}
- _dpk_bb_afe_restore(rtwdev, phy, path, kpath);
+ _dpk_bb_afe_restore(rtwdev, phy, path, kpath, chanctx_idx);
_rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]);
for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) {
@@ -2542,9 +2551,10 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
}
}
-static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
struct rtw89_fem_info *fem = &rtwdev->fem;
if (fem->epa_2g && chan->band_type == RTW89_BAND_2G) {
@@ -2576,17 +2586,18 @@ static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
}
}
-static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force)
+static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force,
+ enum rtw89_chanctx_idx chanctx_idx)
{
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[DPK] ****** DPK Start (Ver: 0x%x, Cv: %d, RF_para: %d) ******\n",
RTW8852B_DPK_VER, rtwdev->hal.cv,
RTW8852B_RF_REL_VERSION);
- if (_dpk_bypass_check(rtwdev, phy))
+ if (_dpk_bypass_check(rtwdev, phy, chanctx_idx))
_dpk_force_bypass(rtwdev, phy);
else
- _dpk_cal_select(rtwdev, force, phy, RF_AB);
+ _dpk_cal_select(rtwdev, force, phy, RF_AB, chanctx_idx);
}
static void _dpk_track(struct rtw89_dev *rtwdev)
@@ -2721,9 +2732,8 @@ static void _set_dpd_backoff(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
}
static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
if (band == RTW89_BAND_2G)
@@ -2733,9 +2743,8 @@ static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
rtw89_rfk_parser(rtwdev, &rtw8852b_tssi_sys_defs_tbl);
@@ -2777,7 +2786,7 @@ static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
#define RTW8852B_TSSI_GET_VAL(ptr, idx) \
({ \
@@ -2791,7 +2800,6 @@ static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx ph
__val; \
})
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u8 subband = chan->subband_type;
const s8 *thm_up_a = NULL;
@@ -2943,9 +2951,8 @@ static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx
}
static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
if (path == RF_PATH_A)
@@ -2959,9 +2966,9 @@ static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy
}
static void _tssi_alignment_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path, bool all)
+ enum rtw89_rf_path path, bool all,
+ const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
const struct rtw89_rfk_tbl *tbl = NULL;
u8 ch = chan->channel;
@@ -3230,10 +3237,9 @@ static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch)
}
static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u32 gidx, gidx_1st, gidx_2nd;
s8 de_1st;
@@ -3266,10 +3272,9 @@ static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u32 tgidx, tgidx_1st, tgidx_2nd;
s8 tde_1st;
@@ -3303,10 +3308,10 @@ static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx ph
return val;
}
-static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u8 gidx;
s8 ofdm_de;
@@ -3319,7 +3324,7 @@ static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx p
for (i = RF_PATH_A; i < RF_PATH_NUM_8852B; i++) {
gidx = _tssi_get_cck_group(rtwdev, ch);
- trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i);
+ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan);
val = tssi_info->tssi_cck[i][gidx] + trim_de;
rtw89_debug(rtwdev, RTW89_DBG_TSSI,
@@ -3335,8 +3340,8 @@ static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx p
rtw89_phy_read32_mask(rtwdev, _tssi_de_cck_long[i],
_TSSI_DE_MASK));
- ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i);
- trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i);
+ ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i, chan);
+ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan);
val = ofdm_de + trim_de;
rtw89_debug(rtwdev, RTW89_DBG_TSSI,
@@ -3382,10 +3387,10 @@ static void _tssi_alimentk_dump_result(struct rtw89_dev *rtwdev, enum rtw89_rf_p
}
static void _tssi_alimentk_done(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy, enum rtw89_rf_path path)
+ enum rtw89_phy_idx phy, enum rtw89_rf_path path,
+ const struct rtw89_chan *chan)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 channel = chan->channel;
u8 band;
@@ -3419,7 +3424,7 @@ static void _tssi_alimentk_done(struct rtw89_dev *rtwdev,
static void _tssi_hw_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path, u16 cnt, u16 period, s16 pwr_dbm,
- u8 enable)
+ u8 enable, const struct rtw89_chan *chan)
{
enum rtw89_rf_path_bit rx_path;
@@ -3433,13 +3438,13 @@ static void _tssi_hw_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
rx_path = RF_ABCD; /* don't change path, but still set others */
if (enable) {
- rtw8852b_bb_set_plcp_tx(rtwdev);
- rtw8852b_bb_cfg_tx_path(rtwdev, path);
- rtw8852b_bb_ctrl_rx_path(rtwdev, rx_path);
- rtw8852b_bb_set_power(rtwdev, pwr_dbm, phy);
+ rtw8852bx_bb_set_plcp_tx(rtwdev);
+ rtw8852bx_bb_cfg_tx_path(rtwdev, path);
+ rtw8852bx_bb_ctrl_rx_path(rtwdev, rx_path, chan);
+ rtw8852bx_bb_set_power(rtwdev, pwr_dbm, phy);
}
- rtw8852b_bb_set_pmac_pkt_tx(rtwdev, enable, cnt, period, 20, phy);
+ rtw8852bx_bb_set_pmac_pkt_tx(rtwdev, enable, cnt, period, 20, phy, chan);
}
static void _tssi_backup_bb_registers(struct rtw89_dev *rtwdev,
@@ -3493,7 +3498,7 @@ static u8 _tssi_ch_to_idx(struct rtw89_dev *rtwdev, u8 channel)
static bool _tssi_get_cw_report(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path, const s16 *power,
- u32 *tssi_cw_rpt)
+ u32 *tssi_cw_rpt, const struct rtw89_chan *chan)
{
u32 tx_counter, tx_counter_tmp;
const int retry = 100;
@@ -3512,9 +3517,10 @@ static bool _tssi_get_cw_report(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy
_tssi_trigger[path], tmp, path);
if (j == 0)
- _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], true);
+ _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], true, chan);
else
- _tssi_hw_tx(rtwdev, phy, RF_PATH_ABCD, 100, 5000, power[j], true);
+ _tssi_hw_tx(rtwdev, phy, RF_PATH_ABCD, 100, 5000, power[j], true,
+ chan);
tx_counter_tmp = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
tx_counter_tmp -= tx_counter;
@@ -3545,14 +3551,14 @@ static bool _tssi_get_cw_report(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy
"[TSSI PA K] TSSI finish bit k > %d mp:100ms normal:30us path=%d\n",
k, path);
- _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], false);
+ _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], false, chan);
return false;
}
tssi_cw_rpt[j] =
rtw89_phy_read32_mask(rtwdev, _tssi_cw_rpt_addr[path], B_TSSI_CWRPT);
- _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], false);
+ _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], false, chan);
tx_counter_tmp = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
tx_counter_tmp -= tx_counter;
@@ -3566,23 +3572,23 @@ static bool _tssi_get_cw_report(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy
}
static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
static const u32 bb_reg[8] = {0x5820, 0x7820, 0x4978, 0x58e4,
0x78e4, 0x49c0, 0x0d18, 0x0d80};
static const s16 power_2g[4] = {48, 20, 4, 4};
static const s16 power_5g[4] = {48, 20, 4, 4};
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
s32 tssi_alim_offset_1, tssi_alim_offset_2, tssi_alim_offset_3;
u32 tssi_cw_rpt[RTW8852B_TSSI_PATH_NR] = {0};
u8 channel = chan->channel;
u8 ch_idx = _tssi_ch_to_idx(rtwdev, channel);
- struct rtw8852b_bb_tssi_bak tssi_bak;
+ struct rtw8852bx_bb_tssi_bak tssi_bak;
s32 aliment_diff, tssi_cw_default;
- u32 start_time, finish_time;
u32 bb_reg_backup[8] = {0};
+ ktime_t start_time;
const s16 *power;
+ s64 this_time;
u8 band;
bool ok;
u32 tmp;
@@ -3608,7 +3614,7 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
return;
}
- start_time = ktime_get_ns();
+ start_time = ktime_get();
if (chan->band_type == RTW89_BAND_2G)
power = power_2g;
@@ -3626,7 +3632,7 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
else
band = TSSI_ALIMK_2G;
- rtw8852b_bb_backup_tssi(rtwdev, phy, &tssi_bak);
+ rtw8852bx_bb_backup_tssi(rtwdev, phy, &tssi_bak);
_tssi_backup_bb_registers(rtwdev, phy, bb_reg, bb_reg_backup, ARRAY_SIZE(bb_reg_backup));
rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, 0x8);
@@ -3634,7 +3640,7 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, 0x2);
rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, 0x2);
- ok = _tssi_get_cw_report(rtwdev, phy, path, power, tssi_cw_rpt);
+ ok = _tssi_get_cw_report(rtwdev, phy, path, power, tssi_cw_rpt, chan);
if (!ok)
goto out;
@@ -3730,15 +3736,15 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
out:
_tssi_reload_bb_registers(rtwdev, phy, bb_reg, bb_reg_backup, ARRAY_SIZE(bb_reg_backup));
- rtw8852b_bb_restore_tssi(rtwdev, phy, &tssi_bak);
- rtw8852b_bb_tx_mode_switch(rtwdev, phy, 0);
+ rtw8852bx_bb_restore_tssi(rtwdev, phy, &tssi_bak);
+ rtw8852bx_bb_tx_mode_switch(rtwdev, phy, 0);
- finish_time = ktime_get_ns();
- tssi_info->tssi_alimk_time += finish_time - start_time;
+ this_time = ktime_us_delta(ktime_get(), start_time);
+ tssi_info->tssi_alimk_time += this_time;
rtw89_debug(rtwdev, RTW89_DBG_RFK,
- "[TSSI PA K] %s processing time = %d ms\n", __func__,
- tssi_info->tssi_alimk_time);
+ "[TSSI PA K] %s processing time = %lld us (acc = %llu us)\n",
+ __func__, this_time, tssi_info->tssi_alimk_time);
}
void rtw8852b_dpk_init(struct rtw89_dev *rtwdev)
@@ -3754,18 +3760,19 @@ void rtw8852b_rck(struct rtw89_dev *rtwdev)
_rck(rtwdev, path);
}
-void rtw8852b_dack(struct rtw89_dev *rtwdev)
+void rtw8852b_dack(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx)
{
- u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0, chanctx_idx);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START);
_dac_cal(rtwdev, false);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP);
}
-void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx);
u32 tx_en;
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START);
@@ -3773,15 +3780,16 @@ void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
_wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx));
_iqk_init(rtwdev);
- _iqk(rtwdev, phy_idx, false);
+ _iqk(rtwdev, phy_idx, false, chanctx_idx);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP);
}
-void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx);
u32 tx_en;
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START);
@@ -3794,9 +3802,10 @@ void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP);
}
-void rtw8852b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+void rtw8852b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx);
u32 tx_en;
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START);
@@ -3805,7 +3814,7 @@ void rtw8852b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
rtwdev->dpk.is_dpk_enable = true;
rtwdev->dpk.is_dpk_reload_en = false;
- _dpk(rtwdev, phy_idx, false);
+ _dpk(rtwdev, phy_idx, false, chanctx_idx);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP);
@@ -3816,9 +3825,11 @@ void rtw8852b_dpk_track(struct rtw89_dev *rtwdev)
_dpk_track(rtwdev);
}
-void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en)
+void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ bool hwtx_en, enum rtw89_chanctx_idx chanctx_idx)
{
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_AB);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_AB, chanctx_idx);
u32 tx_en;
u8 i;
@@ -3828,34 +3839,34 @@ void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_e
_tssi_disable(rtwdev, phy);
for (i = RF_PATH_A; i < RF_PATH_NUM_8852B; i++) {
- _tssi_rf_setting(rtwdev, phy, i);
- _tssi_set_sys(rtwdev, phy, i);
+ _tssi_rf_setting(rtwdev, phy, i, chan);
+ _tssi_set_sys(rtwdev, phy, i, chan);
_tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i);
_tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i);
_tssi_set_dck(rtwdev, phy, i);
- _tssi_set_tmeter_tbl(rtwdev, phy, i);
+ _tssi_set_tmeter_tbl(rtwdev, phy, i, chan);
_tssi_set_dac_gain_tbl(rtwdev, phy, i);
- _tssi_slope_cal_org(rtwdev, phy, i);
- _tssi_alignment_default(rtwdev, phy, i, true);
+ _tssi_slope_cal_org(rtwdev, phy, i, chan);
+ _tssi_alignment_default(rtwdev, phy, i, true, chan);
_tssi_set_tssi_slope(rtwdev, phy, i);
rtw89_chip_stop_sch_tx(rtwdev, phy, &tx_en, RTW89_SCH_TX_SEL_ALL);
_tmac_tx_pause(rtwdev, phy, true);
if (hwtx_en)
- _tssi_alimentk(rtwdev, phy, i);
+ _tssi_alimentk(rtwdev, phy, i, chan);
_tmac_tx_pause(rtwdev, phy, false);
rtw89_chip_resume_sch_tx(rtwdev, phy, tx_en);
}
_tssi_enable(rtwdev, phy);
- _tssi_set_efuse_to_de(rtwdev, phy);
+ _tssi_set_efuse_to_de(rtwdev, phy, chan);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP);
}
-void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
u8 channel = chan->channel;
u8 band;
@@ -3878,24 +3889,25 @@ void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
_tssi_disable(rtwdev, phy);
for (i = RF_PATH_A; i < RTW8852B_TSSI_PATH_NR; i++) {
- _tssi_rf_setting(rtwdev, phy, i);
- _tssi_set_sys(rtwdev, phy, i);
- _tssi_set_tmeter_tbl(rtwdev, phy, i);
+ _tssi_rf_setting(rtwdev, phy, i, chan);
+ _tssi_set_sys(rtwdev, phy, i, chan);
+ _tssi_set_tmeter_tbl(rtwdev, phy, i, chan);
if (tssi_info->alignment_done[i][band])
- _tssi_alimentk_done(rtwdev, phy, i);
+ _tssi_alimentk_done(rtwdev, phy, i, chan);
else
- _tssi_alignment_default(rtwdev, phy, i, true);
+ _tssi_alignment_default(rtwdev, phy, i, true, chan);
}
_tssi_enable(rtwdev, phy);
- _tssi_set_efuse_to_de(rtwdev, phy);
+ _tssi_set_efuse_to_de(rtwdev, phy, chan);
}
static void rtw8852b_tssi_default_txagc(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy, bool enable)
+ enum rtw89_phy_idx phy, bool enable,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
u8 channel = chan->channel;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "======> %s ch=%d\n",
@@ -3903,7 +3915,7 @@ static void rtw8852b_tssi_default_txagc(struct rtw89_dev *rtwdev,
if (enable) {
if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B])
- rtw8852b_tssi(rtwdev, phy, true);
+ rtw8852b_tssi(rtwdev, phy, true, chanctx_idx);
return;
}
@@ -3920,8 +3932,8 @@ static void rtw8852b_tssi_default_txagc(struct rtw89_dev *rtwdev,
rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x0);
rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x1);
- _tssi_alimentk_done(rtwdev, phy, RF_PATH_A);
- _tssi_alimentk_done(rtwdev, phy, RF_PATH_B);
+ _tssi_alimentk_done(rtwdev, phy, RF_PATH_A, chan);
+ _tssi_alimentk_done(rtwdev, phy, RF_PATH_B, chan);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"======>%s 2 SCAN_END Set 0x5818[7:0]=0x%x 0x7818[7:0]=0x%x\n",
@@ -3934,12 +3946,13 @@ static void rtw8852b_tssi_default_txagc(struct rtw89_dev *rtwdev,
}
void rtw8852b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
- enum rtw89_phy_idx phy_idx)
+ enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
{
if (scan_start)
- rtw8852b_tssi_default_txagc(rtwdev, phy_idx, true);
+ rtw8852b_tssi_default_txagc(rtwdev, phy_idx, true, chanctx_idx);
else
- rtw8852b_tssi_default_txagc(rtwdev, phy_idx, false);
+ rtw8852b_tssi_default_txagc(rtwdev, phy_idx, false, chanctx_idx);
}
static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h
index f52832065600..c31ba446e6e0 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h
@@ -8,16 +8,22 @@
#include "core.h"
void rtw8852b_rck(struct rtw89_dev *rtwdev);
-void rtw8852b_dack(struct rtw89_dev *rtwdev);
-void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
-void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
+void rtw8852b_dack(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx);
+void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
+void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
void rtw8852b_dpk_init(struct rtw89_dev *rtwdev);
-void rtw8852b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
+void rtw8852b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
void rtw8852b_dpk_track(struct rtw89_dev *rtwdev);
-void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en);
-void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
+void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ bool hwtx_en, enum rtw89_chanctx_idx chanctx_idx);
+void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan);
void rtw8852b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
- enum rtw89_phy_idx phy_idx);
+ enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852be.c b/drivers/net/wireless/realtek/rtw89/rtw8852be.c
index ed71364e6437..abdeafc14b0b 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852be.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852be.c
@@ -27,6 +27,7 @@ static const struct rtw89_pci_info rtw8852b_pci_info = {
.io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS,
.rx_ring_eq_is_full = false,
.check_rx_tag = false,
+ .no_rxbd_fs = false,
.init_cfg_reg = R_AX_PCIE_INIT_CFG1,
.txhci_en_bit = B_AX_TXHCI_EN,
@@ -46,6 +47,7 @@ static const struct rtw89_pci_info rtw8852b_pci_info = {
.rpwm_addr = R_AX_PCIE_HRPWM,
.cpwm_addr = R_AX_CPWM,
.mit_addr = R_AX_INT_MIT_RX,
+ .wp_sel_addr = 0,
.tx_dma_ch_mask = BIT(RTW89_TXCH_ACH4) | BIT(RTW89_TXCH_ACH5) |
BIT(RTW89_TXCH_ACH6) | BIT(RTW89_TXCH_ACH7) |
BIT(RTW89_TXCH_CH10) | BIT(RTW89_TXCH_CH11),
@@ -59,10 +61,14 @@ static const struct rtw89_pci_info rtw8852b_pci_info = {
.enable_intr = rtw89_pci_enable_intr,
.disable_intr = rtw89_pci_disable_intr,
.recognize_intrs = rtw89_pci_recognize_intrs,
+
+ .ssid_quirks = NULL,
};
static const struct rtw89_driver_info rtw89_8852be_info = {
.chip = &rtw8852b_chip_info,
+ .variant = NULL,
+ .quirks = NULL,
.bus = {
.pci = &rtw8852b_pci_info,
},
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
new file mode 100644
index 000000000000..289dce688d72
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
@@ -0,0 +1,875 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#include "coex.h"
+#include "fw.h"
+#include "mac.h"
+#include "phy.h"
+#include "reg.h"
+#include "rtw8852bt.h"
+#include "rtw8852bt_rfk.h"
+#include "rtw8852b_common.h"
+
+#define RTW8852BT_FW_FORMAT_MAX 0
+#define RTW8852BT_FW_BASENAME "rtw89/rtw8852bt_fw"
+#define RTW8852BT_MODULE_FIRMWARE \
+ RTW8852BT_FW_BASENAME ".bin"
+
+static const struct rtw89_hfc_ch_cfg rtw8852bt_hfc_chcfg_pcie[] = {
+ {16, 742, grp_0}, /* ACH 0 */
+ {16, 742, grp_0}, /* ACH 1 */
+ {16, 742, grp_0}, /* ACH 2 */
+ {16, 742, grp_0}, /* ACH 3 */
+ {0, 0, grp_0}, /* ACH 4 */
+ {0, 0, grp_0}, /* ACH 5 */
+ {0, 0, grp_0}, /* ACH 6 */
+ {0, 0, grp_0}, /* ACH 7 */
+ {15, 743, grp_0}, /* B0MGQ */
+ {15, 743, grp_0}, /* B0HIQ */
+ {0, 0, grp_0}, /* B1MGQ */
+ {0, 0, grp_0}, /* B1HIQ */
+ {40, 0, 0} /* FWCMDQ */
+};
+
+static const struct rtw89_hfc_pub_cfg rtw8852bt_hfc_pubcfg_pcie = {
+ 958, /* Group 0 */
+ 0, /* Group 1 */
+ 958, /* Public Max */
+ 0 /* WP threshold */
+};
+
+static const struct rtw89_hfc_param_ini rtw8852bt_hfc_param_ini_pcie[] = {
+ [RTW89_QTA_SCC] = {rtw8852bt_hfc_chcfg_pcie, &rtw8852bt_hfc_pubcfg_pcie,
+ &rtw89_mac_size.hfc_preccfg_pcie, RTW89_HCIFC_POH},
+ [RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_preccfg_pcie,
+ RTW89_HCIFC_POH},
+ [RTW89_QTA_INVALID] = {NULL},
+};
+
+static const struct rtw89_dle_mem rtw8852bt_dle_mem_pcie[] = {
+ [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size23,
+ &rtw89_mac_size.ple_size9, &rtw89_mac_size.wde_qt23,
+ &rtw89_mac_size.wde_qt23, &rtw89_mac_size.ple_qt57,
+ &rtw89_mac_size.ple_qt59},
+ [RTW89_QTA_WOW] = {RTW89_QTA_WOW, &rtw89_mac_size.wde_size23,
+ &rtw89_mac_size.ple_size9, &rtw89_mac_size.wde_qt23,
+ &rtw89_mac_size.wde_qt23, &rtw89_mac_size.ple_qt57,
+ &rtw89_mac_size.ple_qt_52bt_wow},
+ [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size4,
+ &rtw89_mac_size.ple_size4, &rtw89_mac_size.wde_qt4,
+ &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13,
+ &rtw89_mac_size.ple_qt13},
+ [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL,
+ NULL},
+};
+
+static const u32 rtw8852bt_h2c_regs[RTW89_H2CREG_MAX] = {
+ R_AX_H2CREG_DATA0, R_AX_H2CREG_DATA1, R_AX_H2CREG_DATA2,
+ R_AX_H2CREG_DATA3
+};
+
+static const u32 rtw8852bt_c2h_regs[RTW89_C2HREG_MAX] = {
+ R_AX_C2HREG_DATA0, R_AX_C2HREG_DATA1, R_AX_C2HREG_DATA2,
+ R_AX_C2HREG_DATA3
+};
+
+static const u32 rtw8852bt_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = {
+ R_AX_C2HREG_DATA3 + 3, R_AX_C2HREG_DATA3 + 3,
+};
+
+static const struct rtw89_page_regs rtw8852bt_page_regs = {
+ .hci_fc_ctrl = R_AX_HCI_FC_CTRL,
+ .ch_page_ctrl = R_AX_CH_PAGE_CTRL,
+ .ach_page_ctrl = R_AX_ACH0_PAGE_CTRL,
+ .ach_page_info = R_AX_ACH0_PAGE_INFO,
+ .pub_page_info3 = R_AX_PUB_PAGE_INFO3,
+ .pub_page_ctrl1 = R_AX_PUB_PAGE_CTRL1,
+ .pub_page_ctrl2 = R_AX_PUB_PAGE_CTRL2,
+ .pub_page_info1 = R_AX_PUB_PAGE_INFO1,
+ .pub_page_info2 = R_AX_PUB_PAGE_INFO2,
+ .wp_page_ctrl1 = R_AX_WP_PAGE_CTRL1,
+ .wp_page_ctrl2 = R_AX_WP_PAGE_CTRL2,
+ .wp_page_info1 = R_AX_WP_PAGE_INFO1,
+};
+
+static const struct rtw89_reg_def rtw8852bt_dcfo_comp = {
+ R_DCFO_COMP_S0, B_DCFO_COMP_S0_MSK
+};
+
+static const struct rtw89_imr_info rtw8852bt_imr_info = {
+ .wdrls_imr_set = B_AX_WDRLS_IMR_SET,
+ .wsec_imr_reg = R_AX_SEC_DEBUG,
+ .wsec_imr_set = B_AX_IMR_ERROR,
+ .mpdu_tx_imr_set = 0,
+ .mpdu_rx_imr_set = 0,
+ .sta_sch_imr_set = B_AX_STA_SCHEDULER_IMR_SET,
+ .txpktctl_imr_b0_reg = R_AX_TXPKTCTL_ERR_IMR_ISR,
+ .txpktctl_imr_b0_clr = B_AX_TXPKTCTL_IMR_B0_CLR,
+ .txpktctl_imr_b0_set = B_AX_TXPKTCTL_IMR_B0_SET,
+ .txpktctl_imr_b1_reg = R_AX_TXPKTCTL_ERR_IMR_ISR_B1,
+ .txpktctl_imr_b1_clr = B_AX_TXPKTCTL_IMR_B1_CLR,
+ .txpktctl_imr_b1_set = B_AX_TXPKTCTL_IMR_B1_SET,
+ .wde_imr_clr = B_AX_WDE_IMR_CLR_V01,
+ .wde_imr_set = B_AX_WDE_IMR_SET_V01,
+ .ple_imr_clr = B_AX_PLE_IMR_CLR,
+ .ple_imr_set = B_AX_PLE_IMR_SET,
+ .host_disp_imr_clr = B_AX_HOST_DISP_IMR_CLR,
+ .host_disp_imr_set = B_AX_HOST_DISP_IMR_SET_V01,
+ .cpu_disp_imr_clr = B_AX_CPU_DISP_IMR_CLR,
+ .cpu_disp_imr_set = B_AX_CPU_DISP_IMR_SET,
+ .other_disp_imr_clr = B_AX_OTHER_DISP_IMR_CLR,
+ .other_disp_imr_set = 0,
+ .bbrpt_com_err_imr_reg = R_AX_BBRPT_COM_ERR_IMR_ISR,
+ .bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR_ISR,
+ .bbrpt_err_imr_set = 0,
+ .bbrpt_dfs_err_imr_reg = R_AX_BBRPT_DFS_ERR_IMR_ISR,
+ .ptcl_imr_clr = B_AX_PTCL_IMR_CLR_ALL,
+ .ptcl_imr_set = B_AX_PTCL_IMR_SET,
+ .cdma_imr_0_reg = R_AX_DLE_CTRL,
+ .cdma_imr_0_clr = B_AX_DLE_IMR_CLR,
+ .cdma_imr_0_set = B_AX_DLE_IMR_SET,
+ .cdma_imr_1_reg = 0,
+ .cdma_imr_1_clr = 0,
+ .cdma_imr_1_set = 0,
+ .phy_intf_imr_reg = R_AX_PHYINFO_ERR_IMR,
+ .phy_intf_imr_clr = B_AX_PHYINFO_IMR_EN_ALL,
+ .phy_intf_imr_set = B_AX_PHYINFO_IMR_SET,
+ .rmac_imr_reg = R_AX_RMAC_ERR_ISR,
+ .rmac_imr_clr = B_AX_RMAC_IMR_CLR,
+ .rmac_imr_set = B_AX_RMAC_IMR_SET,
+ .tmac_imr_reg = R_AX_TMAC_ERR_IMR_ISR,
+ .tmac_imr_clr = B_AX_TMAC_IMR_CLR,
+ .tmac_imr_set = B_AX_TMAC_IMR_SET,
+};
+
+static const struct rtw89_rrsr_cfgs rtw8852bt_rrsr_cfgs = {
+ .ref_rate = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_REF_RATE_SEL, 0},
+ .rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2},
+};
+
+static const struct rtw89_rfkill_regs rtw8852bt_rfkill_regs = {
+ .pinmux = {R_AX_GPIO8_15_FUNC_SEL,
+ B_AX_PINMUX_GPIO9_FUNC_SEL_MASK,
+ 0xf},
+ .mode = {R_AX_GPIO_EXT_CTRL + 2,
+ (B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16,
+ 0x0},
+};
+
+static const struct rtw89_dig_regs rtw8852bt_dig_regs = {
+ .seg0_pd_reg = R_SEG0R_PD_V1,
+ .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
+ .pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1,
+ .bmode_pd_reg = R_BMODE_PDTH_EN_V1,
+ .bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1,
+ .bmode_pd_lower_bound_reg = R_BMODE_PDTH_V1,
+ .bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1,
+ .p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK},
+ .p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK},
+ .p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1},
+ .p1_tia_init = {R_PATH1_TIA_INIT_V1, B_PATH1_TIA_INIT_IDX_MSK_V1},
+ .p0_rxb_init = {R_PATH0_RXB_INIT_V1, B_PATH0_RXB_INIT_IDX_MSK_V1},
+ .p1_rxb_init = {R_PATH1_RXB_INIT_V1, B_PATH1_RXB_INIT_IDX_MSK_V1},
+ .p0_p20_pagcugc_en = {R_PATH0_P20_FOLLOW_BY_PAGCUGC_V2,
+ B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK},
+ .p0_s20_pagcugc_en = {R_PATH0_S20_FOLLOW_BY_PAGCUGC_V2,
+ B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
+ .p1_p20_pagcugc_en = {R_PATH1_P20_FOLLOW_BY_PAGCUGC_V2,
+ B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK},
+ .p1_s20_pagcugc_en = {R_PATH1_S20_FOLLOW_BY_PAGCUGC_V2,
+ B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK},
+};
+
+static const struct rtw89_edcca_regs rtw8852bt_edcca_regs = {
+ .edcca_level = R_SEG0R_EDCCA_LVL_V1,
+ .edcca_mask = B_EDCCA_LVL_MSK0,
+ .edcca_p_mask = B_EDCCA_LVL_MSK1,
+ .ppdu_level = R_SEG0R_EDCCA_LVL_V1,
+ .ppdu_mask = B_EDCCA_LVL_MSK3,
+ .p = {{
+ .rpt_a = R_EDCCA_RPT_A,
+ .rpt_b = R_EDCCA_RPT_B,
+ .rpt_sel = R_EDCCA_RPT_SEL,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ }, {
+ .rpt_a = R_EDCCA_RPT_P1_A,
+ .rpt_b = R_EDCCA_RPT_P1_B,
+ .rpt_sel = R_EDCCA_RPT_SEL,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK,
+ }},
+ .tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
+ .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
+};
+
+static const struct rtw89_btc_rf_trx_para rtw89_btc_8852bt_rf_ul[] = {
+ {255, 0, 0, 7}, /* 0 -> original */
+ {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
+ {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
+ {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
+ {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
+ {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */
+ {6, 1, 0, 7},
+ {13, 1, 0, 7},
+ {13, 1, 0, 7}
+};
+
+static const struct rtw89_btc_rf_trx_para rtw89_btc_8852bt_rf_dl[] = {
+ {255, 0, 0, 7}, /* 0 -> original */
+ {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */
+ {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
+ {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
+ {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
+ {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */
+ {255, 1, 0, 7},
+ {255, 1, 0, 7},
+ {255, 1, 0, 7}
+};
+
+static const struct rtw89_btc_fbtc_mreg rtw89_btc_8852bt_mon_reg[] = {
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda24),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda28),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda2c),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda30),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda4c),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda10),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda20),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda34),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xcef4),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x8424),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd200),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xd220),
+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980),
+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4aa4),
+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x4778),
+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x476c),
+};
+
+static const u8 rtw89_btc_8852bt_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {70, 60, 50, 40};
+static const u8 rtw89_btc_8852bt_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20};
+
+static int rtw8852bt_pwr_on_func(struct rtw89_dev *rtwdev)
+{
+ u32 val32;
+ int ret;
+
+ rtw89_write32_set(rtwdev, R_AX_LDO_AON_CTRL0, B_AX_PD_REGU_L);
+ rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN |
+ B_AX_AFSM_PCIE_SUS_EN);
+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_DIS_WLBT_PDNSUSEN_SOPC);
+ rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_DIS_WLBT_LPSEN_LOPC);
+ rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APDM_HPDN);
+ rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_OCP_L1_MASK, 7);
+
+ ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_RDY_SYSPWR,
+ 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
+ if (ret)
+ return ret;
+
+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC);
+
+ ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFN_ONMAC),
+ 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
+ if (ret)
+ return ret;
+
+ rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
+ rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
+ rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
+ rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
+ rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
+ rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1);
+ rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3);
+
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL,
+ XTAL_SI_GND_SHDN_WL, XTAL_SI_GND_SHDN_WL);
+ if (ret)
+ return ret;
+
+ rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3);
+
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL,
+ XTAL_SI_SHDN_WL, XTAL_SI_SHDN_WL);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_WEI,
+ XTAL_SI_OFF_WEI);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_EI,
+ XTAL_SI_OFF_EI);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_RFC2RF);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_WEI,
+ XTAL_SI_PON_WEI);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_EI,
+ XTAL_SI_PON_EI);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SRAM2RFC);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_SRAM_CTRL, 0, XTAL_SI_SRAM_DIS);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0, XTAL_SI_LDO_LPS);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_4, 0, XTAL_SI_LPS_CAP);
+ if (ret)
+ return ret;
+
+ rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
+ rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE);
+ rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15);
+
+ fsleep(1000);
+
+ rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14);
+ rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
+
+ if (!rtwdev->efuse.valid || rtwdev->efuse.power_k_valid)
+ goto func_en;
+
+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_VOL_L1_MASK, 0x9);
+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_VREFPFM_L_MASK, 0xA);
+
+func_en:
+ rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN,
+ B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MPDU_PROC_EN |
+ B_AX_WD_RLS_EN | B_AX_DLE_WDE_EN | B_AX_TXPKT_CTRL_EN |
+ B_AX_STA_SCH_EN | B_AX_DLE_PLE_EN | B_AX_PKT_BUF_EN |
+ B_AX_DMAC_TBL_EN | B_AX_PKT_IN_EN | B_AX_DLE_CPUIO_EN |
+ B_AX_DISPATCHER_EN | B_AX_BBRPT_EN | B_AX_MAC_SEC_EN |
+ B_AX_DMACREG_GCKEN);
+ rtw89_write32_set(rtwdev, R_AX_CMAC_FUNC_EN,
+ B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN |
+ B_AX_FORCE_CMACREG_GCKEN | B_AX_PHYINTF_EN | B_AX_CMAC_DMA_EN |
+ B_AX_PTCLTOP_EN | B_AX_SCHEDULER_EN | B_AX_TMAC_EN |
+ B_AX_RMAC_EN);
+
+ rtw89_write32_mask(rtwdev, R_AX_EECS_EESK_FUNC_SEL,
+ B_AX_PINMUX_EESK_FUNC_SEL_MASK, 0x1);
+
+ return 0;
+}
+
+static int rtw8852bt_pwr_off_func(struct rtw89_dev *rtwdev)
+{
+ u32 val32;
+ int ret;
+
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
+ XTAL_SI_RFC2RF);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_EI);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_WEI);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0, XTAL_SI_RF00);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0, XTAL_SI_RF10);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_SRAM2RFC,
+ XTAL_SI_SRAM2RFC);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_EI);
+ if (ret)
+ return ret;
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_WEI);
+ if (ret)
+ return ret;
+
+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
+ rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
+ rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB);
+ rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3);
+
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SHDN_WL);
+ if (ret)
+ return ret;
+
+ rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3);
+
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_GND_SHDN_WL);
+ if (ret)
+ return ret;
+
+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_OFFMAC);
+
+ ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFM_OFFMAC),
+ 1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
+ if (ret)
+ return ret;
+
+ rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION);
+ rtw89_write32_set(rtwdev, R_AX_SYS_SWR_CTRL1, B_AX_SYM_CTRL_SPS_PWMFREQ);
+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, B_AX_REG_ZCDC_H_MASK, 0x3);
+ rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
+
+ return 0;
+}
+
+static void rtw8852bt_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band,
+ enum rtw89_phy_idx phy_idx, bool en)
+{
+ if (en) {
+ rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS,
+ B_S0_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS,
+ B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx);
+ if (band == RTW89_BAND_2G)
+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0);
+ } else {
+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1);
+ rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS,
+ B_S0_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx);
+ rtw89_phy_write32_idx(rtwdev, R_S1_HW_SI_DIS,
+ B_S1_HW_SI_DIS_W_R_TRIG, 0x7, phy_idx);
+ fsleep(1);
+ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, phy_idx);
+ }
+}
+
+static void rtw8852bt_bb_reset(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
+{
+ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
+ B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI, 0x1);
+ rtw89_phy_write32_set(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
+ B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI, 0x1);
+ rtw89_phy_write32_set(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN);
+ rtw8852bx_bb_reset_all(rtwdev, phy_idx);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
+ B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI, 3);
+ rtw89_phy_write32_clr(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
+ B_P1_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI, 0x3);
+ rtw89_phy_write32_clr(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN);
+}
+
+static void rtw8852bt_set_channel(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_mac_idx mac_idx,
+ enum rtw89_phy_idx phy_idx)
+{
+ rtw8852bx_set_channel_mac(rtwdev, chan, mac_idx);
+ rtw8852bx_set_channel_bb(rtwdev, chan, phy_idx);
+ rtw8852bt_set_channel_rf(rtwdev, chan, phy_idx);
+}
+
+static void rtw8852bt_tssi_cont_en(struct rtw89_dev *rtwdev, bool en,
+ enum rtw89_rf_path path)
+{
+ static const u32 tssi_trk[2] = {R_P0_TSSI_TRK, R_P1_TSSI_TRK};
+
+ if (en)
+ rtw89_phy_write32_mask(rtwdev, tssi_trk[path], B_P0_TSSI_TRK_EN, 0x0);
+ else
+ rtw89_phy_write32_mask(rtwdev, tssi_trk[path], B_P0_TSSI_TRK_EN, 0x1);
+}
+
+static void rtw8852bt_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en,
+ u8 phy_idx, const struct rtw89_chan *chan)
+{
+ if (!rtwdev->dbcc_en) {
+ rtw8852bt_tssi_cont_en(rtwdev, en, RF_PATH_A);
+ rtw8852bt_tssi_cont_en(rtwdev, en, RF_PATH_B);
+ rtw8852bt_tssi_scan(rtwdev, phy_idx, chan);
+ } else {
+ if (phy_idx == RTW89_PHY_0)
+ rtw8852bt_tssi_cont_en(rtwdev, en, RF_PATH_A);
+ else
+ rtw8852bt_tssi_cont_en(rtwdev, en, RF_PATH_B);
+ }
+}
+
+static void rtw8852bt_adc_en(struct rtw89_dev *rtwdev, bool en)
+{
+ if (en)
+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0);
+ else
+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0xf);
+}
+
+static void rtw8852bt_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
+ struct rtw89_channel_help_params *p,
+ const struct rtw89_chan *chan,
+ enum rtw89_mac_idx mac_idx,
+ enum rtw89_phy_idx phy_idx)
+{
+ if (enter) {
+ rtw89_chip_stop_sch_tx(rtwdev, RTW89_MAC_0, &p->tx_en, RTW89_SCH_TX_SEL_ALL);
+ rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false);
+ rtw8852bt_tssi_cont_en_phyidx(rtwdev, false, RTW89_PHY_0, chan);
+ rtw8852bt_adc_en(rtwdev, false);
+ fsleep(40);
+ rtw8852bt_bb_reset_en(rtwdev, chan->band_type, phy_idx, false);
+ } else {
+ rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true);
+ rtw8852bt_adc_en(rtwdev, true);
+ rtw8852bt_tssi_cont_en_phyidx(rtwdev, true, RTW89_PHY_0, chan);
+ rtw8852bt_bb_reset_en(rtwdev, chan->band_type, phy_idx, true);
+ rtw89_chip_resume_sch_tx(rtwdev, RTW89_MAC_0, p->tx_en);
+ }
+}
+
+static void rtw8852bt_rfk_init(struct rtw89_dev *rtwdev)
+{
+ rtwdev->is_tssi_mode[RF_PATH_A] = false;
+ rtwdev->is_tssi_mode[RF_PATH_B] = false;
+
+ rtw8852bt_dpk_init(rtwdev);
+ rtw8852bt_rck(rtwdev);
+ rtw8852bt_dack(rtwdev, RTW89_CHANCTX_0);
+ rtw8852bt_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0);
+}
+
+static void rtw8852bt_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
+ enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
+
+ rtw89_btc_ntfy_conn_rfk(rtwdev, true);
+
+ rtw8852bt_rx_dck(rtwdev, phy_idx, chanctx_idx);
+ rtw8852bt_iqk(rtwdev, phy_idx, chanctx_idx);
+ rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
+ rtw8852bt_tssi(rtwdev, phy_idx, true, chanctx_idx);
+ rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
+ rtw8852bt_dpk(rtwdev, phy_idx, chanctx_idx);
+
+ rtw89_btc_ntfy_conn_rfk(rtwdev, false);
+}
+
+static void rtw8852bt_rfk_band_changed(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan)
+{
+ rtw8852bt_tssi_scan(rtwdev, phy_idx, chan);
+}
+
+static void rtw8852bt_rfk_scan(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ bool start)
+{
+ rtw8852bt_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx,
+ rtwvif_link->chanctx_idx);
+}
+
+static void rtw8852bt_rfk_track(struct rtw89_dev *rtwdev)
+{
+ rtw8852bt_dpk_track(rtwdev);
+}
+
+static void rtw8852bt_btc_set_rfe(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_btc_ver *ver = rtwdev->btc.ver;
+ union rtw89_btc_module_info *md = &rtwdev->btc.mdinfo;
+
+ if (ver->fcxinit == 7) {
+ md->md_v7.rfe_type = rtwdev->efuse.rfe_type;
+ md->md_v7.kt_ver = rtwdev->hal.cv;
+ md->md_v7.kt_ver_adie = rtwdev->hal.acv;
+ md->md_v7.bt_solo = 0;
+ md->md_v7.bt_pos = BTC_BT_BTG;
+ md->md_v7.switch_type = BTC_SWITCH_INTERNAL;
+ md->md_v7.wa_type = 0;
+
+ md->md_v7.ant.type = BTC_ANT_SHARED;
+ md->md_v7.ant.num = 2;
+ md->md_v7.ant.isolation = 10;
+ md->md_v7.ant.diversity = 0;
+ /* WL 1-stream+1-Ant is located at 0:s0(path-A) or 1:s1(path-B) */
+ md->md_v7.ant.single_pos = RF_PATH_A;
+ md->md_v7.ant.btg_pos = RF_PATH_B;
+
+ if (md->md_v7.rfe_type == 0) {
+ rtwdev->btc.dm.error.map.rfe_type0 = true;
+ return;
+ }
+
+ md->md_v7.ant.num = (md->md_v7.rfe_type % 2) ? 2 : 3;
+ md->md_v7.ant.stream_cnt = 2;
+ md->md_v7.wa_type |= BTC_WA_INIT_SCAN;
+
+ if (md->md_v7.ant.num == 2) {
+ md->md_v7.ant.type = BTC_ANT_SHARED;
+ md->md_v7.bt_pos = BTC_BT_BTG;
+ md->md_v7.wa_type |= BTC_WA_HFP_LAG;
+ } else {
+ md->md_v7.ant.type = BTC_ANT_DEDICATED;
+ md->md_v7.bt_pos = BTC_BT_ALONE;
+ }
+ } else {
+ return;
+ }
+}
+
+static void
+rtw8852bt_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val)
+{
+ u16 ctrl_all_time = u32_get_bits(txpwr_val, GENMASK(15, 0));
+ u16 ctrl_gnt_bt = u32_get_bits(txpwr_val, GENMASK(31, 16));
+
+ switch (ctrl_all_time) {
+ case 0xffff:
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_RATE_CTRL,
+ B_AX_FORCE_PWR_BY_RATE_EN, 0x0);
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_RATE_CTRL,
+ B_AX_FORCE_PWR_BY_RATE_VALUE_MASK, 0x0);
+ break;
+ default:
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_RATE_CTRL,
+ B_AX_FORCE_PWR_BY_RATE_VALUE_MASK,
+ ctrl_all_time);
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_RATE_CTRL,
+ B_AX_FORCE_PWR_BY_RATE_EN, 0x1);
+ break;
+ }
+
+ switch (ctrl_gnt_bt) {
+ case 0xffff:
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_COEXT_CTRL,
+ B_AX_TXAGC_BT_EN, 0x0);
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_COEXT_CTRL,
+ B_AX_TXAGC_BT_MASK, 0x0);
+ break;
+ default:
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_COEXT_CTRL,
+ B_AX_TXAGC_BT_MASK, ctrl_gnt_bt);
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_AX_PWR_COEXT_CTRL,
+ B_AX_TXAGC_BT_EN, 0x1);
+ break;
+ }
+}
+
+static const struct rtw89_chip_ops rtw8852bt_chip_ops = {
+ .enable_bb_rf = rtw8852bx_mac_enable_bb_rf,
+ .disable_bb_rf = rtw8852bx_mac_disable_bb_rf,
+ .bb_preinit = NULL,
+ .bb_postinit = NULL,
+ .bb_reset = rtw8852bt_bb_reset,
+ .bb_sethw = rtw8852bx_bb_sethw,
+ .read_rf = rtw89_phy_read_rf_v1,
+ .write_rf = rtw89_phy_write_rf_v1,
+ .set_channel = rtw8852bt_set_channel,
+ .set_channel_help = rtw8852bt_set_channel_help,
+ .read_efuse = rtw8852bx_read_efuse,
+ .read_phycap = rtw8852bx_read_phycap,
+ .fem_setup = NULL,
+ .rfe_gpio = NULL,
+ .rfk_hw_init = NULL,
+ .rfk_init = rtw8852bt_rfk_init,
+ .rfk_init_late = NULL,
+ .rfk_channel = rtw8852bt_rfk_channel,
+ .rfk_band_changed = rtw8852bt_rfk_band_changed,
+ .rfk_scan = rtw8852bt_rfk_scan,
+ .rfk_track = rtw8852bt_rfk_track,
+ .power_trim = rtw8852bx_power_trim,
+ .set_txpwr = rtw8852bx_set_txpwr,
+ .set_txpwr_ctrl = rtw8852bx_set_txpwr_ctrl,
+ .init_txpwr_unit = rtw8852bx_init_txpwr_unit,
+ .get_thermal = rtw8852bx_get_thermal,
+ .ctrl_btg_bt_rx = rtw8852bx_ctrl_btg_bt_rx,
+ .query_ppdu = rtw8852bx_query_ppdu,
+ .convert_rpl_to_rssi = rtw8852bx_convert_rpl_to_rssi,
+ .phy_rpt_to_rssi = NULL,
+ .ctrl_nbtg_bt_tx = rtw8852bx_ctrl_nbtg_bt_tx,
+ .cfg_txrx_path = rtw8852bx_bb_cfg_txrx_path,
+ .set_txpwr_ul_tb_offset = rtw8852bx_set_txpwr_ul_tb_offset,
+ .digital_pwr_comp = NULL,
+ .pwr_on_func = rtw8852bt_pwr_on_func,
+ .pwr_off_func = rtw8852bt_pwr_off_func,
+ .query_rxdesc = rtw89_core_query_rxdesc,
+ .fill_txdesc = rtw89_core_fill_txdesc,
+ .fill_txdesc_fwcmd = rtw89_core_fill_txdesc,
+ .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path,
+ .mac_cfg_gnt = rtw89_mac_cfg_gnt,
+ .stop_sch_tx = rtw89_mac_stop_sch_tx,
+ .resume_sch_tx = rtw89_mac_resume_sch_tx,
+ .h2c_dctl_sec_cam = NULL,
+ .h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl,
+ .h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl,
+ .h2c_ampdu_cmac_tbl = NULL,
+ .h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl,
+ .h2c_default_dmac_tbl = NULL,
+ .h2c_update_beacon = rtw89_fw_h2c_update_beacon,
+ .h2c_ba_cam = rtw89_fw_h2c_ba_cam,
+
+ .btc_set_rfe = rtw8852bt_btc_set_rfe,
+ .btc_init_cfg = rtw8852bx_btc_init_cfg,
+ .btc_set_wl_pri = rtw8852bx_btc_set_wl_pri,
+ .btc_set_wl_txpwr_ctrl = rtw8852bt_btc_set_wl_txpwr_ctrl,
+ .btc_get_bt_rssi = rtw8852bx_btc_get_bt_rssi,
+ .btc_update_bt_cnt = rtw8852bx_btc_update_bt_cnt,
+ .btc_wl_s1_standby = rtw8852bx_btc_wl_s1_standby,
+ .btc_set_wl_rx_gain = rtw8852bx_btc_set_wl_rx_gain,
+ .btc_set_policy = rtw89_btc_set_policy_v1,
+};
+
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support rtw_wowlan_stub_8852bt = {
+ .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
+ .n_patterns = RTW89_MAX_PATTERN_NUM,
+ .pattern_max_len = RTW89_MAX_PATTERN_SIZE,
+ .pattern_min_len = 1,
+};
+#endif
+
+const struct rtw89_chip_info rtw8852bt_chip_info = {
+ .chip_id = RTL8852BT,
+ .chip_gen = RTW89_CHIP_AX,
+ .ops = &rtw8852bt_chip_ops,
+ .mac_def = &rtw89_mac_gen_ax,
+ .phy_def = &rtw89_phy_gen_ax,
+ .fw_basename = RTW8852BT_FW_BASENAME,
+ .fw_format_max = RTW8852BT_FW_FORMAT_MAX,
+ .try_ce_fw = true,
+ .bbmcu_nr = 0,
+ .needed_fw_elms = RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_NO_6GHZ,
+ .fw_blacklist = &rtw89_fw_blacklist_default,
+ .fifo_size = 458752,
+ .small_fifo_size = true,
+ .dle_scc_rsvd_size = 98304,
+ .max_amsdu_limit = 5000,
+ .dis_2g_40m_ul_ofdma = true,
+ .rsvd_ple_ofst = 0x6f800,
+ .hfc_param_ini = rtw8852bt_hfc_param_ini_pcie,
+ .dle_mem = rtw8852bt_dle_mem_pcie,
+ .wde_qempty_acq_grpnum = 4,
+ .wde_qempty_mgq_grpsel = 4,
+ .rf_base_addr = {0xe000, 0xf000},
+ .thermal_th = {0x32, 0x35},
+ .pwr_on_seq = NULL,
+ .pwr_off_seq = NULL,
+ .bb_table = NULL,
+ .bb_gain_table = NULL,
+ .rf_table = {},
+ .nctl_table = NULL,
+ .nctl_post_table = NULL,
+ .dflt_parms = NULL,
+ .rfe_parms_conf = NULL,
+ .txpwr_factor_bb = 3,
+ .txpwr_factor_rf = 2,
+ .txpwr_factor_mac = 1,
+ .dig_table = NULL,
+ .dig_regs = &rtw8852bt_dig_regs,
+ .tssi_dbw_table = NULL,
+ .support_macid_num = RTW89_MAX_MAC_ID_NUM,
+ .support_link_num = 0,
+ .support_chanctx_num = 1,
+ .support_rnr = false,
+ .support_bands = BIT(NL80211_BAND_2GHZ) |
+ BIT(NL80211_BAND_5GHZ),
+ .support_bandwidths = BIT(NL80211_CHAN_WIDTH_20) |
+ BIT(NL80211_CHAN_WIDTH_40) |
+ BIT(NL80211_CHAN_WIDTH_80),
+ .support_unii4 = true,
+ .support_ant_gain = true,
+ .support_tas = false,
+ .support_sar_by_ant = true,
+ .ul_tb_waveform_ctrl = true,
+ .ul_tb_pwr_diff = false,
+ .rx_freq_frome_ie = true,
+ .hw_sec_hdr = false,
+ .hw_mgmt_tx_encrypt = false,
+ .hw_tkip_crypto = true,
+ .hw_mlo_bmc_crypto = false,
+ .rf_path_num = 2,
+ .tx_nss = 2,
+ .rx_nss = 2,
+ .acam_num = 128,
+ .bcam_num = 10,
+ .scam_num = 128,
+ .bacam_num = 2,
+ .bacam_dynamic_num = 4,
+ .bacam_ver = RTW89_BACAM_V0,
+ .ppdu_max_usr = 4,
+ .sec_ctrl_efuse_size = 4,
+ .physical_efuse_size = 1216,
+ .logical_efuse_size = 2048,
+ .limit_efuse_size = 1280,
+ .dav_phy_efuse_size = 96,
+ .dav_log_efuse_size = 16,
+ .efuse_blocks = NULL,
+ .phycap_addr = 0x580,
+ .phycap_size = 128,
+ .para_ver = 0,
+ .wlcx_desired = 0x070e0000,
+ .btcx_desired = 0x7,
+ .scbd = 0x1,
+ .mailbox = 0x1,
+
+ .afh_guard_ch = 6,
+ .wl_rssi_thres = rtw89_btc_8852bt_wl_rssi_thres,
+ .bt_rssi_thres = rtw89_btc_8852bt_bt_rssi_thres,
+ .rssi_tol = 2,
+ .mon_reg_num = ARRAY_SIZE(rtw89_btc_8852bt_mon_reg),
+ .mon_reg = rtw89_btc_8852bt_mon_reg,
+ .rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8852bt_rf_ul),
+ .rf_para_ulink = rtw89_btc_8852bt_rf_ul,
+ .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8852bt_rf_dl),
+ .rf_para_dlink = rtw89_btc_8852bt_rf_dl,
+ .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) |
+ BIT(RTW89_PS_MODE_CLK_GATED) |
+ BIT(RTW89_PS_MODE_PWR_GATED),
+ .low_power_hci_modes = 0,
+ .h2c_cctl_func_id = H2C_FUNC_MAC_CCTLINFO_UD,
+ .hci_func_en_addr = R_AX_HCI_FUNC_EN,
+ .h2c_desc_size = sizeof(struct rtw89_txwd_body),
+ .txwd_body_size = sizeof(struct rtw89_txwd_body),
+ .txwd_info_size = sizeof(struct rtw89_txwd_info),
+ .h2c_ctrl_reg = R_AX_H2CREG_CTRL,
+ .h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8},
+ .h2c_regs = rtw8852bt_h2c_regs,
+ .c2h_ctrl_reg = R_AX_C2HREG_CTRL,
+ .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8},
+ .c2h_regs = rtw8852bt_c2h_regs,
+ .page_regs = &rtw8852bt_page_regs,
+ .wow_reason_reg = rtw8852bt_wow_wakeup_regs,
+ .cfo_src_fd = true,
+ .cfo_hw_comp = true,
+ .dcfo_comp = &rtw8852bt_dcfo_comp,
+ .dcfo_comp_sft = 10,
+ .imr_info = &rtw8852bt_imr_info,
+ .imr_dmac_table = NULL,
+ .imr_cmac_table = NULL,
+ .rrsr_cfgs = &rtw8852bt_rrsr_cfgs,
+ .bss_clr_vld = {R_BSS_CLR_MAP_V1, B_BSS_CLR_MAP_VLD0},
+ .bss_clr_map_reg = R_BSS_CLR_MAP_V1,
+ .rfkill_init = &rtw8852bt_rfkill_regs,
+ .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9},
+ .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) |
+ BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) |
+ BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI),
+ .edcca_regs = &rtw8852bt_edcca_regs,
+#ifdef CONFIG_PM
+ .wowlan_stub = &rtw_wowlan_stub_8852bt,
+#endif
+ .xtal_info = NULL,
+};
+EXPORT_SYMBOL(rtw8852bt_chip_info);
+
+MODULE_FIRMWARE(RTW8852BT_MODULE_FIRMWARE);
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852BT driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.h b/drivers/net/wireless/realtek/rtw89/rtw8852bt.h
new file mode 100644
index 000000000000..b76b36aaf025
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#ifndef __RTW89_8852BT_H__
+#define __RTW89_8852BT_H__
+
+#include "core.h"
+
+#define RF_PATH_NUM_8852BT 2
+#define BB_PATH_NUM_8852BT 2
+
+extern const struct rtw89_chip_info rtw8852bt_chip_info;
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c
new file mode 100644
index 000000000000..6e6889eea9a0
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c
@@ -0,0 +1,4254 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#include "coex.h"
+#include "debug.h"
+#include "fw.h"
+#include "mac.h"
+#include "phy.h"
+#include "reg.h"
+#include "rtw8852bt.h"
+#include "rtw8852bt_rfk.h"
+#include "rtw8852bt_rfk_table.h"
+#include "rtw8852b_common.h"
+
+#define RTW8852BT_RXDCK_VER 0x1
+#define RTW8852BT_IQK_VER 0x2a
+#define RTW8852BT_SS 2
+#define RTW8852BT_TSSI_PATH_NR 2
+#define RTW8852BT_DPK_VER 0x06
+#define DPK_RF_PATH_MAX_8852BT 2
+
+#define _TSSI_DE_MASK GENMASK(21, 12)
+#define DPK_TXAGC_LOWER 0x2e
+#define DPK_TXAGC_UPPER 0x3f
+#define DPK_TXAGC_INVAL 0xff
+#define RFREG_MASKRXBB 0x003e0
+#define RFREG_MASKMODE 0xf0000
+
+enum rf_mode {
+ RF_SHUT_DOWN = 0x0,
+ RF_STANDBY = 0x1,
+ RF_TX = 0x2,
+ RF_RX = 0x3,
+ RF_TXIQK = 0x4,
+ RF_DPK = 0x5,
+ RF_RXK1 = 0x6,
+ RF_RXK2 = 0x7,
+};
+
+enum rtw8852bt_dpk_id {
+ LBK_RXIQK = 0x06,
+ SYNC = 0x10,
+ MDPK_IDL = 0x11,
+ MDPK_MPA = 0x12,
+ GAIN_LOSS = 0x13,
+ GAIN_CAL = 0x14,
+ DPK_RXAGC = 0x15,
+ KIP_PRESET = 0x16,
+ KIP_RESTORE = 0x17,
+ DPK_TXAGC = 0x19,
+ D_KIP_PRESET = 0x28,
+ D_TXAGC = 0x29,
+ D_RXAGC = 0x2a,
+ D_SYNC = 0x2b,
+ D_GAIN_LOSS = 0x2c,
+ D_MDPK_IDL = 0x2d,
+ D_GAIN_NORM = 0x2f,
+ D_KIP_THERMAL = 0x30,
+ D_KIP_RESTORE = 0x31
+};
+
+enum dpk_agc_step {
+ DPK_AGC_STEP_SYNC_DGAIN,
+ DPK_AGC_STEP_GAIN_ADJ,
+ DPK_AGC_STEP_GAIN_LOSS_IDX,
+ DPK_AGC_STEP_GL_GT_CRITERION,
+ DPK_AGC_STEP_GL_LT_CRITERION,
+ DPK_AGC_STEP_SET_TX_GAIN,
+};
+
+enum rtw8852bt_iqk_type {
+ ID_TXAGC = 0x0,
+ ID_FLOK_COARSE = 0x1,
+ ID_FLOK_FINE = 0x2,
+ ID_TXK = 0x3,
+ ID_RXAGC = 0x4,
+ ID_RXK = 0x5,
+ ID_NBTXK = 0x6,
+ ID_NBRXK = 0x7,
+ ID_FLOK_VBUFFER = 0x8,
+ ID_A_FLOK_COARSE = 0x9,
+ ID_G_FLOK_COARSE = 0xa,
+ ID_A_FLOK_FINE = 0xb,
+ ID_G_FLOK_FINE = 0xc,
+ ID_IQK_RESTORE = 0x10,
+};
+
+enum adc_ck {
+ ADC_NA = 0,
+ ADC_480M = 1,
+ ADC_960M = 2,
+ ADC_1920M = 3,
+};
+
+enum dac_ck {
+ DAC_40M = 0,
+ DAC_80M = 1,
+ DAC_120M = 2,
+ DAC_160M = 3,
+ DAC_240M = 4,
+ DAC_320M = 5,
+ DAC_480M = 6,
+ DAC_960M = 7,
+};
+
+static const u32 _tssi_trigger[RTW8852BT_TSSI_PATH_NR] = {0x5820, 0x7820};
+static const u32 _tssi_cw_rpt_addr[RTW8852BT_TSSI_PATH_NR] = {0x1c18, 0x3c18};
+static const u32 _tssi_cw_default_addr[RTW8852BT_TSSI_PATH_NR][4] = {
+ {0x5634, 0x5630, 0x5630, 0x5630},
+ {0x7634, 0x7630, 0x7630, 0x7630} };
+static const u32 _tssi_cw_default_mask[4] = {
+ 0x000003ff, 0x3ff00000, 0x000ffc00, 0x000003ff};
+static const u32 _tssi_de_cck_long[RF_PATH_NUM_8852BT] = {0x5858, 0x7858};
+static const u32 _tssi_de_cck_short[RF_PATH_NUM_8852BT] = {0x5860, 0x7860};
+static const u32 _tssi_de_mcs_20m[RF_PATH_NUM_8852BT] = {0x5838, 0x7838};
+static const u32 _tssi_de_mcs_40m[RF_PATH_NUM_8852BT] = {0x5840, 0x7840};
+static const u32 _tssi_de_mcs_80m[RF_PATH_NUM_8852BT] = {0x5848, 0x7848};
+static const u32 _tssi_de_mcs_80m_80m[RF_PATH_NUM_8852BT] = {0x5850, 0x7850};
+static const u32 _tssi_de_mcs_5m[RF_PATH_NUM_8852BT] = {0x5828, 0x7828};
+static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8852BT] = {0x5830, 0x7830};
+
+static const u32 rtw8852bt_backup_bb_regs[] = {0x2344, 0x5800, 0x7800, 0x0704};
+static const u32 rtw8852bt_backup_rf_regs[] = {
+ 0xde, 0xdf, 0x8b, 0x90, 0x97, 0x85, 0x5, 0x10005};
+static const u32 rtw8852bt_backup_kip_regs[] = {
+ 0x813c, 0x8124, 0x8120, 0xc0d4, 0xc0d8, 0xc0c4, 0xc0ec,
+ 0x823c, 0x8224, 0x8220, 0xc1d4, 0xc1d8, 0xc1c4, 0xc1ec};
+
+#define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852bt_backup_bb_regs)
+#define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8852bt_backup_rf_regs)
+#define BACKUP_KIP_REGS_NR ARRAY_SIZE(rtw8852bt_backup_kip_regs)
+
+static void _rfk_get_thermal(struct rtw89_dev *rtwdev, u8 kidx, enum rtw89_rf_path path)
+{
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+
+ rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x1);
+ rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x1);
+
+ udelay(200);
+
+ dpk->bp[path][kidx].ther_dpk = rtw89_read_rf(rtwdev, path, RR_TM, RR_TM_VAL);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] thermal@DPK = 0x%x\n",
+ dpk->bp[path][kidx].ther_dpk);
+}
+
+static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[])
+{
+ u32 i;
+
+ for (i = 0; i < BACKUP_BB_REGS_NR; i++) {
+ backup_bb_reg_val[i] =
+ rtw89_phy_read32_mask(rtwdev, rtw8852bt_backup_bb_regs[i], MASKDWORD);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[RFK]backup bb reg : %x, value =%x\n",
+ rtw8852bt_backup_bb_regs[i], backup_bb_reg_val[i]);
+ }
+}
+
+static void _rfk_backup_kip_reg(struct rtw89_dev *rtwdev, u32 backup_kip_reg_val[])
+{
+ u32 i;
+
+ for (i = 0; i < BACKUP_KIP_REGS_NR; i++) {
+ backup_kip_reg_val[i] =
+ rtw89_phy_read32_mask(rtwdev, rtw8852bt_backup_kip_regs[i],
+ MASKDWORD);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup 0x%x = %x\n",
+ rtw8852bt_backup_kip_regs[i], backup_kip_reg_val[i]);
+ }
+}
+
+static
+void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[], u8 rf_path)
+{
+ u32 i;
+
+ for (i = 0; i < BACKUP_RF_REGS_NR; i++) {
+ backup_rf_reg_val[i] =
+ rtw89_read_rf(rtwdev, rf_path, rtw8852bt_backup_rf_regs[i],
+ RFREG_MASK);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup RF S%d 0x%x = %x\n",
+ rf_path, rtw8852bt_backup_rf_regs[i], backup_rf_reg_val[i]);
+ }
+}
+
+static void _rfk_reload_bb_reg(struct rtw89_dev *rtwdev, const u32 backup_bb_reg_val[])
+{
+ u32 i;
+
+ for (i = 0; i < BACKUP_BB_REGS_NR; i++) {
+ rtw89_phy_write32_mask(rtwdev, rtw8852bt_backup_bb_regs[i],
+ MASKDWORD, backup_bb_reg_val[i]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[RFK]restore bb reg : %x, value =%x\n",
+ rtw8852bt_backup_bb_regs[i], backup_bb_reg_val[i]);
+ }
+}
+
+static void _rfk_reload_kip_reg(struct rtw89_dev *rtwdev, u32 backup_kip_reg_val[])
+{
+ u32 i;
+
+ for (i = 0; i < BACKUP_KIP_REGS_NR; i++) {
+ rtw89_phy_write32_mask(rtwdev, rtw8852bt_backup_kip_regs[i],
+ MASKDWORD, backup_kip_reg_val[i]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[RFK]restore kip reg : %x, value =%x\n",
+ rtw8852bt_backup_kip_regs[i], backup_kip_reg_val[i]);
+ }
+}
+
+static void _rfk_reload_rf_reg(struct rtw89_dev *rtwdev,
+ const u32 backup_rf_reg_val[], u8 rf_path)
+{
+ u32 i;
+
+ for (i = 0; i < BACKUP_RF_REGS_NR; i++) {
+ rtw89_write_rf(rtwdev, rf_path, rtw8852bt_backup_rf_regs[i],
+ RFREG_MASK, backup_rf_reg_val[i]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[RFK]restore rf S%d reg: %x, value =%x\n", rf_path,
+ rtw8852bt_backup_rf_regs[i], backup_rf_reg_val[i]);
+ }
+}
+
+static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+ u8 val;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x,PHY%d\n",
+ rtwdev->dbcc_en, phy_idx);
+
+ if (!rtwdev->dbcc_en) {
+ val = RF_AB;
+ } else {
+ if (phy_idx == RTW89_PHY_0)
+ val = RF_A;
+ else
+ val = RF_B;
+ }
+ return val;
+}
+
+static
+void _txck_force(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool force,
+ enum dac_ck ck)
+{
+ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, 0x0);
+
+ if (!force)
+ return;
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_VAL, ck);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, 0x1);
+}
+
+static
+void _rxck_force(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool force,
+ enum adc_ck ck)
+{
+ u32 bw = 0;
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x0);
+
+ if (!force)
+ return;
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_VAL, ck);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x1);
+
+ switch (ck) {
+ case ADC_480M:
+ bw = RTW89_CHANNEL_WIDTH_40;
+ break;
+ case ADC_960M:
+ bw = RTW89_CHANNEL_WIDTH_80;
+ break;
+ case ADC_1920M:
+ bw = RTW89_CHANNEL_WIDTH_160;
+ break;
+ default:
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "%s==>Invalid ck", __func__);
+ break;
+ }
+
+ rtw8852bx_adc_cfg(rtwdev, bw, path);
+}
+
+static void _rfk_bb_afe_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, u8 kpath)
+{
+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, MASKHWORD, 0x0303);
+ rtw89_phy_write32_mask(rtwdev, R_P0_ADCFF_EN, B_P0_ADCFF_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_ADCFF_EN, B_P1_ADCFF_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_CLKG_FORCE, 0x3);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_CLKG_FORCE, 0x3);
+ rtw89_phy_write32_mask(rtwdev, R_TXCKEN_FORCE, B_TXCKEN_FORCE_ALL, 0x1ffffff);
+ rtw89_phy_write32_mask(rtwdev, R_FAHM, B_RXTD_CKEN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_GEN_ON, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_TX_COLLISION_T2R_ST, B_TXRX_FORCE_VAL, 0x3ff);
+ rtw89_phy_write32_mask(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_CLKEN, 0x3);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_DPK_RST, B_IQK_DPK_RST, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P0_PATH_RST, B_P0_PATH_RST, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_PATH_RST, B_P1_PATH_RST, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_DCFO_WEIGHT, B_DAC_CLK_IDX, 0x1);
+
+ _txck_force(rtwdev, RF_PATH_A, true, DAC_960M);
+ _txck_force(rtwdev, RF_PATH_B, true, DAC_960M);
+ _rxck_force(rtwdev, RF_PATH_A, true, ADC_1920M);
+ _rxck_force(rtwdev, RF_PATH_B, true, ADC_1920M);
+
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC,
+ B_UPD_CLK_ADC_VAL | B_UPD_CLK_ADC_ON, 0x5);
+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, MASKBYTE3, 0x1f);
+ udelay(1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, MASKBYTE3, 0x13);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, MASKHWORD, 0x0001);
+ udelay(1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, MASKHWORD, 0x0041);
+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_RSTB, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, MASKHWORD, 0x3333);
+
+ rtw89_phy_write32_mask(rtwdev, R_TXPWRB_H, B_TXPWRB_RDY, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_DPD_OFT_EN, MASKLWORD, 0x0000);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_FORCE, B_P1_TXPW_RDY, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TXAGC_TH, MASKLWORD, 0x0000);
+}
+
+static void _rfk_bb_afe_restore(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, u8 kpath)
+{
+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, MASKHWORD, 0x0303);
+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_CLKG_FORCE, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_CLKG_FORCE, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_TXCKEN_FORCE, B_TXCKEN_FORCE_ALL, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_FAHM, B_RXTD_CKEN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_GEN_ON, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_TX_COLLISION_T2R_ST, B_TXRX_FORCE_VAL, 0x63);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_TXCK_ALL, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_TXCK_ALL, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC,
+ B_UPD_CLK_ADC_VAL | B_UPD_CLK_ADC_ON, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, MASKHWORD, 0x0000);
+ rtw89_phy_write32_mask(rtwdev, R_P0_ADCFF_EN, B_P0_ADCFF_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_ADCFF_EN, B_P1_ADCFF_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0);
+
+ rtw89_phy_write32_mask(rtwdev, R_TXPWRB_H, B_TXPWRB_RDY, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TXPW_RSTB, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TXPW_RSTB, 0x2);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_FORCE, B_P1_TXPW_RDY, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TXPW_RSTB, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TXPW_RSTB, 0x2);
+}
+
+static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path)
+{
+ rtw89_write_rf(rtwdev, path, RR_DCK1, RR_DCK1_CLR, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1);
+ mdelay(1);
+}
+
+static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+{
+ u8 path, dck_tune;
+ u32 rf_reg5;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, CV : 0x%x) ******\n",
+ RTW8852BT_RXDCK_VER, rtwdev->hal.cv);
+
+ for (path = 0; path < RF_PATH_NUM_8852BT; path++) {
+ rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK);
+ dck_tune = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_FINE);
+
+ if (rtwdev->is_tssi_mode[path])
+ rtw89_phy_write32_mask(rtwdev,
+ R_P0_TSSI_TRK + (path << 13),
+ B_P0_TSSI_TRK_EN, 0x1);
+
+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX);
+ _set_rx_dck(rtwdev, phy, path);
+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, dck_tune);
+ rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5);
+
+ if (rtwdev->is_tssi_mode[path])
+ rtw89_phy_write32_mask(rtwdev,
+ R_P0_TSSI_TRK + (path << 13),
+ B_P0_TSSI_TRK_EN, 0x0);
+ }
+}
+
+static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
+{
+ u32 rf_reg5;
+ u32 rck_val;
+ u32 val;
+ int ret;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] ====== S%d RCK ======\n", path);
+
+ rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK);
+
+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF0x00 = 0x%05x\n",
+ rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK));
+
+ /* RCK trigger */
+ rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, 0x00240);
+
+ ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 30,
+ false, rtwdev, path, RR_RCKS, BIT(3));
+
+ rck_val = rtw89_read_rf(rtwdev, path, RR_RCKC, RR_RCKC_CA);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] rck_val = 0x%x, ret = %d\n",
+ rck_val, ret);
+
+ rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, rck_val);
+ rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF 0x1b = 0x%x\n",
+ rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK));
+}
+
+static void _drck(struct rtw89_dev *rtwdev)
+{
+ u32 rck_d;
+ u32 val;
+ int ret;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]Ddie RCK start!!!\n");
+ rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_EN, 0x1);
+
+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val,
+ 1, 10000, false,
+ rtwdev, R_DRCK_RES, B_DRCK_POL);
+ if (ret)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DRCK timeout\n");
+
+ rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x1);
+ udelay(1);
+ rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x0);
+
+ rck_d = rtw89_phy_read32_mask(rtwdev, R_DRCK_RES, 0x7c00);
+ rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_IDLE, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_VAL, rck_d);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0xc0c4 = 0x%x\n",
+ rtw89_phy_read32_mask(rtwdev, R_DRCK, MASKDWORD));
+}
+
+static void _dack_backup_s0(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_dack_info *dack = &rtwdev->dack;
+ u8 i;
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1);
+
+ for (i = 0; i < 0x10; i++) {
+ rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_V, i);
+ dack->msbk_d[0][0][i] =
+ rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0M0);
+
+ rtw89_phy_write32_mask(rtwdev, R_DCOF8, B_DCOF8_V, i);
+ dack->msbk_d[0][1][i] =
+ rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0M1);
+ }
+
+ dack->biask_d[0][0] =
+ rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS00, B_DACK_BIAS00);
+ dack->biask_d[0][1] =
+ rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS01, B_DACK_BIAS01);
+
+ dack->dadck_d[0][0] =
+ rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK00, B_DACK_DADCK00);
+ dack->dadck_d[0][1] =
+ rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK01, B_DACK_DADCK01);
+}
+
+static void _dack_backup_s1(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_dack_info *dack = &rtwdev->dack;
+ u8 i;
+
+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1);
+
+ for (i = 0; i < 0x10; i++) {
+ rtw89_phy_write32_mask(rtwdev, R_DACK10, B_DACK10, i);
+ dack->msbk_d[1][0][i] =
+ rtw89_phy_read32_mask(rtwdev, R_DACK10S, B_DACK10S);
+
+ rtw89_phy_write32_mask(rtwdev, R_DACK11, B_DACK11, i);
+ dack->msbk_d[1][1][i] =
+ rtw89_phy_read32_mask(rtwdev, R_DACK11S, B_DACK11S);
+ }
+
+ dack->biask_d[1][0] =
+ rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS10, B_DACK_BIAS10);
+ dack->biask_d[1][1] =
+ rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS11, B_DACK_BIAS11);
+
+ dack->dadck_d[1][0] =
+ rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK10, B_DACK_DADCK10);
+ dack->dadck_d[1][1] =
+ rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK11, B_DACK_DADCK11);
+}
+
+static
+void _dack_reset(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
+{
+ if (path == RF_PATH_A) {
+ rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_RST, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_RST, 0x1);
+ } else {
+ rtw89_phy_write32_mask(rtwdev, R_DACK10, B_DACK10_RST, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_DACK10, B_DACK10_RST, 0x1);
+ }
+}
+
+static
+void _dack_reload_by_path(struct rtw89_dev *rtwdev, u8 path, u8 index)
+{
+ struct rtw89_dack_info *dack = &rtwdev->dack;
+ u32 tmp, tmp_offset, tmp_reg;
+ u32 idx_offset, path_offset;
+ u8 i;
+
+ if (index == 0)
+ idx_offset = 0;
+ else
+ idx_offset = 0x14;
+
+ if (path == RF_PATH_A)
+ path_offset = 0;
+ else
+ path_offset = 0x28;
+
+ tmp_offset = idx_offset + path_offset;
+
+ rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_RST, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_DCOF9, B_DCOF9_RST, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_RST, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_DACK2_K, B_DACK2_RST, 0x1);
+
+ /* msbk_d: 15/14/13/12 */
+ tmp = 0x0;
+ for (i = 0; i < 4; i++)
+ tmp |= dack->msbk_d[path][index][i + 12] << (i * 8);
+ tmp_reg = 0xc200 + tmp_offset;
+ rtw89_phy_write32(rtwdev, tmp_reg, tmp);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg,
+ rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD));
+
+ /* msbk_d: 11/10/9/8 */
+ tmp = 0x0;
+ for (i = 0; i < 4; i++)
+ tmp |= dack->msbk_d[path][index][i + 8] << (i * 8);
+ tmp_reg = 0xc204 + tmp_offset;
+ rtw89_phy_write32(rtwdev, tmp_reg, tmp);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg,
+ rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD));
+
+ /* msbk_d: 7/6/5/4 */
+ tmp = 0x0;
+ for (i = 0; i < 4; i++)
+ tmp |= dack->msbk_d[path][index][i + 4] << (i * 8);
+ tmp_reg = 0xc208 + tmp_offset;
+ rtw89_phy_write32(rtwdev, tmp_reg, tmp);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg,
+ rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD));
+
+ /* msbk_d: 3/2/1/0 */
+ tmp = 0x0;
+ for (i = 0; i < 4; i++)
+ tmp |= dack->msbk_d[path][index][i] << (i * 8);
+ tmp_reg = 0xc20c + tmp_offset;
+ rtw89_phy_write32(rtwdev, tmp_reg, tmp);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg,
+ rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD));
+
+ /* dadak_d/biask_d */
+ tmp = (dack->biask_d[path][index] << 22) |
+ (dack->dadck_d[path][index] << 14);
+ tmp_reg = 0xc210 + tmp_offset;
+ rtw89_phy_write32(rtwdev, tmp_reg, tmp);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg,
+ rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD));
+
+ /* enable DACK result from reg */
+ rtw89_phy_write32_mask(rtwdev, R_DACKN0_CTL + tmp_offset, B_DACKN0_EN, 0x1);
+}
+
+static
+void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
+{
+ u8 i;
+
+ for (i = 0; i < 2; i++)
+ _dack_reload_by_path(rtwdev, path, i);
+}
+
+static bool _dack_s0_poll(struct rtw89_dev *rtwdev)
+{
+ if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P0, B_DACK_S0P0_OK) == 0 ||
+ rtw89_phy_read32_mask(rtwdev, R_DACK_S0P1, B_DACK_S0P1_OK) == 0 ||
+ rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0P2_OK) == 0 ||
+ rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0P3_OK) == 0)
+ return false;
+
+ return true;
+}
+
+static void _dack_s0(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_dack_info *dack = &rtwdev->dack;
+ bool done;
+ int ret;
+
+ _txck_force(rtwdev, RF_PATH_A, true, DAC_160M);
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, BIT(28), 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN1, 0x0);
+ udelay(100);
+ rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_VAL, 0x30);
+ rtw89_phy_write32_mask(rtwdev, R_DCOF9, B_DCOF9_VAL, 0x30);
+
+ _dack_reset(rtwdev, RF_PATH_A);
+
+ rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, 0x1);
+ udelay(1);
+
+ dack->msbk_timeout[0] = false;
+
+ ret = read_poll_timeout_atomic(_dack_s0_poll, done, done,
+ 1, 20000, false, rtwdev);
+ if (ret) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DACK timeout\n");
+ dack->msbk_timeout[0] = true;
+ }
+
+ rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, 0x0);
+
+ _txck_force(rtwdev, RF_PATH_A, false, DAC_960M);
+ _dack_backup_s0(rtwdev);
+ _dack_reload(rtwdev, RF_PATH_A);
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0);
+}
+
+static bool _dack_s1_poll(struct rtw89_dev *rtwdev)
+{
+ if (rtw89_phy_read32_mask(rtwdev, R_DACK_S1P0, B_DACK_S1P0_OK) == 0 ||
+ rtw89_phy_read32_mask(rtwdev, R_DACK_S1P1, B_DACK_S1P1_OK) == 0 ||
+ rtw89_phy_read32_mask(rtwdev, R_DACK_S1P2, B_DACK_S1P2_OK) == 0 ||
+ rtw89_phy_read32_mask(rtwdev, R_DACK_S1P3, B_DACK_S1P3_OK) == 0)
+ return false;
+
+ return true;
+}
+
+static void _dack_s1(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_dack_info *dack = &rtwdev->dack;
+ bool done;
+ int ret;
+
+ _txck_force(rtwdev, RF_PATH_B, true, DAC_160M);
+
+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, BIT(28), 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN1, 0x0);
+ udelay(100);
+ rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_VAL, 0x30);
+ rtw89_phy_write32_mask(rtwdev, R_DACK2_K, B_DACK2_VAL, 0x30);
+
+ _dack_reset(rtwdev, RF_PATH_B);
+
+ rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_EN, 0x1);
+ udelay(1);
+
+ dack->msbk_timeout[1] = false;
+
+ ret = read_poll_timeout_atomic(_dack_s1_poll, done, done,
+ 1, 10000, false, rtwdev);
+ if (ret) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DACK timeout\n");
+ dack->msbk_timeout[1] = true;
+ }
+
+ rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_EN, 0x0);
+
+ _txck_force(rtwdev, RF_PATH_B, false, DAC_960M);
+ _dack_backup_s1(rtwdev);
+ _dack_reload(rtwdev, RF_PATH_B);
+
+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0);
+}
+
+static void _dack(struct rtw89_dev *rtwdev)
+{
+ _dack_s0(rtwdev);
+ _dack_s1(rtwdev);
+}
+
+static void _dack_dump(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_dack_info *dack = &rtwdev->dack;
+ u8 i;
+ u8 t;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n",
+ dack->addck_d[0][0], dack->addck_d[0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]S1 ADC_DCK ic = 0x%x, qc = 0x%x\n",
+ dack->addck_d[1][0], dack->addck_d[1][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n",
+ dack->dadck_d[0][0], dack->dadck_d[0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n",
+ dack->dadck_d[1][0], dack->dadck_d[1][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n",
+ dack->biask_d[0][0], dack->biask_d[0][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DACK]S1 biask ic = 0x%x, qc = 0x%x\n",
+ dack->biask_d[1][0], dack->biask_d[1][1]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n");
+ for (i = 0; i < 0x10; i++) {
+ t = dack->msbk_d[0][0][i];
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t);
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n");
+ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
+ t = dack->msbk_d[0][1][i];
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t);
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n");
+ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
+ t = dack->msbk_d[1][0][i];
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t);
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n");
+ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
+ t = dack->msbk_d[1][1][i];
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t);
+ }
+}
+
+static void _addck_ori(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_dack_info *dack = &rtwdev->dack;
+ u32 val;
+ int ret;
+
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_MAN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_MAN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1);
+
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xf);
+ udelay(100);
+
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, BIT(4), 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0x3);
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_TRG, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_TRG, 0x0);
+ udelay(1);
+
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x1);
+ dack->addck_timeout[0] = false;
+
+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val,
+ 1, 10000, false,
+ rtwdev, R_ADDCKR0, BIT(0));
+ if (ret) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n");
+ dack->addck_timeout[0] = true;
+ }
+
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, BIT(4), 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xc);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x1);
+
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x0);
+ dack->addck_d[0][0] =
+ rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A0);
+ dack->addck_d[0][1] =
+ rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A1);
+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0);
+
+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1);
+
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xf);
+ udelay(100);
+
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, BIT(4), 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0x3);
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_TRG, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_TRG, 0x0);
+ udelay(1);
+
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x1);
+ dack->addck_timeout[1] = false;
+
+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val,
+ 1, 10000, false,
+ rtwdev, R_ADDCKR1, BIT(0));
+ if (ret) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADDCK timeout\n");
+ dack->addck_timeout[1] = true;
+ }
+
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, BIT(4), 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xc);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x1);
+
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x0);
+ dack->addck_d[1][0] =
+ rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, B_ADDCKR1_A0);
+ dack->addck_d[1][1] =
+ rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, B_ADDCKR1_A1);
+
+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0);
+}
+
+static void _addck_reload(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_dack_info *dack = &rtwdev->dack;
+
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL1, dack->addck_d[0][0]);
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL0, dack->addck_d[0][1]);
+
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RLS, 0x3);
+
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RL1, dack->addck_d[1][0]);
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RL0, dack->addck_d[1][1]);
+
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RLS, 0x3);
+}
+
+static void _dack_manual_off(struct rtw89_dev *rtwdev)
+{
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RLS, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RLS, 0x0);
+
+ rtw89_phy_write32_mask(rtwdev, R_DACKN0_CTL, B_DACKN0_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_DACKN1_CTL, B_DACKN1_ON, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_DACKN2_CTL, B_DACKN2_ON, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_DACKN3_CTL, B_DACKN3_ON, 0x0);
+}
+
+static void _dac_cal(struct rtw89_dev *rtwdev, bool force)
+{
+ struct rtw89_dack_info *dack = &rtwdev->dack;
+
+ dack->dack_done = false;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n");
+
+ _drck(rtwdev);
+ _dack_manual_off(rtwdev);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, 0x0);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RFREG_MASK, 0x0);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x337e1);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x337e1);
+ _rxck_force(rtwdev, RF_PATH_A, true, ADC_960M);
+ _rxck_force(rtwdev, RF_PATH_B, true, ADC_960M);
+ _addck_ori(rtwdev);
+
+ _rxck_force(rtwdev, RF_PATH_A, false, ADC_960M);
+ _rxck_force(rtwdev, RF_PATH_B, false, ADC_960M);
+ _addck_reload(rtwdev);
+
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RFREG_MASK, 0x0);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RFREG_MASK, 0x0);
+
+ _dack(rtwdev);
+ _dack_dump(rtwdev);
+ dack->dack_done = true;
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, 0x1);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RFREG_MASK, 0x1);
+
+ dack->dack_cnt++;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n");
+}
+
+static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path, u8 ktype)
+{
+ bool notready = false;
+ u32 val;
+ int ret;
+
+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55,
+ 10, 8200, false,
+ rtwdev, R_RFK_ST, MASKBYTE0);
+ if (ret)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]NCTL1 IQK timeout!!!\n");
+
+ udelay(10);
+
+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x8000,
+ 10, 400, false,
+ rtwdev, R_RPT_COM, B_RPT_COM_RDY);
+ if (ret) {
+ notready = true;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]NCTL2 IQK timeout!!!\n");
+ }
+
+ udelay(10);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0);
+
+ return notready;
+}
+
+static bool _iqk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ u8 path, u8 ktype)
+{
+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
+ u32 iqk_cmd;
+ bool fail;
+
+ switch (ktype) {
+ case ID_TXAGC:
+ iqk_cmd = 0x008 | (1 << (4 + path)) | (path << 1);
+ break;
+ case ID_FLOK_COARSE:
+ iqk_cmd = 0x108 | (1 << (4 + path));
+ break;
+ case ID_FLOK_FINE:
+ iqk_cmd = 0x208 | (1 << (4 + path));
+ break;
+ case ID_FLOK_VBUFFER:
+ iqk_cmd = 0x308 | (1 << (4 + path));
+ break;
+ case ID_TXK:
+ iqk_cmd = 0x008 | (1 << (path + 4)) |
+ (((0x8 + iqk_info->iqk_bw[path]) & 0xf) << 8);
+ break;
+ case ID_RXAGC:
+ iqk_cmd = 0x508 | (1 << (4 + path)) | (path << 1);
+ break;
+ case ID_RXK:
+ iqk_cmd = 0x008 | (1 << (path + 4)) |
+ (((0xb + iqk_info->iqk_bw[path]) & 0xf) << 8);
+ break;
+ case ID_NBTXK:
+ iqk_cmd = 0x408 | (1 << (4 + path));
+ break;
+ case ID_NBRXK:
+ iqk_cmd = 0x608 | (1 << (4 + path));
+ break;
+ default:
+ return false;
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s, iqk_cmd = %x\n",
+ __func__, iqk_cmd + 1);
+
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, iqk_cmd + 1);
+ fail = _iqk_check_cal(rtwdev, path, ktype);
+
+ return fail;
+}
+
+static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path)
+{
+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
+
+ switch (iqk_info->iqk_band[path]) {
+ case RTW89_BAND_2G:
+ rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT2, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, 0x1);
+ rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1);
+ rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M1, 0x00);
+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_IQK, 0x403e);
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x5);
+ udelay(1);
+ break;
+ case RTW89_BAND_5G:
+ rtw89_write_rf(rtwdev, path, RR_BIASA, RR_BIASA_A, 0x1);
+ rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1);
+ rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M1, 0x80);
+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_IQK, 0x403e);
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x4);
+ udelay(1);
+ break;
+ default:
+ break;
+ }
+}
+
+static bool _iqk_2g_lok(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
+{
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__);
+
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x09);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000119 + (path << 4));
+
+ _iqk_check_cal(rtwdev, path, ID_FLOK_COARSE);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x24);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000319 + (path << 4));
+
+ _iqk_check_cal(rtwdev, path, ID_FLOK_VBUFFER);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x09);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000219 + (path << 4));
+
+ _iqk_check_cal(rtwdev, path, ID_FLOK_COARSE);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x24);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000319 + (path << 4));
+
+ _iqk_check_cal(rtwdev, path, ID_FLOK_VBUFFER);
+
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+
+ return false;
+}
+
+static bool _iqk_5g_lok(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
+{
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__);
+
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x09);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000119 + (path << 4));
+
+ _iqk_check_cal(rtwdev, path, ID_FLOK_COARSE);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x24);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000319 + (path << 4));
+
+ _iqk_check_cal(rtwdev, path, ID_FLOK_VBUFFER);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x09);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000219 + (path << 4));
+
+ _iqk_check_cal(rtwdev, path, ID_FLOK_COARSE);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x24);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00000319 + (path << 4));
+
+ _iqk_check_cal(rtwdev, path, ID_FLOK_VBUFFER);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+
+ return false;
+}
+
+static bool _iqk_2g_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
+{
+ static const u32 g_power_range[4] = {0x0, 0x0, 0x0, 0x0};
+ static const u32 g_track_range[4] = {0x4, 0x4, 0x6, 0x6};
+ static const u32 g_gain_bb[4] = {0x08, 0x0e, 0x08, 0x0e};
+ static const u32 g_itqt[4] = {0x09, 0x12, 0x1b, 0x24};
+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
+ bool notready = false;
+ bool kfail = false;
+ u8 gp;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__);
+
+ for (gp = 0x0; gp < 0x4; gp++) {
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0,
+ g_power_range[gp]);
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1,
+ g_track_range[gp]);
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG,
+ g_gain_bb[gp]);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
+ 0x00000100, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
+ 0x00000010, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
+ 0x00000004, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
+ 0x00000003, gp);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT,
+ 0x009);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8),
+ B_KIP_IQP_IQSW, g_itqt[gp]);
+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK);
+ iqk_info->nb_txcfir[path] =
+ rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD);
+
+ if (iqk_info->is_nbiqk)
+ break;
+
+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8),
+ B_KIP_IQP_IQSW, g_itqt[gp]);
+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK]S%x, gp = 0x%x, 0x8%x38 = 0x%x\n",
+ path, gp, 1 << path, iqk_info->nb_txcfir[path]);
+ }
+
+ if (!notready)
+ kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG);
+
+ if (kfail) {
+ iqk_info->nb_txcfir[path] = 0x40000002;
+ rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8),
+ B_IQK_RES_TXCFIR, 0x0);
+ }
+
+ return kfail;
+}
+
+static bool _iqk_5g_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
+{
+ static const u32 a_power_range[4] = {0x0, 0x0, 0x0, 0x0};
+ static const u32 a_track_range[4] = {0x3, 0x3, 0x6, 0x6};
+ static const u32 a_gain_bb[4] = {0x08, 0x10, 0x08, 0x0e};
+ static const u32 a_itqt[4] = {0x09, 0x12, 0x1b, 0x24};
+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
+ bool notready = false;
+ bool kfail = false;
+ u8 gp;
+
+ for (gp = 0x0; gp < 0x4; gp++) {
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, a_power_range[gp]);
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, a_track_range[gp]);
+ rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, a_gain_bb[gp]);
+
+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8),
+ MASKDWORD, a_itqt[gp]);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
+ 0x00000100, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
+ 0x00000010, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
+ 0x00000004, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
+ 0x00000003, gp);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT,
+ 0x009);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8),
+ B_KIP_IQP_IQSW, a_itqt[gp]);
+
+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK);
+ iqk_info->nb_txcfir[path] =
+ rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD);
+
+ if (iqk_info->is_nbiqk)
+ break;
+
+ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8),
+ B_KIP_IQP_IQSW, a_itqt[gp]);
+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK]S%x, gp = 0x%x, 0x8%x38 = 0x%x\n",
+ path, gp, 1 << path, iqk_info->nb_txcfir[path]);
+ }
+
+ if (!notready)
+ kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG);
+
+ if (kfail) {
+ iqk_info->nb_txcfir[path] = 0x40000002;
+ rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8),
+ B_IQK_RES_TXCFIR, 0x0);
+ }
+
+ return kfail;
+}
+
+static void _iqk_adc_fifo_rst(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx, u8 path)
+{
+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0303);
+ udelay(10);
+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x3333);
+}
+
+static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path)
+{
+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__);
+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0303);
+
+ if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80) {
+ _rxck_force(rtwdev, RF_PATH_A, true, ADC_960M);
+ _rxck_force(rtwdev, RF_PATH_B, true, ADC_960M);
+ udelay(1);
+
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC,
+ B_UPD_CLK_ADC_ON, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC,
+ B_UPD_CLK_ADC_VAL, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1,
+ B_PATH0_SAMPL_DLY_T_MSK_V1, 0x2);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1,
+ B_PATH1_SAMPL_DLY_T_MSK_V1, 0x2);
+ rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_BW1, 0x8);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1,
+ B_PATH1_BW_SEL_MSK_V1, 0x8);
+ } else {
+ _rxck_force(rtwdev, RF_PATH_A, true, ADC_480M);
+ _rxck_force(rtwdev, RF_PATH_B, true, ADC_480M);
+ udelay(1);
+
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC,
+ B_UPD_CLK_ADC_ON, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC,
+ B_UPD_CLK_ADC_VAL, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1,
+ B_PATH0_SAMPL_DLY_T_MSK_V1, 0x3);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1,
+ B_PATH1_SAMPL_DLY_T_MSK_V1, 0x3);
+ rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_BW1, 0xf);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1,
+ B_PATH1_BW_SEL_MSK_V1, 0xf);
+ }
+
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, 0x00000780, 0x8);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, 0x00000780, 0x8);
+ rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, 0x00007800, 0x2);
+ rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, 0x00007800, 0x2);
+ rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_MUL, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1);
+ udelay(1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x0f);
+ udelay(1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x03);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa001);
+ udelay(1);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa041);
+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x3333);
+}
+
+static bool _iqk_2g_rx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
+{
+ static const u32 g_idxrxgain[2] = {0x212, 0x310};
+ static const u32 g_idxattc2[2] = {0x00, 0x20};
+ static const u32 g_idxattc1[2] = {0x3, 0x2};
+ static const u32 g_idxrxagc[2] = {0x0, 0x2};
+ static const u32 g_idx[2] = {0x0, 0x2};
+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
+ bool notready = false;
+ bool kfail = false;
+ u32 rf_18, tmp;
+ u8 gp;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__);
+
+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc);
+ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x1);
+ rf_18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK);
+ rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, rf_18);
+
+ for (gp = 0x0; gp < 0x2; gp++) {
+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, g_idxrxgain[gp]);
+ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G, g_idxattc2[gp]);
+ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G, g_idxattc1[gp]);
+
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
+ 0x00000100, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
+ 0x00000010, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
+ 0x00000007, g_idx[gp]);
+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013);
+ udelay(100);
+ udelay(100);
+
+ tmp = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, tmp);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, g_idxrxagc[gp]);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11);
+
+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, rf rxbb = %x\n", path,
+ rtw89_read_rf(rtwdev, path, RR_MOD, 0x003c0));
+
+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013);
+ udelay(100);
+ udelay(100);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011);
+
+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK);
+ iqk_info->nb_rxcfir[path] =
+ rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8),
+ MASKDWORD) | 0x2;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK]S%x, gp = 0x%x, 0x8%x3c = 0x%x\n", path,
+ g_idx[gp], 1 << path, iqk_info->nb_rxcfir[path]);
+
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+
+ if (iqk_info->is_nbiqk)
+ break;
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+ }
+
+ if (!notready)
+ kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG);
+
+ if (kfail) {
+ iqk_info->nb_txcfir[path] = 0x40000002;
+ rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8),
+ B_IQK_RES_RXCFIR, 0x0);
+ }
+ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x0);
+
+ return kfail;
+}
+
+static bool _iqk_5g_rx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
+{
+ static const u32 a_idxrxgain[2] = {0x110, 0x290};
+ static const u32 a_idxattc2[2] = {0x0f, 0x0f};
+ static const u32 a_idxattc1[2] = {0x2, 0x2};
+ static const u32 a_idxrxagc[2] = {0x4, 0x6};
+ static const u32 a_idx[2] = {0x0, 0x2};
+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
+ bool notready = false;
+ bool kfail = false;
+ u32 rf_18, tmp;
+ u8 gp;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__);
+
+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc);
+ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x1);
+ rf_18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK);
+ rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, rf_18);
+
+ for (gp = 0x0; gp < 0x2; gp++) {
+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, a_idxrxgain[gp]);
+ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_HATT, a_idxattc2[gp]);
+ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_CC2, a_idxattc1[gp]);
+
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
+ 0x00000100, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
+ 0x00000010, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
+ 0x00000007, a_idx[gp]);
+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013);
+ udelay(100);
+ udelay(100);
+
+ tmp = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, tmp);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, a_idxrxagc[gp]);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11);
+
+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, rf rxbb = %x\n", path,
+ rtw89_read_rf(rtwdev, path, RR_MOD, 0x003c0));
+
+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013);
+ udelay(200);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011);
+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK);
+ iqk_info->nb_rxcfir[path] =
+ rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8),
+ MASKDWORD) | 0x2;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK]S%x, gp = 0x%x, 0x8%x3c = 0x%x\n",
+ path, a_idx[gp], 1 << path, iqk_info->nb_rxcfir[path]);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+
+ if (iqk_info->is_nbiqk)
+ break;
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+ }
+
+ if (!notready)
+ kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG);
+
+ if (kfail) {
+ iqk_info->nb_txcfir[path] = 0x40000002;
+ rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8),
+ B_IQK_RES_RXCFIR, 0x0);
+ }
+ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x0);
+
+ return kfail;
+}
+
+static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
+{
+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
+ bool lok_result = false;
+ bool txk_result = false;
+ bool rxk_result = false;
+ u8 i;
+
+ for (i = 0; i < 3; i++) {
+ _iqk_txk_setting(rtwdev, path);
+ if (iqk_info->iqk_band[path] == RTW89_BAND_2G)
+ lok_result = _iqk_2g_lok(rtwdev, phy_idx, path);
+ else
+ lok_result = _iqk_5g_lok(rtwdev, phy_idx, path);
+
+ if (!lok_result)
+ break;
+ }
+
+ if (lok_result) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK]!!!!!!!!!!LOK by Pass !!!!!!!!!!!\n");
+ rtw89_write_rf(rtwdev, path, RR_DTXLOK, RFREG_MASK, 0x80200);
+ rtw89_write_rf(rtwdev, path, RR_RSV2, RFREG_MASK, 0x80200);
+ rtw89_write_rf(rtwdev, path, RR_LOKVB, RFREG_MASK, 0x80200);
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]RF_0x08[00:19] = 0x%x\n",
+ rtw89_read_rf(rtwdev, path, RR_DTXLOK, RFREG_MASK));
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]RF_0x09[00:19] = 0x%x\n",
+ rtw89_read_rf(rtwdev, path, RR_RSV2, RFREG_MASK));
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]RF_0x0a[00:19] = 0x%x\n",
+ rtw89_read_rf(rtwdev, path, RR_LOKVB, RFREG_MASK));
+
+ if (iqk_info->iqk_band[path] == RTW89_BAND_2G)
+ txk_result = _iqk_2g_tx(rtwdev, phy_idx, path);
+ else
+ txk_result = _iqk_5g_tx(rtwdev, phy_idx, path);
+
+ _iqk_rxclk_setting(rtwdev, path);
+ _iqk_adc_fifo_rst(rtwdev, phy_idx, path);
+
+ if (iqk_info->iqk_band[path] == RTW89_BAND_2G)
+ rxk_result = _iqk_2g_rx(rtwdev, phy_idx, path);
+ else
+ rxk_result = _iqk_5g_rx(rtwdev, phy_idx, path);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK]result : lok_= %x, txk_= %x, rxk_= %x\n",
+ lok_result, txk_result, rxk_result);
+}
+
+static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
+{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
+ u8 get_empty_table = false;
+ u32 reg_rf18;
+ u32 reg_35c;
+ u8 idx;
+
+ for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) {
+ if (iqk_info->iqk_mcc_ch[idx][path] == 0) {
+ get_empty_table = true;
+ break;
+ }
+ }
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (1)idx = %x\n", idx);
+
+ if (!get_empty_table) {
+ idx = iqk_info->iqk_table_idx[path] + 1;
+ if (idx > 1)
+ idx = 0;
+ }
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (2)idx = %x\n", idx);
+
+ reg_rf18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK);
+ reg_35c = rtw89_phy_read32_mask(rtwdev, R_CIRST, B_CIRST_SYN);
+
+ iqk_info->iqk_band[path] = chan->band_type;
+ iqk_info->iqk_bw[path] = chan->band_width;
+ iqk_info->iqk_ch[path] = chan->channel;
+ iqk_info->iqk_mcc_ch[idx][path] = chan->channel;
+ iqk_info->iqk_table_idx[path] = idx;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x18= 0x%x, idx = %x\n",
+ path, reg_rf18, idx);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x18= 0x%x\n",
+ path, reg_rf18);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x35c= 0x%x\n",
+ path, reg_35c);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]times = 0x%x, ch =%x\n",
+ iqk_info->iqk_times, idx);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_mcc_ch[%x][%x] = 0x%x\n",
+ idx, path, iqk_info->iqk_mcc_ch[idx][path]);
+}
+
+static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
+{
+ _iqk_by_path(rtwdev, phy_idx, path);
+}
+
+static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path)
+{
+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "===> %s\n", __func__);
+
+ if (iqk_info->is_nbiqk) {
+ rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8),
+ MASKDWORD, iqk_info->nb_txcfir[path]);
+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8),
+ MASKDWORD, iqk_info->nb_rxcfir[path]);
+ } else {
+ rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8),
+ MASKDWORD, 0x40000000);
+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8),
+ MASKDWORD, 0x40000000);
+ }
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD,
+ 0x00000e19 + (path << 4));
+
+ _iqk_check_cal(rtwdev, path, 0x0);
+
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000);
+
+ rtw89_phy_write32_mask(rtwdev, R_KIP_CLK, MASKDWORD, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_IQRSN, B_IQRSN_K2, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), BIT(28), 0x0);
+
+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0x3);
+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1);
+ rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1);
+}
+
+static void _iqk_afebb_restore(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx, u8 path)
+{
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "===> %s\n", __func__);
+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0303);
+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_CLKG_FORCE, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_CLKG_FORCE, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_TXCKEN_FORCE, B_TXCKEN_FORCE_ALL, 0x0000000);
+ rtw89_phy_write32_mask(rtwdev, R_FAHM, B_RXTD_CKEN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_GEN_ON, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_TX_COLLISION_T2R_ST, 0x0000001f, 0x03);
+ rtw89_phy_write32_mask(rtwdev, R_TX_COLLISION_T2R_ST, 0x000003e0, 0x03);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_TXCK_ALL, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_TXCK_ALL, 0x00);
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC,
+ B_UPD_CLK_ADC_VAL | B_UPD_CLK_ADC_ON, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0000);
+ rtw89_phy_write32_mask(rtwdev, R_P0_ADCFF_EN, B_P0_ADCFF_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_ADCFF_EN, B_P1_ADCFF_EN, 0x0);
+}
+
+static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path)
+{
+ u8 idx = 0;
+
+ rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), 0x00000001, idx);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), 0x00000008, idx);
+ rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, 0x40000000);
+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, 0x40000000);
+
+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x81ff010a);
+}
+
+static void _iqk_macbb_setting(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx, u8 path)
+{
+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0303);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_GOT_TXRX, 0x3);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_GOT_TXRX, 0x3);
+ rtw89_phy_write32_mask(rtwdev, R_P0_ADCFF_EN, B_P0_ADCFF_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_ADCFF_EN, B_P1_ADCFF_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_CLKG_FORCE, 0x3);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P0_CLKG_FORCE, 0x3);
+ rtw89_phy_write32_mask(rtwdev, R_TXCKEN_FORCE, B_TXCKEN_FORCE_ALL, 0x1ffffff);
+ rtw89_phy_write32_mask(rtwdev, R_FAHM, B_RXTD_CKEN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_GEN_ON, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_TX_COLLISION_T2R_ST, B_TXRX_FORCE_VAL, 0x3ff);
+ rtw89_phy_write32_mask(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_CLKEN, 0x3);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_DPK_RST, B_IQK_DPK_RST, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P0_PATH_RST, B_P0_PATH_RST, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_PATH_RST, B_P1_PATH_RST, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_DCFO_WEIGHT, B_DAC_CLK_IDX, 0x1);
+
+ _txck_force(rtwdev, RF_PATH_A, true, DAC_960M);
+ _txck_force(rtwdev, RF_PATH_B, true, DAC_960M);
+ _rxck_force(rtwdev, RF_PATH_A, true, ADC_1920M);
+ _rxck_force(rtwdev, RF_PATH_B, true, ADC_1920M);
+
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL, 0x2);
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1);
+ udelay(10);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f);
+ udelay(10);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0001);
+ udelay(10);
+ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041);
+ rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_RSTB, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x3333);
+}
+
+static void _iqk_init(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
+ u8 idx, path;
+
+ rtw89_phy_write32_mask(rtwdev, R_IQKINF, MASKDWORD, 0x0);
+
+ if (iqk_info->is_iqk_init)
+ return;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__);
+ iqk_info->is_iqk_init = true;
+ iqk_info->is_nbiqk = false;
+ iqk_info->iqk_fft_en = false;
+ iqk_info->iqk_sram_en = false;
+ iqk_info->iqk_cfir_en = false;
+ iqk_info->iqk_xym_en = false;
+ iqk_info->iqk_times = 0x0;
+
+ for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) {
+ iqk_info->iqk_channel[idx] = 0x0;
+ for (path = 0; path < RTW8852BT_SS; path++) {
+ iqk_info->lok_cor_fail[idx][path] = false;
+ iqk_info->lok_fin_fail[idx][path] = false;
+ iqk_info->iqk_tx_fail[idx][path] = false;
+ iqk_info->iqk_rx_fail[idx][path] = false;
+ iqk_info->iqk_mcc_ch[idx][path] = 0x0;
+ iqk_info->iqk_table_idx[path] = 0x0;
+ }
+ }
+}
+
+static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
+{
+ u32 rf_mode;
+ u8 path;
+ int ret;
+
+ for (path = 0; path < RF_PATH_MAX; path++) {
+ if (!(kpath & BIT(path)))
+ continue;
+
+ ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode,
+ rf_mode != 2, 2, 5000, false,
+ rtwdev, path, RR_MOD, RR_MOD_MASK);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", path, ret);
+ }
+}
+
+static void _tmac_tx_pause(struct rtw89_dev *rtwdev, enum rtw89_phy_idx band_idx,
+ bool is_pause)
+{
+ if (!is_pause)
+ return;
+
+ _wait_rx_mode(rtwdev, _kpath(rtwdev, band_idx));
+}
+
+static void _doiqk(struct rtw89_dev *rtwdev, bool force,
+ enum rtw89_phy_idx phy_idx, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
+{
+ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
+ u32 backup_bb_val[BACKUP_BB_REGS_NR];
+ u32 backup_rf_val[RTW8852BT_SS][BACKUP_RF_REGS_NR];
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx);
+
+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[IQK]==========IQK start!!!!!==========\n");
+ iqk_info->iqk_times++;
+ iqk_info->version = RTW8852BT_IQK_VER;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version);
+ _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx);
+
+ _rfk_backup_bb_reg(rtwdev, backup_bb_val);
+ _rfk_backup_rf_reg(rtwdev, backup_rf_val[path], path);
+ _iqk_macbb_setting(rtwdev, phy_idx, path);
+ _iqk_preset(rtwdev, path);
+ _iqk_start_iqk(rtwdev, phy_idx, path);
+ _iqk_restore(rtwdev, path);
+ _iqk_afebb_restore(rtwdev, phy_idx, path);
+ _rfk_reload_bb_reg(rtwdev, backup_bb_val);
+ _rfk_reload_rf_reg(rtwdev, backup_rf_val[path], path);
+
+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP);
+}
+
+static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force,
+ enum rtw89_chanctx_idx chanctx_idx)
+{
+ u8 kpath = _kpath(rtwdev, phy_idx);
+
+ switch (kpath) {
+ case RF_A:
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx);
+ break;
+ case RF_B:
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx);
+ break;
+ case RF_AB:
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx);
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx);
+ break;
+ default:
+ break;
+ }
+}
+
+static void _dpk_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool off)
+{
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+ u8 val, kidx = dpk->cur_idx[path];
+ bool off_reverse;
+
+ val = dpk->is_dpk_enable && !off && dpk->bp[path][kidx].path_ok;
+
+ if (off)
+ off_reverse = false;
+ else
+ off_reverse = true;
+
+ val = dpk->is_dpk_enable & off_reverse & dpk->bp[path][kidx].path_ok;
+
+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2),
+ BIT(24), val);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path,
+ kidx, str_enable_disable(dpk->is_dpk_enable & off_reverse));
+}
+
+static void _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, enum rtw8852bt_dpk_id id)
+{
+ u16 dpk_cmd;
+ u32 val;
+ int ret;
+
+ dpk_cmd = (id << 8) | (0x19 + (path << 4));
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, dpk_cmd);
+
+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55,
+ 1, 30000, false,
+ rtwdev, R_RFK_ST, MASKBYTE0);
+ if (ret)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot 1 over 30ms!!!!\n");
+
+ udelay(1);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00030000);
+
+ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x8000,
+ 1, 2000, false,
+ rtwdev, R_RPT_COM, MASKLWORD);
+ if (ret)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot 2 over 2ms!!!!\n");
+
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] one-shot for %s = 0x%04x\n",
+ id == 0x06 ? "LBK_RXIQK" :
+ id == 0x10 ? "SYNC" :
+ id == 0x11 ? "MDPK_IDL" :
+ id == 0x12 ? "MDPK_MPA" :
+ id == 0x13 ? "GAIN_LOSS" :
+ id == 0x14 ? "PWR_CAL" :
+ id == 0x15 ? "DPK_RXAGC" :
+ id == 0x16 ? "KIP_PRESET" :
+ id == 0x17 ? "KIP_RESTORE" :
+ "DPK_TXAGC", dpk_cmd);
+}
+
+static void _dpk_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path)
+{
+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1);
+
+ udelay(600);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d RXDCK\n", path);
+}
+
+static void _dpk_information(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx)
+{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+
+ u8 kidx = dpk->cur_idx[path];
+
+ dpk->bp[path][kidx].band = chan->band_type;
+ dpk->bp[path][kidx].ch = chan->channel;
+ dpk->bp[path][kidx].bw = chan->band_width;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n",
+ path, dpk->cur_idx[path], phy,
+ rtwdev->is_tssi_mode[path] ? "on" : "off",
+ rtwdev->dbcc_en ? "on" : "off",
+ dpk->bp[path][kidx].band == 0 ? "2G" :
+ dpk->bp[path][kidx].band == 1 ? "5G" : "6G",
+ dpk->bp[path][kidx].ch,
+ dpk->bp[path][kidx].bw == 0 ? "20M" :
+ dpk->bp[path][kidx].bw == 1 ? "40M" : "80M");
+}
+
+static void _dpk_tssi_pause(struct rtw89_dev *rtwdev,
+ enum rtw89_rf_path path, bool is_pause)
+{
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13),
+ B_P0_TSSI_TRK_EN, is_pause);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI %s\n", path,
+ is_pause ? "pause" : "resume");
+}
+
+static void _dpk_kip_restore(struct rtw89_dev *rtwdev,
+ enum rtw89_rf_path path)
+{
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000);
+
+ if (rtwdev->hal.cv > CHIP_CAV)
+ rtw89_phy_write32_mask(rtwdev, R_DPD_COM + (path << 8),
+ B_DPD_COM_OF, 0x1);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d restore KIP\n", path);
+}
+
+static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, u8 cur_rxbb, u32 rf_18)
+{
+ rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_RXCFIR, 0x0);
+
+ rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, rf_18);
+ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKMODE, 0xd);
+ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x1);
+
+ if (cur_rxbb >= 0x11)
+ rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x13);
+ else if (cur_rxbb <= 0xa)
+ rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x00);
+ else
+ rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x05);
+
+ rtw89_write_rf(rtwdev, path, RR_XGLNA2, RR_XGLNA2_SW, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0);
+ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80014);
+
+ udelay(100);
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x025);
+
+ _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK);
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+
+ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, B_KPATH_CFG_ED, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_DI, 0x1);
+ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKMODE, 0x5);
+}
+
+static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain,
+ enum rtw89_rf_path path, u8 kidx)
+{
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+
+ if (dpk->bp[path][kidx].band == RTW89_BAND_2G) {
+ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 0x50220);
+ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_FATT, 0xf2);
+ rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_TIA, 0x1);
+ rtw89_write_rf(rtwdev, path, RR_TIA, RR_TIA_N6, 0x1);
+ } else {
+ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 0x50220);
+ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RAA2_SWATT, 0x5);
+ rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_TIA, 0x1);
+ rtw89_write_rf(rtwdev, path, RR_TIA, RR_TIA_N6, 0x1);
+ rtw89_write_rf(rtwdev, path, RR_RXA_LNA, RFREG_MASK, 0x920FC);
+ rtw89_write_rf(rtwdev, path, RR_XALNA2, RFREG_MASK, 0x002C0);
+ rtw89_write_rf(rtwdev, path, RR_IQGEN, RFREG_MASK, 0x38800);
+ }
+
+ rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_BW, 0x1);
+ rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_TXBB, dpk->bp[path][kidx].bw + 1);
+ rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_RXBB, 0x0);
+}
+
+static void _dpk_bypass_rxcfir(struct rtw89_dev *rtwdev,
+ enum rtw89_rf_path path, bool is_bypass)
+{
+ if (is_bypass) {
+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8),
+ B_RXIQC_BYPASS2, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8),
+ B_RXIQC_BYPASS, 0x1);
+ } else {
+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8),
+ B_RXIQC_BYPASS2, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8),
+ B_RXIQC_BYPASS, 0x0);
+ }
+}
+
+static
+void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx)
+{
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+
+ if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80)
+ rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x0);
+ else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40)
+ rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x2);
+ else
+ rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x1);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] TPG_Select for %s\n",
+ dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" :
+ dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M");
+}
+
+static void _dpk_table_select(struct rtw89_dev *rtwdev,
+ enum rtw89_rf_path path, u8 kidx, u8 gain)
+{
+ u8 val;
+
+ val = 0x80 + kidx * 0x20 + gain * 0x10;
+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0 + (path << 8), MASKBYTE3, val);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] table select for Kidx[%d], Gain[%d] (0x%x)\n", kidx,
+ gain, val);
+}
+
+static bool _dpk_sync_check(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx)
+{
+#define DPK_SYNC_TH_DC_I 200
+#define DPK_SYNC_TH_DC_Q 200
+#define DPK_SYNC_TH_CORR 170
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+ u8 corr_val, corr_idx;
+ u16 dc_i, dc_q;
+ u32 corr, dc;
+
+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0);
+
+ corr = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD);
+ corr_idx = u32_get_bits(corr, B_PRT_COM_CORI);
+ corr_val = u32_get_bits(corr, B_PRT_COM_CORV);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] S%d Corr_idx / Corr_val = %d / %d\n",
+ path, corr_idx, corr_val);
+
+ dpk->corr_idx[path][kidx] = corr_idx;
+ dpk->corr_val[path][kidx] = corr_val;
+
+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9);
+
+ dc = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD);
+ dc_i = u32_get_bits(dc, B_PRT_COM_DCI);
+ dc_q = u32_get_bits(dc, B_PRT_COM_DCQ);
+
+ dc_i = abs(sign_extend32(dc_i, 11));
+ dc_q = abs(sign_extend32(dc_q, 11));
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d DC I/Q, = %d / %d\n",
+ path, dc_i, dc_q);
+
+ dpk->dc_i[path][kidx] = dc_i;
+ dpk->dc_q[path][kidx] = dc_q;
+
+ if (dc_i > DPK_SYNC_TH_DC_I || dc_q > DPK_SYNC_TH_DC_Q ||
+ corr_val < DPK_SYNC_TH_CORR)
+ return true;
+ else
+ return false;
+}
+
+static void _dpk_sync(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, u8 kidx)
+{
+ _dpk_one_shot(rtwdev, phy, path, SYNC);
+}
+
+static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev)
+{
+ u16 dgain;
+
+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0);
+
+ dgain = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain = 0x%x\n", dgain);
+
+ return dgain;
+}
+
+static s8 _dpk_dgain_mapping(struct rtw89_dev *rtwdev, u16 dgain)
+{
+ static const u16 bnd[15] = {
+ 0xbf1, 0xaa5, 0x97d, 0x875, 0x789, 0x6b7, 0x5fc, 0x556,
+ 0x4c1, 0x43d, 0x3c7, 0x35e, 0x2ac, 0x262, 0x220
+ };
+ s8 offset;
+
+ if (dgain >= bnd[0])
+ offset = 0x6;
+ else if (bnd[0] > dgain && dgain >= bnd[1])
+ offset = 0x6;
+ else if (bnd[1] > dgain && dgain >= bnd[2])
+ offset = 0x5;
+ else if (bnd[2] > dgain && dgain >= bnd[3])
+ offset = 0x4;
+ else if (bnd[3] > dgain && dgain >= bnd[4])
+ offset = 0x3;
+ else if (bnd[4] > dgain && dgain >= bnd[5])
+ offset = 0x2;
+ else if (bnd[5] > dgain && dgain >= bnd[6])
+ offset = 0x1;
+ else if (bnd[6] > dgain && dgain >= bnd[7])
+ offset = 0x0;
+ else if (bnd[7] > dgain && dgain >= bnd[8])
+ offset = 0xff;
+ else if (bnd[8] > dgain && dgain >= bnd[9])
+ offset = 0xfe;
+ else if (bnd[9] > dgain && dgain >= bnd[10])
+ offset = 0xfd;
+ else if (bnd[10] > dgain && dgain >= bnd[11])
+ offset = 0xfc;
+ else if (bnd[11] > dgain && dgain >= bnd[12])
+ offset = 0xfb;
+ else if (bnd[12] > dgain && dgain >= bnd[13])
+ offset = 0xfa;
+ else if (bnd[13] > dgain && dgain >= bnd[14])
+ offset = 0xf9;
+ else if (bnd[14] > dgain)
+ offset = 0xf8;
+ else
+ offset = 0x0;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain offset = %d\n", offset);
+
+ return offset;
+}
+
+static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev)
+{
+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6);
+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1);
+
+ return rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL);
+}
+
+static void _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, u8 kidx)
+{
+ _dpk_one_shot(rtwdev, phy, path, GAIN_LOSS);
+
+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6);
+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1);
+}
+
+static void _dpk_kip_preset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, u8 kidx)
+{
+ _dpk_tpg_sel(rtwdev, path, kidx);
+ _dpk_one_shot(rtwdev, phy, path, KIP_PRESET);
+}
+
+static void _dpk_kip_pwr_clk_on(struct rtw89_dev *rtwdev,
+ enum rtw89_rf_path path)
+{
+ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080);
+ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x807f030a);
+ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0xce000a08);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] KIP Power/CLK on\n");
+}
+
+static
+u8 _dpk_txagc_check_8852bt(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 txagc)
+{
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+
+ if (txagc >= dpk->max_dpk_txagc[path])
+ txagc = dpk->max_dpk_txagc[path];
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Set TxAGC = 0x%x\n", txagc);
+
+ return txagc;
+}
+
+static void _dpk_kip_set_txagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, u8 txagc)
+{
+ u8 val;
+
+ val = _dpk_txagc_check_8852bt(rtwdev, path, txagc);
+ rtw89_write_rf(rtwdev, path, RR_TXAGC, RFREG_MASK, val);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ _dpk_one_shot(rtwdev, phy, path, DPK_TXAGC);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] set TXAGC = 0x%x\n", txagc);
+}
+
+static void _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path)
+{
+ rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, 0x50220);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
+ _dpk_one_shot(rtwdev, phy, path, DPK_RXAGC);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
+}
+
+static u8 _dpk_set_offset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, u8 txagc, s8 gain_offset)
+{
+ txagc = rtw89_read_rf(rtwdev, path, RR_TXAGC, RFREG_MASK);
+
+ if ((txagc - gain_offset) < DPK_TXAGC_LOWER)
+ txagc = DPK_TXAGC_LOWER;
+ else if ((txagc - gain_offset) > DPK_TXAGC_UPPER)
+ txagc = DPK_TXAGC_UPPER;
+ else
+ txagc = txagc - gain_offset;
+
+ _dpk_kip_set_txagc(rtwdev, phy, path, txagc);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] tmp_txagc (GL=%d) = 0x%x\n",
+ gain_offset, txagc);
+ return txagc;
+}
+
+static bool _dpk_pas_read(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
+ u8 is_check)
+{
+ u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0;
+ u8 i;
+
+ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, 0x06);
+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE2, 0x08);
+
+ if (is_check) {
+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x00);
+ val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD);
+ val1_i = abs(sign_extend32(val1_i, 11));
+ val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD);
+ val1_q = abs(sign_extend32(val1_q, 11));
+
+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x1f);
+ val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD);
+ val2_i = abs(sign_extend32(val2_i, 11));
+ val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD);
+ val2_q = abs(sign_extend32(val2_q, 11));
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n",
+ phy_div(val1_i * val1_i + val1_q * val1_q,
+ val2_i * val2_i + val2_q * val2_q));
+ } else {
+ for (i = 0; i < 32; i++) {
+ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, i);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] PAS_Read[%02d]= 0x%08x\n", i,
+ rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD));
+ }
+ }
+
+ if (val1_i * val1_i + val1_q * val1_q >=
+ (val2_i * val2_i + val2_q * val2_q) * 8 / 5)
+ return true;
+
+ return false;
+}
+
+static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, u8 kidx, u8 init_txagc,
+ bool loss_only, enum rtw89_chanctx_idx chanctx_idx)
+{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+ u8 goout = 0, agc_cnt = 0, limited_rxbb = 0, gl_cnt = 0;
+ u8 tmp_txagc, tmp_rxbb, tmp_gl_idx = 0;
+ u8 step = DPK_AGC_STEP_SYNC_DGAIN;
+ int limit = 200;
+ s8 offset = 0;
+ u16 dgain = 0;
+ u32 rf_18;
+
+ tmp_txagc = init_txagc;
+
+ tmp_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB);
+ rf_18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK);
+
+ do {
+ switch (step) {
+ case DPK_AGC_STEP_SYNC_DGAIN:
+ _dpk_sync(rtwdev, phy, path, kidx);
+ if (agc_cnt == 0) {
+ if (chan->band_width < 2)
+ _dpk_bypass_rxcfir(rtwdev, path, true);
+ else
+ _dpk_lbk_rxiqk(rtwdev, phy, path,
+ tmp_rxbb, rf_18);
+ }
+
+ if (_dpk_sync_check(rtwdev, path, kidx) == true) {
+ tmp_txagc = 0xff;
+ goout = 1;
+ break;
+ }
+
+ dgain = _dpk_dgain_read(rtwdev);
+ offset = _dpk_dgain_mapping(rtwdev, dgain);
+
+ if (loss_only == 1 || limited_rxbb == 1 || offset == 0)
+ step = DPK_AGC_STEP_GAIN_LOSS_IDX;
+ else
+ step = DPK_AGC_STEP_GAIN_ADJ;
+ break;
+ case DPK_AGC_STEP_GAIN_ADJ:
+ tmp_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB);
+
+ if (tmp_rxbb + offset > 0x1f) {
+ tmp_rxbb = 0x1f;
+ limited_rxbb = 1;
+ } else if (tmp_rxbb + offset < 0) {
+ tmp_rxbb = 0;
+ limited_rxbb = 1;
+ } else {
+ tmp_rxbb = tmp_rxbb + offset;
+ }
+
+ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB, tmp_rxbb);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] Adjust RXBB (%d) = 0x%x\n", offset, tmp_rxbb);
+
+ if (chan->band_width == RTW89_CHANNEL_WIDTH_80)
+ _dpk_lbk_rxiqk(rtwdev, phy, path, tmp_rxbb, rf_18);
+ if (dgain > 1922 || dgain < 342)
+ step = DPK_AGC_STEP_SYNC_DGAIN;
+ else
+ step = DPK_AGC_STEP_GAIN_LOSS_IDX;
+
+ agc_cnt++;
+ break;
+ case DPK_AGC_STEP_GAIN_LOSS_IDX:
+ _dpk_gainloss(rtwdev, phy, path, kidx);
+
+ tmp_gl_idx = _dpk_gainloss_read(rtwdev);
+
+ if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, path, true)) ||
+ tmp_gl_idx >= 7)
+ step = DPK_AGC_STEP_GL_GT_CRITERION;
+ else if (tmp_gl_idx == 0)
+ step = DPK_AGC_STEP_GL_LT_CRITERION;
+ else
+ step = DPK_AGC_STEP_SET_TX_GAIN;
+
+ gl_cnt++;
+ break;
+ case DPK_AGC_STEP_GL_GT_CRITERION:
+ if (tmp_txagc == 0x2e ||
+ tmp_txagc == dpk->max_dpk_txagc[path]) {
+ goout = 1;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] Txagc@lower bound!!\n");
+ } else {
+ tmp_txagc = _dpk_set_offset(rtwdev, phy, path,
+ tmp_txagc, 0x3);
+ }
+ step = DPK_AGC_STEP_GAIN_LOSS_IDX;
+ agc_cnt++;
+ break;
+
+ case DPK_AGC_STEP_GL_LT_CRITERION:
+ if (tmp_txagc == 0x3f || tmp_txagc == dpk->max_dpk_txagc[path]) {
+ goout = 1;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] Txagc@upper bound!!\n");
+ } else {
+ tmp_txagc = _dpk_set_offset(rtwdev, phy, path,
+ tmp_txagc, 0xfe);
+ }
+ step = DPK_AGC_STEP_GAIN_LOSS_IDX;
+ agc_cnt++;
+ break;
+
+ case DPK_AGC_STEP_SET_TX_GAIN:
+ tmp_txagc = _dpk_set_offset(rtwdev, phy, path, tmp_txagc,
+ tmp_gl_idx);
+ goout = 1;
+ agc_cnt++;
+ break;
+
+ default:
+ goout = 1;
+ break;
+ }
+ } while (!goout && agc_cnt < 6 && limit-- > 0);
+
+ if (gl_cnt >= 6)
+ _dpk_pas_read(rtwdev, path, false);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] Txagc / RXBB for DPK = 0x%x / 0x%x\n", tmp_txagc, tmp_rxbb);
+
+ return tmp_txagc;
+}
+
+static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev,
+ enum rtw89_rf_path path, u8 order)
+{
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+
+ switch (order) {
+ case 0: /* (5,3,1) */
+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order);
+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x3);
+ rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN, 0x1);
+ dpk->dpk_order[path] = 0x3;
+ break;
+ case 1: /* (5,3,0) */
+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order);
+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN, 0x0);
+ dpk->dpk_order[path] = 0x1;
+ break;
+ case 2: /* (5,0,0) */
+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order);
+ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN, 0x0);
+ dpk->dpk_order[path] = 0x0;
+ break;
+ default:
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] Wrong MDPD order!!(0x%x)\n", order);
+ break;
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Set %s for IDL\n",
+ order == 0x0 ? "(5,3,1)" :
+ order == 0x1 ? "(5,3,0)" : "(5,0,0)");
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] Set MDPD order to 0x%x for IDL\n", order);
+}
+
+static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, u8 kidx, u8 gain)
+{
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+
+ if (dpk->bp[path][kidx].bw < RTW89_CHANNEL_WIDTH_80 &&
+ dpk->bp[path][kidx].band == RTW89_BAND_5G)
+ _dpk_set_mdpd_para(rtwdev, path, 0x2);
+ else
+ _dpk_set_mdpd_para(rtwdev, path, 0x0);
+
+ _dpk_one_shot(rtwdev, phy, path, MDPK_IDL);
+}
+
+static void _dpk_fill_result(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, u8 kidx, u8 gain, u8 txagc)
+{
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+ u8 gs = dpk->dpk_gs[phy];
+ u16 pwsf = 0x78;
+
+ rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), BIT(8), kidx);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] Fill txagc/ pwsf/ gs = 0x%x/ 0x%x/ 0x%x\n",
+ txagc, pwsf, gs);
+
+ dpk->bp[path][kidx].txagc_dpk = txagc;
+ rtw89_phy_write32_mask(rtwdev, R_TXAGC_RFK + (path << 8),
+ 0x3F << ((gain << 3) + (kidx << 4)), txagc);
+
+ dpk->bp[path][kidx].pwsf = pwsf;
+ rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2),
+ 0x1FF << (gain << 4), pwsf);
+
+ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x0);
+
+ dpk->bp[path][kidx].gs = gs;
+ if (dpk->dpk_gs[phy] == 0x7f)
+ rtw89_phy_write32_mask(rtwdev,
+ R_DPD_CH0A + (path << 8) + (kidx << 2),
+ MASKDWORD, 0x007f7f7f);
+ else
+ rtw89_phy_write32_mask(rtwdev,
+ R_DPD_CH0A + (path << 8) + (kidx << 2),
+ MASKDWORD, 0x005b5b5b);
+
+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2),
+ B_DPD_ORDER_V1, dpk->dpk_order[path]);
+
+ rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), MASKDWORD, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_SEL, 0x0);
+}
+
+static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx)
+{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+ u8 idx, cur_band, cur_ch;
+ bool is_reload = false;
+
+ cur_band = chan->band_type;
+ cur_ch = chan->channel;
+
+ for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) {
+ if (cur_band != dpk->bp[path][idx].band ||
+ cur_ch != dpk->bp[path][idx].ch)
+ continue;
+
+ rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8),
+ B_COEF_SEL_MDPD, idx);
+ dpk->cur_idx[path] = idx;
+ is_reload = true;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] reload S%d[%d] success\n", path, idx);
+ }
+
+ return is_reload;
+}
+
+static
+void _rf_direct_cntrl(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool is_bybb)
+{
+ if (is_bybb)
+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1);
+ else
+ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0);
+}
+
+static
+void _drf_direct_cntrl(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool is_bybb)
+{
+ if (is_bybb)
+ rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1);
+ else
+ rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0);
+}
+
+static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, u8 gain,
+ enum rtw89_chanctx_idx chanctx_idx)
+{
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+ u8 txagc = 0x38, kidx = dpk->cur_idx[path];
+ bool is_fail = false;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] ========= S%d[%d] DPK Start =========\n", path, kidx);
+
+ _rf_direct_cntrl(rtwdev, path, false);
+ _drf_direct_cntrl(rtwdev, path, false);
+
+ _dpk_kip_pwr_clk_on(rtwdev, path);
+ _dpk_kip_set_txagc(rtwdev, phy, path, txagc);
+ _dpk_rf_setting(rtwdev, gain, path, kidx);
+ _dpk_rx_dck(rtwdev, phy, path);
+ _dpk_kip_preset(rtwdev, phy, path, kidx);
+ _dpk_kip_set_rxagc(rtwdev, phy, path);
+ _dpk_table_select(rtwdev, path, kidx, gain);
+
+ txagc = _dpk_agc(rtwdev, phy, path, kidx, txagc, false, chanctx_idx);
+
+ _rfk_get_thermal(rtwdev, kidx, path);
+
+ if (txagc == 0xff) {
+ is_fail = true;
+ goto _error;
+ }
+
+ _dpk_idl_mpa(rtwdev, phy, path, kidx, gain);
+
+ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKMODE, RF_RX);
+ _dpk_fill_result(rtwdev, phy, path, kidx, gain, txagc);
+
+_error:
+ if (!is_fail)
+ dpk->bp[path][kidx].path_ok = 1;
+ else
+ dpk->bp[path][kidx].path_ok = 0;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s\n", path, kidx,
+ is_fail ? "Check" : "Success");
+
+ _dpk_onoff(rtwdev, path, is_fail);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s\n", path, kidx,
+ is_fail ? "Check" : "Success");
+
+ return is_fail;
+}
+
+static void _dpk_cal_select(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy, u8 kpath,
+ enum rtw89_chanctx_idx chanctx_idx)
+{
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+ u32 backup_kip_val[BACKUP_KIP_REGS_NR];
+ u32 backup_bb_val[BACKUP_BB_REGS_NR];
+ u32 backup_rf_val[RTW8852BT_SS][BACKUP_RF_REGS_NR];
+ bool reloaded[2] = {false};
+ u8 path;
+
+ for (path = 0; path < DPK_RF_PATH_MAX_8852BT; path++) {
+ reloaded[path] = _dpk_reload_check(rtwdev, phy, path, chanctx_idx);
+ if (!reloaded[path] && dpk->bp[path][0].ch != 0)
+ dpk->cur_idx[path] = !dpk->cur_idx[path];
+ else
+ _dpk_onoff(rtwdev, path, false);
+ }
+
+ _rfk_backup_bb_reg(rtwdev, backup_bb_val);
+ _rfk_backup_kip_reg(rtwdev, backup_kip_val);
+
+ for (path = 0; path < DPK_RF_PATH_MAX_8852BT; path++) {
+ _rfk_backup_rf_reg(rtwdev, backup_rf_val[path], path);
+ _dpk_information(rtwdev, phy, path, chanctx_idx);
+ if (rtwdev->is_tssi_mode[path])
+ _dpk_tssi_pause(rtwdev, path, true);
+ }
+
+ _rfk_bb_afe_setting(rtwdev, phy, path, kpath);
+
+ for (path = 0; path < DPK_RF_PATH_MAX_8852BT; path++)
+ _dpk_main(rtwdev, phy, path, 1, chanctx_idx);
+
+ _rfk_bb_afe_restore(rtwdev, phy, path, kpath);
+
+ _dpk_kip_restore(rtwdev, path);
+ _rfk_reload_bb_reg(rtwdev, backup_bb_val);
+ _rfk_reload_kip_reg(rtwdev, backup_kip_val);
+
+ for (path = 0; path < DPK_RF_PATH_MAX_8852BT; path++) {
+ _rfk_reload_rf_reg(rtwdev, backup_rf_val[path], path);
+ if (rtwdev->is_tssi_mode[path])
+ _dpk_tssi_pause(rtwdev, path, false);
+ }
+}
+
+static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_chanctx_idx chanctx_idx)
+{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
+ struct rtw89_fem_info *fem = &rtwdev->fem;
+
+ if (fem->epa_2g && chan->band_type == RTW89_BAND_2G) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] Skip DPK due to 2G_ext_PA exist!!\n");
+ return true;
+ } else if (fem->epa_5g && chan->band_type == RTW89_BAND_5G) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] Skip DPK due to 5G_ext_PA exist!!\n");
+ return true;
+ } else if (fem->epa_6g && chan->band_type == RTW89_BAND_6G) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] Skip DPK due to 6G_ext_PA exist!!\n");
+ return true;
+ }
+
+ return false;
+}
+
+static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+{
+ u8 path, kpath;
+
+ kpath = _kpath(rtwdev, phy);
+
+ for (path = 0; path < RTW8852BT_SS; path++) {
+ if (kpath & BIT(path))
+ _dpk_onoff(rtwdev, path, true);
+ }
+}
+
+static void _dpk_track(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+ s8 txagc_bb, txagc_bb_tp, ini_diff = 0, txagc_ofst;
+ s8 delta_ther[2] = {};
+ u8 trk_idx, txagc_rf;
+ u8 path, kidx;
+ u16 pwsf[2];
+ u8 cur_ther;
+ u32 tmp;
+
+ for (path = 0; path < RF_PATH_NUM_8852BT; path++) {
+ kidx = dpk->cur_idx[path];
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
+ "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n",
+ path, kidx, dpk->bp[path][kidx].ch);
+
+ cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
+ "[DPK_TRK] thermal now = %d\n", cur_ther);
+
+ if (dpk->bp[path][kidx].ch && cur_ther)
+ delta_ther[path] = dpk->bp[path][kidx].ther_dpk - cur_ther;
+
+ if (dpk->bp[path][kidx].band == RTW89_BAND_2G)
+ delta_ther[path] = delta_ther[path] * 3 / 2;
+ else
+ delta_ther[path] = delta_ther[path] * 5 / 2;
+
+ txagc_rf = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13),
+ B_TXAGC_RF);
+
+ if (rtwdev->is_tssi_mode[path]) {
+ trk_idx = rtw89_read_rf(rtwdev, path, RR_TXA, RR_TXA_TRK);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
+ "[DPK_TRK] txagc_RF / track_idx = 0x%x / %d\n",
+ txagc_rf, trk_idx);
+
+ txagc_bb =
+ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13),
+ MASKBYTE2);
+ txagc_bb_tp =
+ rtw89_phy_read32_mask(rtwdev, R_TXAGC_TP + (path << 13),
+ B_TXAGC_TP);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
+ "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n",
+ txagc_bb_tp, txagc_bb);
+
+ txagc_ofst =
+ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13),
+ MASKBYTE3);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
+ "[DPK_TRK] txagc_offset / delta_ther = %d / %d\n",
+ txagc_ofst, delta_ther[path]);
+ tmp = rtw89_phy_read32_mask(rtwdev, R_DPD_COM + (path << 8),
+ B_DPD_COM_OF);
+ if (tmp == 0x1) {
+ txagc_ofst = 0;
+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
+ "[DPK_TRK] HW txagc offset mode\n");
+ }
+
+ if (txagc_rf && cur_ther)
+ ini_diff = txagc_ofst + (delta_ther[path]);
+
+ tmp = rtw89_phy_read32_mask(rtwdev,
+ R_P0_TXDPD + (path << 13),
+ B_P0_TXDPD);
+ if (tmp == 0x0) {
+ pwsf[0] = dpk->bp[path][kidx].pwsf +
+ txagc_bb_tp - txagc_bb + ini_diff;
+ pwsf[1] = dpk->bp[path][kidx].pwsf +
+ txagc_bb_tp - txagc_bb + ini_diff;
+ } else {
+ pwsf[0] = dpk->bp[path][kidx].pwsf + ini_diff;
+ pwsf[1] = dpk->bp[path][kidx].pwsf + ini_diff;
+ }
+ } else {
+ pwsf[0] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff;
+ pwsf[1] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff;
+ }
+
+ tmp = rtw89_phy_read32_mask(rtwdev, R_DPK_TRK, B_DPK_TRK_DIS);
+ if (!tmp && txagc_rf) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
+ "[DPK_TRK] New pwsf[0] / pwsf[1] = 0x%x / 0x%x\n",
+ pwsf[0], pwsf[1]);
+
+ rtw89_phy_write32_mask(rtwdev,
+ R_DPD_BND + (path << 8) + (kidx << 2),
+ B_DPD_BND_0, pwsf[0]);
+ rtw89_phy_write32_mask(rtwdev,
+ R_DPD_BND + (path << 8) + (kidx << 2),
+ B_DPD_BND_1, pwsf[1]);
+ }
+ }
+}
+
+static void _set_dpd_backoff(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+{
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+ u8 tx_scale, ofdm_bkof, path, kpath;
+
+ kpath = _kpath(rtwdev, phy);
+
+ ofdm_bkof = rtw89_phy_read32_mask(rtwdev, R_DPD_BF + (phy << 13), B_DPD_BF_OFDM);
+ tx_scale = rtw89_phy_read32_mask(rtwdev, R_DPD_BF + (phy << 13), B_DPD_BF_SCA);
+
+ if (ofdm_bkof + tx_scale >= 44) {
+ /* move dpd backoff to bb, and set dpd backoff to 0 */
+ dpk->dpk_gs[phy] = 0x7f;
+ for (path = 0; path < RF_PATH_NUM_8852BT; path++) {
+ if (!(kpath & BIT(path)))
+ continue;
+
+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8),
+ B_DPD_CFG, 0x7f7f7f);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[RFK] Set S%d DPD backoff to 0dB\n", path);
+ }
+ } else {
+ dpk->dpk_gs[phy] = 0x5b;
+ }
+}
+
+static void _tssi_dpk_off(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+{
+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A, BIT(24), 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0B, BIT(24), 0x0);
+}
+
+static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
+{
+ enum rtw89_band band = chan->band_type;
+
+ if (band == RTW89_BAND_2G)
+ rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXG, 0x1);
+ else
+ rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXA, 0x1);
+}
+
+static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
+{
+ enum rtw89_band band = chan->band_type;
+
+ rtw89_rfk_parser(rtwdev, &rtw8852bt_tssi_sys_defs_tbl);
+
+ if (chan->band_width == RTW89_CHANNEL_WIDTH_80)
+ rtw89_phy_write32_mask(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_BW80, 0x1);
+ else
+ rtw89_phy_write32_mask(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_BW80, 0x0);
+
+ if (path == RF_PATH_A)
+ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
+ &rtw8852bt_tssi_sys_a_defs_2g_tbl,
+ &rtw8852bt_tssi_sys_a_defs_5g_tbl);
+ else
+ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
+ &rtw8852bt_tssi_sys_b_defs_2g_tbl,
+ &rtw8852bt_tssi_sys_b_defs_5g_tbl);
+}
+
+static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path)
+{
+ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
+ &rtw8852bt_tssi_init_txpwr_defs_a_tbl,
+ &rtw8852bt_tssi_init_txpwr_defs_b_tbl);
+}
+
+static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path)
+{
+ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
+ &rtw8852bt_tssi_init_txpwr_he_tb_defs_a_tbl,
+ &rtw8852bt_tssi_init_txpwr_he_tb_defs_b_tbl);
+}
+
+static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path)
+{
+ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
+ &rtw8852bt_tssi_dck_defs_a_tbl,
+ &rtw8852bt_tssi_dck_defs_b_tbl);
+}
+
+static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
+{
+#define RTW8852BT_TSSI_GET_VAL(ptr, idx) \
+({ \
+ s8 *__ptr = (ptr); \
+ u8 __idx = (idx), __i, __v; \
+ u32 __val = 0; \
+ for (__i = 0; __i < 4; __i++) { \
+ __v = (__ptr[__idx + __i]); \
+ __val |= (__v << (8 * __i)); \
+ } \
+ __val; \
+})
+ struct rtw89_fw_txpwr_track_cfg *trk = rtwdev->fw.elm_info.txpwr_trk;
+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
+ u8 ch = chan->channel;
+ u8 subband = chan->subband_type;
+ const s8 *thm_up_a = NULL;
+ const s8 *thm_down_a = NULL;
+ const s8 *thm_up_b = NULL;
+ const s8 *thm_down_b = NULL;
+ u8 thermal = 0xff;
+ s8 thm_ofst[64] = {0};
+ u32 tmp = 0;
+ u8 i, j;
+
+ switch (subband) {
+ default:
+ case RTW89_CH_2G:
+ thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_P][0];
+ thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_N][0];
+ thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_P][0];
+ thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_N][0];
+ break;
+ case RTW89_CH_5G_BAND_1:
+ thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][0];
+ thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][0];
+ thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][0];
+ thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][0];
+ break;
+ case RTW89_CH_5G_BAND_3:
+ thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][1];
+ thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][1];
+ thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][1];
+ thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][1];
+ break;
+ case RTW89_CH_5G_BAND_4:
+ thm_up_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][2];
+ thm_down_a = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][2];
+ thm_up_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][2];
+ thm_down_b = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][2];
+ break;
+ }
+
+ if (path == RF_PATH_A) {
+ thermal = tssi_info->thermal[RF_PATH_A];
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal);
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, 0x1);
+
+ if (thermal == 0xff) {
+ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 32);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 32);
+
+ for (i = 0; i < 64; i += 4) {
+ rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, 0x0);
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI] write 0x%x val=0x%08x\n",
+ R_P0_TSSI_BASE + i, 0x0);
+ }
+
+ } else {
+ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER,
+ thermal);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL,
+ thermal);
+
+ i = 0;
+ for (j = 0; j < 32; j++)
+ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ?
+ -thm_down_a[i++] :
+ -thm_down_a[DELTA_SWINGIDX_SIZE - 1];
+
+ i = 1;
+ for (j = 63; j >= 32; j--)
+ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ?
+ thm_up_a[i++] :
+ thm_up_a[DELTA_SWINGIDX_SIZE - 1];
+
+ for (i = 0; i < 64; i += 4) {
+ tmp = RTW8852BT_TSSI_GET_VAL(thm_ofst, i);
+ rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, tmp);
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI] write 0x%x val=0x%08x\n",
+ 0x5c00 + i, tmp);
+ }
+ }
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x0);
+
+ } else {
+ thermal = tssi_info->thermal[RF_PATH_B];
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI] ch=%d thermal_pathB=0x%x\n", ch, thermal);
+
+ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_DIS, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_TRK, 0x1);
+
+ if (thermal == 0xff) {
+ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, 32);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, 32);
+
+ for (i = 0; i < 64; i += 4) {
+ rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, 0x0);
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI] write 0x%x val=0x%08x\n",
+ 0x7c00 + i, 0x0);
+ }
+
+ } else {
+ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER,
+ thermal);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL,
+ thermal);
+
+ i = 0;
+ for (j = 0; j < 32; j++)
+ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ?
+ -thm_down_b[i++] :
+ -thm_down_b[DELTA_SWINGIDX_SIZE - 1];
+
+ i = 1;
+ for (j = 63; j >= 32; j--)
+ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ?
+ thm_up_b[i++] :
+ thm_up_b[DELTA_SWINGIDX_SIZE - 1];
+
+ for (i = 0; i < 64; i += 4) {
+ tmp = RTW8852BT_TSSI_GET_VAL(thm_ofst, i);
+ rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, tmp);
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI] write 0x%x val=0x%08x\n",
+ 0x7c00 + i, tmp);
+ }
+ }
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x0);
+ }
+#undef RTW8852BT_TSSI_GET_VAL
+}
+
+static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path)
+{
+ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
+ &rtw8852bt_tssi_dac_gain_defs_a_tbl,
+ &rtw8852bt_tssi_dac_gain_defs_b_tbl);
+}
+
+static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
+{
+ enum rtw89_band band = chan->band_type;
+
+ if (path == RF_PATH_A)
+ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
+ &rtw8852bt_tssi_slope_a_defs_2g_tbl,
+ &rtw8852bt_tssi_slope_a_defs_5g_tbl);
+ else
+ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
+ &rtw8852bt_tssi_slope_b_defs_2g_tbl,
+ &rtw8852bt_tssi_slope_b_defs_5g_tbl);
+}
+
+static void _tssi_alignment_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, bool all,
+ const struct rtw89_chan *chan)
+{
+ enum rtw89_band band = chan->band_type;
+ const struct rtw89_rfk_tbl *tbl = NULL;
+ u8 ch = chan->channel;
+
+ if (path == RF_PATH_A) {
+ if (band == RTW89_BAND_2G)
+ tbl = &rtw8852bt_tssi_align_a_2g_all_defs_tbl;
+ else if (ch >= 36 && ch <= 64)
+ tbl = &rtw8852bt_tssi_align_a_5g1_all_defs_tbl;
+ else if (ch >= 100 && ch <= 144)
+ tbl = &rtw8852bt_tssi_align_a_5g2_all_defs_tbl;
+ else if (ch >= 149 && ch <= 177)
+ tbl = &rtw8852bt_tssi_align_a_5g3_all_defs_tbl;
+ } else {
+ if (ch >= 1 && ch <= 14)
+ tbl = &rtw8852bt_tssi_align_b_2g_all_defs_tbl;
+ else if (ch >= 36 && ch <= 64)
+ tbl = &rtw8852bt_tssi_align_b_5g1_all_defs_tbl;
+ else if (ch >= 100 && ch <= 144)
+ tbl = &rtw8852bt_tssi_align_b_5g2_all_defs_tbl;
+ else if (ch >= 149 && ch <= 177)
+ tbl = &rtw8852bt_tssi_align_b_5g3_all_defs_tbl;
+ }
+
+ if (tbl)
+ rtw89_rfk_parser(rtwdev, tbl);
+}
+
+static void _tssi_set_tssi_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path)
+{
+ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
+ &rtw8852bt_tssi_slope_defs_a_tbl,
+ &rtw8852bt_tssi_slope_defs_b_tbl);
+}
+
+static void _tssi_set_tssi_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path)
+{
+ if (path == RF_PATH_A)
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSIC, B_P0_TSSIC_BYPASS, 0x0);
+ else
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSIC, B_P1_TSSIC_BYPASS, 0x0);
+}
+
+static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path)
+{
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "======>%s path=%d\n", __func__,
+ path);
+
+ if (path == RF_PATH_A)
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG,
+ B_P0_TSSI_MV_MIX, 0x010);
+ else
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG,
+ B_P1_RFCTM_DEL, 0x010);
+}
+
+static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+{
+ u8 i;
+
+ for (i = 0; i < RF_PATH_NUM_8852BT; i++) {
+ _tssi_set_tssi_track(rtwdev, phy, i);
+ _tssi_set_txagc_offset_mv_avg(rtwdev, phy, i);
+
+ if (i == RF_PATH_A) {
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG,
+ B_P0_TSSI_MV_CLR, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG,
+ B_P0_TSSI_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG,
+ B_P0_TSSI_EN, 0x1);
+ rtw89_write_rf(rtwdev, i, RR_TXGA_V1,
+ RR_TXGA_V1_TRK_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK,
+ B_P0_TSSI_RFC, 0x3);
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK,
+ B_P0_TSSI_OFT, 0xc0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK,
+ B_P0_TSSI_OFT_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK,
+ B_P0_TSSI_OFT_EN, 0x1);
+
+ rtwdev->is_tssi_mode[RF_PATH_A] = true;
+ } else {
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG,
+ B_P1_TSSI_MV_CLR, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG,
+ B_P1_TSSI_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG,
+ B_P1_TSSI_EN, 0x1);
+ rtw89_write_rf(rtwdev, i, RR_TXGA_V1,
+ RR_TXGA_V1_TRK_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK,
+ B_P1_TSSI_RFC, 0x3);
+
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK,
+ B_P1_TSSI_OFT, 0xc0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK,
+ B_P1_TSSI_OFT_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK,
+ B_P1_TSSI_OFT_EN, 0x1);
+
+ rtwdev->is_tssi_mode[RF_PATH_B] = true;
+ }
+ }
+}
+
+static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+{
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_RFC, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_CLR, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_RFC, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_CLR, 0x1);
+
+ rtwdev->is_tssi_mode[RF_PATH_A] = false;
+ rtwdev->is_tssi_mode[RF_PATH_B] = false;
+}
+
+static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch)
+{
+ switch (ch) {
+ case 1 ... 2:
+ return 0;
+ case 3 ... 5:
+ return 1;
+ case 6 ... 8:
+ return 2;
+ case 9 ... 11:
+ return 3;
+ case 12 ... 13:
+ return 4;
+ case 14:
+ return 5;
+ }
+
+ return 0;
+}
+
+#define TSSI_EXTRA_GROUP_BIT (BIT(31))
+#define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx))
+#define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT)
+#define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT)
+#define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1)
+
+static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch)
+{
+ switch (ch) {
+ case 1 ... 2:
+ return 0;
+ case 3 ... 5:
+ return 1;
+ case 6 ... 8:
+ return 2;
+ case 9 ... 11:
+ return 3;
+ case 12 ... 14:
+ return 4;
+ case 36 ... 40:
+ return 5;
+ case 41 ... 43:
+ return TSSI_EXTRA_GROUP(5);
+ case 44 ... 48:
+ return 6;
+ case 49 ... 51:
+ return TSSI_EXTRA_GROUP(6);
+ case 52 ... 56:
+ return 7;
+ case 57 ... 59:
+ return TSSI_EXTRA_GROUP(7);
+ case 60 ... 64:
+ return 8;
+ case 100 ... 104:
+ return 9;
+ case 105 ... 107:
+ return TSSI_EXTRA_GROUP(9);
+ case 108 ... 112:
+ return 10;
+ case 113 ... 115:
+ return TSSI_EXTRA_GROUP(10);
+ case 116 ... 120:
+ return 11;
+ case 121 ... 123:
+ return TSSI_EXTRA_GROUP(11);
+ case 124 ... 128:
+ return 12;
+ case 129 ... 131:
+ return TSSI_EXTRA_GROUP(12);
+ case 132 ... 136:
+ return 13;
+ case 137 ... 139:
+ return TSSI_EXTRA_GROUP(13);
+ case 140 ... 144:
+ return 14;
+ case 149 ... 153:
+ return 15;
+ case 154 ... 156:
+ return TSSI_EXTRA_GROUP(15);
+ case 157 ... 161:
+ return 16;
+ case 162 ... 164:
+ return TSSI_EXTRA_GROUP(16);
+ case 165 ... 169:
+ return 17;
+ case 170 ... 172:
+ return TSSI_EXTRA_GROUP(17);
+ case 173 ... 177:
+ return 18;
+ }
+
+ return 0;
+}
+
+static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch)
+{
+ switch (ch) {
+ case 1 ... 8:
+ return 0;
+ case 9 ... 14:
+ return 1;
+ case 36 ... 48:
+ return 2;
+ case 52 ... 64:
+ return 3;
+ case 100 ... 112:
+ return 4;
+ case 116 ... 128:
+ return 5;
+ case 132 ... 144:
+ return 6;
+ case 149 ... 177:
+ return 7;
+ }
+
+ return 0;
+}
+
+static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
+{
+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
+ u8 ch = chan->channel;
+ u32 gidx, gidx_1st, gidx_2nd;
+ s8 de_1st;
+ s8 de_2nd;
+ s8 val;
+
+ gidx = _tssi_get_ofdm_group(rtwdev, ch);
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", path, gidx);
+
+ if (IS_TSSI_EXTRA_GROUP(gidx)) {
+ gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx);
+ gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx);
+ de_1st = tssi_info->tssi_mcs[path][gidx_1st];
+ de_2nd = tssi_info->tssi_mcs[path][gidx_2nd];
+ val = (de_1st + de_2nd) / 2;
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n",
+ path, val, de_1st, de_2nd);
+ } else {
+ val = tssi_info->tssi_mcs[path][gidx];
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val);
+ }
+
+ return val;
+}
+
+static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
+{
+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
+ u8 ch = chan->channel;
+ u32 tgidx, tgidx_1st, tgidx_2nd;
+ s8 tde_1st;
+ s8 tde_2nd;
+ s8 val;
+
+ tgidx = _tssi_get_trim_group(rtwdev, ch);
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n",
+ path, tgidx);
+
+ if (IS_TSSI_EXTRA_GROUP(tgidx)) {
+ tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx);
+ tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx);
+ tde_1st = tssi_info->tssi_trim[path][tgidx_1st];
+ tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd];
+ val = (tde_1st + tde_2nd) / 2;
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n",
+ path, val, tde_1st, tde_2nd);
+ } else {
+ val = tssi_info->tssi_trim[path][tgidx];
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI][TRIM]: path=%d mcs trim_de=%d\n",
+ path, val);
+ }
+
+ return val;
+}
+
+static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan)
+{
+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
+ u8 ch = chan->channel;
+ u8 gidx;
+ s8 ofdm_de;
+ s8 trim_de;
+ s32 val;
+ u32 i;
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n",
+ phy, ch);
+
+ for (i = RF_PATH_A; i < RF_PATH_NUM_8852BT; i++) {
+ gidx = _tssi_get_cck_group(rtwdev, ch);
+ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan);
+ val = tssi_info->tssi_cck[i][gidx] + trim_de;
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n",
+ i, gidx, tssi_info->tssi_cck[i][gidx], trim_de);
+
+ rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_long[i], _TSSI_DE_MASK, val);
+ rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_short[i], _TSSI_DE_MASK, val);
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n",
+ _tssi_de_cck_long[i],
+ rtw89_phy_read32_mask(rtwdev, _tssi_de_cck_long[i],
+ _TSSI_DE_MASK));
+
+ ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i, chan);
+ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan);
+ val = ofdm_de + trim_de;
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n",
+ i, ofdm_de, trim_de);
+
+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_20m[i], _TSSI_DE_MASK, val);
+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_40m[i], _TSSI_DE_MASK, val);
+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m[i], _TSSI_DE_MASK, val);
+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m_80m[i],
+ _TSSI_DE_MASK, val);
+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_5m[i], _TSSI_DE_MASK, val);
+ rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_10m[i], _TSSI_DE_MASK, val);
+
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI,
+ "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n",
+ _tssi_de_mcs_20m[i],
+ rtw89_phy_read32_mask(rtwdev, _tssi_de_mcs_20m[i],
+ _TSSI_DE_MASK));
+ }
+}
+
+static void _tssi_alimentk_dump_result(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
+{
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI PA K]\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n"
+ "0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n",
+ R_TSSI_PA_K1 + (path << 13),
+ rtw89_phy_read32(rtwdev, R_TSSI_PA_K1 + (path << 13)),
+ R_TSSI_PA_K2 + (path << 13),
+ rtw89_phy_read32(rtwdev, R_TSSI_PA_K2 + (path << 13)),
+ R_P0_TSSI_ALIM1 + (path << 13),
+ rtw89_phy_read32(rtwdev, R_P0_TSSI_ALIM1 + (path << 13)),
+ R_P0_TSSI_ALIM3 + (path << 13),
+ rtw89_phy_read32(rtwdev, R_P0_TSSI_ALIM3 + (path << 13)),
+ R_TSSI_PA_K5 + (path << 13),
+ rtw89_phy_read32(rtwdev, R_TSSI_PA_K5 + (path << 13)),
+ R_P0_TSSI_ALIM2 + (path << 13),
+ rtw89_phy_read32(rtwdev, R_P0_TSSI_ALIM2 + (path << 13)),
+ R_P0_TSSI_ALIM4 + (path << 13),
+ rtw89_phy_read32(rtwdev, R_P0_TSSI_ALIM4 + (path << 13)),
+ R_TSSI_PA_K8 + (path << 13),
+ rtw89_phy_read32(rtwdev, R_TSSI_PA_K8 + (path << 13)));
+}
+
+static void _tssi_alimentk_done(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy, enum rtw89_rf_path path,
+ const struct rtw89_chan *chan)
+{
+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
+ u8 channel = chan->channel;
+ u8 band;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "======>%s phy=%d path=%d\n", __func__, phy, path);
+
+ if (channel >= 1 && channel <= 14)
+ band = TSSI_ALIMK_2G;
+ else if (channel >= 36 && channel <= 64)
+ band = TSSI_ALIMK_5GL;
+ else if (channel >= 100 && channel <= 144)
+ band = TSSI_ALIMK_5GM;
+ else if (channel >= 149 && channel <= 177)
+ band = TSSI_ALIMK_5GH;
+ else
+ band = TSSI_ALIMK_2G;
+
+ if (tssi_info->alignment_done[path][band]) {
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD,
+ tssi_info->alignment_value[path][band][0]);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD,
+ tssi_info->alignment_value[path][band][1]);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD,
+ tssi_info->alignment_value[path][band][2]);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD,
+ tssi_info->alignment_value[path][band][3]);
+ }
+
+ _tssi_alimentk_dump_result(rtwdev, path);
+}
+
+static void _tssi_hw_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, u16 cnt, u16 period, s16 pwr_dbm,
+ u8 enable, const struct rtw89_chan *chan)
+{
+ enum rtw89_rf_path_bit rx_path;
+
+ if (path == RF_PATH_A)
+ rx_path = RF_A;
+ else if (path == RF_PATH_B)
+ rx_path = RF_B;
+ else if (path == RF_PATH_AB)
+ rx_path = RF_AB;
+ else
+ rx_path = RF_ABCD; /* don't change path, but still set others */
+
+ if (enable) {
+ rtw8852bx_bb_set_plcp_tx(rtwdev);
+ rtw8852bx_bb_cfg_tx_path(rtwdev, path);
+ rtw8852bx_bb_ctrl_rx_path(rtwdev, rx_path, chan);
+ rtw8852bx_bb_set_power(rtwdev, pwr_dbm, phy);
+ }
+
+ rtw8852bx_bb_set_pmac_pkt_tx(rtwdev, enable, cnt, period, 20, phy, chan);
+}
+
+static void _tssi_backup_bb_registers(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy, const u32 reg[],
+ u32 reg_backup[], u32 reg_num)
+{
+ u32 i;
+
+ for (i = 0; i < reg_num; i++) {
+ reg_backup[i] = rtw89_phy_read32_mask(rtwdev, reg[i], MASKDWORD);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI] Backup BB 0x%x = 0x%x\n", reg[i],
+ reg_backup[i]);
+ }
+}
+
+static void _tssi_reload_bb_registers(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy, const u32 reg[],
+ u32 reg_backup[], u32 reg_num)
+
+{
+ u32 i;
+
+ for (i = 0; i < reg_num; i++) {
+ rtw89_phy_write32_mask(rtwdev, reg[i], MASKDWORD, reg_backup[i]);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI] Reload BB 0x%x = 0x%x\n", reg[i],
+ reg_backup[i]);
+ }
+}
+
+static u8 _tssi_ch_to_idx(struct rtw89_dev *rtwdev, u8 channel)
+{
+ u8 channel_index;
+
+ if (channel >= 1 && channel <= 14)
+ channel_index = channel - 1;
+ else if (channel >= 36 && channel <= 64)
+ channel_index = (channel - 36) / 2 + 14;
+ else if (channel >= 100 && channel <= 144)
+ channel_index = ((channel - 100) / 2) + 15 + 14;
+ else if (channel >= 149 && channel <= 177)
+ channel_index = ((channel - 149) / 2) + 38 + 14;
+ else
+ channel_index = 0;
+
+ return channel_index;
+}
+
+static bool _tssi_get_cw_report(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, const s16 *power,
+ u32 *tssi_cw_rpt, const struct rtw89_chan *chan)
+{
+ u32 tx_counter, tx_counter_tmp;
+ const int retry = 100;
+ u32 tmp;
+ int j, k;
+
+ for (j = 0; j < RTW8852BT_TSSI_PATH_NR; j++) {
+ rtw89_phy_write32_mask(rtwdev, _tssi_trigger[path], B_P0_TSSI_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, _tssi_trigger[path], B_P0_TSSI_EN, 0x1);
+
+ tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
+
+ tmp = rtw89_phy_read32_mask(rtwdev, _tssi_trigger[path], MASKDWORD);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI PA K] 0x%x = 0x%08x path=%d\n",
+ _tssi_trigger[path], tmp, path);
+
+ if (j == 0)
+ _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], true,
+ chan);
+ else
+ _tssi_hw_tx(rtwdev, phy, RF_PATH_ABCD, 100, 5000, power[j], true,
+ chan);
+
+ tx_counter_tmp = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
+ tx_counter_tmp -= tx_counter;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI PA K] First HWTXcounter=%d path=%d\n",
+ tx_counter_tmp, path);
+
+ for (k = 0; k < retry; k++) {
+ tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_rpt_addr[path],
+ B_TSSI_CWRPT_RDY);
+ if (tmp)
+ break;
+
+ udelay(30);
+
+ tx_counter_tmp =
+ rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
+ tx_counter_tmp -= tx_counter;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI PA K] Flow k = %d HWTXcounter=%d path=%d\n",
+ k, tx_counter_tmp, path);
+ }
+
+ if (k >= retry) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI PA K] TSSI finish bit k > %d mp:100ms normal:30us path=%d\n",
+ k, path);
+
+ _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], false, chan);
+ return false;
+ }
+
+ tssi_cw_rpt[j] =
+ rtw89_phy_read32_mask(rtwdev, _tssi_cw_rpt_addr[path],
+ B_TSSI_CWRPT);
+
+ _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], false, chan);
+
+ tx_counter_tmp = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
+ tx_counter_tmp -= tx_counter;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI PA K] Final HWTXcounter=%d path=%d\n",
+ tx_counter_tmp, path);
+ }
+
+ return true;
+}
+
+static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
+{
+ static const u32 bb_reg[8] = {0x5820, 0x7820, 0x4978, 0x58e4,
+ 0x78e4, 0x49c0, 0x0d18, 0x0d80};
+ static const s16 power_2g[4] = {48, 20, 4, -8};
+ static const s16 power_5g[4] = {48, 20, 4, 4};
+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
+ s32 tssi_alim_offset_1, tssi_alim_offset_2, tssi_alim_offset_3;
+ u32 tssi_cw_rpt[RTW8852BT_TSSI_PATH_NR] = {};
+ u8 channel = chan->channel;
+ u8 ch_idx = _tssi_ch_to_idx(rtwdev, channel);
+ struct rtw8852bx_bb_tssi_bak tssi_bak;
+ s32 aliment_diff, tssi_cw_default;
+ u32 bb_reg_backup[8] = {};
+ ktime_t start_time;
+ const s16 *power;
+ s64 this_time;
+ u8 band;
+ bool ok;
+ u32 tmp;
+ u8 j;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "======> %s channel=%d path=%d\n", __func__, channel,
+ path);
+
+ start_time = ktime_get();
+
+ if (chan->band_type == RTW89_BAND_2G)
+ power = power_2g;
+ else
+ power = power_5g;
+
+ if (channel >= 1 && channel <= 14)
+ band = TSSI_ALIMK_2G;
+ else if (channel >= 36 && channel <= 64)
+ band = TSSI_ALIMK_5GL;
+ else if (channel >= 100 && channel <= 144)
+ band = TSSI_ALIMK_5GM;
+ else if (channel >= 149 && channel <= 177)
+ band = TSSI_ALIMK_5GH;
+ else
+ band = TSSI_ALIMK_2G;
+
+ rtw8852bx_bb_backup_tssi(rtwdev, phy, &tssi_bak);
+ _tssi_backup_bb_registers(rtwdev, phy, bb_reg, bb_reg_backup,
+ ARRAY_SIZE(bb_reg_backup));
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, 0x8);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_AVG, 0x8);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, 0x2);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, 0x2);
+
+ ok = _tssi_get_cw_report(rtwdev, phy, path, power, tssi_cw_rpt, chan);
+ if (!ok)
+ goto out;
+
+ for (j = 0; j < RTW8852BT_TSSI_PATH_NR; j++) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI PA K] power[%d]=%d tssi_cw_rpt[%d]=%d\n", j,
+ power[j], j, tssi_cw_rpt[j]);
+ }
+
+ tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][1],
+ _tssi_cw_default_mask[1]);
+ tssi_cw_default = sign_extend32(tmp, 8);
+ tssi_alim_offset_1 = tssi_cw_rpt[0] - ((power[0] - power[1]) * 2) -
+ tssi_cw_rpt[1] + tssi_cw_default;
+ aliment_diff = tssi_alim_offset_1 - tssi_cw_default;
+
+ tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][2],
+ _tssi_cw_default_mask[2]);
+ tssi_cw_default = sign_extend32(tmp, 8);
+ tssi_alim_offset_2 = tssi_cw_default + aliment_diff;
+
+ tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][3],
+ _tssi_cw_default_mask[3]);
+ tssi_cw_default = sign_extend32(tmp, 8);
+ tssi_alim_offset_3 = tssi_cw_default + aliment_diff;
+
+ if (path == RF_PATH_A) {
+ tmp = FIELD_PREP(B_P1_TSSI_ALIM11, tssi_alim_offset_1) |
+ FIELD_PREP(B_P1_TSSI_ALIM12, tssi_alim_offset_2) |
+ FIELD_PREP(B_P1_TSSI_ALIM13, tssi_alim_offset_3);
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM1, tmp);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2, B_P0_TSSI_ALIM2, tmp);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI PA K] tssi_alim_offset = 0x%x 0x%x 0x%x 0x%x\n",
+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3, B_P0_TSSI_ALIM31),
+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM11),
+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM12),
+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM13));
+ } else {
+ tmp = FIELD_PREP(B_P1_TSSI_ALIM11, tssi_alim_offset_1) |
+ FIELD_PREP(B_P1_TSSI_ALIM12, tssi_alim_offset_2) |
+ FIELD_PREP(B_P1_TSSI_ALIM13, tssi_alim_offset_3);
+
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM1, tmp);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_ALIM2, B_P1_TSSI_ALIM2, tmp);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI PA K] tssi_alim_offset = 0x%x 0x%x 0x%x 0x%x\n",
+ rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM3, B_P1_TSSI_ALIM31),
+ rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM11),
+ rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM12),
+ rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM13));
+ }
+
+ tssi_info->alignment_done[path][band] = true;
+ tssi_info->alignment_value[path][band][0] =
+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD);
+ tssi_info->alignment_value[path][band][1] =
+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD);
+ tssi_info->alignment_value[path][band][2] =
+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD);
+ tssi_info->alignment_value[path][band][3] =
+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD);
+
+ tssi_info->check_backup_aligmk[path][ch_idx] = true;
+ tssi_info->alignment_backup_by_ch[path][ch_idx][0] =
+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD);
+ tssi_info->alignment_backup_by_ch[path][ch_idx][1] =
+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD);
+ tssi_info->alignment_backup_by_ch[path][ch_idx][2] =
+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD);
+ tssi_info->alignment_backup_by_ch[path][ch_idx][3] =
+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][0], 0x%x = 0x%08x\n",
+ path, band, R_P0_TSSI_ALIM1 + (path << 13),
+ tssi_info->alignment_value[path][band][0]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][1], 0x%x = 0x%08x\n",
+ path, band, R_P0_TSSI_ALIM3 + (path << 13),
+ tssi_info->alignment_value[path][band][1]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][2], 0x%x = 0x%08x\n",
+ path, band, R_P0_TSSI_ALIM2 + (path << 13),
+ tssi_info->alignment_value[path][band][2]);
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][3], 0x%x = 0x%08x\n",
+ path, band, R_P0_TSSI_ALIM4 + (path << 13),
+ tssi_info->alignment_value[path][band][3]);
+
+out:
+ _tssi_reload_bb_registers(rtwdev, phy, bb_reg, bb_reg_backup,
+ ARRAY_SIZE(bb_reg_backup));
+ rtw8852bx_bb_restore_tssi(rtwdev, phy, &tssi_bak);
+ rtw8852bx_bb_tx_mode_switch(rtwdev, phy, 0);
+
+ this_time = ktime_us_delta(ktime_get(), start_time);
+ tssi_info->tssi_alimk_time += this_time;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[TSSI PA K] %s processing time = %lld us (acc = %llu us)\n",
+ __func__, this_time, tssi_info->tssi_alimk_time);
+}
+
+void rtw8852bt_dpk_init(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+
+ u8 path;
+
+ for (path = 0; path < 2; path++) {
+ dpk->cur_idx[path] = 0;
+ dpk->max_dpk_txagc[path] = 0x3F;
+ }
+
+ dpk->is_dpk_enable = true;
+ dpk->is_dpk_reload_en = false;
+ _set_dpd_backoff(rtwdev, RTW89_PHY_0);
+}
+
+void rtw8852bt_rck(struct rtw89_dev *rtwdev)
+{
+ u8 path;
+
+ for (path = 0; path < RF_PATH_NUM_8852BT; path++)
+ _rck(rtwdev, path);
+}
+
+void rtw8852bt_dack(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx)
+{
+ u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0, chanctx_idx);
+
+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START);
+ _dac_cal(rtwdev, false);
+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP);
+}
+
+void rtw8852bt_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
+{
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx);
+ u32 tx_en;
+
+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START);
+ rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
+ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx));
+
+ _iqk_init(rtwdev);
+ _iqk(rtwdev, phy_idx, false, chanctx_idx);
+
+ rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP);
+}
+
+void rtw8852bt_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
+{
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx);
+ u32 tx_en;
+
+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START);
+ rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
+ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx));
+
+ _rx_dck(rtwdev, phy_idx);
+
+ rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP);
+}
+
+void rtw8852bt_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
+{
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[DPK] ****** DPK Start (Ver: 0x%x) ******\n", RTW8852BT_DPK_VER);
+
+ if (_dpk_bypass_check(rtwdev, phy_idx, chanctx_idx))
+ _dpk_force_bypass(rtwdev, phy_idx);
+ else
+ _dpk_cal_select(rtwdev, phy_idx, RF_AB, chanctx_idx);
+}
+
+void rtw8852bt_dpk_track(struct rtw89_dev *rtwdev)
+{
+ _dpk_track(rtwdev);
+}
+
+void rtw8852bt_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ bool hwtx_en, enum rtw89_chanctx_idx chanctx_idx)
+{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
+ static const u32 reg[2] = {R_DPD_CH0A, R_DPD_CH0B};
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_AB, chanctx_idx);
+ u32 reg_backup[2] = {};
+ u32 tx_en;
+ u8 i;
+
+ _tssi_backup_bb_registers(rtwdev, phy, reg, reg_backup, 2);
+ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", __func__, phy);
+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START);
+
+ _tssi_dpk_off(rtwdev, phy);
+ _tssi_disable(rtwdev, phy);
+
+ for (i = RF_PATH_A; i < RF_PATH_NUM_8852BT; i++) {
+ _tssi_rf_setting(rtwdev, phy, i, chan);
+ _tssi_set_sys(rtwdev, phy, i, chan);
+ _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i);
+ _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i);
+ _tssi_set_dck(rtwdev, phy, i);
+ _tssi_set_tmeter_tbl(rtwdev, phy, i, chan);
+ _tssi_set_dac_gain_tbl(rtwdev, phy, i);
+ _tssi_slope_cal_org(rtwdev, phy, i, chan);
+ _tssi_alignment_default(rtwdev, phy, i, true, chan);
+ _tssi_set_tssi_slope(rtwdev, phy, i);
+
+ rtw89_chip_stop_sch_tx(rtwdev, phy, &tx_en, RTW89_SCH_TX_SEL_ALL);
+ _tmac_tx_pause(rtwdev, phy, true);
+ if (hwtx_en)
+ _tssi_alimentk(rtwdev, phy, i, chan);
+ _tmac_tx_pause(rtwdev, phy, false);
+ rtw89_chip_resume_sch_tx(rtwdev, phy, tx_en);
+ }
+
+ _tssi_enable(rtwdev, phy);
+ _tssi_set_efuse_to_de(rtwdev, phy, chan);
+
+ _tssi_reload_bb_registers(rtwdev, phy, reg, reg_backup, 2);
+
+ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP);
+}
+
+void rtw8852bt_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan)
+{
+ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
+ u8 channel = chan->channel;
+ u8 band;
+ u32 i;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "======>%s phy=%d channel=%d\n", __func__, phy, channel);
+
+ if (channel >= 1 && channel <= 14)
+ band = TSSI_ALIMK_2G;
+ else if (channel >= 36 && channel <= 64)
+ band = TSSI_ALIMK_5GL;
+ else if (channel >= 100 && channel <= 144)
+ band = TSSI_ALIMK_5GM;
+ else if (channel >= 149 && channel <= 177)
+ band = TSSI_ALIMK_5GH;
+ else
+ band = TSSI_ALIMK_2G;
+
+ _tssi_disable(rtwdev, phy);
+
+ for (i = RF_PATH_A; i < RTW8852BT_TSSI_PATH_NR; i++) {
+ _tssi_rf_setting(rtwdev, phy, i, chan);
+ _tssi_set_sys(rtwdev, phy, i, chan);
+ _tssi_set_tmeter_tbl(rtwdev, phy, i, chan);
+
+ if (tssi_info->alignment_done[i][band])
+ _tssi_alimentk_done(rtwdev, phy, i, chan);
+ else
+ _tssi_alignment_default(rtwdev, phy, i, true, chan);
+ }
+
+ _tssi_enable(rtwdev, phy);
+ _tssi_set_efuse_to_de(rtwdev, phy, chan);
+}
+
+static void rtw8852bt_tssi_default_txagc(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy, bool enable,
+ enum rtw89_chanctx_idx chanctx_idx)
+{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
+ u8 channel = chan->channel;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "======> %s ch=%d\n",
+ __func__, channel);
+
+ if (enable)
+ return;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "======>%s 1 SCAN_END Set 0x5818[7:0]=0x%x 0x7818[7:0]=0x%x\n",
+ __func__,
+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT),
+ rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT));
+
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, 0xc0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT, 0xc0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x0);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x1);
+
+ _tssi_alimentk_done(rtwdev, phy, RF_PATH_A, chan);
+ _tssi_alimentk_done(rtwdev, phy, RF_PATH_B, chan);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "======>%s 2 SCAN_END Set 0x5818[7:0]=0x%x 0x7818[7:0]=0x%x\n",
+ __func__,
+ rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT),
+ rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT));
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "======> %s SCAN_END\n", __func__);
+}
+
+void rtw8852bt_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
+ enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
+{
+ if (scan_start)
+ rtw8852bt_tssi_default_txagc(rtwdev, phy_idx, true, chanctx_idx);
+ else
+ rtw8852bt_tssi_default_txagc(rtwdev, phy_idx, false, chanctx_idx);
+}
+
+static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
+ enum rtw89_bandwidth bw, bool dav)
+{
+ u32 rf_reg18;
+ u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__);
+
+ rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK);
+ if (rf_reg18 == INV_RF_DATA) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[RFK]Invalid RF_0x18 for Path-%d\n", path);
+ return;
+ }
+ rf_reg18 &= ~RR_CFGCH_BW;
+
+ switch (bw) {
+ case RTW89_CHANNEL_WIDTH_5:
+ case RTW89_CHANNEL_WIDTH_10:
+ case RTW89_CHANNEL_WIDTH_20:
+ rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_20M);
+ break;
+ case RTW89_CHANNEL_WIDTH_40:
+ rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_40M);
+ break;
+ case RTW89_CHANNEL_WIDTH_80:
+ rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_80M);
+ break;
+ default:
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]Fail to set CH\n");
+ }
+
+ rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN |
+ RR_CFGCH_BW2) & RFREG_MASK;
+ rf_reg18 |= RR_CFGCH_BW2;
+ rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set %x at path%d, %x =0x%x\n",
+ bw, path, reg18_addr,
+ rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK));
+}
+
+static void _ctrl_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_bandwidth bw)
+{
+ _bw_setting(rtwdev, RF_PATH_A, bw, true);
+ _bw_setting(rtwdev, RF_PATH_B, bw, true);
+ _bw_setting(rtwdev, RF_PATH_A, bw, false);
+ _bw_setting(rtwdev, RF_PATH_B, bw, false);
+}
+
+static bool _set_s0_arfc18(struct rtw89_dev *rtwdev, u32 val)
+{
+ u32 tmp;
+ int ret;
+
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK, val);
+
+ ret = read_poll_timeout_atomic(rtw89_read_rf, tmp, tmp == 0, 1, 1000,
+ false, rtwdev, RF_PATH_A, RR_LPF, RR_LPF_BUSY);
+ if (ret)
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]LCK timeout\n");
+
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0);
+ return !!ret;
+}
+
+static void _lck_check(struct rtw89_dev *rtwdev)
+{
+ u32 tmp;
+
+ if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN MMD reset\n");
+
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x1);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x0);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x1);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x0);
+ }
+
+ udelay(10);
+
+ if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]re-set RF 0x18\n");
+
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1);
+ tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK);
+ _set_s0_arfc18(rtwdev, tmp);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0);
+ }
+
+ if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) {
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN off/on\n");
+
+ tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK, tmp);
+ tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK, tmp);
+
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x1);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x0);
+
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1);
+ tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK);
+ _set_s0_arfc18(rtwdev, tmp);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]0xb2=%x, 0xc5=%x\n",
+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_VCO, RFREG_MASK),
+ rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RFREG_MASK));
+ }
+}
+
+static void _set_ch(struct rtw89_dev *rtwdev, u32 val)
+{
+ bool timeout;
+ u32 bak;
+
+ bak = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RR_LDO_SEL, 0x1);
+ timeout = _set_s0_arfc18(rtwdev, val);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK, bak);
+ if (!timeout)
+ _lck_check(rtwdev);
+}
+
+static void _ch_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
+ u8 central_ch, bool dav)
+{
+ u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1;
+ bool is_2g_ch = central_ch <= 14;
+ u32 rf_reg18;
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__);
+
+ rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK);
+ rf_reg18 &= ~(RR_CFGCH_BAND1 | RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH |
+ RR_CFGCH_BCN | RR_CFGCH_BAND0 | RR_CFGCH_CH);
+ rf_reg18 |= FIELD_PREP(RR_CFGCH_CH, central_ch);
+
+ if (!is_2g_ch)
+ rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_5G) |
+ FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_5G);
+
+ rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN |
+ RR_CFGCH_BW2) & RFREG_MASK;
+ rf_reg18 |= RR_CFGCH_BW2;
+
+ if (path == RF_PATH_A && dav)
+ _set_ch(rtwdev, rf_reg18);
+ else
+ rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18);
+
+ rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 0);
+ rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 1);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK,
+ "[RFK]CH: %d for Path-%d, reg0x%x = 0x%x\n",
+ central_ch, path, reg18_addr,
+ rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK));
+}
+
+static void _ctrl_ch(struct rtw89_dev *rtwdev, u8 central_ch)
+{
+ _ch_setting(rtwdev, RF_PATH_A, central_ch, true);
+ _ch_setting(rtwdev, RF_PATH_B, central_ch, true);
+ _ch_setting(rtwdev, RF_PATH_A, central_ch, false);
+ _ch_setting(rtwdev, RF_PATH_B, central_ch, false);
+}
+
+static void _set_rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_bandwidth bw,
+ enum rtw89_rf_path path)
+{
+ rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1);
+ rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0x12);
+
+ if (bw == RTW89_CHANNEL_WIDTH_20)
+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x1b);
+ else if (bw == RTW89_CHANNEL_WIDTH_40)
+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x13);
+ else if (bw == RTW89_CHANNEL_WIDTH_80)
+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0xb);
+ else
+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x3);
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set S%d RXBB BW 0x3F = 0x%x\n",
+ path, rtw89_read_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB));
+
+ rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0);
+}
+
+static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_bandwidth bw)
+{
+ u8 kpath, path;
+
+ kpath = _kpath(rtwdev, phy);
+
+ for (path = 0; path < RF_PATH_NUM_8852BT; path++) {
+ if (!(kpath & BIT(path)))
+ continue;
+
+ _set_rxbb_bw(rtwdev, bw, path);
+ }
+}
+
+static void rtw8852bt_ctrl_bw_ch(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy, u8 central_ch,
+ enum rtw89_band band, enum rtw89_bandwidth bw)
+{
+ _ctrl_ch(rtwdev, central_ch);
+ _ctrl_bw(rtwdev, phy, bw);
+ _rxbb_bw(rtwdev, phy, bw);
+}
+
+void rtw8852bt_set_channel_rf(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+{
+ rtw8852bt_ctrl_bw_ch(rtwdev, phy_idx, chan->channel, chan->band_type,
+ chan->band_width);
+}
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.h
new file mode 100644
index 000000000000..e34560b4905f
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#ifndef __RTW89_8852BT_RFK_H__
+#define __RTW89_8852BT_RFK_H__
+
+#include "core.h"
+
+void rtw8852bt_rck(struct rtw89_dev *rtwdev);
+void rtw8852bt_dack(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx);
+void rtw8852bt_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
+void rtw8852bt_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
+void rtw8852bt_dpk_init(struct rtw89_dev *rtwdev);
+void rtw8852bt_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
+void rtw8852bt_dpk_track(struct rtw89_dev *rtwdev);
+void rtw8852bt_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ bool hwtx_en, enum rtw89_chanctx_idx chanctx_idx);
+void rtw8852bt_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan);
+void rtw8852bt_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
+ enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
+void rtw8852bt_set_channel_rf(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx);
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.c
new file mode 100644
index 000000000000..782144bb7f49
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.c
@@ -0,0 +1,490 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#include "rtw8852bt_rfk_table.h"
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_sys_defs[] = {
+ RTW89_DECL_RFK_WM(0x12a8, 0x0000000f, 0x4),
+ RTW89_DECL_RFK_WM(0x32a8, 0x0000000f, 0x4),
+ RTW89_DECL_RFK_WM(0x12bc, 0x000ffff0, 0x5555),
+ RTW89_DECL_RFK_WM(0x32bc, 0x000ffff0, 0x5555),
+ RTW89_DECL_RFK_WM(0x0300, 0xff000000, 0x16),
+ RTW89_DECL_RFK_WM(0x0304, 0x000000ff, 0x19),
+ RTW89_DECL_RFK_WM(0x0314, 0xffff0000, 0x2041),
+ RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x2041),
+ RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x20012041),
+ RTW89_DECL_RFK_WM(0x0020, 0x00006000, 0x3),
+ RTW89_DECL_RFK_WM(0x0024, 0x00006000, 0x3),
+ RTW89_DECL_RFK_WM(0x0704, 0xffff0000, 0x601e),
+ RTW89_DECL_RFK_WM(0x2704, 0xffff0000, 0x601e),
+ RTW89_DECL_RFK_WM(0x0700, 0xf0000000, 0x4),
+ RTW89_DECL_RFK_WM(0x2700, 0xf0000000, 0x4),
+ RTW89_DECL_RFK_WM(0x0650, 0x3c000000, 0x0),
+ RTW89_DECL_RFK_WM(0x2650, 0x3c000000, 0x0),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_sys_defs);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_sys_a_defs_2g[] = {
+ RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x33),
+ RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x33),
+ RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x1),
+ RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1e),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_sys_a_defs_2g);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_sys_a_defs_5g[] = {
+ RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x44),
+ RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x44),
+ RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x0),
+ RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1d),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_sys_a_defs_5g);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_sys_b_defs_2g[] = {
+ RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x33),
+ RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x33),
+ RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x1),
+ RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1e),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_sys_b_defs_2g);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_sys_b_defs_5g[] = {
+ RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x44),
+ RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x44),
+ RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x0),
+ RTW89_DECL_RFK_WM(0x0304, 0x0000ff00, 0x1d),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_sys_b_defs_5g);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_init_txpwr_defs_a[] = {
+ RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0),
+ RTW89_DECL_RFK_WM(0x5800, 0xffffffff, 0x003f807f),
+ RTW89_DECL_RFK_WM(0x580c, 0x0000007f, 0x40),
+ RTW89_DECL_RFK_WM(0x580c, 0x0fffff00, 0x00040),
+ RTW89_DECL_RFK_WM(0x5810, 0xffffffff, 0x59010000),
+ RTW89_DECL_RFK_WM(0x5814, 0x01ffffff, 0x002d000),
+ RTW89_DECL_RFK_WM(0x5814, 0xf8000000, 0x00),
+ RTW89_DECL_RFK_WM(0x5818, 0xffffffff, 0x002c1800),
+ RTW89_DECL_RFK_WM(0x581c, 0x3fffffff, 0x1dc80280),
+ RTW89_DECL_RFK_WM(0x5820, 0xffffffff, 0x00002080),
+ RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1),
+ RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1),
+ RTW89_DECL_RFK_WM(0x5834, 0x3fffffff, 0x000115f2),
+ RTW89_DECL_RFK_WM(0x5838, 0x7fffffff, 0x0000121),
+ RTW89_DECL_RFK_WM(0x5854, 0x3fffffff, 0x000115f2),
+ RTW89_DECL_RFK_WM(0x5858, 0x7fffffff, 0x0000121),
+ RTW89_DECL_RFK_WM(0x5860, 0x80000000, 0x0),
+ RTW89_DECL_RFK_WM(0x5864, 0x07ffffff, 0x00801ff),
+ RTW89_DECL_RFK_WM(0x5898, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x589c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x58a4, 0x000000ff, 0x16),
+ RTW89_DECL_RFK_WM(0x58b0, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x58b4, 0x7fffffff, 0x0a002000),
+ RTW89_DECL_RFK_WM(0x58b8, 0x7fffffff, 0x00007628),
+ RTW89_DECL_RFK_WM(0x58bc, 0x07ffffff, 0x7a7807f),
+ RTW89_DECL_RFK_WM(0x58c0, 0xfffe0000, 0x003f),
+ RTW89_DECL_RFK_WM(0x58c4, 0xffffffff, 0x0003ffff),
+ RTW89_DECL_RFK_WM(0x58c8, 0x00ffffff, 0x000000),
+ RTW89_DECL_RFK_WM(0x58c8, 0xf0000000, 0x0),
+ RTW89_DECL_RFK_WM(0x58cc, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x58d0, 0x07ffffff, 0x2008101),
+ RTW89_DECL_RFK_WM(0x58d4, 0x000000ff, 0x00),
+ RTW89_DECL_RFK_WM(0x58d4, 0x0003fe00, 0x0ff),
+ RTW89_DECL_RFK_WM(0x58d4, 0x07fc0000, 0x100),
+ RTW89_DECL_RFK_WM(0x58d8, 0xffffffff, 0x8008016c),
+ RTW89_DECL_RFK_WM(0x58dc, 0x0001ffff, 0x0807f),
+ RTW89_DECL_RFK_WM(0x58dc, 0xfff00000, 0xc00),
+ RTW89_DECL_RFK_WM(0x58f0, 0x0003ffff, 0x001ff),
+ RTW89_DECL_RFK_WM(0x58f4, 0x000fffff, 0x000),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_init_txpwr_defs_a);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_init_txpwr_defs_b[] = {
+ RTW89_DECL_RFK_WM(0x566c, 0x00001000, 0x0),
+ RTW89_DECL_RFK_WM(0x7800, 0xffffffff, 0x003f807f),
+ RTW89_DECL_RFK_WM(0x780c, 0x0000007f, 0x40),
+ RTW89_DECL_RFK_WM(0x780c, 0x0fffff00, 0x00040),
+ RTW89_DECL_RFK_WM(0x7810, 0xffffffff, 0x59010000),
+ RTW89_DECL_RFK_WM(0x7814, 0x01ffffff, 0x002d000),
+ RTW89_DECL_RFK_WM(0x7814, 0xf8000000, 0x00),
+ RTW89_DECL_RFK_WM(0x7818, 0xffffffff, 0x002c1800),
+ RTW89_DECL_RFK_WM(0x781c, 0x3fffffff, 0x1dc80280),
+ RTW89_DECL_RFK_WM(0x7820, 0xffffffff, 0x00002080),
+ RTW89_DECL_RFK_WM(0x780c, 0x10000000, 0x1),
+ RTW89_DECL_RFK_WM(0x780c, 0x40000000, 0x1),
+ RTW89_DECL_RFK_WM(0x7834, 0x3fffffff, 0x000115f2),
+ RTW89_DECL_RFK_WM(0x7838, 0x7fffffff, 0x0000121),
+ RTW89_DECL_RFK_WM(0x7854, 0x3fffffff, 0x000115f2),
+ RTW89_DECL_RFK_WM(0x7858, 0x7fffffff, 0x0000121),
+ RTW89_DECL_RFK_WM(0x7860, 0x80000000, 0x0),
+ RTW89_DECL_RFK_WM(0x7864, 0x07ffffff, 0x00801ff),
+ RTW89_DECL_RFK_WM(0x7898, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x789c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x78a4, 0x000000ff, 0x16),
+ RTW89_DECL_RFK_WM(0x78b0, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x78b4, 0x7fffffff, 0x0a002000),
+ RTW89_DECL_RFK_WM(0x78b8, 0x7fffffff, 0x00007628),
+ RTW89_DECL_RFK_WM(0x78bc, 0x07ffffff, 0x7a7807f),
+ RTW89_DECL_RFK_WM(0x78c0, 0xfffe0000, 0x003f),
+ RTW89_DECL_RFK_WM(0x78c4, 0xffffffff, 0x0003ffff),
+ RTW89_DECL_RFK_WM(0x78c8, 0x00ffffff, 0x000000),
+ RTW89_DECL_RFK_WM(0x78c8, 0xf0000000, 0x0),
+ RTW89_DECL_RFK_WM(0x78cc, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x78d0, 0x07ffffff, 0x2008101),
+ RTW89_DECL_RFK_WM(0x78d4, 0x000000ff, 0x00),
+ RTW89_DECL_RFK_WM(0x78d4, 0x0003fe00, 0x0ff),
+ RTW89_DECL_RFK_WM(0x78d4, 0x07fc0000, 0x100),
+ RTW89_DECL_RFK_WM(0x78d8, 0xffffffff, 0x8008016c),
+ RTW89_DECL_RFK_WM(0x78dc, 0x0001ffff, 0x0807f),
+ RTW89_DECL_RFK_WM(0x78dc, 0xfff00000, 0xc00),
+ RTW89_DECL_RFK_WM(0x78f0, 0x0003ffff, 0x001ff),
+ RTW89_DECL_RFK_WM(0x78f4, 0x000fffff, 0x000),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_init_txpwr_defs_b);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_init_txpwr_he_tb_defs_a[] = {
+ RTW89_DECL_RFK_WM(0x58a0, 0xffffffff, 0x000000fe),
+ RTW89_DECL_RFK_WM(0x58e4, 0x0000007f, 0x1f),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_init_txpwr_he_tb_defs_a);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_init_txpwr_he_tb_defs_b[] = {
+ RTW89_DECL_RFK_WM(0x78a0, 0xffffffff, 0x000000fe),
+ RTW89_DECL_RFK_WM(0x78e4, 0x0000007f, 0x1f),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_init_txpwr_he_tb_defs_b);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_dck_defs_a[] = {
+ RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000),
+ RTW89_DECL_RFK_WM(0x5814, 0x003ff000, 0x0ef),
+ RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_dck_defs_a);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_dck_defs_b[] = {
+ RTW89_DECL_RFK_WM(0x780c, 0x0fff0000, 0x000),
+ RTW89_DECL_RFK_WM(0x7814, 0x003ff000, 0x0ef),
+ RTW89_DECL_RFK_WM(0x7814, 0x18000000, 0x0),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_dck_defs_b);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_dac_gain_defs_a[] = {
+ RTW89_DECL_RFK_WM(0x58b0, 0x00000400, 0x1),
+ RTW89_DECL_RFK_WM(0x58b0, 0x00000fff, 0x000),
+ RTW89_DECL_RFK_WM(0x58b0, 0x00000800, 0x1),
+ RTW89_DECL_RFK_WM(0x5a00, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a04, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a08, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a0c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a10, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a14, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a18, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a1c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a20, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a24, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a28, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a2c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a30, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a34, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a38, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a3c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a40, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a44, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a48, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a4c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a50, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a54, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a58, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a5c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a60, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a64, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a68, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a6c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a70, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a74, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a78, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a7c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a80, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a84, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a88, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a8c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a90, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a94, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a98, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5a9c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5aa0, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5aa4, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5aa8, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5aac, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5ab0, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5ab4, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5ab8, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5abc, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5ac0, 0xffffffff, 0x00000000),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_dac_gain_defs_a);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_dac_gain_defs_b[] = {
+ RTW89_DECL_RFK_WM(0x78b0, 0x00000fff, 0x000),
+ RTW89_DECL_RFK_WM(0x78b0, 0x00000800, 0x1),
+ RTW89_DECL_RFK_WM(0x7a00, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a04, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a08, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a0c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a10, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a14, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a18, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a1c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a20, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a24, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a28, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a2c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a30, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a34, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a38, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a3c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a40, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a44, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a48, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a4c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a50, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a54, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a58, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a5c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a60, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a64, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a68, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a6c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a70, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a74, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a78, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a7c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a80, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a84, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a88, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a8c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a90, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a94, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a98, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7a9c, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7aa0, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7aa4, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7aa8, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7aac, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7ab0, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7ab4, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7ab8, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7abc, 0xffffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7ac0, 0xffffffff, 0x00000000),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_dac_gain_defs_b);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_slope_a_defs_2g[] = {
+ RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0801008),
+ RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201020),
+ RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201008),
+ RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0804008),
+ RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008),
+ RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008),
+ RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808),
+ RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08081e28),
+ RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808),
+ RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08081e28),
+ RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808),
+ RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_slope_a_defs_2g);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_slope_a_defs_5g[] = {
+ RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008),
+ RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201019),
+ RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201008),
+ RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008),
+ RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008),
+ RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008),
+ RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808),
+ RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08081808),
+ RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080808),
+ RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808),
+ RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x0808),
+ RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_slope_a_defs_5g);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_slope_b_defs_2g[] = {
+ RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0801008),
+ RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201020),
+ RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0201008),
+ RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0804008),
+ RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0201008),
+ RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x008),
+ RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808),
+ RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08081e28),
+ RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08080808),
+ RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08081e28),
+ RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x0808),
+ RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x1),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_slope_b_defs_2g);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_slope_b_defs_5g[] = {
+ RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0201008),
+ RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201019),
+ RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0201008),
+ RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0201008),
+ RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0201008),
+ RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x008),
+ RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808),
+ RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08081808),
+ RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08080808),
+ RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08080808),
+ RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x0808),
+ RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x1),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_slope_b_defs_5g);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_align_a_2g_all_defs[] = {
+ RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
+ RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721),
+ RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101),
+ RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x029f57c0),
+ RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000077),
+ RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000),
+ RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x029f5bc0),
+ RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000076),
+ RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_a_2g_all_defs);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_align_a_5g1_all_defs[] = {
+ RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
+ RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721),
+ RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101),
+ RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x007ff3d7),
+ RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000068),
+ RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000),
+ RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_a_5g1_all_defs);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_align_a_5g2_all_defs[] = {
+ RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
+ RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721),
+ RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101),
+ RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00a003db),
+ RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000065),
+ RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000),
+ RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_a_5g2_all_defs);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_align_a_5g3_all_defs[] = {
+ RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
+ RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x3f2d2721),
+ RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x010101),
+ RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01101be2),
+ RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000065),
+ RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000),
+ RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_a_5g3_all_defs);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_align_b_2g_all_defs[] = {
+ RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1),
+ RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721),
+ RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101),
+ RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x023f3fb9),
+ RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000075),
+ RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000),
+ RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x01df3fb8),
+ RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000074),
+ RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_b_2g_all_defs);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_align_b_5g1_all_defs[] = {
+ RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1),
+ RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721),
+ RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101),
+ RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x010017e0),
+ RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069),
+ RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000),
+ RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_b_5g1_all_defs);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_align_b_5g2_all_defs[] = {
+ RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1),
+ RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721),
+ RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101),
+ RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x01201fe2),
+ RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000066),
+ RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000),
+ RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_b_5g2_all_defs);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_align_b_5g3_all_defs[] = {
+ RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1),
+ RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x3f2d2721),
+ RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x010101),
+ RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x01602fe5),
+ RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000068),
+ RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000),
+ RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000),
+ RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_align_b_5g3_all_defs);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_slope_defs_a[] = {
+ RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x1),
+ RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1),
+ RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x1),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_slope_defs_a);
+
+static const struct rtw89_reg5_def rtw8852bt_tssi_slope_defs_b[] = {
+ RTW89_DECL_RFK_WM(0x7814, 0x00000800, 0x1),
+ RTW89_DECL_RFK_WM(0x781c, 0x20000000, 0x1),
+ RTW89_DECL_RFK_WM(0x7814, 0x20000000, 0x1),
+};
+
+RTW89_DECLARE_RFK_TBL(rtw8852bt_tssi_slope_defs_b);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.h
new file mode 100644
index 000000000000..beb246237d17
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk_table.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#ifndef __RTW89_8852BT_RFK_TABLE_H__
+#define __RTW89_8852BT_RFK_TABLE_H__
+
+#include "phy.h"
+
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_sys_defs_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_sys_a_defs_2g_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_sys_a_defs_5g_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_sys_b_defs_2g_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_sys_b_defs_5g_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_init_txpwr_defs_a_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_init_txpwr_defs_b_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_init_txpwr_he_tb_defs_a_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_init_txpwr_he_tb_defs_b_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_dck_defs_a_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_dck_defs_b_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_dac_gain_defs_a_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_dac_gain_defs_b_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_slope_a_defs_2g_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_slope_a_defs_5g_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_slope_b_defs_2g_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_slope_b_defs_5g_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_a_2g_all_defs_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_a_5g1_all_defs_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_a_5g2_all_defs_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_a_5g3_all_defs_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_b_2g_all_defs_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_b_5g1_all_defs_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_b_5g2_all_defs_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_align_b_5g3_all_defs_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_slope_defs_a_tbl;
+extern const struct rtw89_rfk_tbl rtw8852bt_tssi_slope_defs_b_tbl;
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bte.c b/drivers/net/wireless/realtek/rtw89/rtw8852bte.c
new file mode 100644
index 000000000000..b69fa17beb33
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bte.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include "pci.h"
+#include "reg.h"
+#include "rtw8852bt.h"
+
+static const struct rtw89_pci_ssid_quirk rtw8852bt_pci_ssid_quirks[] = {
+ {RTW89_PCI_SSID(PCI_VENDOR_ID_REALTEK, 0xB520, 0x103C, 0x88E9, HP),
+ .bitmap = BIT(RTW89_QUIRK_THERMAL_PROT_110C)},
+ {},
+};
+
+static const struct rtw89_pci_info rtw8852bt_pci_info = {
+ .gen_def = &rtw89_pci_gen_ax,
+ .txbd_trunc_mode = MAC_AX_BD_TRUNC,
+ .rxbd_trunc_mode = MAC_AX_BD_TRUNC,
+ .rxbd_mode = MAC_AX_RXBD_PKT,
+ .tag_mode = MAC_AX_TAG_MULTI,
+ .tx_burst = MAC_AX_TX_BURST_2048B,
+ .rx_burst = MAC_AX_RX_BURST_128B,
+ .wd_dma_idle_intvl = MAC_AX_WD_DMA_INTVL_256NS,
+ .wd_dma_act_intvl = MAC_AX_WD_DMA_INTVL_256NS,
+ .multi_tag_num = MAC_AX_TAG_NUM_8,
+ .lbc_en = MAC_AX_PCIE_ENABLE,
+ .lbc_tmr = MAC_AX_LBC_TMR_2MS,
+ .autok_en = MAC_AX_PCIE_DISABLE,
+ .io_rcy_en = MAC_AX_PCIE_DISABLE,
+ .io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS,
+ .rx_ring_eq_is_full = false,
+ .check_rx_tag = false,
+ .no_rxbd_fs = false,
+
+ .init_cfg_reg = R_AX_PCIE_INIT_CFG1,
+ .txhci_en_bit = B_AX_TXHCI_EN,
+ .rxhci_en_bit = B_AX_RXHCI_EN,
+ .rxbd_mode_bit = B_AX_RXBD_MODE,
+ .exp_ctrl_reg = R_AX_PCIE_EXP_CTRL,
+ .max_tag_num_mask = B_AX_MAX_TAG_NUM,
+ .rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR,
+ .txbd_rwptr_clr2_reg = 0,
+ .dma_io_stop = {R_AX_PCIE_DMA_STOP1, B_AX_STOP_PCIEIO},
+ .dma_stop1 = {R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_MASK_V1},
+ .dma_stop2 = {0},
+ .dma_busy1 = {R_AX_PCIE_DMA_BUSY1, DMA_BUSY1_CHECK_V1},
+ .dma_busy2_reg = 0,
+ .dma_busy3_reg = R_AX_PCIE_DMA_BUSY1,
+
+ .rpwm_addr = R_AX_PCIE_HRPWM,
+ .cpwm_addr = R_AX_CPWM,
+ .mit_addr = R_AX_INT_MIT_RX,
+ .wp_sel_addr = 0,
+ .tx_dma_ch_mask = BIT(RTW89_TXCH_ACH4) | BIT(RTW89_TXCH_ACH5) |
+ BIT(RTW89_TXCH_ACH6) | BIT(RTW89_TXCH_ACH7) |
+ BIT(RTW89_TXCH_CH10) | BIT(RTW89_TXCH_CH11),
+ .bd_idx_addr_low_power = NULL,
+ .dma_addr_set = &rtw89_pci_ch_dma_addr_set,
+ .bd_ram_table = &rtw89_bd_ram_table_single,
+
+ .ltr_set = rtw89_pci_ltr_set,
+ .fill_txaddr_info = rtw89_pci_fill_txaddr_info,
+ .config_intr_mask = rtw89_pci_config_intr_mask,
+ .enable_intr = rtw89_pci_enable_intr,
+ .disable_intr = rtw89_pci_disable_intr,
+ .recognize_intrs = rtw89_pci_recognize_intrs,
+
+ .ssid_quirks = rtw8852bt_pci_ssid_quirks,
+};
+
+static const struct rtw89_driver_info rtw89_8852bte_info = {
+ .chip = &rtw8852bt_chip_info,
+ .variant = NULL,
+ .quirks = NULL,
+ .bus = {
+ .pci = &rtw8852bt_pci_info,
+ },
+};
+
+static const struct pci_device_id rtw89_8852bte_id_table[] = {
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb520),
+ .driver_data = (kernel_ulong_t)&rtw89_8852bte_info,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(pci, rtw89_8852bte_id_table);
+
+static struct pci_driver rtw89_8852bte_driver = {
+ .name = "rtw89_8852bte",
+ .id_table = rtw89_8852bte_id_table,
+ .probe = rtw89_pci_probe,
+ .remove = rtw89_pci_remove,
+ .driver.pm = &rtw89_pm_ops,
+};
+module_pci_driver(rtw89_8852bte_driver);
+
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852BE-VT driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index 17e6164855fa..2a6143a8d256 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -12,12 +12,13 @@
#include "rtw8852c.h"
#include "rtw8852c_rfk.h"
#include "rtw8852c_table.h"
+#include "sar.h"
#include "util.h"
-#define RTW8852C_FW_FORMAT_MAX 0
+#define RTW8852C_FW_FORMAT_MAX 2
#define RTW8852C_FW_BASENAME "rtw89/rtw8852c_fw"
#define RTW8852C_MODULE_FIRMWARE \
- RTW8852C_FW_BASENAME ".bin"
+ RTW8852C_FW_BASENAME "-" __stringify(RTW8852C_FW_FORMAT_MAX) ".bin"
static const struct rtw89_hfc_ch_cfg rtw8852c_hfc_chcfg_pcie[] = {
{13, 1614, grp_0}, /* ACH 0 */
@@ -73,6 +74,10 @@ static const u32 rtw8852c_c2h_regs[RTW89_H2CREG_MAX] = {
R_AX_C2HREG_DATA3_V1
};
+static const u32 rtw8852c_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = {
+ R_AX_C2HREG_DATA3_V1 + 3, R_AX_DBG_WOW,
+};
+
static const struct rtw89_page_regs rtw8852c_page_regs = {
.hci_fc_ctrl = R_AX_HCI_FC_CTRL_V1,
.ch_page_ctrl = R_AX_CH_PAGE_CTRL_V1,
@@ -143,6 +148,15 @@ static const struct rtw89_rrsr_cfgs rtw8852c_rrsr_cfgs = {
.rsc = {R_AX_PTCL_RRSR1, B_AX_RSC_MASK, 2},
};
+static const struct rtw89_rfkill_regs rtw8852c_rfkill_regs = {
+ .pinmux = {R_AX_GPIO8_15_FUNC_SEL,
+ B_AX_PINMUX_GPIO9_FUNC_SEL_MASK,
+ 0xf},
+ .mode = {R_AX_GPIO_EXT_CTRL + 2,
+ (B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16,
+ 0x0},
+};
+
static const struct rtw89_dig_regs rtw8852c_dig_regs = {
.seg0_pd_reg = R_SEG0R_PD,
.pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
@@ -173,10 +187,17 @@ static const struct rtw89_edcca_regs rtw8852c_edcca_regs = {
.edcca_p_mask = B_EDCCA_LVL_MSK1,
.ppdu_level = R_SEG0R_EDCCA_LVL,
.ppdu_mask = B_EDCCA_LVL_MSK3,
- .rpt_a = R_EDCCA_RPT_A,
- .rpt_b = R_EDCCA_RPT_B,
- .rpt_sel = R_EDCCA_RPT_SEL,
- .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ .p = {{
+ .rpt_a = R_EDCCA_RPT_A,
+ .rpt_b = R_EDCCA_RPT_B,
+ .rpt_sel = R_EDCCA_RPT_SEL,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ }, {
+ .rpt_a = R_EDCCA_RPT_P1_A,
+ .rpt_b = R_EDCCA_RPT_P1_B,
+ .rpt_sel = R_EDCCA_RPT_SEL,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK,
+ }},
.tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
.tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
};
@@ -190,7 +211,7 @@ static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path,
static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
{
u32 val32;
- u32 ret;
+ int ret;
val32 = rtw89_read32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_PAD_HCI_SEL_V2_MASK);
if (val32 == MAC_AX_HCI_SEL_PCIE_USB)
@@ -203,6 +224,9 @@ static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APDM_HPDN);
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0,
+ B_AX_OCP_L1_MASK, 0x7);
+
ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_RDY_SYSPWR,
1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
if (ret)
@@ -266,7 +290,7 @@ static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SRAM2RFC);
if (ret)
return ret;
- ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0, XTAL_SI_LDO_LPS);
+ ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0x10, XTAL_SI_LDO_LPS);
if (ret)
return ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_4, 0, XTAL_SI_LPS_CAP);
@@ -308,7 +332,7 @@ static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
{
u32 val32;
- u32 ret;
+ int ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
XTAL_SI_RFC2RF);
@@ -338,6 +362,7 @@ static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
return ret;
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
+ rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB);
rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
B_AX_R_SYM_FEN_WLBBGLB_1 | B_AX_R_SYM_FEN_WLBBFUN_1);
@@ -360,8 +385,11 @@ static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
if (ret)
return ret;
- rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, 0x0001A0B0);
+ rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION);
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_XTAL_OFF_A_DIE);
+ rtw89_write32_set(rtwdev, R_AX_SYS_SWR_CTRL1, B_AX_SYM_CTRL_SPS_PWMFREQ);
+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0,
+ B_AX_REG_ZCDC_H_MASK, 0x3);
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
return 0;
@@ -1797,7 +1825,7 @@ static void rtw8852c_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
RTW89_SCH_TX_SEL_ALL);
rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, false);
rtw8852c_dfs_en(rtwdev, false);
- rtw8852c_tssi_cont_en_phyidx(rtwdev, false, phy_idx);
+ rtw8852c_tssi_cont_en_phyidx(rtwdev, false, phy_idx, chan);
rtw8852c_adc_en(rtwdev, false);
fsleep(40);
rtw8852c_bb_reset_en(rtwdev, chan->band_type, phy_idx, false);
@@ -1805,7 +1833,7 @@ static void rtw8852c_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx, true);
rtw8852c_adc_en(rtwdev, true);
rtw8852c_dfs_en(rtwdev, true);
- rtw8852c_tssi_cont_en_phyidx(rtwdev, true, phy_idx);
+ rtw8852c_tssi_cont_en_phyidx(rtwdev, true, phy_idx, chan);
rtw8852c_bb_reset_en(rtwdev, chan->band_type, phy_idx, true);
rtw89_chip_resume_sch_tx(rtwdev, mac_idx, p->tx_en);
}
@@ -1822,31 +1850,42 @@ static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev)
rtw8852c_dpk_init(rtwdev);
rtw8852c_rck(rtwdev);
- rtw8852c_dack(rtwdev);
+ rtw8852c_dack(rtwdev, RTW89_CHANCTX_0);
rtw8852c_rx_dck(rtwdev, RTW89_PHY_0, false);
}
-static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev)
+static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
+ enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
+ enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw8852c_mcc_get_ch_info(rtwdev, phy_idx);
+ rtw89_btc_ntfy_conn_rfk(rtwdev, true);
+
rtw8852c_rx_dck(rtwdev, phy_idx, false);
- rtw8852c_iqk(rtwdev, phy_idx);
- rtw8852c_tssi(rtwdev, phy_idx);
- rtw8852c_dpk(rtwdev, phy_idx);
+ rtw8852c_iqk(rtwdev, phy_idx, chanctx_idx);
+ rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
+ rtw8852c_tssi(rtwdev, phy_idx, chanctx_idx);
+ rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
+ rtw8852c_dpk(rtwdev, phy_idx, chanctx_idx);
+
+ rtw89_btc_ntfy_conn_rfk(rtwdev, false);
rtw89_fw_h2c_rf_ntfy_mcc(rtwdev);
}
static void rtw8852c_rfk_band_changed(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx)
+ enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan)
{
- rtw8852c_tssi_scan(rtwdev, phy_idx);
+ rtw8852c_tssi_scan(rtwdev, phy_idx, chan);
}
-static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev, bool start)
+static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ bool start)
{
- rtw8852c_wifi_scan_notify(rtwdev, start, RTW89_PHY_0);
+ rtw8852c_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx);
}
static void rtw8852c_rfk_track(struct rtw89_dev *rtwdev)
@@ -1857,9 +1896,9 @@ static void rtw8852c_rfk_track(struct rtw89_dev *rtwdev)
}
static u32 rtw8852c_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx, s16 ref)
+ enum rtw89_phy_idx phy_idx,
+ s16 ref, u16 pwr_ofst_decrease)
{
- s8 ofst_int = 0;
u8 base_cw_0db = 0x27;
u16 tssi_16dbm_cw = 0x12c;
s16 pwr_s10_3 = 0;
@@ -1868,13 +1907,14 @@ static u32 rtw8852c_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev,
u32 pwr_cw = 0;
u32 tssi_ofst_cw = 0;
- pwr_s10_3 = (ref << 1) + (s16)(ofst_int) + (s16)(base_cw_0db << 3);
+ pwr_s10_3 = (ref << 1) + (s16)(base_cw_0db << 3) - pwr_ofst_decrease;
bb_pwr_cw = FIELD_GET(GENMASK(2, 0), pwr_s10_3);
rf_pwr_cw = FIELD_GET(GENMASK(8, 3), pwr_s10_3);
rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63);
pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw;
- tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3));
+ tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3)) -
+ pwr_ofst_decrease;
rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
"[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n",
tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw);
@@ -1918,9 +1958,10 @@ void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
}
static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx)
+ enum rtw89_phy_idx phy_idx, s16 pwr_ofst)
{
static const u32 addr[RF_PATH_NUM_8852C] = {0x5800, 0x7800};
+ u16 ofst_dec[RF_PATH_NUM_8852C];
const u32 mask = 0x7FFFFFF;
const u8 ofst_ofdm = 0x4;
const u8 ofst_cck = 0x8;
@@ -1934,19 +1975,20 @@ static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev,
rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL,
GENMASK(27, 10), 0x0);
- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n");
- val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm);
+ ofst_dec[RF_PATH_A] = pwr_ofst > 0 ? 0 : abs(pwr_ofst);
+ ofst_dec[RF_PATH_B] = pwr_ofst > 0 ? pwr_ofst : 0;
- for (i = 0; i < RF_PATH_NUM_8852C; i++)
- rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val,
- phy_idx);
+ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n");
+ for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+ val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm, ofst_dec[i]);
+ rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val, phy_idx);
+ }
rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n");
- val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck);
-
- for (i = 0; i < RF_PATH_NUM_8852C; i++)
- rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val,
- phy_idx);
+ for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+ val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck, ofst_dec[i]);
+ rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, phy_idx);
+ }
}
static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev,
@@ -2027,6 +2069,41 @@ static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev,
B_P1_DAC_COMP_POST_DPD_EN);
}
+static void rtw8852c_set_txpwr_diff(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+{
+ s16 pwr_ofst;
+
+ pwr_ofst = rtw89_phy_ant_gain_pwr_offset(rtwdev, chan);
+ rtw8852c_set_txpwr_ref(rtwdev, phy_idx, pwr_ofst);
+}
+
+static void rtw8852c_set_txpwr_sar_diff(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+{
+ struct rtw89_sar_parm sar_parm = {
+ .center_freq = chan->freq,
+ .force_path = true,
+ };
+ s16 sar_rf;
+ s8 sar_mac;
+
+ if (phy_idx != RTW89_PHY_0)
+ return;
+
+ sar_parm.path = RF_PATH_A;
+ sar_mac = rtw89_query_sar(rtwdev, &sar_parm);
+ sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac);
+ rtw89_phy_write32_mask(rtwdev, R_TXPWRB, B_TXPWRB_MAX, sar_rf);
+
+ sar_parm.path = RF_PATH_B;
+ sar_mac = rtw89_query_sar(rtwdev, &sar_parm);
+ sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TXPWRB, B_TXPWRB_MAX, sar_rf);
+}
+
static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
@@ -2036,12 +2113,14 @@ static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev,
rtw8852c_set_tx_shape(rtwdev, chan, phy_idx);
rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx);
rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
+ rtw8852c_set_txpwr_diff(rtwdev, chan, phy_idx);
+ rtw8852c_set_txpwr_sar_diff(rtwdev, chan, phy_idx);
}
static void rtw8852c_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
- rtw8852c_set_txpwr_ref(rtwdev, phy_idx);
+ rtw8852c_set_txpwr_ref(rtwdev, phy_idx, 0);
}
static void
@@ -2097,7 +2176,7 @@ rtw8852c_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
static void rtw8852c_bb_cfg_rx_path(struct rtw89_dev *rtwdev, u8 rx_path)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
u8 band = chan->band_type;
u32 rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI;
u32 rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI;
@@ -2768,7 +2847,10 @@ static void rtw8852c_query_ppdu(struct rtw89_dev *rtwdev,
u8 path;
u8 *rx_power = phy_ppdu->rssi;
- status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A], rx_power[RF_PATH_B]));
+ if (!status->signal)
+ status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A],
+ rx_power[RF_PATH_B]));
+
for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
status->chains |= BIT(path);
status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]);
@@ -2816,6 +2898,7 @@ static int rtw8852c_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
static int rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
{
+ rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
@@ -2824,14 +2907,17 @@ static int rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
static const struct rtw89_chanctx_listener rtw8852c_chanctx_listener = {
.callbacks[RTW89_CHANCTX_CALLBACK_RFK] = rtw8852c_rfk_chanctx_cb,
+ .callbacks[RTW89_CHANCTX_CALLBACK_TAS] = rtw89_tas_chanctx_cb,
};
#ifdef CONFIG_PM
static const struct wiphy_wowlan_support rtw_wowlan_stub_8852c = {
- .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
+ .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
+ WIPHY_WOWLAN_NET_DETECT,
.n_patterns = RTW89_MAX_PATTERN_NUM,
.pattern_max_len = RTW89_MAX_PATTERN_SIZE,
.pattern_min_len = 1,
+ .max_nd_match_sets = RTW89_SCANOFLD_MAX_SSID,
};
#endif
@@ -2864,9 +2950,12 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
.get_thermal = rtw8852c_get_thermal,
.ctrl_btg_bt_rx = rtw8852c_ctrl_btg_bt_rx,
.query_ppdu = rtw8852c_query_ppdu,
+ .convert_rpl_to_rssi = NULL,
+ .phy_rpt_to_rssi = NULL,
.ctrl_nbtg_bt_tx = rtw8852c_ctrl_nbtg_bt_tx,
.cfg_txrx_path = rtw8852c_bb_cfg_txrx_path,
.set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset,
+ .digital_pwr_comp = NULL,
.pwr_on_func = rtw8852c_pwr_on_func,
.pwr_off_func = rtw8852c_pwr_off_func,
.query_rxdesc = rtw89_core_query_rxdesc,
@@ -2880,6 +2969,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
.h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl,
.h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl,
.h2c_ampdu_cmac_tbl = NULL,
+ .h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl,
.h2c_default_dmac_tbl = NULL,
.h2c_update_beacon = rtw89_fw_h2c_update_beacon,
.h2c_ba_cam = rtw89_fw_h2c_ba_cam,
@@ -2906,6 +2996,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.try_ce_fw = false,
.bbmcu_nr = 0,
.needed_fw_elms = 0,
+ .fw_blacklist = &rtw89_fw_blacklist_default,
.fifo_size = 458752,
.small_fifo_size = false,
.dle_scc_rsvd_size = 0,
@@ -2917,6 +3008,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.wde_qempty_acq_grpnum = 16,
.wde_qempty_mgq_grpsel = 16,
.rf_base_addr = {0xe000, 0xf000},
+ .thermal_th = {0x32, 0x35},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
.bb_table = &rtw89_8852c_phy_bb_table,
@@ -2928,12 +3020,16 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.dflt_parms = &rtw89_8852c_dflt_parms,
.rfe_parms_conf = NULL,
.chanctx_listener = &rtw8852c_chanctx_listener,
+ .txpwr_factor_bb = 3,
.txpwr_factor_rf = 2,
.txpwr_factor_mac = 1,
.dig_table = NULL,
.dig_regs = &rtw8852c_dig_regs,
.tssi_dbw_table = &rtw89_8852c_tssi_dbw_table,
+ .support_macid_num = RTW89_MAX_MAC_ID_NUM,
+ .support_link_num = 0,
.support_chanctx_num = 2,
+ .support_rnr = false,
.support_bands = BIT(NL80211_BAND_2GHZ) |
BIT(NL80211_BAND_5GHZ) |
BIT(NL80211_BAND_6GHZ),
@@ -2942,9 +3038,16 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
BIT(NL80211_CHAN_WIDTH_80) |
BIT(NL80211_CHAN_WIDTH_160),
.support_unii4 = true,
+ .support_ant_gain = true,
+ .support_tas = true,
+ .support_sar_by_ant = true,
.ul_tb_waveform_ctrl = false,
.ul_tb_pwr_diff = true,
+ .rx_freq_frome_ie = false,
.hw_sec_hdr = true,
+ .hw_mgmt_tx_encrypt = true,
+ .hw_tkip_crypto = true,
+ .hw_mlo_bmc_crypto = false,
.rf_path_num = 2,
.tx_nss = 2,
.rx_nss = 2,
@@ -2997,7 +3100,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8},
.c2h_regs = rtw8852c_c2h_regs,
.page_regs = &rtw8852c_page_regs,
- .wow_reason_reg = R_AX_C2HREG_DATA3_V1 + 3,
+ .wow_reason_reg = rtw8852c_wow_wakeup_regs,
.cfo_src_fd = false,
.cfo_hw_comp = false,
.dcfo_comp = &rtw8852c_dcfo_comp,
@@ -3008,6 +3111,8 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.rrsr_cfgs = &rtw8852c_rrsr_cfgs,
.bss_clr_vld = {R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0},
.bss_clr_map_reg = R_BSS_CLR_MAP,
+ .rfkill_init = &rtw8852c_rfkill_regs,
+ .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9},
.dma_ch_mask = 0,
.edcca_regs = &rtw8852c_edcca_regs,
#ifdef CONFIG_PM
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
index 654e3e5507cb..b92e2ce4f4ad 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
@@ -5,6 +5,7 @@
#include "chan.h"
#include "coex.h"
#include "debug.h"
+#include "fw.h"
#include "phy.h"
#include "reg.h"
#include "rtw8852c.h"
@@ -584,11 +585,12 @@ static void _drck(struct rtw89_dev *rtwdev)
rtw89_phy_read32_mask(rtwdev, R_DRCK, MASKDWORD));
}
-static void _dac_cal(struct rtw89_dev *rtwdev, bool force)
+static void _dac_cal(struct rtw89_dev *rtwdev, bool force,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_dack_info *dack = &rtwdev->dack;
u32 rf0_0, rf1_0;
- u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, RF_AB);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, RF_AB, chanctx_idx);
dack->dack_done = false;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK b\n");
@@ -1063,7 +1065,7 @@ static bool _iqk_nbtxk(struct rtw89_dev *rtwdev,
static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path)
{
- struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
+ struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u8 idx = rfk_mcc->table_idx;
bool is_fail1, is_fail2;
@@ -1321,9 +1323,10 @@ static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u
}
static void _iqk_get_ch_info(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy, u8 path)
+ enum rtw89_phy_idx phy, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__);
@@ -1405,7 +1408,7 @@ static void _iqk_afebb_restore(struct rtw89_dev *rtwdev,
static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path)
{
- struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
+ struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
u8 idx = 0;
idx = rfk_mcc->table_idx;
@@ -1516,12 +1519,13 @@ static void _iqk_init(struct rtw89_dev *rtwdev)
}
static void _doiqk(struct rtw89_dev *rtwdev, bool force,
- enum rtw89_phy_idx phy_idx, u8 path)
+ enum rtw89_phy_idx phy_idx, u8 path,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u32 backup_bb_val[BACKUP_BB_REGS_NR];
u32 backup_rf_val[RTW8852C_IQK_SS][BACKUP_RF_REGS_NR];
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START);
@@ -1531,7 +1535,7 @@ static void _doiqk(struct rtw89_dev *rtwdev, bool force,
iqk_info->version = RTW8852C_IQK_VER;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version);
- _iqk_get_ch_info(rtwdev, phy_idx, path);
+ _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx);
_rfk_backup_bb_reg(rtwdev, backup_bb_val);
_rfk_backup_rf_reg(rtwdev, backup_rf_val[path], path);
_iqk_macbb_setting(rtwdev, phy_idx, path);
@@ -1544,18 +1548,19 @@ static void _doiqk(struct rtw89_dev *rtwdev, bool force,
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP);
}
-static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force)
+static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force,
+ enum rtw89_chanctx_idx chanctx_idx)
{
switch (_kpath(rtwdev, phy_idx)) {
case RF_A:
- _doiqk(rtwdev, force, phy_idx, RF_PATH_A);
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx);
break;
case RF_B:
- _doiqk(rtwdev, force, phy_idx, RF_PATH_B);
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx);
break;
case RF_AB:
- _doiqk(rtwdev, force, phy_idx, RF_PATH_A);
- _doiqk(rtwdev, force, phy_idx, RF_PATH_B);
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx);
+ _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx);
break;
default:
break;
@@ -1764,10 +1769,10 @@ u8 _rx_dck_channel_calc(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan)
target_ch = chan->channel - 33;
}
} else if (chan->band_type == RTW89_BAND_6G) {
- if (chan->channel >= 1 && chan->channel <= 125)
- target_ch = chan->channel + 32;
- else
+ if (chan->channel > 125)
target_ch = chan->channel - 32;
+ else
+ target_ch = chan->channel + 32;
} else {
target_ch = chan->channel;
}
@@ -1901,9 +1906,9 @@ static u8 _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
static void _dpk_information(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
u8 kidx = dpk->cur_idx[path];
@@ -2345,7 +2350,7 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
if (dgain > 0x5fc || dgain < 0x556) {
_dpk_one_shot(rtwdev, phy, path, D_SYNC);
- dgain = _dpk_dgain_read(rtwdev);
+ _dpk_dgain_read(rtwdev);
}
if (agc_cnt == 0) {
@@ -2495,9 +2500,9 @@ static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
bool is_reload = false;
u8 idx, cur_band, cur_ch;
@@ -2689,7 +2694,8 @@ static void _dpk_drf_direct_cntrl(struct rtw89_dev *rtwdev, u8 path, bool is_byb
}
static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
- enum rtw89_phy_idx phy, u8 kpath)
+ enum rtw89_phy_idx phy, u8 kpath,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120, 0xc0c4, 0xc0e8, 0xc0d4, 0xc0d8};
@@ -2705,7 +2711,8 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
if (!(kpath & BIT(path)))
continue;
- reloaded[path] = _dpk_reload_check(rtwdev, phy, path);
+ reloaded[path] = _dpk_reload_check(rtwdev, phy, path,
+ chanctx_idx);
if (!reloaded[path] && dpk->bp[path][0].ch != 0)
dpk->cur_idx[path] = !dpk->cur_idx[path];
else
@@ -2722,7 +2729,7 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
path, dpk->cur_idx[path]);
_dpk_bkup_kip(rtwdev, kip_reg, kip_bkup, path);
_rfk_backup_rf_reg(rtwdev, backup_rf_val[path], path);
- _dpk_information(rtwdev, phy, path);
+ _dpk_information(rtwdev, phy, path, chanctx_idx);
_dpk_init(rtwdev, path);
if (rtwdev->is_tssi_mode[path])
_dpk_tssi_pause(rtwdev, path, true);
@@ -2755,10 +2762,11 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
_dpk_kip_pwr_clk_onoff(rtwdev, false);
}
-static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_chanctx_idx chanctx_idx)
{
struct rtw89_fem_info *fem = &rtwdev->fem;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
u8 band = chan->band_type;
if (rtwdev->hal.cv == CHIP_CAV && band != RTW89_BAND_2G) {
@@ -2790,17 +2798,18 @@ static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
}
}
-static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force)
+static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force,
+ enum rtw89_chanctx_idx chanctx_idx)
{
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[DPK] ****** DPK Start (Ver: 0x%x, Cv: %d, RF_para: %d) ******\n",
RTW8852C_DPK_VER, rtwdev->hal.cv,
RTW8852C_RF_REL_VERSION);
- if (_dpk_bypass_check(rtwdev, phy))
+ if (_dpk_bypass_check(rtwdev, phy, chanctx_idx))
_dpk_force_bypass(rtwdev, phy);
else
- _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy));
+ _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy), chanctx_idx);
if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_DCKC, RR_DCKC_CHK) == 0x1)
rtw8852c_rx_dck(rtwdev, phy, false);
@@ -2891,9 +2900,8 @@ static void _dpk_track(struct rtw89_dev *rtwdev)
}
static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_bandwidth bw = chan->band_width;
enum rtw89_band band = chan->band_type;
u32 clk = 0x0;
@@ -2945,9 +2953,8 @@ static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev,
}
static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
if (path == RF_PATH_A) {
@@ -2972,7 +2979,7 @@ static void _tssi_set_bbgain_split(struct rtw89_dev *rtwdev, enum rtw89_phy_idx
}
static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
#define RTW8852C_TSSI_GET_VAL(ptr, idx) \
({ \
@@ -2985,8 +2992,8 @@ static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx ph
} \
__val; \
})
+ struct rtw89_fw_txpwr_track_cfg *trk = rtwdev->fw.elm_info.txpwr_trk;
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u8 subband = chan->subband_type;
const s8 *thm_up_a = NULL;
@@ -3001,56 +3008,88 @@ static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx ph
switch (subband) {
default:
case RTW89_CH_2G:
- thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_2ga_p;
- thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_2ga_n;
- thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_2gb_p;
- thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_2gb_n;
+ thm_up_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_P][0] :
+ rtw89_8852c_trk_cfg.delta_swingidx_2ga_p;
+ thm_down_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_N][0] :
+ rtw89_8852c_trk_cfg.delta_swingidx_2ga_n;
+ thm_up_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_P][0] :
+ rtw89_8852c_trk_cfg.delta_swingidx_2gb_p;
+ thm_down_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_N][0] :
+ rtw89_8852c_trk_cfg.delta_swingidx_2gb_n;
break;
case RTW89_CH_5G_BAND_1:
- thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_p[0];
- thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_n[0];
- thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_p[0];
- thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_n[0];
+ thm_up_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][0] :
+ rtw89_8852c_trk_cfg.delta_swingidx_5ga_p[0];
+ thm_down_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][0] :
+ rtw89_8852c_trk_cfg.delta_swingidx_5ga_n[0];
+ thm_up_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][0] :
+ rtw89_8852c_trk_cfg.delta_swingidx_5gb_p[0];
+ thm_down_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][0] :
+ rtw89_8852c_trk_cfg.delta_swingidx_5gb_n[0];
break;
case RTW89_CH_5G_BAND_3:
- thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_p[1];
- thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_n[1];
- thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_p[1];
- thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_n[1];
+ thm_up_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][1] :
+ rtw89_8852c_trk_cfg.delta_swingidx_5ga_p[1];
+ thm_down_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][1] :
+ rtw89_8852c_trk_cfg.delta_swingidx_5ga_n[1];
+ thm_up_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][1] :
+ rtw89_8852c_trk_cfg.delta_swingidx_5gb_p[1];
+ thm_down_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][1] :
+ rtw89_8852c_trk_cfg.delta_swingidx_5gb_n[1];
break;
case RTW89_CH_5G_BAND_4:
- thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_p[2];
- thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_n[2];
- thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_p[2];
- thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_n[2];
+ thm_up_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][2] :
+ rtw89_8852c_trk_cfg.delta_swingidx_5ga_p[2];
+ thm_down_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][2] :
+ rtw89_8852c_trk_cfg.delta_swingidx_5ga_n[2];
+ thm_up_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][2] :
+ rtw89_8852c_trk_cfg.delta_swingidx_5gb_p[2];
+ thm_down_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][2] :
+ rtw89_8852c_trk_cfg.delta_swingidx_5gb_n[2];
break;
case RTW89_CH_6G_BAND_IDX0:
case RTW89_CH_6G_BAND_IDX1:
- thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[0];
- thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[0];
- thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[0];
- thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[0];
+ thm_up_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][0] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[0];
+ thm_down_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][0] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[0];
+ thm_up_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][0] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[0];
+ thm_down_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][0] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[0];
break;
case RTW89_CH_6G_BAND_IDX2:
case RTW89_CH_6G_BAND_IDX3:
- thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[1];
- thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[1];
- thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[1];
- thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[1];
+ thm_up_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][1] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[1];
+ thm_down_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][1] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[1];
+ thm_up_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][1] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[1];
+ thm_down_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][1] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[1];
break;
case RTW89_CH_6G_BAND_IDX4:
case RTW89_CH_6G_BAND_IDX5:
- thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[2];
- thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[2];
- thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[2];
- thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[2];
+ thm_up_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][2] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[2];
+ thm_down_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][2] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[2];
+ thm_up_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][2] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[2];
+ thm_down_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][2] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[2];
break;
case RTW89_CH_6G_BAND_IDX6:
case RTW89_CH_6G_BAND_IDX7:
- thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[3];
- thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[3];
- thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[3];
- thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[3];
+ thm_up_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][3] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[3];
+ thm_down_a = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][3] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[3];
+ thm_up_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][3] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[3];
+ thm_down_b = trk ? trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][3] :
+ rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[3];
break;
}
@@ -3158,9 +3197,8 @@ static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx ph
}
static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
if (path == RF_PATH_A) {
@@ -3175,9 +3213,9 @@ static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy
}
static void _tssi_set_aligk_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path,
+ const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
const struct rtw89_rfk_tbl *tbl;
@@ -3586,10 +3624,9 @@ static u32 _tssi_get_6g_trim_group(struct rtw89_dev *rtwdev, u8 ch)
}
static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
u8 ch = chan->channel;
u32 gidx, gidx_1st, gidx_2nd;
@@ -3650,10 +3687,9 @@ static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
enum rtw89_band band = chan->band_type;
u8 ch = chan->channel;
u32 tgidx, tgidx_1st, tgidx_2nd;
@@ -3715,10 +3751,9 @@ static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev,
}
static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy)
+ enum rtw89_phy_idx phy, const struct rtw89_chan *chan)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u8 gidx;
s8 ofdm_de;
@@ -3741,7 +3776,7 @@ static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev,
for (i = path; i < path_max; i++) {
gidx = _tssi_get_cck_group(rtwdev, ch);
- trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i);
+ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan);
val = tssi_info->tssi_cck[i][gidx] + trim_de;
rtw89_debug(rtwdev, RTW89_DBG_TSSI,
@@ -3757,8 +3792,8 @@ static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev,
rtw89_phy_read32_mask(rtwdev, _tssi_de_cck_long[i],
_TSSI_DE_MASK));
- ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i);
- trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i);
+ ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i, chan);
+ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan);
val = ofdm_de + trim_de;
rtw89_debug(rtwdev, RTW89_DBG_TSSI,
@@ -3781,7 +3816,7 @@ static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev,
}
static void rtw8852c_tssi_cont_en(struct rtw89_dev *rtwdev, bool en,
- enum rtw89_rf_path path)
+ enum rtw89_rf_path path, const struct rtw89_chan *chan)
{
static const u32 tssi_trk[2] = {0x5818, 0x7818};
static const u32 tssi_en[2] = {0x5820, 0x7820};
@@ -3790,25 +3825,26 @@ static void rtw8852c_tssi_cont_en(struct rtw89_dev *rtwdev, bool en,
rtw89_phy_write32_mask(rtwdev, tssi_trk[path], BIT(30), 0x0);
rtw89_phy_write32_mask(rtwdev, tssi_en[path], BIT(31), 0x0);
if (rtwdev->dbcc_en && path == RF_PATH_B)
- _tssi_set_efuse_to_de(rtwdev, RTW89_PHY_1);
+ _tssi_set_efuse_to_de(rtwdev, RTW89_PHY_1, chan);
else
- _tssi_set_efuse_to_de(rtwdev, RTW89_PHY_0);
+ _tssi_set_efuse_to_de(rtwdev, RTW89_PHY_0, chan);
} else {
rtw89_phy_write32_mask(rtwdev, tssi_trk[path], BIT(30), 0x1);
rtw89_phy_write32_mask(rtwdev, tssi_en[path], BIT(31), 0x1);
}
}
-void rtw8852c_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx)
+void rtw8852c_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx,
+ const struct rtw89_chan *chan)
{
if (!rtwdev->dbcc_en) {
- rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_A);
- rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_B);
+ rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_A, chan);
+ rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_B, chan);
} else {
if (phy_idx == RTW89_PHY_0)
- rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_A);
+ rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_A, chan);
else
- rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_B);
+ rtw8852c_tssi_cont_en(rtwdev, en, RF_PATH_B, chan);
}
}
@@ -4069,52 +4105,38 @@ void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev,
void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
- struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
- DECLARE_BITMAP(map, RTW89_IQK_CHS_NR) = {};
+ struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
+ struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V0] = {};
const struct rtw89_chan *chan;
enum rtw89_entity_mode mode;
u8 chan_idx;
u8 idx;
- u8 i;
mode = rtw89_get_entity_mode(rtwdev);
switch (mode) {
case RTW89_ENTITY_MODE_MCC_PREPARE:
- chan_idx = RTW89_SUB_ENTITY_1;
+ chan_idx = RTW89_CHANCTX_1;
break;
default:
- chan_idx = RTW89_SUB_ENTITY_0;
+ chan_idx = RTW89_CHANCTX_0;
break;
}
- for (i = 0; i <= chan_idx; i++) {
- chan = rtw89_chan_get(rtwdev, i);
+ chan = rtw89_chan_get(rtwdev, chan_idx);
- for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) {
- if (rfk_mcc->ch[idx] == chan->channel &&
- rfk_mcc->band[idx] == chan->band_type) {
- if (i != chan_idx) {
- set_bit(idx, map);
- break;
- }
+ for (idx = 0; idx < ARRAY_SIZE(desc); idx++) {
+ struct rtw89_rfk_chan_desc *p = &desc[idx];
- goto bottom;
- }
- }
- }
+ p->ch = rfk_mcc->ch[idx];
- idx = find_first_zero_bit(map, RTW89_IQK_CHS_NR);
- if (idx == RTW89_IQK_CHS_NR) {
- rtw89_debug(rtwdev, RTW89_DBG_RFK,
- "%s: no empty rfk table; force replace the first\n",
- __func__);
- idx = 0;
+ p->has_band = true;
+ p->band = rfk_mcc->band[idx];
}
+ idx = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan);
+
rfk_mcc->ch[idx] = chan->channel;
rfk_mcc->band[idx] = chan->band_type;
-
-bottom:
rfk_mcc->table_idx = idx;
}
@@ -4126,26 +4148,27 @@ void rtw8852c_rck(struct rtw89_dev *rtwdev)
_rck(rtwdev, path);
}
-void rtw8852c_dack(struct rtw89_dev *rtwdev)
+void rtw8852c_dack(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx)
{
- u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0, chanctx_idx);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START);
- _dac_cal(rtwdev, false);
+ _dac_cal(rtwdev, false, chanctx_idx);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP);
}
-void rtw8852c_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+void rtw8852c_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
{
u32 tx_en;
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START);
rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
_wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx));
_iqk_init(rtwdev);
- _iqk(rtwdev, phy_idx, false);
+ _iqk(rtwdev, phy_idx, false, chanctx_idx);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP);
@@ -4216,10 +4239,11 @@ void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_a
void rtw8852c_rx_dck_track(struct rtw89_dev *rtwdev)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ enum rtw89_chanctx_idx chanctx_idx = RTW89_CHANCTX_0;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
struct rtw89_rx_dck_info *rx_dck = &rtwdev->rx_dck;
enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx);
u8 dck_channel;
u8 cur_thermal;
u32 tx_en;
@@ -4273,16 +4297,17 @@ void rtw8852c_dpk_init(struct rtw89_dev *rtwdev)
dpk->is_dpk_reload_en = false;
}
-void rtw8852c_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+void rtw8852c_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx)
{
u32 tx_en;
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START);
rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
_wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx));
- _dpk(rtwdev, phy_idx, false);
+ _dpk(rtwdev, phy_idx, false, chanctx_idx);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP);
@@ -4293,8 +4318,10 @@ void rtw8852c_dpk_track(struct rtw89_dev *rtwdev)
_dpk_track(rtwdev);
}
-void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_chanctx_idx chanctx_idx)
{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C;
rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", __func__, phy);
@@ -4312,23 +4339,24 @@ void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
_tssi_disable(rtwdev, phy);
for (i = path; i < path_max; i++) {
- _tssi_set_sys(rtwdev, phy, i);
+ _tssi_set_sys(rtwdev, phy, i, chan);
_tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i);
_tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i);
- _tssi_set_dck(rtwdev, phy, i);
+ _tssi_set_dck(rtwdev, phy, i, chan);
_tssi_set_bbgain_split(rtwdev, phy, i);
- _tssi_set_tmeter_tbl(rtwdev, phy, i);
- _tssi_slope_cal_org(rtwdev, phy, i);
- _tssi_set_aligk_default(rtwdev, phy, i);
+ _tssi_set_tmeter_tbl(rtwdev, phy, i, chan);
+ _tssi_slope_cal_org(rtwdev, phy, i, chan);
+ _tssi_set_aligk_default(rtwdev, phy, i, chan);
_tssi_set_slope(rtwdev, phy, i);
_tssi_run_slope(rtwdev, phy, i);
}
_tssi_enable(rtwdev, phy);
- _tssi_set_efuse_to_de(rtwdev, phy);
+ _tssi_set_efuse_to_de(rtwdev, phy, chan);
}
-void rtw8852c_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
+void rtw8852c_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan)
{
u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C;
@@ -4353,15 +4381,15 @@ void rtw8852c_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
_tssi_disable(rtwdev, phy);
for (i = path; i < path_max; i++) {
- _tssi_set_sys(rtwdev, phy, i);
- _tssi_set_dck(rtwdev, phy, i);
- _tssi_set_tmeter_tbl(rtwdev, phy, i);
- _tssi_slope_cal_org(rtwdev, phy, i);
- _tssi_set_aligk_default(rtwdev, phy, i);
+ _tssi_set_sys(rtwdev, phy, i, chan);
+ _tssi_set_dck(rtwdev, phy, i, chan);
+ _tssi_set_tmeter_tbl(rtwdev, phy, i, chan);
+ _tssi_slope_cal_org(rtwdev, phy, i, chan);
+ _tssi_set_aligk_default(rtwdev, phy, i, chan);
}
_tssi_enable(rtwdev, phy);
- _tssi_set_efuse_to_de(rtwdev, phy);
+ _tssi_set_efuse_to_de(rtwdev, phy, chan);
}
static void rtw8852c_tssi_default_txagc(struct rtw89_dev *rtwdev,
@@ -4436,7 +4464,7 @@ void rtw8852c_rfk_chanctx_cb(struct rtw89_dev *rtwdev,
dpk->is_dpk_enable = true;
for (path = 0; path < RTW8852C_DPK_RF_PATH; path++)
_dpk_onoff(rtwdev, path, false);
- rtw8852c_dpk(rtwdev, RTW89_PHY_0);
+ rtw8852c_dpk(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0);
break;
default:
break;
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h
index 6605137e61aa..306dd0a0be73 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h
@@ -9,16 +9,21 @@
void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
void rtw8852c_rck(struct rtw89_dev *rtwdev);
-void rtw8852c_dack(struct rtw89_dev *rtwdev);
-void rtw8852c_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
+void rtw8852c_dack(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx);
+void rtw8852c_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool is_afe);
void rtw8852c_rx_dck_track(struct rtw89_dev *rtwdev);
void rtw8852c_dpk_init(struct rtw89_dev *rtwdev);
-void rtw8852c_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
+void rtw8852c_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
+ enum rtw89_chanctx_idx chanctx_idx);
void rtw8852c_dpk_track(struct rtw89_dev *rtwdev);
-void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
-void rtw8852c_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy);
-void rtw8852c_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx);
+void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ enum rtw89_chanctx_idx chanctx_idx);
+void rtw8852c_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+ const struct rtw89_chan *chan);
+void rtw8852c_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx,
+ const struct rtw89_chan *chan);
void rtw8852c_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
enum rtw89_phy_idx phy_idx);
void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c
index ab1a0aadc869..24c390b6f3d3 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c
@@ -34521,7 +34521,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_FCC][48] = 72,
[0][0][1][0][RTW89_ETSI][48] = 127,
[0][0][1][0][RTW89_MKK][48] = 127,
- [0][0][1][0][RTW89_IC][48] = 127,
+ [0][0][1][0][RTW89_IC][48] = 72,
[0][0][1][0][RTW89_KCC][48] = 127,
[0][0][1][0][RTW89_ACMA][48] = 127,
[0][0][1][0][RTW89_CN][48] = 127,
@@ -34534,7 +34534,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_FCC][50] = 72,
[0][0][1][0][RTW89_ETSI][50] = 127,
[0][0][1][0][RTW89_MKK][50] = 127,
- [0][0][1][0][RTW89_IC][50] = 127,
+ [0][0][1][0][RTW89_IC][50] = 72,
[0][0][1][0][RTW89_KCC][50] = 127,
[0][0][1][0][RTW89_ACMA][50] = 127,
[0][0][1][0][RTW89_CN][50] = 127,
@@ -34547,7 +34547,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_FCC][52] = 72,
[0][0][1][0][RTW89_ETSI][52] = 127,
[0][0][1][0][RTW89_MKK][52] = 127,
- [0][0][1][0][RTW89_IC][52] = 127,
+ [0][0][1][0][RTW89_IC][52] = 72,
[0][0][1][0][RTW89_KCC][52] = 127,
[0][0][1][0][RTW89_ACMA][52] = 127,
[0][0][1][0][RTW89_CN][52] = 127,
@@ -34885,7 +34885,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_FCC][48] = 48,
[0][1][1][0][RTW89_ETSI][48] = 127,
[0][1][1][0][RTW89_MKK][48] = 127,
- [0][1][1][0][RTW89_IC][48] = 127,
+ [0][1][1][0][RTW89_IC][48] = 48,
[0][1][1][0][RTW89_KCC][48] = 127,
[0][1][1][0][RTW89_ACMA][48] = 127,
[0][1][1][0][RTW89_CN][48] = 127,
@@ -34898,7 +34898,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_FCC][50] = 48,
[0][1][1][0][RTW89_ETSI][50] = 127,
[0][1][1][0][RTW89_MKK][50] = 127,
- [0][1][1][0][RTW89_IC][50] = 127,
+ [0][1][1][0][RTW89_IC][50] = 48,
[0][1][1][0][RTW89_KCC][50] = 127,
[0][1][1][0][RTW89_ACMA][50] = 127,
[0][1][1][0][RTW89_CN][50] = 127,
@@ -34911,7 +34911,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_FCC][52] = 48,
[0][1][1][0][RTW89_ETSI][52] = 127,
[0][1][1][0][RTW89_MKK][52] = 127,
- [0][1][1][0][RTW89_IC][52] = 127,
+ [0][1][1][0][RTW89_IC][52] = 48,
[0][1][1][0][RTW89_KCC][52] = 127,
[0][1][1][0][RTW89_ACMA][52] = 127,
[0][1][1][0][RTW89_CN][52] = 127,
@@ -35249,7 +35249,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_FCC][48] = 72,
[0][0][2][0][RTW89_ETSI][48] = 127,
[0][0][2][0][RTW89_MKK][48] = 127,
- [0][0][2][0][RTW89_IC][48] = 127,
+ [0][0][2][0][RTW89_IC][48] = 72,
[0][0][2][0][RTW89_KCC][48] = 127,
[0][0][2][0][RTW89_ACMA][48] = 127,
[0][0][2][0][RTW89_CN][48] = 127,
@@ -35262,7 +35262,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_FCC][50] = 72,
[0][0][2][0][RTW89_ETSI][50] = 127,
[0][0][2][0][RTW89_MKK][50] = 127,
- [0][0][2][0][RTW89_IC][50] = 127,
+ [0][0][2][0][RTW89_IC][50] = 72,
[0][0][2][0][RTW89_KCC][50] = 127,
[0][0][2][0][RTW89_ACMA][50] = 127,
[0][0][2][0][RTW89_CN][50] = 127,
@@ -35275,7 +35275,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_FCC][52] = 72,
[0][0][2][0][RTW89_ETSI][52] = 127,
[0][0][2][0][RTW89_MKK][52] = 127,
- [0][0][2][0][RTW89_IC][52] = 127,
+ [0][0][2][0][RTW89_IC][52] = 72,
[0][0][2][0][RTW89_KCC][52] = 127,
[0][0][2][0][RTW89_ACMA][52] = 127,
[0][0][2][0][RTW89_CN][52] = 127,
@@ -35613,7 +35613,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_FCC][48] = 48,
[0][1][2][0][RTW89_ETSI][48] = 127,
[0][1][2][0][RTW89_MKK][48] = 127,
- [0][1][2][0][RTW89_IC][48] = 127,
+ [0][1][2][0][RTW89_IC][48] = 48,
[0][1][2][0][RTW89_KCC][48] = 127,
[0][1][2][0][RTW89_ACMA][48] = 127,
[0][1][2][0][RTW89_CN][48] = 127,
@@ -35626,7 +35626,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_FCC][50] = 50,
[0][1][2][0][RTW89_ETSI][50] = 127,
[0][1][2][0][RTW89_MKK][50] = 127,
- [0][1][2][0][RTW89_IC][50] = 127,
+ [0][1][2][0][RTW89_IC][50] = 50,
[0][1][2][0][RTW89_KCC][50] = 127,
[0][1][2][0][RTW89_ACMA][50] = 127,
[0][1][2][0][RTW89_CN][50] = 127,
@@ -35639,7 +35639,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_FCC][52] = 48,
[0][1][2][0][RTW89_ETSI][52] = 127,
[0][1][2][0][RTW89_MKK][52] = 127,
- [0][1][2][0][RTW89_IC][52] = 127,
+ [0][1][2][0][RTW89_IC][52] = 48,
[0][1][2][0][RTW89_KCC][52] = 127,
[0][1][2][0][RTW89_ACMA][52] = 127,
[0][1][2][0][RTW89_CN][52] = 127,
@@ -35977,7 +35977,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_FCC][48] = 48,
[0][1][2][1][RTW89_ETSI][48] = 127,
[0][1][2][1][RTW89_MKK][48] = 127,
- [0][1][2][1][RTW89_IC][48] = 127,
+ [0][1][2][1][RTW89_IC][48] = 48,
[0][1][2][1][RTW89_KCC][48] = 127,
[0][1][2][1][RTW89_ACMA][48] = 127,
[0][1][2][1][RTW89_CN][48] = 127,
@@ -35990,7 +35990,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_FCC][50] = 50,
[0][1][2][1][RTW89_ETSI][50] = 127,
[0][1][2][1][RTW89_MKK][50] = 127,
- [0][1][2][1][RTW89_IC][50] = 127,
+ [0][1][2][1][RTW89_IC][50] = 50,
[0][1][2][1][RTW89_KCC][50] = 127,
[0][1][2][1][RTW89_ACMA][50] = 127,
[0][1][2][1][RTW89_CN][50] = 127,
@@ -36003,7 +36003,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_FCC][52] = 48,
[0][1][2][1][RTW89_ETSI][52] = 127,
[0][1][2][1][RTW89_MKK][52] = 127,
- [0][1][2][1][RTW89_IC][52] = 127,
+ [0][1][2][1][RTW89_IC][52] = 48,
[0][1][2][1][RTW89_KCC][52] = 127,
[0][1][2][1][RTW89_ACMA][52] = 127,
[0][1][2][1][RTW89_CN][52] = 127,
@@ -36172,7 +36172,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_FCC][47] = 68,
[1][0][2][0][RTW89_ETSI][47] = 127,
[1][0][2][0][RTW89_MKK][47] = 127,
- [1][0][2][0][RTW89_IC][47] = 127,
+ [1][0][2][0][RTW89_IC][47] = 68,
[1][0][2][0][RTW89_KCC][47] = 127,
[1][0][2][0][RTW89_ACMA][47] = 127,
[1][0][2][0][RTW89_CN][47] = 127,
@@ -36185,7 +36185,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_FCC][51] = 68,
[1][0][2][0][RTW89_ETSI][51] = 127,
[1][0][2][0][RTW89_MKK][51] = 127,
- [1][0][2][0][RTW89_IC][51] = 127,
+ [1][0][2][0][RTW89_IC][51] = 68,
[1][0][2][0][RTW89_KCC][51] = 127,
[1][0][2][0][RTW89_ACMA][51] = 127,
[1][0][2][0][RTW89_CN][51] = 127,
@@ -36354,7 +36354,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_FCC][47] = 62,
[1][1][2][0][RTW89_ETSI][47] = 127,
[1][1][2][0][RTW89_MKK][47] = 127,
- [1][1][2][0][RTW89_IC][47] = 127,
+ [1][1][2][0][RTW89_IC][47] = 62,
[1][1][2][0][RTW89_KCC][47] = 127,
[1][1][2][0][RTW89_ACMA][47] = 127,
[1][1][2][0][RTW89_CN][47] = 127,
@@ -36367,7 +36367,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_FCC][51] = 60,
[1][1][2][0][RTW89_ETSI][51] = 127,
[1][1][2][0][RTW89_MKK][51] = 127,
- [1][1][2][0][RTW89_IC][51] = 127,
+ [1][1][2][0][RTW89_IC][51] = 60,
[1][1][2][0][RTW89_KCC][51] = 127,
[1][1][2][0][RTW89_ACMA][51] = 127,
[1][1][2][0][RTW89_CN][51] = 127,
@@ -36536,7 +36536,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_FCC][47] = 62,
[1][1][2][1][RTW89_ETSI][47] = 127,
[1][1][2][1][RTW89_MKK][47] = 127,
- [1][1][2][1][RTW89_IC][47] = 127,
+ [1][1][2][1][RTW89_IC][47] = 62,
[1][1][2][1][RTW89_KCC][47] = 127,
[1][1][2][1][RTW89_ACMA][47] = 127,
[1][1][2][1][RTW89_CN][47] = 127,
@@ -36549,7 +36549,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_FCC][51] = 60,
[1][1][2][1][RTW89_ETSI][51] = 127,
[1][1][2][1][RTW89_MKK][51] = 127,
- [1][1][2][1][RTW89_IC][51] = 127,
+ [1][1][2][1][RTW89_IC][51] = 60,
[1][1][2][1][RTW89_KCC][51] = 127,
[1][1][2][1][RTW89_ACMA][51] = 127,
[1][1][2][1][RTW89_CN][51] = 127,
@@ -36640,7 +36640,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_FCC][49] = 62,
[2][0][2][0][RTW89_ETSI][49] = 127,
[2][0][2][0][RTW89_MKK][49] = 127,
- [2][0][2][0][RTW89_IC][49] = 127,
+ [2][0][2][0][RTW89_IC][49] = 62,
[2][0][2][0][RTW89_KCC][49] = 127,
[2][0][2][0][RTW89_ACMA][49] = 127,
[2][0][2][0][RTW89_CN][49] = 127,
@@ -36731,7 +36731,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_FCC][49] = 62,
[2][1][2][0][RTW89_ETSI][49] = 127,
[2][1][2][0][RTW89_MKK][49] = 127,
- [2][1][2][0][RTW89_IC][49] = 127,
+ [2][1][2][0][RTW89_IC][49] = 62,
[2][1][2][0][RTW89_KCC][49] = 127,
[2][1][2][0][RTW89_ACMA][49] = 127,
[2][1][2][0][RTW89_CN][49] = 127,
@@ -36822,7 +36822,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_FCC][49] = 62,
[2][1][2][1][RTW89_ETSI][49] = 127,
[2][1][2][1][RTW89_MKK][49] = 127,
- [2][1][2][1][RTW89_IC][49] = 127,
+ [2][1][2][1][RTW89_IC][49] = 62,
[2][1][2][1][RTW89_KCC][49] = 127,
[2][1][2][1][RTW89_ACMA][49] = 127,
[2][1][2][1][RTW89_CN][49] = 127,
@@ -36861,7 +36861,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[3][0][2][0][RTW89_FCC][45] = 52,
[3][0][2][0][RTW89_ETSI][45] = 127,
[3][0][2][0][RTW89_MKK][45] = 127,
- [3][0][2][0][RTW89_IC][45] = 127,
+ [3][0][2][0][RTW89_IC][45] = 52,
[3][0][2][0][RTW89_KCC][45] = 127,
[3][0][2][0][RTW89_ACMA][45] = 127,
[3][0][2][0][RTW89_CN][45] = 127,
@@ -36900,7 +36900,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][0][RTW89_FCC][45] = 46,
[3][1][2][0][RTW89_ETSI][45] = 127,
[3][1][2][0][RTW89_MKK][45] = 127,
- [3][1][2][0][RTW89_IC][45] = 127,
+ [3][1][2][0][RTW89_IC][45] = 46,
[3][1][2][0][RTW89_KCC][45] = 127,
[3][1][2][0][RTW89_ACMA][45] = 127,
[3][1][2][0][RTW89_CN][45] = 127,
@@ -36939,7 +36939,7 @@ const s8 rtw89_8852c_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][1][RTW89_FCC][45] = 46,
[3][1][2][1][RTW89_ETSI][45] = 127,
[3][1][2][1][RTW89_MKK][45] = 127,
- [3][1][2][1][RTW89_IC][45] = 127,
+ [3][1][2][1][RTW89_IC][45] = 46,
[3][1][2][1][RTW89_KCC][45] = 127,
[3][1][2][1][RTW89_ACMA][45] = 127,
[3][1][2][1][RTW89_CN][45] = 127,
@@ -36958,1476 +36958,986 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[RTW89_6G_CH_NUM] = {
[0][0][1][0][RTW89_WW][0][0] = 24,
[0][0][1][0][RTW89_WW][1][0] = 24,
- [0][0][1][0][RTW89_WW][2][0] = 56,
[0][0][1][0][RTW89_WW][0][2] = 22,
[0][0][1][0][RTW89_WW][1][2] = 22,
- [0][0][1][0][RTW89_WW][2][2] = 56,
[0][0][1][0][RTW89_WW][0][4] = 22,
[0][0][1][0][RTW89_WW][1][4] = 22,
- [0][0][1][0][RTW89_WW][2][4] = 56,
[0][0][1][0][RTW89_WW][0][6] = 22,
[0][0][1][0][RTW89_WW][1][6] = 22,
- [0][0][1][0][RTW89_WW][2][6] = 56,
[0][0][1][0][RTW89_WW][0][8] = 22,
[0][0][1][0][RTW89_WW][1][8] = 22,
- [0][0][1][0][RTW89_WW][2][8] = 56,
[0][0][1][0][RTW89_WW][0][10] = 22,
[0][0][1][0][RTW89_WW][1][10] = 22,
- [0][0][1][0][RTW89_WW][2][10] = 56,
[0][0][1][0][RTW89_WW][0][12] = 22,
[0][0][1][0][RTW89_WW][1][12] = 22,
- [0][0][1][0][RTW89_WW][2][12] = 56,
[0][0][1][0][RTW89_WW][0][14] = 22,
[0][0][1][0][RTW89_WW][1][14] = 22,
- [0][0][1][0][RTW89_WW][2][14] = 56,
[0][0][1][0][RTW89_WW][0][15] = 22,
[0][0][1][0][RTW89_WW][1][15] = 22,
- [0][0][1][0][RTW89_WW][2][15] = 56,
[0][0][1][0][RTW89_WW][0][17] = 22,
[0][0][1][0][RTW89_WW][1][17] = 22,
- [0][0][1][0][RTW89_WW][2][17] = 56,
[0][0][1][0][RTW89_WW][0][19] = 22,
[0][0][1][0][RTW89_WW][1][19] = 22,
- [0][0][1][0][RTW89_WW][2][19] = 56,
[0][0][1][0][RTW89_WW][0][21] = 22,
[0][0][1][0][RTW89_WW][1][21] = 22,
- [0][0][1][0][RTW89_WW][2][21] = 56,
[0][0][1][0][RTW89_WW][0][23] = 22,
[0][0][1][0][RTW89_WW][1][23] = 22,
- [0][0][1][0][RTW89_WW][2][23] = 70,
[0][0][1][0][RTW89_WW][0][25] = 22,
[0][0][1][0][RTW89_WW][1][25] = 22,
- [0][0][1][0][RTW89_WW][2][25] = 70,
[0][0][1][0][RTW89_WW][0][27] = 22,
[0][0][1][0][RTW89_WW][1][27] = 22,
- [0][0][1][0][RTW89_WW][2][27] = 70,
[0][0][1][0][RTW89_WW][0][29] = 22,
[0][0][1][0][RTW89_WW][1][29] = 22,
- [0][0][1][0][RTW89_WW][2][29] = 70,
[0][0][1][0][RTW89_WW][0][30] = 22,
[0][0][1][0][RTW89_WW][1][30] = 22,
- [0][0][1][0][RTW89_WW][2][30] = 70,
[0][0][1][0][RTW89_WW][0][32] = 22,
[0][0][1][0][RTW89_WW][1][32] = 22,
- [0][0][1][0][RTW89_WW][2][32] = 70,
[0][0][1][0][RTW89_WW][0][34] = 22,
[0][0][1][0][RTW89_WW][1][34] = 22,
- [0][0][1][0][RTW89_WW][2][34] = 70,
[0][0][1][0][RTW89_WW][0][36] = 22,
[0][0][1][0][RTW89_WW][1][36] = 22,
- [0][0][1][0][RTW89_WW][2][36] = 70,
[0][0][1][0][RTW89_WW][0][38] = 22,
[0][0][1][0][RTW89_WW][1][38] = 22,
- [0][0][1][0][RTW89_WW][2][38] = 70,
[0][0][1][0][RTW89_WW][0][40] = 22,
[0][0][1][0][RTW89_WW][1][40] = 22,
- [0][0][1][0][RTW89_WW][2][40] = 70,
[0][0][1][0][RTW89_WW][0][42] = 22,
[0][0][1][0][RTW89_WW][1][42] = 22,
- [0][0][1][0][RTW89_WW][2][42] = 70,
[0][0][1][0][RTW89_WW][0][44] = 22,
[0][0][1][0][RTW89_WW][1][44] = 22,
- [0][0][1][0][RTW89_WW][2][44] = 70,
[0][0][1][0][RTW89_WW][0][45] = 22,
[0][0][1][0][RTW89_WW][1][45] = 22,
- [0][0][1][0][RTW89_WW][2][45] = 70,
[0][0][1][0][RTW89_WW][0][47] = 22,
[0][0][1][0][RTW89_WW][1][47] = 22,
- [0][0][1][0][RTW89_WW][2][47] = 70,
[0][0][1][0][RTW89_WW][0][49] = 24,
[0][0][1][0][RTW89_WW][1][49] = 24,
- [0][0][1][0][RTW89_WW][2][49] = 70,
[0][0][1][0][RTW89_WW][0][51] = 22,
[0][0][1][0][RTW89_WW][1][51] = 22,
- [0][0][1][0][RTW89_WW][2][51] = 70,
[0][0][1][0][RTW89_WW][0][53] = 22,
[0][0][1][0][RTW89_WW][1][53] = 22,
- [0][0][1][0][RTW89_WW][2][53] = 70,
[0][0][1][0][RTW89_WW][0][55] = 22,
[0][0][1][0][RTW89_WW][1][55] = 22,
- [0][0][1][0][RTW89_WW][2][55] = 68,
[0][0][1][0][RTW89_WW][0][57] = 22,
[0][0][1][0][RTW89_WW][1][57] = 22,
- [0][0][1][0][RTW89_WW][2][57] = 68,
[0][0][1][0][RTW89_WW][0][59] = 22,
[0][0][1][0][RTW89_WW][1][59] = 22,
- [0][0][1][0][RTW89_WW][2][59] = 68,
[0][0][1][0][RTW89_WW][0][60] = 22,
[0][0][1][0][RTW89_WW][1][60] = 22,
- [0][0][1][0][RTW89_WW][2][60] = 68,
[0][0][1][0][RTW89_WW][0][62] = 22,
[0][0][1][0][RTW89_WW][1][62] = 22,
- [0][0][1][0][RTW89_WW][2][62] = 68,
[0][0][1][0][RTW89_WW][0][64] = 22,
[0][0][1][0][RTW89_WW][1][64] = 22,
- [0][0][1][0][RTW89_WW][2][64] = 68,
[0][0][1][0][RTW89_WW][0][66] = 22,
[0][0][1][0][RTW89_WW][1][66] = 22,
- [0][0][1][0][RTW89_WW][2][66] = 68,
[0][0][1][0][RTW89_WW][0][68] = 22,
[0][0][1][0][RTW89_WW][1][68] = 22,
- [0][0][1][0][RTW89_WW][2][68] = 68,
[0][0][1][0][RTW89_WW][0][70] = 24,
[0][0][1][0][RTW89_WW][1][70] = 24,
- [0][0][1][0][RTW89_WW][2][70] = 68,
[0][0][1][0][RTW89_WW][0][72] = 22,
[0][0][1][0][RTW89_WW][1][72] = 22,
- [0][0][1][0][RTW89_WW][2][72] = 68,
[0][0][1][0][RTW89_WW][0][74] = 22,
[0][0][1][0][RTW89_WW][1][74] = 22,
- [0][0][1][0][RTW89_WW][2][74] = 68,
[0][0][1][0][RTW89_WW][0][75] = 22,
[0][0][1][0][RTW89_WW][1][75] = 22,
- [0][0][1][0][RTW89_WW][2][75] = 68,
[0][0][1][0][RTW89_WW][0][77] = 22,
[0][0][1][0][RTW89_WW][1][77] = 22,
- [0][0][1][0][RTW89_WW][2][77] = 68,
[0][0][1][0][RTW89_WW][0][79] = 22,
[0][0][1][0][RTW89_WW][1][79] = 22,
- [0][0][1][0][RTW89_WW][2][79] = 68,
[0][0][1][0][RTW89_WW][0][81] = 22,
[0][0][1][0][RTW89_WW][1][81] = 22,
- [0][0][1][0][RTW89_WW][2][81] = 68,
[0][0][1][0][RTW89_WW][0][83] = 22,
[0][0][1][0][RTW89_WW][1][83] = 22,
- [0][0][1][0][RTW89_WW][2][83] = 68,
[0][0][1][0][RTW89_WW][0][85] = 22,
[0][0][1][0][RTW89_WW][1][85] = 22,
- [0][0][1][0][RTW89_WW][2][85] = 68,
[0][0][1][0][RTW89_WW][0][87] = 22,
[0][0][1][0][RTW89_WW][1][87] = 22,
- [0][0][1][0][RTW89_WW][2][87] = 0,
[0][0][1][0][RTW89_WW][0][89] = 22,
[0][0][1][0][RTW89_WW][1][89] = 22,
- [0][0][1][0][RTW89_WW][2][89] = 0,
[0][0][1][0][RTW89_WW][0][90] = 22,
[0][0][1][0][RTW89_WW][1][90] = 22,
- [0][0][1][0][RTW89_WW][2][90] = 0,
[0][0][1][0][RTW89_WW][0][92] = 22,
[0][0][1][0][RTW89_WW][1][92] = 22,
- [0][0][1][0][RTW89_WW][2][92] = 0,
[0][0][1][0][RTW89_WW][0][94] = 22,
[0][0][1][0][RTW89_WW][1][94] = 22,
- [0][0][1][0][RTW89_WW][2][94] = 0,
[0][0][1][0][RTW89_WW][0][96] = 22,
[0][0][1][0][RTW89_WW][1][96] = 22,
- [0][0][1][0][RTW89_WW][2][96] = 0,
[0][0][1][0][RTW89_WW][0][98] = 22,
[0][0][1][0][RTW89_WW][1][98] = 22,
- [0][0][1][0][RTW89_WW][2][98] = 0,
[0][0][1][0][RTW89_WW][0][100] = 22,
[0][0][1][0][RTW89_WW][1][100] = 22,
- [0][0][1][0][RTW89_WW][2][100] = 0,
[0][0][1][0][RTW89_WW][0][102] = 22,
[0][0][1][0][RTW89_WW][1][102] = 22,
- [0][0][1][0][RTW89_WW][2][102] = 0,
[0][0][1][0][RTW89_WW][0][104] = 22,
[0][0][1][0][RTW89_WW][1][104] = 22,
- [0][0][1][0][RTW89_WW][2][104] = 0,
[0][0][1][0][RTW89_WW][0][105] = 22,
[0][0][1][0][RTW89_WW][1][105] = 22,
- [0][0][1][0][RTW89_WW][2][105] = 0,
[0][0][1][0][RTW89_WW][0][107] = 24,
[0][0][1][0][RTW89_WW][1][107] = 24,
- [0][0][1][0][RTW89_WW][2][107] = 0,
[0][0][1][0][RTW89_WW][0][109] = 24,
[0][0][1][0][RTW89_WW][1][109] = 24,
- [0][0][1][0][RTW89_WW][2][109] = 0,
[0][0][1][0][RTW89_WW][0][111] = 0,
[0][0][1][0][RTW89_WW][1][111] = 0,
- [0][0][1][0][RTW89_WW][2][111] = 0,
[0][0][1][0][RTW89_WW][0][113] = 0,
[0][0][1][0][RTW89_WW][1][113] = 0,
- [0][0][1][0][RTW89_WW][2][113] = 0,
[0][0][1][0][RTW89_WW][0][115] = 0,
[0][0][1][0][RTW89_WW][1][115] = 0,
- [0][0][1][0][RTW89_WW][2][115] = 0,
[0][0][1][0][RTW89_WW][0][117] = 0,
[0][0][1][0][RTW89_WW][1][117] = 0,
- [0][0][1][0][RTW89_WW][2][117] = 0,
[0][0][1][0][RTW89_WW][0][119] = 0,
[0][0][1][0][RTW89_WW][1][119] = 0,
- [0][0][1][0][RTW89_WW][2][119] = 0,
[0][1][1][0][RTW89_WW][0][0] = -2,
[0][1][1][0][RTW89_WW][1][0] = -2,
- [0][1][1][0][RTW89_WW][2][0] = 54,
[0][1][1][0][RTW89_WW][0][2] = -4,
[0][1][1][0][RTW89_WW][1][2] = -4,
- [0][1][1][0][RTW89_WW][2][2] = 54,
[0][1][1][0][RTW89_WW][0][4] = -4,
[0][1][1][0][RTW89_WW][1][4] = -4,
- [0][1][1][0][RTW89_WW][2][4] = 54,
[0][1][1][0][RTW89_WW][0][6] = -4,
[0][1][1][0][RTW89_WW][1][6] = -4,
- [0][1][1][0][RTW89_WW][2][6] = 54,
[0][1][1][0][RTW89_WW][0][8] = -4,
[0][1][1][0][RTW89_WW][1][8] = -4,
- [0][1][1][0][RTW89_WW][2][8] = 54,
[0][1][1][0][RTW89_WW][0][10] = -4,
[0][1][1][0][RTW89_WW][1][10] = -4,
- [0][1][1][0][RTW89_WW][2][10] = 54,
[0][1][1][0][RTW89_WW][0][12] = -4,
[0][1][1][0][RTW89_WW][1][12] = -4,
- [0][1][1][0][RTW89_WW][2][12] = 54,
[0][1][1][0][RTW89_WW][0][14] = -4,
[0][1][1][0][RTW89_WW][1][14] = -4,
- [0][1][1][0][RTW89_WW][2][14] = 54,
[0][1][1][0][RTW89_WW][0][15] = -4,
[0][1][1][0][RTW89_WW][1][15] = -4,
- [0][1][1][0][RTW89_WW][2][15] = 54,
[0][1][1][0][RTW89_WW][0][17] = -4,
[0][1][1][0][RTW89_WW][1][17] = -4,
- [0][1][1][0][RTW89_WW][2][17] = 54,
[0][1][1][0][RTW89_WW][0][19] = -4,
[0][1][1][0][RTW89_WW][1][19] = -4,
- [0][1][1][0][RTW89_WW][2][19] = 54,
[0][1][1][0][RTW89_WW][0][21] = -4,
[0][1][1][0][RTW89_WW][1][21] = -4,
- [0][1][1][0][RTW89_WW][2][21] = 54,
[0][1][1][0][RTW89_WW][0][23] = -4,
[0][1][1][0][RTW89_WW][1][23] = -4,
- [0][1][1][0][RTW89_WW][2][23] = 68,
[0][1][1][0][RTW89_WW][0][25] = -4,
[0][1][1][0][RTW89_WW][1][25] = -4,
- [0][1][1][0][RTW89_WW][2][25] = 68,
[0][1][1][0][RTW89_WW][0][27] = -4,
[0][1][1][0][RTW89_WW][1][27] = -4,
- [0][1][1][0][RTW89_WW][2][27] = 68,
[0][1][1][0][RTW89_WW][0][29] = -4,
[0][1][1][0][RTW89_WW][1][29] = -4,
- [0][1][1][0][RTW89_WW][2][29] = 68,
[0][1][1][0][RTW89_WW][0][30] = -4,
[0][1][1][0][RTW89_WW][1][30] = -4,
- [0][1][1][0][RTW89_WW][2][30] = 68,
[0][1][1][0][RTW89_WW][0][32] = -4,
[0][1][1][0][RTW89_WW][1][32] = -4,
- [0][1][1][0][RTW89_WW][2][32] = 68,
[0][1][1][0][RTW89_WW][0][34] = -4,
[0][1][1][0][RTW89_WW][1][34] = -4,
- [0][1][1][0][RTW89_WW][2][34] = 68,
[0][1][1][0][RTW89_WW][0][36] = -4,
[0][1][1][0][RTW89_WW][1][36] = -4,
- [0][1][1][0][RTW89_WW][2][36] = 68,
[0][1][1][0][RTW89_WW][0][38] = -4,
[0][1][1][0][RTW89_WW][1][38] = -4,
- [0][1][1][0][RTW89_WW][2][38] = 68,
[0][1][1][0][RTW89_WW][0][40] = -4,
[0][1][1][0][RTW89_WW][1][40] = -4,
- [0][1][1][0][RTW89_WW][2][40] = 68,
[0][1][1][0][RTW89_WW][0][42] = -4,
[0][1][1][0][RTW89_WW][1][42] = -4,
- [0][1][1][0][RTW89_WW][2][42] = 68,
[0][1][1][0][RTW89_WW][0][44] = -2,
[0][1][1][0][RTW89_WW][1][44] = -2,
- [0][1][1][0][RTW89_WW][2][44] = 68,
[0][1][1][0][RTW89_WW][0][45] = -2,
[0][1][1][0][RTW89_WW][1][45] = -2,
- [0][1][1][0][RTW89_WW][2][45] = 70,
[0][1][1][0][RTW89_WW][0][47] = -2,
[0][1][1][0][RTW89_WW][1][47] = -2,
- [0][1][1][0][RTW89_WW][2][47] = 68,
[0][1][1][0][RTW89_WW][0][49] = -2,
[0][1][1][0][RTW89_WW][1][49] = -2,
- [0][1][1][0][RTW89_WW][2][49] = 68,
[0][1][1][0][RTW89_WW][0][51] = -2,
[0][1][1][0][RTW89_WW][1][51] = -2,
- [0][1][1][0][RTW89_WW][2][51] = 68,
[0][1][1][0][RTW89_WW][0][53] = -2,
[0][1][1][0][RTW89_WW][1][53] = -2,
- [0][1][1][0][RTW89_WW][2][53] = 68,
[0][1][1][0][RTW89_WW][0][55] = -2,
[0][1][1][0][RTW89_WW][1][55] = -2,
- [0][1][1][0][RTW89_WW][2][55] = 68,
[0][1][1][0][RTW89_WW][0][57] = -2,
[0][1][1][0][RTW89_WW][1][57] = -2,
- [0][1][1][0][RTW89_WW][2][57] = 68,
[0][1][1][0][RTW89_WW][0][59] = -2,
[0][1][1][0][RTW89_WW][1][59] = -2,
- [0][1][1][0][RTW89_WW][2][59] = 68,
[0][1][1][0][RTW89_WW][0][60] = -2,
[0][1][1][0][RTW89_WW][1][60] = -2,
- [0][1][1][0][RTW89_WW][2][60] = 68,
[0][1][1][0][RTW89_WW][0][62] = -2,
[0][1][1][0][RTW89_WW][1][62] = -2,
- [0][1][1][0][RTW89_WW][2][62] = 68,
[0][1][1][0][RTW89_WW][0][64] = -2,
[0][1][1][0][RTW89_WW][1][64] = -2,
- [0][1][1][0][RTW89_WW][2][64] = 68,
[0][1][1][0][RTW89_WW][0][66] = -2,
[0][1][1][0][RTW89_WW][1][66] = -2,
- [0][1][1][0][RTW89_WW][2][66] = 68,
[0][1][1][0][RTW89_WW][0][68] = -2,
[0][1][1][0][RTW89_WW][1][68] = -2,
- [0][1][1][0][RTW89_WW][2][68] = 68,
[0][1][1][0][RTW89_WW][0][70] = -2,
[0][1][1][0][RTW89_WW][1][70] = -2,
- [0][1][1][0][RTW89_WW][2][70] = 68,
[0][1][1][0][RTW89_WW][0][72] = -2,
[0][1][1][0][RTW89_WW][1][72] = -2,
- [0][1][1][0][RTW89_WW][2][72] = 68,
[0][1][1][0][RTW89_WW][0][74] = -2,
[0][1][1][0][RTW89_WW][1][74] = -2,
- [0][1][1][0][RTW89_WW][2][74] = 68,
[0][1][1][0][RTW89_WW][0][75] = -2,
[0][1][1][0][RTW89_WW][1][75] = -2,
- [0][1][1][0][RTW89_WW][2][75] = 68,
[0][1][1][0][RTW89_WW][0][77] = -2,
[0][1][1][0][RTW89_WW][1][77] = -2,
- [0][1][1][0][RTW89_WW][2][77] = 68,
[0][1][1][0][RTW89_WW][0][79] = -2,
[0][1][1][0][RTW89_WW][1][79] = -2,
- [0][1][1][0][RTW89_WW][2][79] = 68,
[0][1][1][0][RTW89_WW][0][81] = -2,
[0][1][1][0][RTW89_WW][1][81] = -2,
- [0][1][1][0][RTW89_WW][2][81] = 68,
[0][1][1][0][RTW89_WW][0][83] = -2,
[0][1][1][0][RTW89_WW][1][83] = -2,
- [0][1][1][0][RTW89_WW][2][83] = 68,
[0][1][1][0][RTW89_WW][0][85] = -2,
[0][1][1][0][RTW89_WW][1][85] = -2,
- [0][1][1][0][RTW89_WW][2][85] = 68,
[0][1][1][0][RTW89_WW][0][87] = -2,
[0][1][1][0][RTW89_WW][1][87] = -2,
- [0][1][1][0][RTW89_WW][2][87] = 0,
[0][1][1][0][RTW89_WW][0][89] = -2,
[0][1][1][0][RTW89_WW][1][89] = -2,
- [0][1][1][0][RTW89_WW][2][89] = 0,
[0][1][1][0][RTW89_WW][0][90] = -2,
[0][1][1][0][RTW89_WW][1][90] = -2,
- [0][1][1][0][RTW89_WW][2][90] = 0,
[0][1][1][0][RTW89_WW][0][92] = -2,
[0][1][1][0][RTW89_WW][1][92] = -2,
- [0][1][1][0][RTW89_WW][2][92] = 0,
[0][1][1][0][RTW89_WW][0][94] = -2,
[0][1][1][0][RTW89_WW][1][94] = -2,
- [0][1][1][0][RTW89_WW][2][94] = 0,
[0][1][1][0][RTW89_WW][0][96] = -2,
[0][1][1][0][RTW89_WW][1][96] = -2,
- [0][1][1][0][RTW89_WW][2][96] = 0,
[0][1][1][0][RTW89_WW][0][98] = -2,
[0][1][1][0][RTW89_WW][1][98] = -2,
- [0][1][1][0][RTW89_WW][2][98] = 0,
[0][1][1][0][RTW89_WW][0][100] = -2,
[0][1][1][0][RTW89_WW][1][100] = -2,
- [0][1][1][0][RTW89_WW][2][100] = 0,
[0][1][1][0][RTW89_WW][0][102] = -2,
[0][1][1][0][RTW89_WW][1][102] = -2,
- [0][1][1][0][RTW89_WW][2][102] = 0,
[0][1][1][0][RTW89_WW][0][104] = -2,
[0][1][1][0][RTW89_WW][1][104] = -2,
- [0][1][1][0][RTW89_WW][2][104] = 0,
[0][1][1][0][RTW89_WW][0][105] = -2,
[0][1][1][0][RTW89_WW][1][105] = -2,
- [0][1][1][0][RTW89_WW][2][105] = 0,
[0][1][1][0][RTW89_WW][0][107] = 1,
[0][1][1][0][RTW89_WW][1][107] = 1,
- [0][1][1][0][RTW89_WW][2][107] = 0,
[0][1][1][0][RTW89_WW][0][109] = 1,
[0][1][1][0][RTW89_WW][1][109] = 1,
- [0][1][1][0][RTW89_WW][2][109] = 0,
[0][1][1][0][RTW89_WW][0][111] = 0,
[0][1][1][0][RTW89_WW][1][111] = 0,
- [0][1][1][0][RTW89_WW][2][111] = 0,
[0][1][1][0][RTW89_WW][0][113] = 0,
[0][1][1][0][RTW89_WW][1][113] = 0,
- [0][1][1][0][RTW89_WW][2][113] = 0,
[0][1][1][0][RTW89_WW][0][115] = 0,
[0][1][1][0][RTW89_WW][1][115] = 0,
- [0][1][1][0][RTW89_WW][2][115] = 0,
[0][1][1][0][RTW89_WW][0][117] = 0,
[0][1][1][0][RTW89_WW][1][117] = 0,
- [0][1][1][0][RTW89_WW][2][117] = 0,
[0][1][1][0][RTW89_WW][0][119] = 0,
[0][1][1][0][RTW89_WW][1][119] = 0,
- [0][1][1][0][RTW89_WW][2][119] = 0,
[0][0][2][0][RTW89_WW][0][0] = 24,
[0][0][2][0][RTW89_WW][1][0] = 24,
- [0][0][2][0][RTW89_WW][2][0] = 56,
[0][0][2][0][RTW89_WW][0][2] = 22,
[0][0][2][0][RTW89_WW][1][2] = 22,
- [0][0][2][0][RTW89_WW][2][2] = 56,
[0][0][2][0][RTW89_WW][0][4] = 22,
[0][0][2][0][RTW89_WW][1][4] = 22,
- [0][0][2][0][RTW89_WW][2][4] = 56,
[0][0][2][0][RTW89_WW][0][6] = 22,
[0][0][2][0][RTW89_WW][1][6] = 22,
- [0][0][2][0][RTW89_WW][2][6] = 56,
[0][0][2][0][RTW89_WW][0][8] = 22,
[0][0][2][0][RTW89_WW][1][8] = 22,
- [0][0][2][0][RTW89_WW][2][8] = 56,
[0][0][2][0][RTW89_WW][0][10] = 22,
[0][0][2][0][RTW89_WW][1][10] = 22,
- [0][0][2][0][RTW89_WW][2][10] = 56,
[0][0][2][0][RTW89_WW][0][12] = 22,
[0][0][2][0][RTW89_WW][1][12] = 22,
- [0][0][2][0][RTW89_WW][2][12] = 56,
[0][0][2][0][RTW89_WW][0][14] = 22,
[0][0][2][0][RTW89_WW][1][14] = 22,
- [0][0][2][0][RTW89_WW][2][14] = 56,
[0][0][2][0][RTW89_WW][0][15] = 22,
[0][0][2][0][RTW89_WW][1][15] = 22,
- [0][0][2][0][RTW89_WW][2][15] = 56,
[0][0][2][0][RTW89_WW][0][17] = 22,
[0][0][2][0][RTW89_WW][1][17] = 22,
- [0][0][2][0][RTW89_WW][2][17] = 56,
[0][0][2][0][RTW89_WW][0][19] = 22,
[0][0][2][0][RTW89_WW][1][19] = 22,
- [0][0][2][0][RTW89_WW][2][19] = 56,
[0][0][2][0][RTW89_WW][0][21] = 22,
[0][0][2][0][RTW89_WW][1][21] = 22,
- [0][0][2][0][RTW89_WW][2][21] = 56,
[0][0][2][0][RTW89_WW][0][23] = 22,
[0][0][2][0][RTW89_WW][1][23] = 22,
- [0][0][2][0][RTW89_WW][2][23] = 70,
[0][0][2][0][RTW89_WW][0][25] = 22,
[0][0][2][0][RTW89_WW][1][25] = 22,
- [0][0][2][0][RTW89_WW][2][25] = 70,
[0][0][2][0][RTW89_WW][0][27] = 22,
[0][0][2][0][RTW89_WW][1][27] = 22,
- [0][0][2][0][RTW89_WW][2][27] = 70,
[0][0][2][0][RTW89_WW][0][29] = 22,
[0][0][2][0][RTW89_WW][1][29] = 22,
- [0][0][2][0][RTW89_WW][2][29] = 70,
[0][0][2][0][RTW89_WW][0][30] = 22,
[0][0][2][0][RTW89_WW][1][30] = 22,
- [0][0][2][0][RTW89_WW][2][30] = 70,
[0][0][2][0][RTW89_WW][0][32] = 22,
[0][0][2][0][RTW89_WW][1][32] = 22,
- [0][0][2][0][RTW89_WW][2][32] = 70,
[0][0][2][0][RTW89_WW][0][34] = 22,
[0][0][2][0][RTW89_WW][1][34] = 22,
- [0][0][2][0][RTW89_WW][2][34] = 70,
[0][0][2][0][RTW89_WW][0][36] = 22,
[0][0][2][0][RTW89_WW][1][36] = 22,
- [0][0][2][0][RTW89_WW][2][36] = 70,
[0][0][2][0][RTW89_WW][0][38] = 22,
[0][0][2][0][RTW89_WW][1][38] = 22,
- [0][0][2][0][RTW89_WW][2][38] = 70,
[0][0][2][0][RTW89_WW][0][40] = 22,
[0][0][2][0][RTW89_WW][1][40] = 22,
- [0][0][2][0][RTW89_WW][2][40] = 70,
[0][0][2][0][RTW89_WW][0][42] = 22,
[0][0][2][0][RTW89_WW][1][42] = 22,
- [0][0][2][0][RTW89_WW][2][42] = 70,
[0][0][2][0][RTW89_WW][0][44] = 22,
[0][0][2][0][RTW89_WW][1][44] = 22,
- [0][0][2][0][RTW89_WW][2][44] = 70,
[0][0][2][0][RTW89_WW][0][45] = 22,
[0][0][2][0][RTW89_WW][1][45] = 22,
- [0][0][2][0][RTW89_WW][2][45] = 70,
[0][0][2][0][RTW89_WW][0][47] = 22,
[0][0][2][0][RTW89_WW][1][47] = 22,
- [0][0][2][0][RTW89_WW][2][47] = 70,
[0][0][2][0][RTW89_WW][0][49] = 24,
[0][0][2][0][RTW89_WW][1][49] = 24,
- [0][0][2][0][RTW89_WW][2][49] = 70,
[0][0][2][0][RTW89_WW][0][51] = 22,
[0][0][2][0][RTW89_WW][1][51] = 22,
- [0][0][2][0][RTW89_WW][2][51] = 70,
[0][0][2][0][RTW89_WW][0][53] = 22,
[0][0][2][0][RTW89_WW][1][53] = 22,
- [0][0][2][0][RTW89_WW][2][53] = 70,
[0][0][2][0][RTW89_WW][0][55] = 22,
[0][0][2][0][RTW89_WW][1][55] = 22,
- [0][0][2][0][RTW89_WW][2][55] = 68,
[0][0][2][0][RTW89_WW][0][57] = 22,
[0][0][2][0][RTW89_WW][1][57] = 22,
- [0][0][2][0][RTW89_WW][2][57] = 68,
[0][0][2][0][RTW89_WW][0][59] = 22,
[0][0][2][0][RTW89_WW][1][59] = 22,
- [0][0][2][0][RTW89_WW][2][59] = 68,
[0][0][2][0][RTW89_WW][0][60] = 22,
[0][0][2][0][RTW89_WW][1][60] = 22,
- [0][0][2][0][RTW89_WW][2][60] = 68,
[0][0][2][0][RTW89_WW][0][62] = 22,
[0][0][2][0][RTW89_WW][1][62] = 22,
- [0][0][2][0][RTW89_WW][2][62] = 68,
[0][0][2][0][RTW89_WW][0][64] = 22,
[0][0][2][0][RTW89_WW][1][64] = 22,
- [0][0][2][0][RTW89_WW][2][64] = 68,
[0][0][2][0][RTW89_WW][0][66] = 22,
[0][0][2][0][RTW89_WW][1][66] = 22,
- [0][0][2][0][RTW89_WW][2][66] = 68,
[0][0][2][0][RTW89_WW][0][68] = 22,
[0][0][2][0][RTW89_WW][1][68] = 22,
- [0][0][2][0][RTW89_WW][2][68] = 68,
[0][0][2][0][RTW89_WW][0][70] = 24,
[0][0][2][0][RTW89_WW][1][70] = 24,
- [0][0][2][0][RTW89_WW][2][70] = 68,
[0][0][2][0][RTW89_WW][0][72] = 22,
[0][0][2][0][RTW89_WW][1][72] = 22,
- [0][0][2][0][RTW89_WW][2][72] = 68,
[0][0][2][0][RTW89_WW][0][74] = 22,
[0][0][2][0][RTW89_WW][1][74] = 22,
- [0][0][2][0][RTW89_WW][2][74] = 68,
[0][0][2][0][RTW89_WW][0][75] = 22,
[0][0][2][0][RTW89_WW][1][75] = 22,
- [0][0][2][0][RTW89_WW][2][75] = 68,
[0][0][2][0][RTW89_WW][0][77] = 22,
[0][0][2][0][RTW89_WW][1][77] = 22,
- [0][0][2][0][RTW89_WW][2][77] = 68,
[0][0][2][0][RTW89_WW][0][79] = 22,
[0][0][2][0][RTW89_WW][1][79] = 22,
- [0][0][2][0][RTW89_WW][2][79] = 68,
[0][0][2][0][RTW89_WW][0][81] = 22,
[0][0][2][0][RTW89_WW][1][81] = 22,
- [0][0][2][0][RTW89_WW][2][81] = 68,
[0][0][2][0][RTW89_WW][0][83] = 22,
[0][0][2][0][RTW89_WW][1][83] = 22,
- [0][0][2][0][RTW89_WW][2][83] = 68,
[0][0][2][0][RTW89_WW][0][85] = 22,
[0][0][2][0][RTW89_WW][1][85] = 22,
- [0][0][2][0][RTW89_WW][2][85] = 68,
[0][0][2][0][RTW89_WW][0][87] = 22,
[0][0][2][0][RTW89_WW][1][87] = 22,
- [0][0][2][0][RTW89_WW][2][87] = 0,
[0][0][2][0][RTW89_WW][0][89] = 22,
[0][0][2][0][RTW89_WW][1][89] = 22,
- [0][0][2][0][RTW89_WW][2][89] = 0,
[0][0][2][0][RTW89_WW][0][90] = 22,
[0][0][2][0][RTW89_WW][1][90] = 22,
- [0][0][2][0][RTW89_WW][2][90] = 0,
[0][0][2][0][RTW89_WW][0][92] = 22,
[0][0][2][0][RTW89_WW][1][92] = 22,
- [0][0][2][0][RTW89_WW][2][92] = 0,
[0][0][2][0][RTW89_WW][0][94] = 22,
[0][0][2][0][RTW89_WW][1][94] = 22,
- [0][0][2][0][RTW89_WW][2][94] = 0,
[0][0][2][0][RTW89_WW][0][96] = 22,
[0][0][2][0][RTW89_WW][1][96] = 22,
- [0][0][2][0][RTW89_WW][2][96] = 0,
[0][0][2][0][RTW89_WW][0][98] = 22,
[0][0][2][0][RTW89_WW][1][98] = 22,
- [0][0][2][0][RTW89_WW][2][98] = 0,
[0][0][2][0][RTW89_WW][0][100] = 22,
[0][0][2][0][RTW89_WW][1][100] = 22,
- [0][0][2][0][RTW89_WW][2][100] = 0,
[0][0][2][0][RTW89_WW][0][102] = 22,
[0][0][2][0][RTW89_WW][1][102] = 22,
- [0][0][2][0][RTW89_WW][2][102] = 0,
[0][0][2][0][RTW89_WW][0][104] = 22,
[0][0][2][0][RTW89_WW][1][104] = 22,
- [0][0][2][0][RTW89_WW][2][104] = 0,
[0][0][2][0][RTW89_WW][0][105] = 22,
[0][0][2][0][RTW89_WW][1][105] = 22,
- [0][0][2][0][RTW89_WW][2][105] = 0,
[0][0][2][0][RTW89_WW][0][107] = 24,
[0][0][2][0][RTW89_WW][1][107] = 24,
- [0][0][2][0][RTW89_WW][2][107] = 0,
[0][0][2][0][RTW89_WW][0][109] = 24,
[0][0][2][0][RTW89_WW][1][109] = 24,
- [0][0][2][0][RTW89_WW][2][109] = 0,
[0][0][2][0][RTW89_WW][0][111] = 0,
[0][0][2][0][RTW89_WW][1][111] = 0,
- [0][0][2][0][RTW89_WW][2][111] = 0,
[0][0][2][0][RTW89_WW][0][113] = 0,
[0][0][2][0][RTW89_WW][1][113] = 0,
- [0][0][2][0][RTW89_WW][2][113] = 0,
[0][0][2][0][RTW89_WW][0][115] = 0,
[0][0][2][0][RTW89_WW][1][115] = 0,
- [0][0][2][0][RTW89_WW][2][115] = 0,
[0][0][2][0][RTW89_WW][0][117] = 0,
[0][0][2][0][RTW89_WW][1][117] = 0,
- [0][0][2][0][RTW89_WW][2][117] = 0,
[0][0][2][0][RTW89_WW][0][119] = 0,
[0][0][2][0][RTW89_WW][1][119] = 0,
- [0][0][2][0][RTW89_WW][2][119] = 0,
[0][1][2][0][RTW89_WW][0][0] = -2,
[0][1][2][0][RTW89_WW][1][0] = -2,
- [0][1][2][0][RTW89_WW][2][0] = 54,
[0][1][2][0][RTW89_WW][0][2] = -4,
[0][1][2][0][RTW89_WW][1][2] = -4,
- [0][1][2][0][RTW89_WW][2][2] = 54,
[0][1][2][0][RTW89_WW][0][4] = -4,
[0][1][2][0][RTW89_WW][1][4] = -4,
- [0][1][2][0][RTW89_WW][2][4] = 54,
[0][1][2][0][RTW89_WW][0][6] = -4,
[0][1][2][0][RTW89_WW][1][6] = -4,
- [0][1][2][0][RTW89_WW][2][6] = 54,
[0][1][2][0][RTW89_WW][0][8] = -4,
[0][1][2][0][RTW89_WW][1][8] = -4,
- [0][1][2][0][RTW89_WW][2][8] = 54,
[0][1][2][0][RTW89_WW][0][10] = -4,
[0][1][2][0][RTW89_WW][1][10] = -4,
- [0][1][2][0][RTW89_WW][2][10] = 54,
[0][1][2][0][RTW89_WW][0][12] = -4,
[0][1][2][0][RTW89_WW][1][12] = -4,
- [0][1][2][0][RTW89_WW][2][12] = 54,
[0][1][2][0][RTW89_WW][0][14] = -4,
[0][1][2][0][RTW89_WW][1][14] = -4,
- [0][1][2][0][RTW89_WW][2][14] = 54,
[0][1][2][0][RTW89_WW][0][15] = -4,
[0][1][2][0][RTW89_WW][1][15] = -4,
- [0][1][2][0][RTW89_WW][2][15] = 54,
[0][1][2][0][RTW89_WW][0][17] = -4,
[0][1][2][0][RTW89_WW][1][17] = -4,
- [0][1][2][0][RTW89_WW][2][17] = 54,
[0][1][2][0][RTW89_WW][0][19] = -4,
[0][1][2][0][RTW89_WW][1][19] = -4,
- [0][1][2][0][RTW89_WW][2][19] = 54,
[0][1][2][0][RTW89_WW][0][21] = -4,
[0][1][2][0][RTW89_WW][1][21] = -4,
- [0][1][2][0][RTW89_WW][2][21] = 54,
[0][1][2][0][RTW89_WW][0][23] = -4,
[0][1][2][0][RTW89_WW][1][23] = -4,
- [0][1][2][0][RTW89_WW][2][23] = 68,
[0][1][2][0][RTW89_WW][0][25] = -4,
[0][1][2][0][RTW89_WW][1][25] = -4,
- [0][1][2][0][RTW89_WW][2][25] = 68,
[0][1][2][0][RTW89_WW][0][27] = -4,
[0][1][2][0][RTW89_WW][1][27] = -4,
- [0][1][2][0][RTW89_WW][2][27] = 68,
[0][1][2][0][RTW89_WW][0][29] = -4,
[0][1][2][0][RTW89_WW][1][29] = -4,
- [0][1][2][0][RTW89_WW][2][29] = 68,
[0][1][2][0][RTW89_WW][0][30] = -4,
[0][1][2][0][RTW89_WW][1][30] = -4,
- [0][1][2][0][RTW89_WW][2][30] = 68,
[0][1][2][0][RTW89_WW][0][32] = -4,
[0][1][2][0][RTW89_WW][1][32] = -4,
- [0][1][2][0][RTW89_WW][2][32] = 68,
[0][1][2][0][RTW89_WW][0][34] = -4,
[0][1][2][0][RTW89_WW][1][34] = -4,
- [0][1][2][0][RTW89_WW][2][34] = 68,
[0][1][2][0][RTW89_WW][0][36] = -4,
[0][1][2][0][RTW89_WW][1][36] = -4,
- [0][1][2][0][RTW89_WW][2][36] = 68,
[0][1][2][0][RTW89_WW][0][38] = -4,
[0][1][2][0][RTW89_WW][1][38] = -4,
- [0][1][2][0][RTW89_WW][2][38] = 68,
[0][1][2][0][RTW89_WW][0][40] = -4,
[0][1][2][0][RTW89_WW][1][40] = -4,
- [0][1][2][0][RTW89_WW][2][40] = 68,
[0][1][2][0][RTW89_WW][0][42] = -4,
[0][1][2][0][RTW89_WW][1][42] = -4,
- [0][1][2][0][RTW89_WW][2][42] = 68,
[0][1][2][0][RTW89_WW][0][44] = -2,
[0][1][2][0][RTW89_WW][1][44] = -2,
- [0][1][2][0][RTW89_WW][2][44] = 68,
[0][1][2][0][RTW89_WW][0][45] = -2,
[0][1][2][0][RTW89_WW][1][45] = -2,
- [0][1][2][0][RTW89_WW][2][45] = 70,
[0][1][2][0][RTW89_WW][0][47] = -2,
[0][1][2][0][RTW89_WW][1][47] = -2,
- [0][1][2][0][RTW89_WW][2][47] = 68,
[0][1][2][0][RTW89_WW][0][49] = -2,
[0][1][2][0][RTW89_WW][1][49] = -2,
- [0][1][2][0][RTW89_WW][2][49] = 68,
[0][1][2][0][RTW89_WW][0][51] = -2,
[0][1][2][0][RTW89_WW][1][51] = -2,
- [0][1][2][0][RTW89_WW][2][51] = 68,
[0][1][2][0][RTW89_WW][0][53] = -2,
[0][1][2][0][RTW89_WW][1][53] = -2,
- [0][1][2][0][RTW89_WW][2][53] = 68,
[0][1][2][0][RTW89_WW][0][55] = -2,
[0][1][2][0][RTW89_WW][1][55] = -2,
- [0][1][2][0][RTW89_WW][2][55] = 68,
[0][1][2][0][RTW89_WW][0][57] = -2,
[0][1][2][0][RTW89_WW][1][57] = -2,
- [0][1][2][0][RTW89_WW][2][57] = 68,
[0][1][2][0][RTW89_WW][0][59] = -2,
[0][1][2][0][RTW89_WW][1][59] = -2,
- [0][1][2][0][RTW89_WW][2][59] = 68,
[0][1][2][0][RTW89_WW][0][60] = -2,
[0][1][2][0][RTW89_WW][1][60] = -2,
- [0][1][2][0][RTW89_WW][2][60] = 68,
[0][1][2][0][RTW89_WW][0][62] = -2,
[0][1][2][0][RTW89_WW][1][62] = -2,
- [0][1][2][0][RTW89_WW][2][62] = 68,
[0][1][2][0][RTW89_WW][0][64] = -2,
[0][1][2][0][RTW89_WW][1][64] = -2,
- [0][1][2][0][RTW89_WW][2][64] = 68,
[0][1][2][0][RTW89_WW][0][66] = -2,
[0][1][2][0][RTW89_WW][1][66] = -2,
- [0][1][2][0][RTW89_WW][2][66] = 68,
[0][1][2][0][RTW89_WW][0][68] = -2,
[0][1][2][0][RTW89_WW][1][68] = -2,
- [0][1][2][0][RTW89_WW][2][68] = 68,
[0][1][2][0][RTW89_WW][0][70] = -2,
[0][1][2][0][RTW89_WW][1][70] = -2,
- [0][1][2][0][RTW89_WW][2][70] = 68,
[0][1][2][0][RTW89_WW][0][72] = -2,
[0][1][2][0][RTW89_WW][1][72] = -2,
- [0][1][2][0][RTW89_WW][2][72] = 68,
[0][1][2][0][RTW89_WW][0][74] = -2,
[0][1][2][0][RTW89_WW][1][74] = -2,
- [0][1][2][0][RTW89_WW][2][74] = 68,
[0][1][2][0][RTW89_WW][0][75] = -2,
[0][1][2][0][RTW89_WW][1][75] = -2,
- [0][1][2][0][RTW89_WW][2][75] = 68,
[0][1][2][0][RTW89_WW][0][77] = -2,
[0][1][2][0][RTW89_WW][1][77] = -2,
- [0][1][2][0][RTW89_WW][2][77] = 68,
[0][1][2][0][RTW89_WW][0][79] = -2,
[0][1][2][0][RTW89_WW][1][79] = -2,
- [0][1][2][0][RTW89_WW][2][79] = 68,
[0][1][2][0][RTW89_WW][0][81] = -2,
[0][1][2][0][RTW89_WW][1][81] = -2,
- [0][1][2][0][RTW89_WW][2][81] = 68,
[0][1][2][0][RTW89_WW][0][83] = -2,
[0][1][2][0][RTW89_WW][1][83] = -2,
- [0][1][2][0][RTW89_WW][2][83] = 68,
[0][1][2][0][RTW89_WW][0][85] = -2,
[0][1][2][0][RTW89_WW][1][85] = -2,
- [0][1][2][0][RTW89_WW][2][85] = 68,
[0][1][2][0][RTW89_WW][0][87] = -2,
[0][1][2][0][RTW89_WW][1][87] = -2,
- [0][1][2][0][RTW89_WW][2][87] = 0,
[0][1][2][0][RTW89_WW][0][89] = -2,
[0][1][2][0][RTW89_WW][1][89] = -2,
- [0][1][2][0][RTW89_WW][2][89] = 0,
[0][1][2][0][RTW89_WW][0][90] = -2,
[0][1][2][0][RTW89_WW][1][90] = -2,
- [0][1][2][0][RTW89_WW][2][90] = 0,
[0][1][2][0][RTW89_WW][0][92] = -2,
[0][1][2][0][RTW89_WW][1][92] = -2,
- [0][1][2][0][RTW89_WW][2][92] = 0,
[0][1][2][0][RTW89_WW][0][94] = -2,
[0][1][2][0][RTW89_WW][1][94] = -2,
- [0][1][2][0][RTW89_WW][2][94] = 0,
[0][1][2][0][RTW89_WW][0][96] = -2,
[0][1][2][0][RTW89_WW][1][96] = -2,
- [0][1][2][0][RTW89_WW][2][96] = 0,
[0][1][2][0][RTW89_WW][0][98] = -2,
[0][1][2][0][RTW89_WW][1][98] = -2,
- [0][1][2][0][RTW89_WW][2][98] = 0,
[0][1][2][0][RTW89_WW][0][100] = -2,
[0][1][2][0][RTW89_WW][1][100] = -2,
- [0][1][2][0][RTW89_WW][2][100] = 0,
[0][1][2][0][RTW89_WW][0][102] = -2,
[0][1][2][0][RTW89_WW][1][102] = -2,
- [0][1][2][0][RTW89_WW][2][102] = 0,
[0][1][2][0][RTW89_WW][0][104] = -2,
[0][1][2][0][RTW89_WW][1][104] = -2,
- [0][1][2][0][RTW89_WW][2][104] = 0,
[0][1][2][0][RTW89_WW][0][105] = -2,
[0][1][2][0][RTW89_WW][1][105] = -2,
- [0][1][2][0][RTW89_WW][2][105] = 0,
[0][1][2][0][RTW89_WW][0][107] = 1,
[0][1][2][0][RTW89_WW][1][107] = 1,
- [0][1][2][0][RTW89_WW][2][107] = 0,
[0][1][2][0][RTW89_WW][0][109] = 1,
[0][1][2][0][RTW89_WW][1][109] = 1,
- [0][1][2][0][RTW89_WW][2][109] = 0,
[0][1][2][0][RTW89_WW][0][111] = 0,
[0][1][2][0][RTW89_WW][1][111] = 0,
- [0][1][2][0][RTW89_WW][2][111] = 0,
[0][1][2][0][RTW89_WW][0][113] = 0,
[0][1][2][0][RTW89_WW][1][113] = 0,
- [0][1][2][0][RTW89_WW][2][113] = 0,
[0][1][2][0][RTW89_WW][0][115] = 0,
[0][1][2][0][RTW89_WW][1][115] = 0,
- [0][1][2][0][RTW89_WW][2][115] = 0,
[0][1][2][0][RTW89_WW][0][117] = 0,
[0][1][2][0][RTW89_WW][1][117] = 0,
- [0][1][2][0][RTW89_WW][2][117] = 0,
[0][1][2][0][RTW89_WW][0][119] = 0,
[0][1][2][0][RTW89_WW][1][119] = 0,
- [0][1][2][0][RTW89_WW][2][119] = 0,
[0][1][2][1][RTW89_WW][0][0] = -2,
[0][1][2][1][RTW89_WW][1][0] = -2,
- [0][1][2][1][RTW89_WW][2][0] = 54,
[0][1][2][1][RTW89_WW][0][2] = -4,
[0][1][2][1][RTW89_WW][1][2] = -4,
- [0][1][2][1][RTW89_WW][2][2] = 54,
[0][1][2][1][RTW89_WW][0][4] = -4,
[0][1][2][1][RTW89_WW][1][4] = -4,
- [0][1][2][1][RTW89_WW][2][4] = 54,
[0][1][2][1][RTW89_WW][0][6] = -4,
[0][1][2][1][RTW89_WW][1][6] = -4,
- [0][1][2][1][RTW89_WW][2][6] = 54,
[0][1][2][1][RTW89_WW][0][8] = -4,
[0][1][2][1][RTW89_WW][1][8] = -4,
- [0][1][2][1][RTW89_WW][2][8] = 54,
[0][1][2][1][RTW89_WW][0][10] = -4,
[0][1][2][1][RTW89_WW][1][10] = -4,
- [0][1][2][1][RTW89_WW][2][10] = 54,
[0][1][2][1][RTW89_WW][0][12] = -4,
[0][1][2][1][RTW89_WW][1][12] = -4,
- [0][1][2][1][RTW89_WW][2][12] = 54,
[0][1][2][1][RTW89_WW][0][14] = -4,
[0][1][2][1][RTW89_WW][1][14] = -4,
- [0][1][2][1][RTW89_WW][2][14] = 54,
[0][1][2][1][RTW89_WW][0][15] = -4,
[0][1][2][1][RTW89_WW][1][15] = -4,
- [0][1][2][1][RTW89_WW][2][15] = 54,
[0][1][2][1][RTW89_WW][0][17] = -4,
[0][1][2][1][RTW89_WW][1][17] = -4,
- [0][1][2][1][RTW89_WW][2][17] = 54,
[0][1][2][1][RTW89_WW][0][19] = -4,
[0][1][2][1][RTW89_WW][1][19] = -4,
- [0][1][2][1][RTW89_WW][2][19] = 54,
[0][1][2][1][RTW89_WW][0][21] = -4,
[0][1][2][1][RTW89_WW][1][21] = -4,
- [0][1][2][1][RTW89_WW][2][21] = 54,
[0][1][2][1][RTW89_WW][0][23] = -4,
[0][1][2][1][RTW89_WW][1][23] = -4,
- [0][1][2][1][RTW89_WW][2][23] = 68,
[0][1][2][1][RTW89_WW][0][25] = -4,
[0][1][2][1][RTW89_WW][1][25] = -4,
- [0][1][2][1][RTW89_WW][2][25] = 68,
[0][1][2][1][RTW89_WW][0][27] = -4,
[0][1][2][1][RTW89_WW][1][27] = -4,
- [0][1][2][1][RTW89_WW][2][27] = 68,
[0][1][2][1][RTW89_WW][0][29] = -4,
[0][1][2][1][RTW89_WW][1][29] = -4,
- [0][1][2][1][RTW89_WW][2][29] = 68,
[0][1][2][1][RTW89_WW][0][30] = -4,
[0][1][2][1][RTW89_WW][1][30] = -4,
- [0][1][2][1][RTW89_WW][2][30] = 68,
[0][1][2][1][RTW89_WW][0][32] = -4,
[0][1][2][1][RTW89_WW][1][32] = -4,
- [0][1][2][1][RTW89_WW][2][32] = 68,
[0][1][2][1][RTW89_WW][0][34] = -4,
[0][1][2][1][RTW89_WW][1][34] = -4,
- [0][1][2][1][RTW89_WW][2][34] = 68,
[0][1][2][1][RTW89_WW][0][36] = -4,
[0][1][2][1][RTW89_WW][1][36] = -4,
- [0][1][2][1][RTW89_WW][2][36] = 68,
[0][1][2][1][RTW89_WW][0][38] = -4,
[0][1][2][1][RTW89_WW][1][38] = -4,
- [0][1][2][1][RTW89_WW][2][38] = 68,
[0][1][2][1][RTW89_WW][0][40] = -4,
[0][1][2][1][RTW89_WW][1][40] = -4,
- [0][1][2][1][RTW89_WW][2][40] = 68,
[0][1][2][1][RTW89_WW][0][42] = -4,
[0][1][2][1][RTW89_WW][1][42] = -4,
- [0][1][2][1][RTW89_WW][2][42] = 68,
[0][1][2][1][RTW89_WW][0][44] = -2,
[0][1][2][1][RTW89_WW][1][44] = -2,
- [0][1][2][1][RTW89_WW][2][44] = 68,
[0][1][2][1][RTW89_WW][0][45] = -2,
[0][1][2][1][RTW89_WW][1][45] = -2,
- [0][1][2][1][RTW89_WW][2][45] = 70,
[0][1][2][1][RTW89_WW][0][47] = -2,
[0][1][2][1][RTW89_WW][1][47] = -2,
- [0][1][2][1][RTW89_WW][2][47] = 68,
[0][1][2][1][RTW89_WW][0][49] = -2,
[0][1][2][1][RTW89_WW][1][49] = -2,
- [0][1][2][1][RTW89_WW][2][49] = 68,
[0][1][2][1][RTW89_WW][0][51] = -2,
[0][1][2][1][RTW89_WW][1][51] = -2,
- [0][1][2][1][RTW89_WW][2][51] = 68,
[0][1][2][1][RTW89_WW][0][53] = -2,
[0][1][2][1][RTW89_WW][1][53] = -2,
- [0][1][2][1][RTW89_WW][2][53] = 68,
[0][1][2][1][RTW89_WW][0][55] = -2,
[0][1][2][1][RTW89_WW][1][55] = -2,
- [0][1][2][1][RTW89_WW][2][55] = 68,
[0][1][2][1][RTW89_WW][0][57] = -2,
[0][1][2][1][RTW89_WW][1][57] = -2,
- [0][1][2][1][RTW89_WW][2][57] = 68,
[0][1][2][1][RTW89_WW][0][59] = -2,
[0][1][2][1][RTW89_WW][1][59] = -2,
- [0][1][2][1][RTW89_WW][2][59] = 68,
[0][1][2][1][RTW89_WW][0][60] = -2,
[0][1][2][1][RTW89_WW][1][60] = -2,
- [0][1][2][1][RTW89_WW][2][60] = 68,
[0][1][2][1][RTW89_WW][0][62] = -2,
[0][1][2][1][RTW89_WW][1][62] = -2,
- [0][1][2][1][RTW89_WW][2][62] = 68,
[0][1][2][1][RTW89_WW][0][64] = -2,
[0][1][2][1][RTW89_WW][1][64] = -2,
- [0][1][2][1][RTW89_WW][2][64] = 68,
[0][1][2][1][RTW89_WW][0][66] = -2,
[0][1][2][1][RTW89_WW][1][66] = -2,
- [0][1][2][1][RTW89_WW][2][66] = 68,
[0][1][2][1][RTW89_WW][0][68] = -2,
[0][1][2][1][RTW89_WW][1][68] = -2,
- [0][1][2][1][RTW89_WW][2][68] = 68,
[0][1][2][1][RTW89_WW][0][70] = -2,
[0][1][2][1][RTW89_WW][1][70] = -2,
- [0][1][2][1][RTW89_WW][2][70] = 68,
[0][1][2][1][RTW89_WW][0][72] = -2,
[0][1][2][1][RTW89_WW][1][72] = -2,
- [0][1][2][1][RTW89_WW][2][72] = 68,
[0][1][2][1][RTW89_WW][0][74] = -2,
[0][1][2][1][RTW89_WW][1][74] = -2,
- [0][1][2][1][RTW89_WW][2][74] = 68,
[0][1][2][1][RTW89_WW][0][75] = -2,
[0][1][2][1][RTW89_WW][1][75] = -2,
- [0][1][2][1][RTW89_WW][2][75] = 68,
[0][1][2][1][RTW89_WW][0][77] = -2,
[0][1][2][1][RTW89_WW][1][77] = -2,
- [0][1][2][1][RTW89_WW][2][77] = 68,
[0][1][2][1][RTW89_WW][0][79] = -2,
[0][1][2][1][RTW89_WW][1][79] = -2,
- [0][1][2][1][RTW89_WW][2][79] = 68,
[0][1][2][1][RTW89_WW][0][81] = -2,
[0][1][2][1][RTW89_WW][1][81] = -2,
- [0][1][2][1][RTW89_WW][2][81] = 68,
[0][1][2][1][RTW89_WW][0][83] = -2,
[0][1][2][1][RTW89_WW][1][83] = -2,
- [0][1][2][1][RTW89_WW][2][83] = 68,
[0][1][2][1][RTW89_WW][0][85] = -2,
[0][1][2][1][RTW89_WW][1][85] = -2,
- [0][1][2][1][RTW89_WW][2][85] = 68,
[0][1][2][1][RTW89_WW][0][87] = -2,
[0][1][2][1][RTW89_WW][1][87] = -2,
- [0][1][2][1][RTW89_WW][2][87] = 0,
[0][1][2][1][RTW89_WW][0][89] = -2,
[0][1][2][1][RTW89_WW][1][89] = -2,
- [0][1][2][1][RTW89_WW][2][89] = 0,
[0][1][2][1][RTW89_WW][0][90] = -2,
[0][1][2][1][RTW89_WW][1][90] = -2,
- [0][1][2][1][RTW89_WW][2][90] = 0,
[0][1][2][1][RTW89_WW][0][92] = -2,
[0][1][2][1][RTW89_WW][1][92] = -2,
- [0][1][2][1][RTW89_WW][2][92] = 0,
[0][1][2][1][RTW89_WW][0][94] = -2,
[0][1][2][1][RTW89_WW][1][94] = -2,
- [0][1][2][1][RTW89_WW][2][94] = 0,
[0][1][2][1][RTW89_WW][0][96] = -2,
[0][1][2][1][RTW89_WW][1][96] = -2,
- [0][1][2][1][RTW89_WW][2][96] = 0,
[0][1][2][1][RTW89_WW][0][98] = -2,
[0][1][2][1][RTW89_WW][1][98] = -2,
- [0][1][2][1][RTW89_WW][2][98] = 0,
[0][1][2][1][RTW89_WW][0][100] = -2,
[0][1][2][1][RTW89_WW][1][100] = -2,
- [0][1][2][1][RTW89_WW][2][100] = 0,
[0][1][2][1][RTW89_WW][0][102] = -2,
[0][1][2][1][RTW89_WW][1][102] = -2,
- [0][1][2][1][RTW89_WW][2][102] = 0,
[0][1][2][1][RTW89_WW][0][104] = -2,
[0][1][2][1][RTW89_WW][1][104] = -2,
- [0][1][2][1][RTW89_WW][2][104] = 0,
[0][1][2][1][RTW89_WW][0][105] = -2,
[0][1][2][1][RTW89_WW][1][105] = -2,
- [0][1][2][1][RTW89_WW][2][105] = 0,
[0][1][2][1][RTW89_WW][0][107] = 1,
[0][1][2][1][RTW89_WW][1][107] = 1,
- [0][1][2][1][RTW89_WW][2][107] = 0,
[0][1][2][1][RTW89_WW][0][109] = 1,
[0][1][2][1][RTW89_WW][1][109] = 1,
- [0][1][2][1][RTW89_WW][2][109] = 0,
[0][1][2][1][RTW89_WW][0][111] = 0,
[0][1][2][1][RTW89_WW][1][111] = 0,
- [0][1][2][1][RTW89_WW][2][111] = 0,
[0][1][2][1][RTW89_WW][0][113] = 0,
[0][1][2][1][RTW89_WW][1][113] = 0,
- [0][1][2][1][RTW89_WW][2][113] = 0,
[0][1][2][1][RTW89_WW][0][115] = 0,
[0][1][2][1][RTW89_WW][1][115] = 0,
- [0][1][2][1][RTW89_WW][2][115] = 0,
[0][1][2][1][RTW89_WW][0][117] = 0,
[0][1][2][1][RTW89_WW][1][117] = 0,
- [0][1][2][1][RTW89_WW][2][117] = 0,
[0][1][2][1][RTW89_WW][0][119] = 0,
[0][1][2][1][RTW89_WW][1][119] = 0,
- [0][1][2][1][RTW89_WW][2][119] = 0,
[1][0][2][0][RTW89_WW][0][1] = 24,
[1][0][2][0][RTW89_WW][1][1] = 34,
- [1][0][2][0][RTW89_WW][2][1] = 70,
[1][0][2][0][RTW89_WW][0][5] = 24,
[1][0][2][0][RTW89_WW][1][5] = 34,
- [1][0][2][0][RTW89_WW][2][5] = 70,
[1][0][2][0][RTW89_WW][0][9] = 24,
[1][0][2][0][RTW89_WW][1][9] = 34,
- [1][0][2][0][RTW89_WW][2][9] = 70,
[1][0][2][0][RTW89_WW][0][13] = 24,
[1][0][2][0][RTW89_WW][1][13] = 34,
- [1][0][2][0][RTW89_WW][2][13] = 70,
[1][0][2][0][RTW89_WW][0][16] = 24,
[1][0][2][0][RTW89_WW][1][16] = 34,
- [1][0][2][0][RTW89_WW][2][16] = 70,
[1][0][2][0][RTW89_WW][0][20] = 24,
[1][0][2][0][RTW89_WW][1][20] = 34,
- [1][0][2][0][RTW89_WW][2][20] = 70,
[1][0][2][0][RTW89_WW][0][24] = 26,
[1][0][2][0][RTW89_WW][1][24] = 36,
- [1][0][2][0][RTW89_WW][2][24] = 70,
[1][0][2][0][RTW89_WW][0][28] = 26,
[1][0][2][0][RTW89_WW][1][28] = 34,
- [1][0][2][0][RTW89_WW][2][28] = 70,
[1][0][2][0][RTW89_WW][0][31] = 26,
[1][0][2][0][RTW89_WW][1][31] = 34,
- [1][0][2][0][RTW89_WW][2][31] = 70,
[1][0][2][0][RTW89_WW][0][35] = 26,
[1][0][2][0][RTW89_WW][1][35] = 34,
- [1][0][2][0][RTW89_WW][2][35] = 70,
[1][0][2][0][RTW89_WW][0][39] = 26,
[1][0][2][0][RTW89_WW][1][39] = 34,
- [1][0][2][0][RTW89_WW][2][39] = 70,
[1][0][2][0][RTW89_WW][0][43] = 26,
[1][0][2][0][RTW89_WW][1][43] = 34,
- [1][0][2][0][RTW89_WW][2][43] = 70,
[1][0][2][0][RTW89_WW][0][46] = 34,
[1][0][2][0][RTW89_WW][1][46] = 34,
- [1][0][2][0][RTW89_WW][2][46] = 68,
[1][0][2][0][RTW89_WW][0][50] = 34,
[1][0][2][0][RTW89_WW][1][50] = 34,
- [1][0][2][0][RTW89_WW][2][50] = 68,
[1][0][2][0][RTW89_WW][0][54] = 36,
[1][0][2][0][RTW89_WW][1][54] = 36,
- [1][0][2][0][RTW89_WW][2][54] = 0,
[1][0][2][0][RTW89_WW][0][58] = 36,
[1][0][2][0][RTW89_WW][1][58] = 36,
- [1][0][2][0][RTW89_WW][2][58] = 66,
[1][0][2][0][RTW89_WW][0][61] = 34,
[1][0][2][0][RTW89_WW][1][61] = 34,
- [1][0][2][0][RTW89_WW][2][61] = 66,
[1][0][2][0][RTW89_WW][0][65] = 34,
[1][0][2][0][RTW89_WW][1][65] = 34,
- [1][0][2][0][RTW89_WW][2][65] = 66,
[1][0][2][0][RTW89_WW][0][69] = 34,
[1][0][2][0][RTW89_WW][1][69] = 34,
- [1][0][2][0][RTW89_WW][2][69] = 66,
[1][0][2][0][RTW89_WW][0][73] = 34,
[1][0][2][0][RTW89_WW][1][73] = 34,
- [1][0][2][0][RTW89_WW][2][73] = 66,
[1][0][2][0][RTW89_WW][0][76] = 34,
[1][0][2][0][RTW89_WW][1][76] = 34,
- [1][0][2][0][RTW89_WW][2][76] = 66,
[1][0][2][0][RTW89_WW][0][80] = 34,
[1][0][2][0][RTW89_WW][1][80] = 34,
- [1][0][2][0][RTW89_WW][2][80] = 66,
[1][0][2][0][RTW89_WW][0][84] = 34,
[1][0][2][0][RTW89_WW][1][84] = 34,
- [1][0][2][0][RTW89_WW][2][84] = 66,
[1][0][2][0][RTW89_WW][0][88] = 34,
[1][0][2][0][RTW89_WW][1][88] = 34,
- [1][0][2][0][RTW89_WW][2][88] = 0,
[1][0][2][0][RTW89_WW][0][91] = 36,
[1][0][2][0][RTW89_WW][1][91] = 36,
- [1][0][2][0][RTW89_WW][2][91] = 0,
[1][0][2][0][RTW89_WW][0][95] = 34,
[1][0][2][0][RTW89_WW][1][95] = 34,
- [1][0][2][0][RTW89_WW][2][95] = 0,
[1][0][2][0][RTW89_WW][0][99] = 34,
[1][0][2][0][RTW89_WW][1][99] = 34,
- [1][0][2][0][RTW89_WW][2][99] = 0,
[1][0][2][0][RTW89_WW][0][103] = 34,
[1][0][2][0][RTW89_WW][1][103] = 34,
- [1][0][2][0][RTW89_WW][2][103] = 0,
[1][0][2][0][RTW89_WW][0][106] = 36,
[1][0][2][0][RTW89_WW][1][106] = 36,
- [1][0][2][0][RTW89_WW][2][106] = 0,
[1][0][2][0][RTW89_WW][0][110] = 0,
[1][0][2][0][RTW89_WW][1][110] = 0,
- [1][0][2][0][RTW89_WW][2][110] = 0,
[1][0][2][0][RTW89_WW][0][114] = 0,
[1][0][2][0][RTW89_WW][1][114] = 0,
- [1][0][2][0][RTW89_WW][2][114] = 0,
[1][0][2][0][RTW89_WW][0][118] = 0,
[1][0][2][0][RTW89_WW][1][118] = 0,
- [1][0][2][0][RTW89_WW][2][118] = 0,
[1][1][2][0][RTW89_WW][0][1] = 10,
[1][1][2][0][RTW89_WW][1][1] = 10,
- [1][1][2][0][RTW89_WW][2][1] = 58,
[1][1][2][0][RTW89_WW][0][5] = 10,
[1][1][2][0][RTW89_WW][1][5] = 10,
- [1][1][2][0][RTW89_WW][2][5] = 58,
[1][1][2][0][RTW89_WW][0][9] = 10,
[1][1][2][0][RTW89_WW][1][9] = 10,
- [1][1][2][0][RTW89_WW][2][9] = 58,
[1][1][2][0][RTW89_WW][0][13] = 10,
[1][1][2][0][RTW89_WW][1][13] = 10,
- [1][1][2][0][RTW89_WW][2][13] = 58,
[1][1][2][0][RTW89_WW][0][16] = 10,
[1][1][2][0][RTW89_WW][1][16] = 10,
- [1][1][2][0][RTW89_WW][2][16] = 58,
[1][1][2][0][RTW89_WW][0][20] = 10,
[1][1][2][0][RTW89_WW][1][20] = 10,
- [1][1][2][0][RTW89_WW][2][20] = 58,
[1][1][2][0][RTW89_WW][0][24] = 10,
[1][1][2][0][RTW89_WW][1][24] = 10,
- [1][1][2][0][RTW89_WW][2][24] = 70,
[1][1][2][0][RTW89_WW][0][28] = 10,
[1][1][2][0][RTW89_WW][1][28] = 10,
- [1][1][2][0][RTW89_WW][2][28] = 70,
[1][1][2][0][RTW89_WW][0][31] = 10,
[1][1][2][0][RTW89_WW][1][31] = 10,
- [1][1][2][0][RTW89_WW][2][31] = 70,
[1][1][2][0][RTW89_WW][0][35] = 10,
[1][1][2][0][RTW89_WW][1][35] = 10,
- [1][1][2][0][RTW89_WW][2][35] = 70,
[1][1][2][0][RTW89_WW][0][39] = 10,
[1][1][2][0][RTW89_WW][1][39] = 10,
- [1][1][2][0][RTW89_WW][2][39] = 70,
[1][1][2][0][RTW89_WW][0][43] = 10,
[1][1][2][0][RTW89_WW][1][43] = 10,
- [1][1][2][0][RTW89_WW][2][43] = 70,
[1][1][2][0][RTW89_WW][0][46] = 12,
[1][1][2][0][RTW89_WW][1][46] = 12,
- [1][1][2][0][RTW89_WW][2][46] = 68,
[1][1][2][0][RTW89_WW][0][50] = 12,
[1][1][2][0][RTW89_WW][1][50] = 12,
- [1][1][2][0][RTW89_WW][2][50] = 68,
[1][1][2][0][RTW89_WW][0][54] = 10,
[1][1][2][0][RTW89_WW][1][54] = 10,
- [1][1][2][0][RTW89_WW][2][54] = 0,
[1][1][2][0][RTW89_WW][0][58] = 10,
[1][1][2][0][RTW89_WW][1][58] = 10,
- [1][1][2][0][RTW89_WW][2][58] = 66,
[1][1][2][0][RTW89_WW][0][61] = 10,
[1][1][2][0][RTW89_WW][1][61] = 10,
- [1][1][2][0][RTW89_WW][2][61] = 66,
[1][1][2][0][RTW89_WW][0][65] = 10,
[1][1][2][0][RTW89_WW][1][65] = 10,
- [1][1][2][0][RTW89_WW][2][65] = 66,
[1][1][2][0][RTW89_WW][0][69] = 10,
[1][1][2][0][RTW89_WW][1][69] = 10,
- [1][1][2][0][RTW89_WW][2][69] = 66,
[1][1][2][0][RTW89_WW][0][73] = 10,
[1][1][2][0][RTW89_WW][1][73] = 10,
- [1][1][2][0][RTW89_WW][2][73] = 66,
[1][1][2][0][RTW89_WW][0][76] = 10,
[1][1][2][0][RTW89_WW][1][76] = 10,
- [1][1][2][0][RTW89_WW][2][76] = 66,
[1][1][2][0][RTW89_WW][0][80] = 10,
[1][1][2][0][RTW89_WW][1][80] = 10,
- [1][1][2][0][RTW89_WW][2][80] = 66,
[1][1][2][0][RTW89_WW][0][84] = 10,
[1][1][2][0][RTW89_WW][1][84] = 10,
- [1][1][2][0][RTW89_WW][2][84] = 66,
[1][1][2][0][RTW89_WW][0][88] = 10,
[1][1][2][0][RTW89_WW][1][88] = 10,
- [1][1][2][0][RTW89_WW][2][88] = 0,
[1][1][2][0][RTW89_WW][0][91] = 12,
[1][1][2][0][RTW89_WW][1][91] = 12,
- [1][1][2][0][RTW89_WW][2][91] = 0,
[1][1][2][0][RTW89_WW][0][95] = 10,
[1][1][2][0][RTW89_WW][1][95] = 10,
- [1][1][2][0][RTW89_WW][2][95] = 0,
[1][1][2][0][RTW89_WW][0][99] = 10,
[1][1][2][0][RTW89_WW][1][99] = 10,
- [1][1][2][0][RTW89_WW][2][99] = 0,
[1][1][2][0][RTW89_WW][0][103] = 10,
[1][1][2][0][RTW89_WW][1][103] = 10,
- [1][1][2][0][RTW89_WW][2][103] = 0,
[1][1][2][0][RTW89_WW][0][106] = 12,
[1][1][2][0][RTW89_WW][1][106] = 12,
- [1][1][2][0][RTW89_WW][2][106] = 0,
[1][1][2][0][RTW89_WW][0][110] = 0,
[1][1][2][0][RTW89_WW][1][110] = 0,
- [1][1][2][0][RTW89_WW][2][110] = 0,
[1][1][2][0][RTW89_WW][0][114] = 0,
[1][1][2][0][RTW89_WW][1][114] = 0,
- [1][1][2][0][RTW89_WW][2][114] = 0,
[1][1][2][0][RTW89_WW][0][118] = 0,
[1][1][2][0][RTW89_WW][1][118] = 0,
- [1][1][2][0][RTW89_WW][2][118] = 0,
[1][1][2][1][RTW89_WW][0][1] = 6,
[1][1][2][1][RTW89_WW][1][1] = 10,
- [1][1][2][1][RTW89_WW][2][1] = 58,
[1][1][2][1][RTW89_WW][0][5] = 6,
[1][1][2][1][RTW89_WW][1][5] = 10,
- [1][1][2][1][RTW89_WW][2][5] = 58,
[1][1][2][1][RTW89_WW][0][9] = 6,
[1][1][2][1][RTW89_WW][1][9] = 10,
- [1][1][2][1][RTW89_WW][2][9] = 58,
[1][1][2][1][RTW89_WW][0][13] = 6,
[1][1][2][1][RTW89_WW][1][13] = 10,
- [1][1][2][1][RTW89_WW][2][13] = 58,
[1][1][2][1][RTW89_WW][0][16] = 6,
[1][1][2][1][RTW89_WW][1][16] = 10,
- [1][1][2][1][RTW89_WW][2][16] = 58,
[1][1][2][1][RTW89_WW][0][20] = 6,
[1][1][2][1][RTW89_WW][1][20] = 10,
- [1][1][2][1][RTW89_WW][2][20] = 58,
[1][1][2][1][RTW89_WW][0][24] = 6,
[1][1][2][1][RTW89_WW][1][24] = 10,
- [1][1][2][1][RTW89_WW][2][24] = 70,
[1][1][2][1][RTW89_WW][0][28] = 6,
[1][1][2][1][RTW89_WW][1][28] = 10,
- [1][1][2][1][RTW89_WW][2][28] = 70,
[1][1][2][1][RTW89_WW][0][31] = 6,
[1][1][2][1][RTW89_WW][1][31] = 10,
- [1][1][2][1][RTW89_WW][2][31] = 70,
[1][1][2][1][RTW89_WW][0][35] = 6,
[1][1][2][1][RTW89_WW][1][35] = 10,
- [1][1][2][1][RTW89_WW][2][35] = 70,
[1][1][2][1][RTW89_WW][0][39] = 6,
[1][1][2][1][RTW89_WW][1][39] = 10,
- [1][1][2][1][RTW89_WW][2][39] = 70,
[1][1][2][1][RTW89_WW][0][43] = 6,
[1][1][2][1][RTW89_WW][1][43] = 10,
- [1][1][2][1][RTW89_WW][2][43] = 70,
[1][1][2][1][RTW89_WW][0][46] = 12,
[1][1][2][1][RTW89_WW][1][46] = 12,
- [1][1][2][1][RTW89_WW][2][46] = 68,
[1][1][2][1][RTW89_WW][0][50] = 12,
[1][1][2][1][RTW89_WW][1][50] = 12,
- [1][1][2][1][RTW89_WW][2][50] = 68,
[1][1][2][1][RTW89_WW][0][54] = 10,
[1][1][2][1][RTW89_WW][1][54] = 10,
- [1][1][2][1][RTW89_WW][2][54] = 0,
[1][1][2][1][RTW89_WW][0][58] = 10,
[1][1][2][1][RTW89_WW][1][58] = 10,
- [1][1][2][1][RTW89_WW][2][58] = 66,
[1][1][2][1][RTW89_WW][0][61] = 10,
[1][1][2][1][RTW89_WW][1][61] = 10,
- [1][1][2][1][RTW89_WW][2][61] = 66,
[1][1][2][1][RTW89_WW][0][65] = 10,
[1][1][2][1][RTW89_WW][1][65] = 10,
- [1][1][2][1][RTW89_WW][2][65] = 66,
[1][1][2][1][RTW89_WW][0][69] = 10,
[1][1][2][1][RTW89_WW][1][69] = 10,
- [1][1][2][1][RTW89_WW][2][69] = 66,
[1][1][2][1][RTW89_WW][0][73] = 10,
[1][1][2][1][RTW89_WW][1][73] = 10,
- [1][1][2][1][RTW89_WW][2][73] = 66,
[1][1][2][1][RTW89_WW][0][76] = 10,
[1][1][2][1][RTW89_WW][1][76] = 10,
- [1][1][2][1][RTW89_WW][2][76] = 66,
[1][1][2][1][RTW89_WW][0][80] = 10,
[1][1][2][1][RTW89_WW][1][80] = 10,
- [1][1][2][1][RTW89_WW][2][80] = 66,
[1][1][2][1][RTW89_WW][0][84] = 10,
[1][1][2][1][RTW89_WW][1][84] = 10,
- [1][1][2][1][RTW89_WW][2][84] = 66,
[1][1][2][1][RTW89_WW][0][88] = 10,
[1][1][2][1][RTW89_WW][1][88] = 10,
- [1][1][2][1][RTW89_WW][2][88] = 0,
[1][1][2][1][RTW89_WW][0][91] = 12,
[1][1][2][1][RTW89_WW][1][91] = 12,
- [1][1][2][1][RTW89_WW][2][91] = 0,
[1][1][2][1][RTW89_WW][0][95] = 10,
[1][1][2][1][RTW89_WW][1][95] = 10,
- [1][1][2][1][RTW89_WW][2][95] = 0,
[1][1][2][1][RTW89_WW][0][99] = 10,
[1][1][2][1][RTW89_WW][1][99] = 10,
- [1][1][2][1][RTW89_WW][2][99] = 0,
[1][1][2][1][RTW89_WW][0][103] = 10,
[1][1][2][1][RTW89_WW][1][103] = 10,
- [1][1][2][1][RTW89_WW][2][103] = 0,
[1][1][2][1][RTW89_WW][0][106] = 12,
[1][1][2][1][RTW89_WW][1][106] = 12,
- [1][1][2][1][RTW89_WW][2][106] = 0,
[1][1][2][1][RTW89_WW][0][110] = 0,
[1][1][2][1][RTW89_WW][1][110] = 0,
- [1][1][2][1][RTW89_WW][2][110] = 0,
[1][1][2][1][RTW89_WW][0][114] = 0,
[1][1][2][1][RTW89_WW][1][114] = 0,
- [1][1][2][1][RTW89_WW][2][114] = 0,
[1][1][2][1][RTW89_WW][0][118] = 0,
[1][1][2][1][RTW89_WW][1][118] = 0,
- [1][1][2][1][RTW89_WW][2][118] = 0,
[2][0][2][0][RTW89_WW][0][3] = 24,
[2][0][2][0][RTW89_WW][1][3] = 46,
- [2][0][2][0][RTW89_WW][2][3] = 60,
[2][0][2][0][RTW89_WW][0][11] = 24,
[2][0][2][0][RTW89_WW][1][11] = 46,
- [2][0][2][0][RTW89_WW][2][11] = 60,
[2][0][2][0][RTW89_WW][0][18] = 24,
[2][0][2][0][RTW89_WW][1][18] = 46,
- [2][0][2][0][RTW89_WW][2][18] = 60,
[2][0][2][0][RTW89_WW][0][26] = 24,
[2][0][2][0][RTW89_WW][1][26] = 46,
- [2][0][2][0][RTW89_WW][2][26] = 60,
[2][0][2][0][RTW89_WW][0][33] = 24,
[2][0][2][0][RTW89_WW][1][33] = 46,
- [2][0][2][0][RTW89_WW][2][33] = 60,
[2][0][2][0][RTW89_WW][0][41] = 24,
[2][0][2][0][RTW89_WW][1][41] = 46,
- [2][0][2][0][RTW89_WW][2][41] = 60,
[2][0][2][0][RTW89_WW][0][48] = 46,
[2][0][2][0][RTW89_WW][1][48] = 46,
- [2][0][2][0][RTW89_WW][2][48] = 60,
[2][0][2][0][RTW89_WW][0][56] = 46,
[2][0][2][0][RTW89_WW][1][56] = 46,
- [2][0][2][0][RTW89_WW][2][56] = 58,
[2][0][2][0][RTW89_WW][0][63] = 46,
[2][0][2][0][RTW89_WW][1][63] = 46,
- [2][0][2][0][RTW89_WW][2][63] = 58,
[2][0][2][0][RTW89_WW][0][71] = 46,
[2][0][2][0][RTW89_WW][1][71] = 46,
- [2][0][2][0][RTW89_WW][2][71] = 58,
[2][0][2][0][RTW89_WW][0][78] = 46,
[2][0][2][0][RTW89_WW][1][78] = 46,
- [2][0][2][0][RTW89_WW][2][78] = 58,
[2][0][2][0][RTW89_WW][0][86] = 46,
[2][0][2][0][RTW89_WW][1][86] = 46,
- [2][0][2][0][RTW89_WW][2][86] = 0,
[2][0][2][0][RTW89_WW][0][93] = 46,
[2][0][2][0][RTW89_WW][1][93] = 46,
- [2][0][2][0][RTW89_WW][2][93] = 0,
[2][0][2][0][RTW89_WW][0][101] = 44,
[2][0][2][0][RTW89_WW][1][101] = 44,
- [2][0][2][0][RTW89_WW][2][101] = 0,
[2][0][2][0][RTW89_WW][0][108] = 0,
[2][0][2][0][RTW89_WW][1][108] = 0,
- [2][0][2][0][RTW89_WW][2][108] = 0,
[2][0][2][0][RTW89_WW][0][116] = 0,
[2][0][2][0][RTW89_WW][1][116] = 0,
- [2][0][2][0][RTW89_WW][2][116] = 0,
[2][1][2][0][RTW89_WW][0][3] = 12,
[2][1][2][0][RTW89_WW][1][3] = 22,
- [2][1][2][0][RTW89_WW][2][3] = 50,
[2][1][2][0][RTW89_WW][0][11] = 12,
[2][1][2][0][RTW89_WW][1][11] = 20,
- [2][1][2][0][RTW89_WW][2][11] = 50,
[2][1][2][0][RTW89_WW][0][18] = 12,
[2][1][2][0][RTW89_WW][1][18] = 20,
- [2][1][2][0][RTW89_WW][2][18] = 50,
[2][1][2][0][RTW89_WW][0][26] = 12,
[2][1][2][0][RTW89_WW][1][26] = 20,
- [2][1][2][0][RTW89_WW][2][26] = 60,
[2][1][2][0][RTW89_WW][0][33] = 12,
[2][1][2][0][RTW89_WW][1][33] = 20,
- [2][1][2][0][RTW89_WW][2][33] = 60,
[2][1][2][0][RTW89_WW][0][41] = 12,
[2][1][2][0][RTW89_WW][1][41] = 22,
- [2][1][2][0][RTW89_WW][2][41] = 60,
[2][1][2][0][RTW89_WW][0][48] = 22,
[2][1][2][0][RTW89_WW][1][48] = 22,
- [2][1][2][0][RTW89_WW][2][48] = 60,
[2][1][2][0][RTW89_WW][0][56] = 20,
[2][1][2][0][RTW89_WW][1][56] = 20,
- [2][1][2][0][RTW89_WW][2][56] = 56,
[2][1][2][0][RTW89_WW][0][63] = 22,
[2][1][2][0][RTW89_WW][1][63] = 22,
- [2][1][2][0][RTW89_WW][2][63] = 58,
[2][1][2][0][RTW89_WW][0][71] = 20,
[2][1][2][0][RTW89_WW][1][71] = 20,
- [2][1][2][0][RTW89_WW][2][71] = 58,
[2][1][2][0][RTW89_WW][0][78] = 20,
[2][1][2][0][RTW89_WW][1][78] = 20,
- [2][1][2][0][RTW89_WW][2][78] = 58,
[2][1][2][0][RTW89_WW][0][86] = 20,
[2][1][2][0][RTW89_WW][1][86] = 20,
- [2][1][2][0][RTW89_WW][2][86] = 0,
[2][1][2][0][RTW89_WW][0][93] = 22,
[2][1][2][0][RTW89_WW][1][93] = 22,
- [2][1][2][0][RTW89_WW][2][93] = 0,
[2][1][2][0][RTW89_WW][0][101] = 22,
[2][1][2][0][RTW89_WW][1][101] = 22,
- [2][1][2][0][RTW89_WW][2][101] = 0,
[2][1][2][0][RTW89_WW][0][108] = 0,
[2][1][2][0][RTW89_WW][1][108] = 0,
- [2][1][2][0][RTW89_WW][2][108] = 0,
[2][1][2][0][RTW89_WW][0][116] = 0,
[2][1][2][0][RTW89_WW][1][116] = 0,
- [2][1][2][0][RTW89_WW][2][116] = 0,
[2][1][2][1][RTW89_WW][0][3] = 6,
[2][1][2][1][RTW89_WW][1][3] = 22,
- [2][1][2][1][RTW89_WW][2][3] = 50,
[2][1][2][1][RTW89_WW][0][11] = 6,
[2][1][2][1][RTW89_WW][1][11] = 20,
- [2][1][2][1][RTW89_WW][2][11] = 50,
[2][1][2][1][RTW89_WW][0][18] = 6,
[2][1][2][1][RTW89_WW][1][18] = 20,
- [2][1][2][1][RTW89_WW][2][18] = 50,
[2][1][2][1][RTW89_WW][0][26] = 6,
[2][1][2][1][RTW89_WW][1][26] = 20,
- [2][1][2][1][RTW89_WW][2][26] = 60,
[2][1][2][1][RTW89_WW][0][33] = 6,
[2][1][2][1][RTW89_WW][1][33] = 20,
- [2][1][2][1][RTW89_WW][2][33] = 60,
[2][1][2][1][RTW89_WW][0][41] = 6,
[2][1][2][1][RTW89_WW][1][41] = 22,
- [2][1][2][1][RTW89_WW][2][41] = 60,
[2][1][2][1][RTW89_WW][0][48] = 22,
[2][1][2][1][RTW89_WW][1][48] = 22,
- [2][1][2][1][RTW89_WW][2][48] = 60,
[2][1][2][1][RTW89_WW][0][56] = 20,
[2][1][2][1][RTW89_WW][1][56] = 20,
- [2][1][2][1][RTW89_WW][2][56] = 56,
[2][1][2][1][RTW89_WW][0][63] = 22,
[2][1][2][1][RTW89_WW][1][63] = 22,
- [2][1][2][1][RTW89_WW][2][63] = 58,
[2][1][2][1][RTW89_WW][0][71] = 20,
[2][1][2][1][RTW89_WW][1][71] = 20,
- [2][1][2][1][RTW89_WW][2][71] = 58,
[2][1][2][1][RTW89_WW][0][78] = 20,
[2][1][2][1][RTW89_WW][1][78] = 20,
- [2][1][2][1][RTW89_WW][2][78] = 58,
[2][1][2][1][RTW89_WW][0][86] = 20,
[2][1][2][1][RTW89_WW][1][86] = 20,
- [2][1][2][1][RTW89_WW][2][86] = 0,
[2][1][2][1][RTW89_WW][0][93] = 22,
[2][1][2][1][RTW89_WW][1][93] = 22,
- [2][1][2][1][RTW89_WW][2][93] = 0,
[2][1][2][1][RTW89_WW][0][101] = 22,
[2][1][2][1][RTW89_WW][1][101] = 22,
- [2][1][2][1][RTW89_WW][2][101] = 0,
[2][1][2][1][RTW89_WW][0][108] = 0,
[2][1][2][1][RTW89_WW][1][108] = 0,
- [2][1][2][1][RTW89_WW][2][108] = 0,
[2][1][2][1][RTW89_WW][0][116] = 0,
[2][1][2][1][RTW89_WW][1][116] = 0,
- [2][1][2][1][RTW89_WW][2][116] = 0,
[3][0][2][0][RTW89_WW][0][7] = 22,
[3][0][2][0][RTW89_WW][1][7] = 42,
- [3][0][2][0][RTW89_WW][2][7] = 52,
[3][0][2][0][RTW89_WW][0][22] = 20,
[3][0][2][0][RTW89_WW][1][22] = 42,
- [3][0][2][0][RTW89_WW][2][22] = 52,
[3][0][2][0][RTW89_WW][0][37] = 20,
[3][0][2][0][RTW89_WW][1][37] = 42,
- [3][0][2][0][RTW89_WW][2][37] = 52,
[3][0][2][0][RTW89_WW][0][52] = 54,
[3][0][2][0][RTW89_WW][1][52] = 54,
- [3][0][2][0][RTW89_WW][2][52] = 56,
[3][0][2][0][RTW89_WW][0][67] = 54,
[3][0][2][0][RTW89_WW][1][67] = 54,
- [3][0][2][0][RTW89_WW][2][67] = 54,
[3][0][2][0][RTW89_WW][0][82] = 26,
[3][0][2][0][RTW89_WW][1][82] = 26,
- [3][0][2][0][RTW89_WW][2][82] = 0,
[3][0][2][0][RTW89_WW][0][97] = 26,
[3][0][2][0][RTW89_WW][1][97] = 26,
- [3][0][2][0][RTW89_WW][2][97] = 0,
[3][0][2][0][RTW89_WW][0][112] = 0,
[3][0][2][0][RTW89_WW][1][112] = 0,
- [3][0][2][0][RTW89_WW][2][112] = 0,
[3][1][2][0][RTW89_WW][0][7] = 10,
[3][1][2][0][RTW89_WW][1][7] = 32,
- [3][1][2][0][RTW89_WW][2][7] = 46,
[3][1][2][0][RTW89_WW][0][22] = 8,
[3][1][2][0][RTW89_WW][1][22] = 30,
- [3][1][2][0][RTW89_WW][2][22] = 52,
[3][1][2][0][RTW89_WW][0][37] = 8,
[3][1][2][0][RTW89_WW][1][37] = 30,
- [3][1][2][0][RTW89_WW][2][37] = 52,
[3][1][2][0][RTW89_WW][0][52] = 30,
[3][1][2][0][RTW89_WW][1][52] = 30,
- [3][1][2][0][RTW89_WW][2][52] = 56,
[3][1][2][0][RTW89_WW][0][67] = 32,
[3][1][2][0][RTW89_WW][1][67] = 32,
- [3][1][2][0][RTW89_WW][2][67] = 54,
[3][1][2][0][RTW89_WW][0][82] = 24,
[3][1][2][0][RTW89_WW][1][82] = 24,
- [3][1][2][0][RTW89_WW][2][82] = 0,
[3][1][2][0][RTW89_WW][0][97] = 24,
[3][1][2][0][RTW89_WW][1][97] = 24,
- [3][1][2][0][RTW89_WW][2][97] = 0,
[3][1][2][0][RTW89_WW][0][112] = 0,
[3][1][2][0][RTW89_WW][1][112] = 0,
- [3][1][2][0][RTW89_WW][2][112] = 0,
[3][1][2][1][RTW89_WW][0][7] = 6,
[3][1][2][1][RTW89_WW][1][7] = 32,
- [3][1][2][1][RTW89_WW][2][7] = 46,
[3][1][2][1][RTW89_WW][0][22] = 6,
[3][1][2][1][RTW89_WW][1][22] = 30,
- [3][1][2][1][RTW89_WW][2][22] = 52,
[3][1][2][1][RTW89_WW][0][37] = 6,
[3][1][2][1][RTW89_WW][1][37] = 30,
- [3][1][2][1][RTW89_WW][2][37] = 52,
[3][1][2][1][RTW89_WW][0][52] = 30,
[3][1][2][1][RTW89_WW][1][52] = 30,
- [3][1][2][1][RTW89_WW][2][52] = 56,
[3][1][2][1][RTW89_WW][0][67] = 32,
[3][1][2][1][RTW89_WW][1][67] = 32,
- [3][1][2][1][RTW89_WW][2][67] = 54,
[3][1][2][1][RTW89_WW][0][82] = 24,
[3][1][2][1][RTW89_WW][1][82] = 24,
- [3][1][2][1][RTW89_WW][2][82] = 0,
[3][1][2][1][RTW89_WW][0][97] = 24,
[3][1][2][1][RTW89_WW][1][97] = 24,
- [3][1][2][1][RTW89_WW][2][97] = 0,
[3][1][2][1][RTW89_WW][0][112] = 0,
[3][1][2][1][RTW89_WW][1][112] = 0,
- [3][1][2][1][RTW89_WW][2][112] = 0,
[0][0][1][0][RTW89_FCC][1][0] = 24,
- [0][0][1][0][RTW89_FCC][2][0] = 56,
[0][0][1][0][RTW89_ETSI][1][0] = 66,
[0][0][1][0][RTW89_ETSI][0][0] = 28,
[0][0][1][0][RTW89_MKK][1][0] = 66,
[0][0][1][0][RTW89_MKK][0][0] = 26,
[0][0][1][0][RTW89_IC][1][0] = 24,
- [0][0][1][0][RTW89_IC][2][0] = 56,
[0][0][1][0][RTW89_KCC][1][0] = 24,
[0][0][1][0][RTW89_KCC][0][0] = 24,
[0][0][1][0][RTW89_ACMA][1][0] = 66,
@@ -38440,13 +37950,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][0] = 56,
[0][0][1][0][RTW89_THAILAND][0][0] = 24,
[0][0][1][0][RTW89_FCC][1][2] = 22,
- [0][0][1][0][RTW89_FCC][2][2] = 56,
[0][0][1][0][RTW89_ETSI][1][2] = 66,
[0][0][1][0][RTW89_ETSI][0][2] = 28,
[0][0][1][0][RTW89_MKK][1][2] = 66,
[0][0][1][0][RTW89_MKK][0][2] = 26,
[0][0][1][0][RTW89_IC][1][2] = 22,
- [0][0][1][0][RTW89_IC][2][2] = 56,
[0][0][1][0][RTW89_KCC][1][2] = 24,
[0][0][1][0][RTW89_KCC][0][2] = 24,
[0][0][1][0][RTW89_ACMA][1][2] = 66,
@@ -38459,13 +37967,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][2] = 56,
[0][0][1][0][RTW89_THAILAND][0][2] = 22,
[0][0][1][0][RTW89_FCC][1][4] = 22,
- [0][0][1][0][RTW89_FCC][2][4] = 56,
[0][0][1][0][RTW89_ETSI][1][4] = 66,
[0][0][1][0][RTW89_ETSI][0][4] = 28,
[0][0][1][0][RTW89_MKK][1][4] = 66,
[0][0][1][0][RTW89_MKK][0][4] = 26,
[0][0][1][0][RTW89_IC][1][4] = 22,
- [0][0][1][0][RTW89_IC][2][4] = 56,
[0][0][1][0][RTW89_KCC][1][4] = 24,
[0][0][1][0][RTW89_KCC][0][4] = 24,
[0][0][1][0][RTW89_ACMA][1][4] = 66,
@@ -38478,13 +37984,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][4] = 56,
[0][0][1][0][RTW89_THAILAND][0][4] = 22,
[0][0][1][0][RTW89_FCC][1][6] = 22,
- [0][0][1][0][RTW89_FCC][2][6] = 56,
[0][0][1][0][RTW89_ETSI][1][6] = 66,
[0][0][1][0][RTW89_ETSI][0][6] = 28,
[0][0][1][0][RTW89_MKK][1][6] = 66,
[0][0][1][0][RTW89_MKK][0][6] = 26,
[0][0][1][0][RTW89_IC][1][6] = 22,
- [0][0][1][0][RTW89_IC][2][6] = 56,
[0][0][1][0][RTW89_KCC][1][6] = 24,
[0][0][1][0][RTW89_KCC][0][6] = 24,
[0][0][1][0][RTW89_ACMA][1][6] = 66,
@@ -38497,13 +38001,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][6] = 56,
[0][0][1][0][RTW89_THAILAND][0][6] = 22,
[0][0][1][0][RTW89_FCC][1][8] = 22,
- [0][0][1][0][RTW89_FCC][2][8] = 56,
[0][0][1][0][RTW89_ETSI][1][8] = 66,
[0][0][1][0][RTW89_ETSI][0][8] = 28,
[0][0][1][0][RTW89_MKK][1][8] = 66,
[0][0][1][0][RTW89_MKK][0][8] = 26,
[0][0][1][0][RTW89_IC][1][8] = 22,
- [0][0][1][0][RTW89_IC][2][8] = 56,
[0][0][1][0][RTW89_KCC][1][8] = 24,
[0][0][1][0][RTW89_KCC][0][8] = 24,
[0][0][1][0][RTW89_ACMA][1][8] = 66,
@@ -38516,13 +38018,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][8] = 56,
[0][0][1][0][RTW89_THAILAND][0][8] = 22,
[0][0][1][0][RTW89_FCC][1][10] = 22,
- [0][0][1][0][RTW89_FCC][2][10] = 56,
[0][0][1][0][RTW89_ETSI][1][10] = 66,
[0][0][1][0][RTW89_ETSI][0][10] = 28,
[0][0][1][0][RTW89_MKK][1][10] = 66,
[0][0][1][0][RTW89_MKK][0][10] = 26,
[0][0][1][0][RTW89_IC][1][10] = 22,
- [0][0][1][0][RTW89_IC][2][10] = 56,
[0][0][1][0][RTW89_KCC][1][10] = 24,
[0][0][1][0][RTW89_KCC][0][10] = 24,
[0][0][1][0][RTW89_ACMA][1][10] = 66,
@@ -38535,13 +38035,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][10] = 56,
[0][0][1][0][RTW89_THAILAND][0][10] = 22,
[0][0][1][0][RTW89_FCC][1][12] = 22,
- [0][0][1][0][RTW89_FCC][2][12] = 56,
[0][0][1][0][RTW89_ETSI][1][12] = 66,
[0][0][1][0][RTW89_ETSI][0][12] = 28,
[0][0][1][0][RTW89_MKK][1][12] = 66,
[0][0][1][0][RTW89_MKK][0][12] = 26,
[0][0][1][0][RTW89_IC][1][12] = 22,
- [0][0][1][0][RTW89_IC][2][12] = 56,
[0][0][1][0][RTW89_KCC][1][12] = 24,
[0][0][1][0][RTW89_KCC][0][12] = 24,
[0][0][1][0][RTW89_ACMA][1][12] = 66,
@@ -38554,13 +38052,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][12] = 56,
[0][0][1][0][RTW89_THAILAND][0][12] = 22,
[0][0][1][0][RTW89_FCC][1][14] = 22,
- [0][0][1][0][RTW89_FCC][2][14] = 56,
[0][0][1][0][RTW89_ETSI][1][14] = 66,
[0][0][1][0][RTW89_ETSI][0][14] = 28,
[0][0][1][0][RTW89_MKK][1][14] = 66,
[0][0][1][0][RTW89_MKK][0][14] = 26,
[0][0][1][0][RTW89_IC][1][14] = 22,
- [0][0][1][0][RTW89_IC][2][14] = 56,
[0][0][1][0][RTW89_KCC][1][14] = 24,
[0][0][1][0][RTW89_KCC][0][14] = 24,
[0][0][1][0][RTW89_ACMA][1][14] = 66,
@@ -38573,13 +38069,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][14] = 56,
[0][0][1][0][RTW89_THAILAND][0][14] = 22,
[0][0][1][0][RTW89_FCC][1][15] = 22,
- [0][0][1][0][RTW89_FCC][2][15] = 56,
[0][0][1][0][RTW89_ETSI][1][15] = 66,
[0][0][1][0][RTW89_ETSI][0][15] = 28,
[0][0][1][0][RTW89_MKK][1][15] = 66,
[0][0][1][0][RTW89_MKK][0][15] = 26,
[0][0][1][0][RTW89_IC][1][15] = 22,
- [0][0][1][0][RTW89_IC][2][15] = 56,
[0][0][1][0][RTW89_KCC][1][15] = 24,
[0][0][1][0][RTW89_KCC][0][15] = 24,
[0][0][1][0][RTW89_ACMA][1][15] = 66,
@@ -38592,13 +38086,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][15] = 56,
[0][0][1][0][RTW89_THAILAND][0][15] = 22,
[0][0][1][0][RTW89_FCC][1][17] = 22,
- [0][0][1][0][RTW89_FCC][2][17] = 56,
[0][0][1][0][RTW89_ETSI][1][17] = 66,
[0][0][1][0][RTW89_ETSI][0][17] = 28,
[0][0][1][0][RTW89_MKK][1][17] = 66,
[0][0][1][0][RTW89_MKK][0][17] = 26,
[0][0][1][0][RTW89_IC][1][17] = 22,
- [0][0][1][0][RTW89_IC][2][17] = 56,
[0][0][1][0][RTW89_KCC][1][17] = 24,
[0][0][1][0][RTW89_KCC][0][17] = 24,
[0][0][1][0][RTW89_ACMA][1][17] = 66,
@@ -38611,13 +38103,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][17] = 56,
[0][0][1][0][RTW89_THAILAND][0][17] = 22,
[0][0][1][0][RTW89_FCC][1][19] = 22,
- [0][0][1][0][RTW89_FCC][2][19] = 56,
[0][0][1][0][RTW89_ETSI][1][19] = 66,
[0][0][1][0][RTW89_ETSI][0][19] = 28,
[0][0][1][0][RTW89_MKK][1][19] = 66,
[0][0][1][0][RTW89_MKK][0][19] = 26,
[0][0][1][0][RTW89_IC][1][19] = 22,
- [0][0][1][0][RTW89_IC][2][19] = 56,
[0][0][1][0][RTW89_KCC][1][19] = 24,
[0][0][1][0][RTW89_KCC][0][19] = 24,
[0][0][1][0][RTW89_ACMA][1][19] = 66,
@@ -38630,13 +38120,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][19] = 56,
[0][0][1][0][RTW89_THAILAND][0][19] = 22,
[0][0][1][0][RTW89_FCC][1][21] = 22,
- [0][0][1][0][RTW89_FCC][2][21] = 56,
[0][0][1][0][RTW89_ETSI][1][21] = 66,
[0][0][1][0][RTW89_ETSI][0][21] = 28,
[0][0][1][0][RTW89_MKK][1][21] = 66,
[0][0][1][0][RTW89_MKK][0][21] = 26,
[0][0][1][0][RTW89_IC][1][21] = 22,
- [0][0][1][0][RTW89_IC][2][21] = 56,
[0][0][1][0][RTW89_KCC][1][21] = 24,
[0][0][1][0][RTW89_KCC][0][21] = 24,
[0][0][1][0][RTW89_ACMA][1][21] = 66,
@@ -38649,13 +38137,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][21] = 56,
[0][0][1][0][RTW89_THAILAND][0][21] = 22,
[0][0][1][0][RTW89_FCC][1][23] = 22,
- [0][0][1][0][RTW89_FCC][2][23] = 70,
[0][0][1][0][RTW89_ETSI][1][23] = 66,
[0][0][1][0][RTW89_ETSI][0][23] = 28,
[0][0][1][0][RTW89_MKK][1][23] = 66,
[0][0][1][0][RTW89_MKK][0][23] = 26,
[0][0][1][0][RTW89_IC][1][23] = 22,
- [0][0][1][0][RTW89_IC][2][23] = 70,
[0][0][1][0][RTW89_KCC][1][23] = 24,
[0][0][1][0][RTW89_KCC][0][23] = 26,
[0][0][1][0][RTW89_ACMA][1][23] = 66,
@@ -38668,13 +38154,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][23] = 66,
[0][0][1][0][RTW89_THAILAND][0][23] = 22,
[0][0][1][0][RTW89_FCC][1][25] = 22,
- [0][0][1][0][RTW89_FCC][2][25] = 70,
[0][0][1][0][RTW89_ETSI][1][25] = 66,
[0][0][1][0][RTW89_ETSI][0][25] = 28,
[0][0][1][0][RTW89_MKK][1][25] = 66,
[0][0][1][0][RTW89_MKK][0][25] = 26,
[0][0][1][0][RTW89_IC][1][25] = 22,
- [0][0][1][0][RTW89_IC][2][25] = 70,
[0][0][1][0][RTW89_KCC][1][25] = 24,
[0][0][1][0][RTW89_KCC][0][25] = 26,
[0][0][1][0][RTW89_ACMA][1][25] = 66,
@@ -38687,13 +38171,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][25] = 66,
[0][0][1][0][RTW89_THAILAND][0][25] = 22,
[0][0][1][0][RTW89_FCC][1][27] = 22,
- [0][0][1][0][RTW89_FCC][2][27] = 70,
[0][0][1][0][RTW89_ETSI][1][27] = 66,
[0][0][1][0][RTW89_ETSI][0][27] = 28,
[0][0][1][0][RTW89_MKK][1][27] = 66,
[0][0][1][0][RTW89_MKK][0][27] = 26,
[0][0][1][0][RTW89_IC][1][27] = 22,
- [0][0][1][0][RTW89_IC][2][27] = 70,
[0][0][1][0][RTW89_KCC][1][27] = 24,
[0][0][1][0][RTW89_KCC][0][27] = 26,
[0][0][1][0][RTW89_ACMA][1][27] = 66,
@@ -38706,13 +38188,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][27] = 66,
[0][0][1][0][RTW89_THAILAND][0][27] = 22,
[0][0][1][0][RTW89_FCC][1][29] = 22,
- [0][0][1][0][RTW89_FCC][2][29] = 70,
[0][0][1][0][RTW89_ETSI][1][29] = 66,
[0][0][1][0][RTW89_ETSI][0][29] = 28,
[0][0][1][0][RTW89_MKK][1][29] = 66,
[0][0][1][0][RTW89_MKK][0][29] = 26,
[0][0][1][0][RTW89_IC][1][29] = 22,
- [0][0][1][0][RTW89_IC][2][29] = 70,
[0][0][1][0][RTW89_KCC][1][29] = 24,
[0][0][1][0][RTW89_KCC][0][29] = 26,
[0][0][1][0][RTW89_ACMA][1][29] = 66,
@@ -38725,13 +38205,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][29] = 66,
[0][0][1][0][RTW89_THAILAND][0][29] = 22,
[0][0][1][0][RTW89_FCC][1][30] = 22,
- [0][0][1][0][RTW89_FCC][2][30] = 70,
[0][0][1][0][RTW89_ETSI][1][30] = 66,
[0][0][1][0][RTW89_ETSI][0][30] = 28,
[0][0][1][0][RTW89_MKK][1][30] = 66,
[0][0][1][0][RTW89_MKK][0][30] = 26,
[0][0][1][0][RTW89_IC][1][30] = 22,
- [0][0][1][0][RTW89_IC][2][30] = 70,
[0][0][1][0][RTW89_KCC][1][30] = 24,
[0][0][1][0][RTW89_KCC][0][30] = 26,
[0][0][1][0][RTW89_ACMA][1][30] = 66,
@@ -38744,13 +38222,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][30] = 66,
[0][0][1][0][RTW89_THAILAND][0][30] = 22,
[0][0][1][0][RTW89_FCC][1][32] = 22,
- [0][0][1][0][RTW89_FCC][2][32] = 70,
[0][0][1][0][RTW89_ETSI][1][32] = 66,
[0][0][1][0][RTW89_ETSI][0][32] = 28,
[0][0][1][0][RTW89_MKK][1][32] = 66,
[0][0][1][0][RTW89_MKK][0][32] = 26,
[0][0][1][0][RTW89_IC][1][32] = 22,
- [0][0][1][0][RTW89_IC][2][32] = 70,
[0][0][1][0][RTW89_KCC][1][32] = 24,
[0][0][1][0][RTW89_KCC][0][32] = 26,
[0][0][1][0][RTW89_ACMA][1][32] = 66,
@@ -38763,13 +38239,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][32] = 66,
[0][0][1][0][RTW89_THAILAND][0][32] = 22,
[0][0][1][0][RTW89_FCC][1][34] = 22,
- [0][0][1][0][RTW89_FCC][2][34] = 70,
[0][0][1][0][RTW89_ETSI][1][34] = 66,
[0][0][1][0][RTW89_ETSI][0][34] = 28,
[0][0][1][0][RTW89_MKK][1][34] = 66,
[0][0][1][0][RTW89_MKK][0][34] = 26,
[0][0][1][0][RTW89_IC][1][34] = 22,
- [0][0][1][0][RTW89_IC][2][34] = 70,
[0][0][1][0][RTW89_KCC][1][34] = 24,
[0][0][1][0][RTW89_KCC][0][34] = 26,
[0][0][1][0][RTW89_ACMA][1][34] = 66,
@@ -38782,13 +38256,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][34] = 66,
[0][0][1][0][RTW89_THAILAND][0][34] = 22,
[0][0][1][0][RTW89_FCC][1][36] = 22,
- [0][0][1][0][RTW89_FCC][2][36] = 70,
[0][0][1][0][RTW89_ETSI][1][36] = 66,
[0][0][1][0][RTW89_ETSI][0][36] = 28,
[0][0][1][0][RTW89_MKK][1][36] = 66,
[0][0][1][0][RTW89_MKK][0][36] = 26,
[0][0][1][0][RTW89_IC][1][36] = 22,
- [0][0][1][0][RTW89_IC][2][36] = 70,
[0][0][1][0][RTW89_KCC][1][36] = 24,
[0][0][1][0][RTW89_KCC][0][36] = 26,
[0][0][1][0][RTW89_ACMA][1][36] = 66,
@@ -38801,13 +38273,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][36] = 66,
[0][0][1][0][RTW89_THAILAND][0][36] = 22,
[0][0][1][0][RTW89_FCC][1][38] = 22,
- [0][0][1][0][RTW89_FCC][2][38] = 70,
[0][0][1][0][RTW89_ETSI][1][38] = 66,
[0][0][1][0][RTW89_ETSI][0][38] = 28,
[0][0][1][0][RTW89_MKK][1][38] = 66,
[0][0][1][0][RTW89_MKK][0][38] = 26,
[0][0][1][0][RTW89_IC][1][38] = 22,
- [0][0][1][0][RTW89_IC][2][38] = 70,
[0][0][1][0][RTW89_KCC][1][38] = 24,
[0][0][1][0][RTW89_KCC][0][38] = 26,
[0][0][1][0][RTW89_ACMA][1][38] = 66,
@@ -38820,13 +38290,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][38] = 66,
[0][0][1][0][RTW89_THAILAND][0][38] = 22,
[0][0][1][0][RTW89_FCC][1][40] = 22,
- [0][0][1][0][RTW89_FCC][2][40] = 70,
[0][0][1][0][RTW89_ETSI][1][40] = 66,
[0][0][1][0][RTW89_ETSI][0][40] = 28,
[0][0][1][0][RTW89_MKK][1][40] = 66,
[0][0][1][0][RTW89_MKK][0][40] = 26,
[0][0][1][0][RTW89_IC][1][40] = 22,
- [0][0][1][0][RTW89_IC][2][40] = 70,
[0][0][1][0][RTW89_KCC][1][40] = 24,
[0][0][1][0][RTW89_KCC][0][40] = 26,
[0][0][1][0][RTW89_ACMA][1][40] = 66,
@@ -38839,13 +38307,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][40] = 66,
[0][0][1][0][RTW89_THAILAND][0][40] = 22,
[0][0][1][0][RTW89_FCC][1][42] = 22,
- [0][0][1][0][RTW89_FCC][2][42] = 70,
[0][0][1][0][RTW89_ETSI][1][42] = 66,
[0][0][1][0][RTW89_ETSI][0][42] = 28,
[0][0][1][0][RTW89_MKK][1][42] = 66,
[0][0][1][0][RTW89_MKK][0][42] = 26,
[0][0][1][0][RTW89_IC][1][42] = 22,
- [0][0][1][0][RTW89_IC][2][42] = 70,
[0][0][1][0][RTW89_KCC][1][42] = 24,
[0][0][1][0][RTW89_KCC][0][42] = 26,
[0][0][1][0][RTW89_ACMA][1][42] = 66,
@@ -38858,13 +38324,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][42] = 66,
[0][0][1][0][RTW89_THAILAND][0][42] = 22,
[0][0][1][0][RTW89_FCC][1][44] = 22,
- [0][0][1][0][RTW89_FCC][2][44] = 70,
[0][0][1][0][RTW89_ETSI][1][44] = 66,
[0][0][1][0][RTW89_ETSI][0][44] = 30,
[0][0][1][0][RTW89_MKK][1][44] = 44,
[0][0][1][0][RTW89_MKK][0][44] = 28,
[0][0][1][0][RTW89_IC][1][44] = 22,
- [0][0][1][0][RTW89_IC][2][44] = 70,
[0][0][1][0][RTW89_KCC][1][44] = 24,
[0][0][1][0][RTW89_KCC][0][44] = 26,
[0][0][1][0][RTW89_ACMA][1][44] = 66,
@@ -38877,13 +38341,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][44] = 68,
[0][0][1][0][RTW89_THAILAND][0][44] = 22,
[0][0][1][0][RTW89_FCC][1][45] = 22,
- [0][0][1][0][RTW89_FCC][2][45] = 127,
[0][0][1][0][RTW89_ETSI][1][45] = 127,
[0][0][1][0][RTW89_ETSI][0][45] = 127,
[0][0][1][0][RTW89_MKK][1][45] = 127,
[0][0][1][0][RTW89_MKK][0][45] = 127,
[0][0][1][0][RTW89_IC][1][45] = 22,
- [0][0][1][0][RTW89_IC][2][45] = 70,
[0][0][1][0][RTW89_KCC][1][45] = 24,
[0][0][1][0][RTW89_KCC][0][45] = 127,
[0][0][1][0][RTW89_ACMA][1][45] = 127,
@@ -38896,13 +38358,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][45] = 127,
[0][0][1][0][RTW89_THAILAND][0][45] = 127,
[0][0][1][0][RTW89_FCC][1][47] = 22,
- [0][0][1][0][RTW89_FCC][2][47] = 127,
[0][0][1][0][RTW89_ETSI][1][47] = 127,
[0][0][1][0][RTW89_ETSI][0][47] = 127,
[0][0][1][0][RTW89_MKK][1][47] = 127,
[0][0][1][0][RTW89_MKK][0][47] = 127,
[0][0][1][0][RTW89_IC][1][47] = 22,
- [0][0][1][0][RTW89_IC][2][47] = 70,
[0][0][1][0][RTW89_KCC][1][47] = 24,
[0][0][1][0][RTW89_KCC][0][47] = 127,
[0][0][1][0][RTW89_ACMA][1][47] = 127,
@@ -38915,13 +38375,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][47] = 127,
[0][0][1][0][RTW89_THAILAND][0][47] = 127,
[0][0][1][0][RTW89_FCC][1][49] = 24,
- [0][0][1][0][RTW89_FCC][2][49] = 127,
[0][0][1][0][RTW89_ETSI][1][49] = 127,
[0][0][1][0][RTW89_ETSI][0][49] = 127,
[0][0][1][0][RTW89_MKK][1][49] = 127,
[0][0][1][0][RTW89_MKK][0][49] = 127,
[0][0][1][0][RTW89_IC][1][49] = 24,
- [0][0][1][0][RTW89_IC][2][49] = 70,
[0][0][1][0][RTW89_KCC][1][49] = 24,
[0][0][1][0][RTW89_KCC][0][49] = 127,
[0][0][1][0][RTW89_ACMA][1][49] = 127,
@@ -38934,13 +38392,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][49] = 127,
[0][0][1][0][RTW89_THAILAND][0][49] = 127,
[0][0][1][0][RTW89_FCC][1][51] = 22,
- [0][0][1][0][RTW89_FCC][2][51] = 127,
[0][0][1][0][RTW89_ETSI][1][51] = 127,
[0][0][1][0][RTW89_ETSI][0][51] = 127,
[0][0][1][0][RTW89_MKK][1][51] = 127,
[0][0][1][0][RTW89_MKK][0][51] = 127,
[0][0][1][0][RTW89_IC][1][51] = 22,
- [0][0][1][0][RTW89_IC][2][51] = 70,
[0][0][1][0][RTW89_KCC][1][51] = 24,
[0][0][1][0][RTW89_KCC][0][51] = 127,
[0][0][1][0][RTW89_ACMA][1][51] = 127,
@@ -38953,13 +38409,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][51] = 127,
[0][0][1][0][RTW89_THAILAND][0][51] = 127,
[0][0][1][0][RTW89_FCC][1][53] = 22,
- [0][0][1][0][RTW89_FCC][2][53] = 127,
[0][0][1][0][RTW89_ETSI][1][53] = 127,
[0][0][1][0][RTW89_ETSI][0][53] = 127,
[0][0][1][0][RTW89_MKK][1][53] = 127,
[0][0][1][0][RTW89_MKK][0][53] = 127,
[0][0][1][0][RTW89_IC][1][53] = 22,
- [0][0][1][0][RTW89_IC][2][53] = 70,
[0][0][1][0][RTW89_KCC][1][53] = 24,
[0][0][1][0][RTW89_KCC][0][53] = 127,
[0][0][1][0][RTW89_ACMA][1][53] = 127,
@@ -38972,13 +38426,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][53] = 127,
[0][0][1][0][RTW89_THAILAND][0][53] = 127,
[0][0][1][0][RTW89_FCC][1][55] = 22,
- [0][0][1][0][RTW89_FCC][2][55] = 68,
[0][0][1][0][RTW89_ETSI][1][55] = 127,
[0][0][1][0][RTW89_ETSI][0][55] = 127,
[0][0][1][0][RTW89_MKK][1][55] = 127,
[0][0][1][0][RTW89_MKK][0][55] = 127,
[0][0][1][0][RTW89_IC][1][55] = 22,
- [0][0][1][0][RTW89_IC][2][55] = 68,
[0][0][1][0][RTW89_KCC][1][55] = 26,
[0][0][1][0][RTW89_KCC][0][55] = 127,
[0][0][1][0][RTW89_ACMA][1][55] = 127,
@@ -38991,13 +38443,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][55] = 127,
[0][0][1][0][RTW89_THAILAND][0][55] = 127,
[0][0][1][0][RTW89_FCC][1][57] = 22,
- [0][0][1][0][RTW89_FCC][2][57] = 68,
[0][0][1][0][RTW89_ETSI][1][57] = 127,
[0][0][1][0][RTW89_ETSI][0][57] = 127,
[0][0][1][0][RTW89_MKK][1][57] = 127,
[0][0][1][0][RTW89_MKK][0][57] = 127,
[0][0][1][0][RTW89_IC][1][57] = 22,
- [0][0][1][0][RTW89_IC][2][57] = 68,
[0][0][1][0][RTW89_KCC][1][57] = 26,
[0][0][1][0][RTW89_KCC][0][57] = 127,
[0][0][1][0][RTW89_ACMA][1][57] = 127,
@@ -39010,13 +38460,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][57] = 127,
[0][0][1][0][RTW89_THAILAND][0][57] = 127,
[0][0][1][0][RTW89_FCC][1][59] = 22,
- [0][0][1][0][RTW89_FCC][2][59] = 68,
[0][0][1][0][RTW89_ETSI][1][59] = 127,
[0][0][1][0][RTW89_ETSI][0][59] = 127,
[0][0][1][0][RTW89_MKK][1][59] = 127,
[0][0][1][0][RTW89_MKK][0][59] = 127,
[0][0][1][0][RTW89_IC][1][59] = 22,
- [0][0][1][0][RTW89_IC][2][59] = 68,
[0][0][1][0][RTW89_KCC][1][59] = 26,
[0][0][1][0][RTW89_KCC][0][59] = 127,
[0][0][1][0][RTW89_ACMA][1][59] = 127,
@@ -39029,13 +38477,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][59] = 127,
[0][0][1][0][RTW89_THAILAND][0][59] = 127,
[0][0][1][0][RTW89_FCC][1][60] = 22,
- [0][0][1][0][RTW89_FCC][2][60] = 68,
[0][0][1][0][RTW89_ETSI][1][60] = 127,
[0][0][1][0][RTW89_ETSI][0][60] = 127,
[0][0][1][0][RTW89_MKK][1][60] = 127,
[0][0][1][0][RTW89_MKK][0][60] = 127,
[0][0][1][0][RTW89_IC][1][60] = 22,
- [0][0][1][0][RTW89_IC][2][60] = 68,
[0][0][1][0][RTW89_KCC][1][60] = 26,
[0][0][1][0][RTW89_KCC][0][60] = 127,
[0][0][1][0][RTW89_ACMA][1][60] = 127,
@@ -39048,13 +38494,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][60] = 127,
[0][0][1][0][RTW89_THAILAND][0][60] = 127,
[0][0][1][0][RTW89_FCC][1][62] = 22,
- [0][0][1][0][RTW89_FCC][2][62] = 68,
[0][0][1][0][RTW89_ETSI][1][62] = 127,
[0][0][1][0][RTW89_ETSI][0][62] = 127,
[0][0][1][0][RTW89_MKK][1][62] = 127,
[0][0][1][0][RTW89_MKK][0][62] = 127,
[0][0][1][0][RTW89_IC][1][62] = 22,
- [0][0][1][0][RTW89_IC][2][62] = 68,
[0][0][1][0][RTW89_KCC][1][62] = 26,
[0][0][1][0][RTW89_KCC][0][62] = 127,
[0][0][1][0][RTW89_ACMA][1][62] = 127,
@@ -39067,13 +38511,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][62] = 127,
[0][0][1][0][RTW89_THAILAND][0][62] = 127,
[0][0][1][0][RTW89_FCC][1][64] = 22,
- [0][0][1][0][RTW89_FCC][2][64] = 68,
[0][0][1][0][RTW89_ETSI][1][64] = 127,
[0][0][1][0][RTW89_ETSI][0][64] = 127,
[0][0][1][0][RTW89_MKK][1][64] = 127,
[0][0][1][0][RTW89_MKK][0][64] = 127,
[0][0][1][0][RTW89_IC][1][64] = 22,
- [0][0][1][0][RTW89_IC][2][64] = 68,
[0][0][1][0][RTW89_KCC][1][64] = 26,
[0][0][1][0][RTW89_KCC][0][64] = 127,
[0][0][1][0][RTW89_ACMA][1][64] = 127,
@@ -39086,13 +38528,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][64] = 127,
[0][0][1][0][RTW89_THAILAND][0][64] = 127,
[0][0][1][0][RTW89_FCC][1][66] = 22,
- [0][0][1][0][RTW89_FCC][2][66] = 68,
[0][0][1][0][RTW89_ETSI][1][66] = 127,
[0][0][1][0][RTW89_ETSI][0][66] = 127,
[0][0][1][0][RTW89_MKK][1][66] = 127,
[0][0][1][0][RTW89_MKK][0][66] = 127,
[0][0][1][0][RTW89_IC][1][66] = 22,
- [0][0][1][0][RTW89_IC][2][66] = 68,
[0][0][1][0][RTW89_KCC][1][66] = 26,
[0][0][1][0][RTW89_KCC][0][66] = 127,
[0][0][1][0][RTW89_ACMA][1][66] = 127,
@@ -39105,13 +38545,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][66] = 127,
[0][0][1][0][RTW89_THAILAND][0][66] = 127,
[0][0][1][0][RTW89_FCC][1][68] = 22,
- [0][0][1][0][RTW89_FCC][2][68] = 68,
[0][0][1][0][RTW89_ETSI][1][68] = 127,
[0][0][1][0][RTW89_ETSI][0][68] = 127,
[0][0][1][0][RTW89_MKK][1][68] = 127,
[0][0][1][0][RTW89_MKK][0][68] = 127,
[0][0][1][0][RTW89_IC][1][68] = 22,
- [0][0][1][0][RTW89_IC][2][68] = 68,
[0][0][1][0][RTW89_KCC][1][68] = 26,
[0][0][1][0][RTW89_KCC][0][68] = 127,
[0][0][1][0][RTW89_ACMA][1][68] = 127,
@@ -39124,13 +38562,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][68] = 127,
[0][0][1][0][RTW89_THAILAND][0][68] = 127,
[0][0][1][0][RTW89_FCC][1][70] = 24,
- [0][0][1][0][RTW89_FCC][2][70] = 68,
[0][0][1][0][RTW89_ETSI][1][70] = 127,
[0][0][1][0][RTW89_ETSI][0][70] = 127,
[0][0][1][0][RTW89_MKK][1][70] = 127,
[0][0][1][0][RTW89_MKK][0][70] = 127,
[0][0][1][0][RTW89_IC][1][70] = 24,
- [0][0][1][0][RTW89_IC][2][70] = 68,
[0][0][1][0][RTW89_KCC][1][70] = 26,
[0][0][1][0][RTW89_KCC][0][70] = 127,
[0][0][1][0][RTW89_ACMA][1][70] = 127,
@@ -39143,13 +38579,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][70] = 127,
[0][0][1][0][RTW89_THAILAND][0][70] = 127,
[0][0][1][0][RTW89_FCC][1][72] = 22,
- [0][0][1][0][RTW89_FCC][2][72] = 68,
[0][0][1][0][RTW89_ETSI][1][72] = 127,
[0][0][1][0][RTW89_ETSI][0][72] = 127,
[0][0][1][0][RTW89_MKK][1][72] = 127,
[0][0][1][0][RTW89_MKK][0][72] = 127,
[0][0][1][0][RTW89_IC][1][72] = 22,
- [0][0][1][0][RTW89_IC][2][72] = 68,
[0][0][1][0][RTW89_KCC][1][72] = 26,
[0][0][1][0][RTW89_KCC][0][72] = 127,
[0][0][1][0][RTW89_ACMA][1][72] = 127,
@@ -39162,13 +38596,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][72] = 127,
[0][0][1][0][RTW89_THAILAND][0][72] = 127,
[0][0][1][0][RTW89_FCC][1][74] = 22,
- [0][0][1][0][RTW89_FCC][2][74] = 68,
[0][0][1][0][RTW89_ETSI][1][74] = 127,
[0][0][1][0][RTW89_ETSI][0][74] = 127,
[0][0][1][0][RTW89_MKK][1][74] = 127,
[0][0][1][0][RTW89_MKK][0][74] = 127,
[0][0][1][0][RTW89_IC][1][74] = 22,
- [0][0][1][0][RTW89_IC][2][74] = 68,
[0][0][1][0][RTW89_KCC][1][74] = 26,
[0][0][1][0][RTW89_KCC][0][74] = 127,
[0][0][1][0][RTW89_ACMA][1][74] = 127,
@@ -39181,13 +38613,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][74] = 127,
[0][0][1][0][RTW89_THAILAND][0][74] = 127,
[0][0][1][0][RTW89_FCC][1][75] = 22,
- [0][0][1][0][RTW89_FCC][2][75] = 68,
[0][0][1][0][RTW89_ETSI][1][75] = 127,
[0][0][1][0][RTW89_ETSI][0][75] = 127,
[0][0][1][0][RTW89_MKK][1][75] = 127,
[0][0][1][0][RTW89_MKK][0][75] = 127,
[0][0][1][0][RTW89_IC][1][75] = 22,
- [0][0][1][0][RTW89_IC][2][75] = 68,
[0][0][1][0][RTW89_KCC][1][75] = 26,
[0][0][1][0][RTW89_KCC][0][75] = 127,
[0][0][1][0][RTW89_ACMA][1][75] = 127,
@@ -39200,13 +38630,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][75] = 127,
[0][0][1][0][RTW89_THAILAND][0][75] = 127,
[0][0][1][0][RTW89_FCC][1][77] = 22,
- [0][0][1][0][RTW89_FCC][2][77] = 68,
[0][0][1][0][RTW89_ETSI][1][77] = 127,
[0][0][1][0][RTW89_ETSI][0][77] = 127,
[0][0][1][0][RTW89_MKK][1][77] = 127,
[0][0][1][0][RTW89_MKK][0][77] = 127,
[0][0][1][0][RTW89_IC][1][77] = 22,
- [0][0][1][0][RTW89_IC][2][77] = 68,
[0][0][1][0][RTW89_KCC][1][77] = 26,
[0][0][1][0][RTW89_KCC][0][77] = 127,
[0][0][1][0][RTW89_ACMA][1][77] = 127,
@@ -39219,13 +38647,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][77] = 127,
[0][0][1][0][RTW89_THAILAND][0][77] = 127,
[0][0][1][0][RTW89_FCC][1][79] = 22,
- [0][0][1][0][RTW89_FCC][2][79] = 68,
[0][0][1][0][RTW89_ETSI][1][79] = 127,
[0][0][1][0][RTW89_ETSI][0][79] = 127,
[0][0][1][0][RTW89_MKK][1][79] = 127,
[0][0][1][0][RTW89_MKK][0][79] = 127,
[0][0][1][0][RTW89_IC][1][79] = 22,
- [0][0][1][0][RTW89_IC][2][79] = 68,
[0][0][1][0][RTW89_KCC][1][79] = 26,
[0][0][1][0][RTW89_KCC][0][79] = 127,
[0][0][1][0][RTW89_ACMA][1][79] = 127,
@@ -39238,13 +38664,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][79] = 127,
[0][0][1][0][RTW89_THAILAND][0][79] = 127,
[0][0][1][0][RTW89_FCC][1][81] = 22,
- [0][0][1][0][RTW89_FCC][2][81] = 68,
[0][0][1][0][RTW89_ETSI][1][81] = 127,
[0][0][1][0][RTW89_ETSI][0][81] = 127,
[0][0][1][0][RTW89_MKK][1][81] = 127,
[0][0][1][0][RTW89_MKK][0][81] = 127,
[0][0][1][0][RTW89_IC][1][81] = 22,
- [0][0][1][0][RTW89_IC][2][81] = 68,
[0][0][1][0][RTW89_KCC][1][81] = 26,
[0][0][1][0][RTW89_KCC][0][81] = 127,
[0][0][1][0][RTW89_ACMA][1][81] = 127,
@@ -39257,13 +38681,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][81] = 127,
[0][0][1][0][RTW89_THAILAND][0][81] = 127,
[0][0][1][0][RTW89_FCC][1][83] = 22,
- [0][0][1][0][RTW89_FCC][2][83] = 68,
[0][0][1][0][RTW89_ETSI][1][83] = 127,
[0][0][1][0][RTW89_ETSI][0][83] = 127,
[0][0][1][0][RTW89_MKK][1][83] = 127,
[0][0][1][0][RTW89_MKK][0][83] = 127,
[0][0][1][0][RTW89_IC][1][83] = 22,
- [0][0][1][0][RTW89_IC][2][83] = 68,
[0][0][1][0][RTW89_KCC][1][83] = 32,
[0][0][1][0][RTW89_KCC][0][83] = 127,
[0][0][1][0][RTW89_ACMA][1][83] = 127,
@@ -39276,13 +38698,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][83] = 127,
[0][0][1][0][RTW89_THAILAND][0][83] = 127,
[0][0][1][0][RTW89_FCC][1][85] = 22,
- [0][0][1][0][RTW89_FCC][2][85] = 68,
[0][0][1][0][RTW89_ETSI][1][85] = 127,
[0][0][1][0][RTW89_ETSI][0][85] = 127,
[0][0][1][0][RTW89_MKK][1][85] = 127,
[0][0][1][0][RTW89_MKK][0][85] = 127,
[0][0][1][0][RTW89_IC][1][85] = 22,
- [0][0][1][0][RTW89_IC][2][85] = 68,
[0][0][1][0][RTW89_KCC][1][85] = 32,
[0][0][1][0][RTW89_KCC][0][85] = 127,
[0][0][1][0][RTW89_ACMA][1][85] = 127,
@@ -39295,13 +38715,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][85] = 127,
[0][0][1][0][RTW89_THAILAND][0][85] = 127,
[0][0][1][0][RTW89_FCC][1][87] = 22,
- [0][0][1][0][RTW89_FCC][2][87] = 127,
[0][0][1][0][RTW89_ETSI][1][87] = 127,
[0][0][1][0][RTW89_ETSI][0][87] = 127,
[0][0][1][0][RTW89_MKK][1][87] = 127,
[0][0][1][0][RTW89_MKK][0][87] = 127,
[0][0][1][0][RTW89_IC][1][87] = 22,
- [0][0][1][0][RTW89_IC][2][87] = 127,
[0][0][1][0][RTW89_KCC][1][87] = 32,
[0][0][1][0][RTW89_KCC][0][87] = 127,
[0][0][1][0][RTW89_ACMA][1][87] = 127,
@@ -39314,13 +38732,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][87] = 127,
[0][0][1][0][RTW89_THAILAND][0][87] = 127,
[0][0][1][0][RTW89_FCC][1][89] = 22,
- [0][0][1][0][RTW89_FCC][2][89] = 127,
[0][0][1][0][RTW89_ETSI][1][89] = 127,
[0][0][1][0][RTW89_ETSI][0][89] = 127,
[0][0][1][0][RTW89_MKK][1][89] = 127,
[0][0][1][0][RTW89_MKK][0][89] = 127,
[0][0][1][0][RTW89_IC][1][89] = 22,
- [0][0][1][0][RTW89_IC][2][89] = 127,
[0][0][1][0][RTW89_KCC][1][89] = 32,
[0][0][1][0][RTW89_KCC][0][89] = 127,
[0][0][1][0][RTW89_ACMA][1][89] = 127,
@@ -39333,13 +38749,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][89] = 127,
[0][0][1][0][RTW89_THAILAND][0][89] = 127,
[0][0][1][0][RTW89_FCC][1][90] = 22,
- [0][0][1][0][RTW89_FCC][2][90] = 127,
[0][0][1][0][RTW89_ETSI][1][90] = 127,
[0][0][1][0][RTW89_ETSI][0][90] = 127,
[0][0][1][0][RTW89_MKK][1][90] = 127,
[0][0][1][0][RTW89_MKK][0][90] = 127,
[0][0][1][0][RTW89_IC][1][90] = 22,
- [0][0][1][0][RTW89_IC][2][90] = 127,
[0][0][1][0][RTW89_KCC][1][90] = 32,
[0][0][1][0][RTW89_KCC][0][90] = 127,
[0][0][1][0][RTW89_ACMA][1][90] = 127,
@@ -39352,13 +38766,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][90] = 127,
[0][0][1][0][RTW89_THAILAND][0][90] = 127,
[0][0][1][0][RTW89_FCC][1][92] = 22,
- [0][0][1][0][RTW89_FCC][2][92] = 127,
[0][0][1][0][RTW89_ETSI][1][92] = 127,
[0][0][1][0][RTW89_ETSI][0][92] = 127,
[0][0][1][0][RTW89_MKK][1][92] = 127,
[0][0][1][0][RTW89_MKK][0][92] = 127,
[0][0][1][0][RTW89_IC][1][92] = 22,
- [0][0][1][0][RTW89_IC][2][92] = 127,
[0][0][1][0][RTW89_KCC][1][92] = 32,
[0][0][1][0][RTW89_KCC][0][92] = 127,
[0][0][1][0][RTW89_ACMA][1][92] = 127,
@@ -39371,13 +38783,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][92] = 127,
[0][0][1][0][RTW89_THAILAND][0][92] = 127,
[0][0][1][0][RTW89_FCC][1][94] = 22,
- [0][0][1][0][RTW89_FCC][2][94] = 127,
[0][0][1][0][RTW89_ETSI][1][94] = 127,
[0][0][1][0][RTW89_ETSI][0][94] = 127,
[0][0][1][0][RTW89_MKK][1][94] = 127,
[0][0][1][0][RTW89_MKK][0][94] = 127,
[0][0][1][0][RTW89_IC][1][94] = 22,
- [0][0][1][0][RTW89_IC][2][94] = 127,
[0][0][1][0][RTW89_KCC][1][94] = 32,
[0][0][1][0][RTW89_KCC][0][94] = 127,
[0][0][1][0][RTW89_ACMA][1][94] = 127,
@@ -39390,13 +38800,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][94] = 127,
[0][0][1][0][RTW89_THAILAND][0][94] = 127,
[0][0][1][0][RTW89_FCC][1][96] = 22,
- [0][0][1][0][RTW89_FCC][2][96] = 127,
[0][0][1][0][RTW89_ETSI][1][96] = 127,
[0][0][1][0][RTW89_ETSI][0][96] = 127,
[0][0][1][0][RTW89_MKK][1][96] = 127,
[0][0][1][0][RTW89_MKK][0][96] = 127,
[0][0][1][0][RTW89_IC][1][96] = 22,
- [0][0][1][0][RTW89_IC][2][96] = 127,
[0][0][1][0][RTW89_KCC][1][96] = 32,
[0][0][1][0][RTW89_KCC][0][96] = 127,
[0][0][1][0][RTW89_ACMA][1][96] = 127,
@@ -39409,13 +38817,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][96] = 127,
[0][0][1][0][RTW89_THAILAND][0][96] = 127,
[0][0][1][0][RTW89_FCC][1][98] = 22,
- [0][0][1][0][RTW89_FCC][2][98] = 127,
[0][0][1][0][RTW89_ETSI][1][98] = 127,
[0][0][1][0][RTW89_ETSI][0][98] = 127,
[0][0][1][0][RTW89_MKK][1][98] = 127,
[0][0][1][0][RTW89_MKK][0][98] = 127,
[0][0][1][0][RTW89_IC][1][98] = 22,
- [0][0][1][0][RTW89_IC][2][98] = 127,
[0][0][1][0][RTW89_KCC][1][98] = 32,
[0][0][1][0][RTW89_KCC][0][98] = 127,
[0][0][1][0][RTW89_ACMA][1][98] = 127,
@@ -39428,13 +38834,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][98] = 127,
[0][0][1][0][RTW89_THAILAND][0][98] = 127,
[0][0][1][0][RTW89_FCC][1][100] = 22,
- [0][0][1][0][RTW89_FCC][2][100] = 127,
[0][0][1][0][RTW89_ETSI][1][100] = 127,
[0][0][1][0][RTW89_ETSI][0][100] = 127,
[0][0][1][0][RTW89_MKK][1][100] = 127,
[0][0][1][0][RTW89_MKK][0][100] = 127,
[0][0][1][0][RTW89_IC][1][100] = 22,
- [0][0][1][0][RTW89_IC][2][100] = 127,
[0][0][1][0][RTW89_KCC][1][100] = 32,
[0][0][1][0][RTW89_KCC][0][100] = 127,
[0][0][1][0][RTW89_ACMA][1][100] = 127,
@@ -39447,13 +38851,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][100] = 127,
[0][0][1][0][RTW89_THAILAND][0][100] = 127,
[0][0][1][0][RTW89_FCC][1][102] = 22,
- [0][0][1][0][RTW89_FCC][2][102] = 127,
[0][0][1][0][RTW89_ETSI][1][102] = 127,
[0][0][1][0][RTW89_ETSI][0][102] = 127,
[0][0][1][0][RTW89_MKK][1][102] = 127,
[0][0][1][0][RTW89_MKK][0][102] = 127,
[0][0][1][0][RTW89_IC][1][102] = 22,
- [0][0][1][0][RTW89_IC][2][102] = 127,
[0][0][1][0][RTW89_KCC][1][102] = 32,
[0][0][1][0][RTW89_KCC][0][102] = 127,
[0][0][1][0][RTW89_ACMA][1][102] = 127,
@@ -39466,13 +38868,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][102] = 127,
[0][0][1][0][RTW89_THAILAND][0][102] = 127,
[0][0][1][0][RTW89_FCC][1][104] = 22,
- [0][0][1][0][RTW89_FCC][2][104] = 127,
[0][0][1][0][RTW89_ETSI][1][104] = 127,
[0][0][1][0][RTW89_ETSI][0][104] = 127,
[0][0][1][0][RTW89_MKK][1][104] = 127,
[0][0][1][0][RTW89_MKK][0][104] = 127,
[0][0][1][0][RTW89_IC][1][104] = 22,
- [0][0][1][0][RTW89_IC][2][104] = 127,
[0][0][1][0][RTW89_KCC][1][104] = 32,
[0][0][1][0][RTW89_KCC][0][104] = 127,
[0][0][1][0][RTW89_ACMA][1][104] = 127,
@@ -39485,13 +38885,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][104] = 127,
[0][0][1][0][RTW89_THAILAND][0][104] = 127,
[0][0][1][0][RTW89_FCC][1][105] = 22,
- [0][0][1][0][RTW89_FCC][2][105] = 127,
[0][0][1][0][RTW89_ETSI][1][105] = 127,
[0][0][1][0][RTW89_ETSI][0][105] = 127,
[0][0][1][0][RTW89_MKK][1][105] = 127,
[0][0][1][0][RTW89_MKK][0][105] = 127,
[0][0][1][0][RTW89_IC][1][105] = 22,
- [0][0][1][0][RTW89_IC][2][105] = 127,
[0][0][1][0][RTW89_KCC][1][105] = 32,
[0][0][1][0][RTW89_KCC][0][105] = 127,
[0][0][1][0][RTW89_ACMA][1][105] = 127,
@@ -39504,13 +38902,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][105] = 127,
[0][0][1][0][RTW89_THAILAND][0][105] = 127,
[0][0][1][0][RTW89_FCC][1][107] = 24,
- [0][0][1][0][RTW89_FCC][2][107] = 127,
[0][0][1][0][RTW89_ETSI][1][107] = 127,
[0][0][1][0][RTW89_ETSI][0][107] = 127,
[0][0][1][0][RTW89_MKK][1][107] = 127,
[0][0][1][0][RTW89_MKK][0][107] = 127,
[0][0][1][0][RTW89_IC][1][107] = 24,
- [0][0][1][0][RTW89_IC][2][107] = 127,
[0][0][1][0][RTW89_KCC][1][107] = 32,
[0][0][1][0][RTW89_KCC][0][107] = 127,
[0][0][1][0][RTW89_ACMA][1][107] = 127,
@@ -39523,13 +38919,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][107] = 127,
[0][0][1][0][RTW89_THAILAND][0][107] = 127,
[0][0][1][0][RTW89_FCC][1][109] = 24,
- [0][0][1][0][RTW89_FCC][2][109] = 127,
[0][0][1][0][RTW89_ETSI][1][109] = 127,
[0][0][1][0][RTW89_ETSI][0][109] = 127,
[0][0][1][0][RTW89_MKK][1][109] = 127,
[0][0][1][0][RTW89_MKK][0][109] = 127,
[0][0][1][0][RTW89_IC][1][109] = 24,
- [0][0][1][0][RTW89_IC][2][109] = 127,
[0][0][1][0][RTW89_KCC][1][109] = 32,
[0][0][1][0][RTW89_KCC][0][109] = 127,
[0][0][1][0][RTW89_ACMA][1][109] = 127,
@@ -39542,13 +38936,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][109] = 127,
[0][0][1][0][RTW89_THAILAND][0][109] = 127,
[0][0][1][0][RTW89_FCC][1][111] = 127,
- [0][0][1][0][RTW89_FCC][2][111] = 127,
[0][0][1][0][RTW89_ETSI][1][111] = 127,
[0][0][1][0][RTW89_ETSI][0][111] = 127,
[0][0][1][0][RTW89_MKK][1][111] = 127,
[0][0][1][0][RTW89_MKK][0][111] = 127,
[0][0][1][0][RTW89_IC][1][111] = 127,
- [0][0][1][0][RTW89_IC][2][111] = 127,
[0][0][1][0][RTW89_KCC][1][111] = 127,
[0][0][1][0][RTW89_KCC][0][111] = 127,
[0][0][1][0][RTW89_ACMA][1][111] = 127,
@@ -39561,13 +38953,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][111] = 127,
[0][0][1][0][RTW89_THAILAND][0][111] = 127,
[0][0][1][0][RTW89_FCC][1][113] = 127,
- [0][0][1][0][RTW89_FCC][2][113] = 127,
[0][0][1][0][RTW89_ETSI][1][113] = 127,
[0][0][1][0][RTW89_ETSI][0][113] = 127,
[0][0][1][0][RTW89_MKK][1][113] = 127,
[0][0][1][0][RTW89_MKK][0][113] = 127,
[0][0][1][0][RTW89_IC][1][113] = 127,
- [0][0][1][0][RTW89_IC][2][113] = 127,
[0][0][1][0][RTW89_KCC][1][113] = 127,
[0][0][1][0][RTW89_KCC][0][113] = 127,
[0][0][1][0][RTW89_ACMA][1][113] = 127,
@@ -39580,13 +38970,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][113] = 127,
[0][0][1][0][RTW89_THAILAND][0][113] = 127,
[0][0][1][0][RTW89_FCC][1][115] = 127,
- [0][0][1][0][RTW89_FCC][2][115] = 127,
[0][0][1][0][RTW89_ETSI][1][115] = 127,
[0][0][1][0][RTW89_ETSI][0][115] = 127,
[0][0][1][0][RTW89_MKK][1][115] = 127,
[0][0][1][0][RTW89_MKK][0][115] = 127,
[0][0][1][0][RTW89_IC][1][115] = 127,
- [0][0][1][0][RTW89_IC][2][115] = 127,
[0][0][1][0][RTW89_KCC][1][115] = 127,
[0][0][1][0][RTW89_KCC][0][115] = 127,
[0][0][1][0][RTW89_ACMA][1][115] = 127,
@@ -39599,13 +38987,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][115] = 127,
[0][0][1][0][RTW89_THAILAND][0][115] = 127,
[0][0][1][0][RTW89_FCC][1][117] = 127,
- [0][0][1][0][RTW89_FCC][2][117] = 127,
[0][0][1][0][RTW89_ETSI][1][117] = 127,
[0][0][1][0][RTW89_ETSI][0][117] = 127,
[0][0][1][0][RTW89_MKK][1][117] = 127,
[0][0][1][0][RTW89_MKK][0][117] = 127,
[0][0][1][0][RTW89_IC][1][117] = 127,
- [0][0][1][0][RTW89_IC][2][117] = 127,
[0][0][1][0][RTW89_KCC][1][117] = 127,
[0][0][1][0][RTW89_KCC][0][117] = 127,
[0][0][1][0][RTW89_ACMA][1][117] = 127,
@@ -39618,13 +39004,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][117] = 127,
[0][0][1][0][RTW89_THAILAND][0][117] = 127,
[0][0][1][0][RTW89_FCC][1][119] = 127,
- [0][0][1][0][RTW89_FCC][2][119] = 127,
[0][0][1][0][RTW89_ETSI][1][119] = 127,
[0][0][1][0][RTW89_ETSI][0][119] = 127,
[0][0][1][0][RTW89_MKK][1][119] = 127,
[0][0][1][0][RTW89_MKK][0][119] = 127,
[0][0][1][0][RTW89_IC][1][119] = 127,
- [0][0][1][0][RTW89_IC][2][119] = 127,
[0][0][1][0][RTW89_KCC][1][119] = 127,
[0][0][1][0][RTW89_KCC][0][119] = 127,
[0][0][1][0][RTW89_ACMA][1][119] = 127,
@@ -39637,13 +39021,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][1][0][RTW89_THAILAND][1][119] = 127,
[0][0][1][0][RTW89_THAILAND][0][119] = 127,
[0][1][1][0][RTW89_FCC][1][0] = -2,
- [0][1][1][0][RTW89_FCC][2][0] = 54,
[0][1][1][0][RTW89_ETSI][1][0] = 54,
[0][1][1][0][RTW89_ETSI][0][0] = 18,
[0][1][1][0][RTW89_MKK][1][0] = 56,
[0][1][1][0][RTW89_MKK][0][0] = 16,
[0][1][1][0][RTW89_IC][1][0] = -2,
- [0][1][1][0][RTW89_IC][2][0] = 54,
[0][1][1][0][RTW89_KCC][1][0] = 12,
[0][1][1][0][RTW89_KCC][0][0] = 10,
[0][1][1][0][RTW89_ACMA][1][0] = 54,
@@ -39656,13 +39038,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][0] = 44,
[0][1][1][0][RTW89_THAILAND][0][0] = -2,
[0][1][1][0][RTW89_FCC][1][2] = -4,
- [0][1][1][0][RTW89_FCC][2][2] = 54,
[0][1][1][0][RTW89_ETSI][1][2] = 54,
[0][1][1][0][RTW89_ETSI][0][2] = 18,
[0][1][1][0][RTW89_MKK][1][2] = 54,
[0][1][1][0][RTW89_MKK][0][2] = 16,
[0][1][1][0][RTW89_IC][1][2] = -4,
- [0][1][1][0][RTW89_IC][2][2] = 54,
[0][1][1][0][RTW89_KCC][1][2] = 12,
[0][1][1][0][RTW89_KCC][0][2] = 12,
[0][1][1][0][RTW89_ACMA][1][2] = 54,
@@ -39675,13 +39055,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][2] = 44,
[0][1][1][0][RTW89_THAILAND][0][2] = -4,
[0][1][1][0][RTW89_FCC][1][4] = -4,
- [0][1][1][0][RTW89_FCC][2][4] = 54,
[0][1][1][0][RTW89_ETSI][1][4] = 54,
[0][1][1][0][RTW89_ETSI][0][4] = 18,
[0][1][1][0][RTW89_MKK][1][4] = 54,
[0][1][1][0][RTW89_MKK][0][4] = 16,
[0][1][1][0][RTW89_IC][1][4] = -4,
- [0][1][1][0][RTW89_IC][2][4] = 54,
[0][1][1][0][RTW89_KCC][1][4] = 12,
[0][1][1][0][RTW89_KCC][0][4] = 12,
[0][1][1][0][RTW89_ACMA][1][4] = 54,
@@ -39694,13 +39072,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][4] = 44,
[0][1][1][0][RTW89_THAILAND][0][4] = -4,
[0][1][1][0][RTW89_FCC][1][6] = -4,
- [0][1][1][0][RTW89_FCC][2][6] = 54,
[0][1][1][0][RTW89_ETSI][1][6] = 54,
[0][1][1][0][RTW89_ETSI][0][6] = 18,
[0][1][1][0][RTW89_MKK][1][6] = 54,
[0][1][1][0][RTW89_MKK][0][6] = 16,
[0][1][1][0][RTW89_IC][1][6] = -4,
- [0][1][1][0][RTW89_IC][2][6] = 54,
[0][1][1][0][RTW89_KCC][1][6] = 12,
[0][1][1][0][RTW89_KCC][0][6] = 12,
[0][1][1][0][RTW89_ACMA][1][6] = 54,
@@ -39713,13 +39089,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][6] = 44,
[0][1][1][0][RTW89_THAILAND][0][6] = -4,
[0][1][1][0][RTW89_FCC][1][8] = -4,
- [0][1][1][0][RTW89_FCC][2][8] = 54,
[0][1][1][0][RTW89_ETSI][1][8] = 54,
[0][1][1][0][RTW89_ETSI][0][8] = 18,
[0][1][1][0][RTW89_MKK][1][8] = 54,
[0][1][1][0][RTW89_MKK][0][8] = 16,
[0][1][1][0][RTW89_IC][1][8] = -4,
- [0][1][1][0][RTW89_IC][2][8] = 54,
[0][1][1][0][RTW89_KCC][1][8] = 12,
[0][1][1][0][RTW89_KCC][0][8] = 12,
[0][1][1][0][RTW89_ACMA][1][8] = 54,
@@ -39732,13 +39106,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][8] = 44,
[0][1][1][0][RTW89_THAILAND][0][8] = -4,
[0][1][1][0][RTW89_FCC][1][10] = -4,
- [0][1][1][0][RTW89_FCC][2][10] = 54,
[0][1][1][0][RTW89_ETSI][1][10] = 54,
[0][1][1][0][RTW89_ETSI][0][10] = 18,
[0][1][1][0][RTW89_MKK][1][10] = 54,
[0][1][1][0][RTW89_MKK][0][10] = 16,
[0][1][1][0][RTW89_IC][1][10] = -4,
- [0][1][1][0][RTW89_IC][2][10] = 54,
[0][1][1][0][RTW89_KCC][1][10] = 12,
[0][1][1][0][RTW89_KCC][0][10] = 12,
[0][1][1][0][RTW89_ACMA][1][10] = 54,
@@ -39751,13 +39123,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][10] = 44,
[0][1][1][0][RTW89_THAILAND][0][10] = -4,
[0][1][1][0][RTW89_FCC][1][12] = -4,
- [0][1][1][0][RTW89_FCC][2][12] = 54,
[0][1][1][0][RTW89_ETSI][1][12] = 54,
[0][1][1][0][RTW89_ETSI][0][12] = 18,
[0][1][1][0][RTW89_MKK][1][12] = 54,
[0][1][1][0][RTW89_MKK][0][12] = 16,
[0][1][1][0][RTW89_IC][1][12] = -4,
- [0][1][1][0][RTW89_IC][2][12] = 54,
[0][1][1][0][RTW89_KCC][1][12] = 12,
[0][1][1][0][RTW89_KCC][0][12] = 12,
[0][1][1][0][RTW89_ACMA][1][12] = 54,
@@ -39770,13 +39140,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][12] = 44,
[0][1][1][0][RTW89_THAILAND][0][12] = -4,
[0][1][1][0][RTW89_FCC][1][14] = -4,
- [0][1][1][0][RTW89_FCC][2][14] = 54,
[0][1][1][0][RTW89_ETSI][1][14] = 54,
[0][1][1][0][RTW89_ETSI][0][14] = 18,
[0][1][1][0][RTW89_MKK][1][14] = 54,
[0][1][1][0][RTW89_MKK][0][14] = 16,
[0][1][1][0][RTW89_IC][1][14] = -4,
- [0][1][1][0][RTW89_IC][2][14] = 54,
[0][1][1][0][RTW89_KCC][1][14] = 12,
[0][1][1][0][RTW89_KCC][0][14] = 12,
[0][1][1][0][RTW89_ACMA][1][14] = 54,
@@ -39789,13 +39157,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][14] = 44,
[0][1][1][0][RTW89_THAILAND][0][14] = -4,
[0][1][1][0][RTW89_FCC][1][15] = -4,
- [0][1][1][0][RTW89_FCC][2][15] = 54,
[0][1][1][0][RTW89_ETSI][1][15] = 54,
[0][1][1][0][RTW89_ETSI][0][15] = 18,
[0][1][1][0][RTW89_MKK][1][15] = 54,
[0][1][1][0][RTW89_MKK][0][15] = 16,
[0][1][1][0][RTW89_IC][1][15] = -4,
- [0][1][1][0][RTW89_IC][2][15] = 54,
[0][1][1][0][RTW89_KCC][1][15] = 12,
[0][1][1][0][RTW89_KCC][0][15] = 12,
[0][1][1][0][RTW89_ACMA][1][15] = 54,
@@ -39808,13 +39174,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][15] = 44,
[0][1][1][0][RTW89_THAILAND][0][15] = -4,
[0][1][1][0][RTW89_FCC][1][17] = -4,
- [0][1][1][0][RTW89_FCC][2][17] = 54,
[0][1][1][0][RTW89_ETSI][1][17] = 54,
[0][1][1][0][RTW89_ETSI][0][17] = 18,
[0][1][1][0][RTW89_MKK][1][17] = 54,
[0][1][1][0][RTW89_MKK][0][17] = 16,
[0][1][1][0][RTW89_IC][1][17] = -4,
- [0][1][1][0][RTW89_IC][2][17] = 54,
[0][1][1][0][RTW89_KCC][1][17] = 12,
[0][1][1][0][RTW89_KCC][0][17] = 12,
[0][1][1][0][RTW89_ACMA][1][17] = 54,
@@ -39827,13 +39191,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][17] = 44,
[0][1][1][0][RTW89_THAILAND][0][17] = -4,
[0][1][1][0][RTW89_FCC][1][19] = -4,
- [0][1][1][0][RTW89_FCC][2][19] = 54,
[0][1][1][0][RTW89_ETSI][1][19] = 54,
[0][1][1][0][RTW89_ETSI][0][19] = 18,
[0][1][1][0][RTW89_MKK][1][19] = 54,
[0][1][1][0][RTW89_MKK][0][19] = 16,
[0][1][1][0][RTW89_IC][1][19] = -4,
- [0][1][1][0][RTW89_IC][2][19] = 54,
[0][1][1][0][RTW89_KCC][1][19] = 12,
[0][1][1][0][RTW89_KCC][0][19] = 12,
[0][1][1][0][RTW89_ACMA][1][19] = 54,
@@ -39846,13 +39208,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][19] = 44,
[0][1][1][0][RTW89_THAILAND][0][19] = -4,
[0][1][1][0][RTW89_FCC][1][21] = -4,
- [0][1][1][0][RTW89_FCC][2][21] = 54,
[0][1][1][0][RTW89_ETSI][1][21] = 54,
[0][1][1][0][RTW89_ETSI][0][21] = 18,
[0][1][1][0][RTW89_MKK][1][21] = 54,
[0][1][1][0][RTW89_MKK][0][21] = 16,
[0][1][1][0][RTW89_IC][1][21] = -4,
- [0][1][1][0][RTW89_IC][2][21] = 54,
[0][1][1][0][RTW89_KCC][1][21] = 12,
[0][1][1][0][RTW89_KCC][0][21] = 12,
[0][1][1][0][RTW89_ACMA][1][21] = 54,
@@ -39865,13 +39225,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][21] = 44,
[0][1][1][0][RTW89_THAILAND][0][21] = -4,
[0][1][1][0][RTW89_FCC][1][23] = -4,
- [0][1][1][0][RTW89_FCC][2][23] = 68,
[0][1][1][0][RTW89_ETSI][1][23] = 54,
[0][1][1][0][RTW89_ETSI][0][23] = 18,
[0][1][1][0][RTW89_MKK][1][23] = 54,
[0][1][1][0][RTW89_MKK][0][23] = 16,
[0][1][1][0][RTW89_IC][1][23] = -4,
- [0][1][1][0][RTW89_IC][2][23] = 68,
[0][1][1][0][RTW89_KCC][1][23] = 12,
[0][1][1][0][RTW89_KCC][0][23] = 10,
[0][1][1][0][RTW89_ACMA][1][23] = 54,
@@ -39884,13 +39242,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][23] = 44,
[0][1][1][0][RTW89_THAILAND][0][23] = -4,
[0][1][1][0][RTW89_FCC][1][25] = -4,
- [0][1][1][0][RTW89_FCC][2][25] = 68,
[0][1][1][0][RTW89_ETSI][1][25] = 54,
[0][1][1][0][RTW89_ETSI][0][25] = 18,
[0][1][1][0][RTW89_MKK][1][25] = 54,
[0][1][1][0][RTW89_MKK][0][25] = 16,
[0][1][1][0][RTW89_IC][1][25] = -4,
- [0][1][1][0][RTW89_IC][2][25] = 68,
[0][1][1][0][RTW89_KCC][1][25] = 12,
[0][1][1][0][RTW89_KCC][0][25] = 14,
[0][1][1][0][RTW89_ACMA][1][25] = 54,
@@ -39903,13 +39259,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][25] = 42,
[0][1][1][0][RTW89_THAILAND][0][25] = -4,
[0][1][1][0][RTW89_FCC][1][27] = -4,
- [0][1][1][0][RTW89_FCC][2][27] = 68,
[0][1][1][0][RTW89_ETSI][1][27] = 54,
[0][1][1][0][RTW89_ETSI][0][27] = 18,
[0][1][1][0][RTW89_MKK][1][27] = 54,
[0][1][1][0][RTW89_MKK][0][27] = 16,
[0][1][1][0][RTW89_IC][1][27] = -4,
- [0][1][1][0][RTW89_IC][2][27] = 68,
[0][1][1][0][RTW89_KCC][1][27] = 12,
[0][1][1][0][RTW89_KCC][0][27] = 14,
[0][1][1][0][RTW89_ACMA][1][27] = 54,
@@ -39922,13 +39276,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][27] = 42,
[0][1][1][0][RTW89_THAILAND][0][27] = -4,
[0][1][1][0][RTW89_FCC][1][29] = -4,
- [0][1][1][0][RTW89_FCC][2][29] = 68,
[0][1][1][0][RTW89_ETSI][1][29] = 54,
[0][1][1][0][RTW89_ETSI][0][29] = 18,
[0][1][1][0][RTW89_MKK][1][29] = 54,
[0][1][1][0][RTW89_MKK][0][29] = 16,
[0][1][1][0][RTW89_IC][1][29] = -4,
- [0][1][1][0][RTW89_IC][2][29] = 68,
[0][1][1][0][RTW89_KCC][1][29] = 12,
[0][1][1][0][RTW89_KCC][0][29] = 14,
[0][1][1][0][RTW89_ACMA][1][29] = 54,
@@ -39941,13 +39293,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][29] = 42,
[0][1][1][0][RTW89_THAILAND][0][29] = -4,
[0][1][1][0][RTW89_FCC][1][30] = -4,
- [0][1][1][0][RTW89_FCC][2][30] = 68,
[0][1][1][0][RTW89_ETSI][1][30] = 54,
[0][1][1][0][RTW89_ETSI][0][30] = 18,
[0][1][1][0][RTW89_MKK][1][30] = 54,
[0][1][1][0][RTW89_MKK][0][30] = 16,
[0][1][1][0][RTW89_IC][1][30] = -4,
- [0][1][1][0][RTW89_IC][2][30] = 68,
[0][1][1][0][RTW89_KCC][1][30] = 12,
[0][1][1][0][RTW89_KCC][0][30] = 14,
[0][1][1][0][RTW89_ACMA][1][30] = 54,
@@ -39960,13 +39310,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][30] = 42,
[0][1][1][0][RTW89_THAILAND][0][30] = -4,
[0][1][1][0][RTW89_FCC][1][32] = -4,
- [0][1][1][0][RTW89_FCC][2][32] = 68,
[0][1][1][0][RTW89_ETSI][1][32] = 54,
[0][1][1][0][RTW89_ETSI][0][32] = 18,
[0][1][1][0][RTW89_MKK][1][32] = 54,
[0][1][1][0][RTW89_MKK][0][32] = 16,
[0][1][1][0][RTW89_IC][1][32] = -4,
- [0][1][1][0][RTW89_IC][2][32] = 68,
[0][1][1][0][RTW89_KCC][1][32] = 12,
[0][1][1][0][RTW89_KCC][0][32] = 14,
[0][1][1][0][RTW89_ACMA][1][32] = 54,
@@ -39979,13 +39327,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][32] = 42,
[0][1][1][0][RTW89_THAILAND][0][32] = -4,
[0][1][1][0][RTW89_FCC][1][34] = -4,
- [0][1][1][0][RTW89_FCC][2][34] = 68,
[0][1][1][0][RTW89_ETSI][1][34] = 54,
[0][1][1][0][RTW89_ETSI][0][34] = 18,
[0][1][1][0][RTW89_MKK][1][34] = 54,
[0][1][1][0][RTW89_MKK][0][34] = 16,
[0][1][1][0][RTW89_IC][1][34] = -4,
- [0][1][1][0][RTW89_IC][2][34] = 68,
[0][1][1][0][RTW89_KCC][1][34] = 12,
[0][1][1][0][RTW89_KCC][0][34] = 14,
[0][1][1][0][RTW89_ACMA][1][34] = 54,
@@ -39998,13 +39344,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][34] = 42,
[0][1][1][0][RTW89_THAILAND][0][34] = -4,
[0][1][1][0][RTW89_FCC][1][36] = -4,
- [0][1][1][0][RTW89_FCC][2][36] = 68,
[0][1][1][0][RTW89_ETSI][1][36] = 54,
[0][1][1][0][RTW89_ETSI][0][36] = 18,
[0][1][1][0][RTW89_MKK][1][36] = 54,
[0][1][1][0][RTW89_MKK][0][36] = 16,
[0][1][1][0][RTW89_IC][1][36] = -4,
- [0][1][1][0][RTW89_IC][2][36] = 68,
[0][1][1][0][RTW89_KCC][1][36] = 12,
[0][1][1][0][RTW89_KCC][0][36] = 14,
[0][1][1][0][RTW89_ACMA][1][36] = 54,
@@ -40017,13 +39361,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][36] = 42,
[0][1][1][0][RTW89_THAILAND][0][36] = -4,
[0][1][1][0][RTW89_FCC][1][38] = -4,
- [0][1][1][0][RTW89_FCC][2][38] = 68,
[0][1][1][0][RTW89_ETSI][1][38] = 54,
[0][1][1][0][RTW89_ETSI][0][38] = 18,
[0][1][1][0][RTW89_MKK][1][38] = 54,
[0][1][1][0][RTW89_MKK][0][38] = 16,
[0][1][1][0][RTW89_IC][1][38] = -4,
- [0][1][1][0][RTW89_IC][2][38] = 68,
[0][1][1][0][RTW89_KCC][1][38] = 12,
[0][1][1][0][RTW89_KCC][0][38] = 14,
[0][1][1][0][RTW89_ACMA][1][38] = 54,
@@ -40036,13 +39378,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][38] = 42,
[0][1][1][0][RTW89_THAILAND][0][38] = -4,
[0][1][1][0][RTW89_FCC][1][40] = -4,
- [0][1][1][0][RTW89_FCC][2][40] = 68,
[0][1][1][0][RTW89_ETSI][1][40] = 54,
[0][1][1][0][RTW89_ETSI][0][40] = 18,
[0][1][1][0][RTW89_MKK][1][40] = 54,
[0][1][1][0][RTW89_MKK][0][40] = 16,
[0][1][1][0][RTW89_IC][1][40] = -4,
- [0][1][1][0][RTW89_IC][2][40] = 68,
[0][1][1][0][RTW89_KCC][1][40] = 12,
[0][1][1][0][RTW89_KCC][0][40] = 14,
[0][1][1][0][RTW89_ACMA][1][40] = 54,
@@ -40055,13 +39395,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][40] = 42,
[0][1][1][0][RTW89_THAILAND][0][40] = -4,
[0][1][1][0][RTW89_FCC][1][42] = -4,
- [0][1][1][0][RTW89_FCC][2][42] = 68,
[0][1][1][0][RTW89_ETSI][1][42] = 54,
[0][1][1][0][RTW89_ETSI][0][42] = 18,
[0][1][1][0][RTW89_MKK][1][42] = 54,
[0][1][1][0][RTW89_MKK][0][42] = 16,
[0][1][1][0][RTW89_IC][1][42] = -4,
- [0][1][1][0][RTW89_IC][2][42] = 68,
[0][1][1][0][RTW89_KCC][1][42] = 12,
[0][1][1][0][RTW89_KCC][0][42] = 14,
[0][1][1][0][RTW89_ACMA][1][42] = 54,
@@ -40074,13 +39412,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][42] = 42,
[0][1][1][0][RTW89_THAILAND][0][42] = -4,
[0][1][1][0][RTW89_FCC][1][44] = -2,
- [0][1][1][0][RTW89_FCC][2][44] = 68,
[0][1][1][0][RTW89_ETSI][1][44] = 54,
[0][1][1][0][RTW89_ETSI][0][44] = 18,
[0][1][1][0][RTW89_MKK][1][44] = 34,
[0][1][1][0][RTW89_MKK][0][44] = 16,
[0][1][1][0][RTW89_IC][1][44] = -2,
- [0][1][1][0][RTW89_IC][2][44] = 68,
[0][1][1][0][RTW89_KCC][1][44] = 12,
[0][1][1][0][RTW89_KCC][0][44] = 12,
[0][1][1][0][RTW89_ACMA][1][44] = 54,
@@ -40093,13 +39429,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][44] = 42,
[0][1][1][0][RTW89_THAILAND][0][44] = -2,
[0][1][1][0][RTW89_FCC][1][45] = -2,
- [0][1][1][0][RTW89_FCC][2][45] = 127,
[0][1][1][0][RTW89_ETSI][1][45] = 127,
[0][1][1][0][RTW89_ETSI][0][45] = 127,
[0][1][1][0][RTW89_MKK][1][45] = 127,
[0][1][1][0][RTW89_MKK][0][45] = 127,
[0][1][1][0][RTW89_IC][1][45] = -2,
- [0][1][1][0][RTW89_IC][2][45] = 70,
[0][1][1][0][RTW89_KCC][1][45] = 12,
[0][1][1][0][RTW89_KCC][0][45] = 127,
[0][1][1][0][RTW89_ACMA][1][45] = 127,
@@ -40112,13 +39446,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][45] = 127,
[0][1][1][0][RTW89_THAILAND][0][45] = 127,
[0][1][1][0][RTW89_FCC][1][47] = -2,
- [0][1][1][0][RTW89_FCC][2][47] = 127,
[0][1][1][0][RTW89_ETSI][1][47] = 127,
[0][1][1][0][RTW89_ETSI][0][47] = 127,
[0][1][1][0][RTW89_MKK][1][47] = 127,
[0][1][1][0][RTW89_MKK][0][47] = 127,
[0][1][1][0][RTW89_IC][1][47] = -2,
- [0][1][1][0][RTW89_IC][2][47] = 68,
[0][1][1][0][RTW89_KCC][1][47] = 12,
[0][1][1][0][RTW89_KCC][0][47] = 127,
[0][1][1][0][RTW89_ACMA][1][47] = 127,
@@ -40131,13 +39463,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][47] = 127,
[0][1][1][0][RTW89_THAILAND][0][47] = 127,
[0][1][1][0][RTW89_FCC][1][49] = -2,
- [0][1][1][0][RTW89_FCC][2][49] = 127,
[0][1][1][0][RTW89_ETSI][1][49] = 127,
[0][1][1][0][RTW89_ETSI][0][49] = 127,
[0][1][1][0][RTW89_MKK][1][49] = 127,
[0][1][1][0][RTW89_MKK][0][49] = 127,
[0][1][1][0][RTW89_IC][1][49] = -2,
- [0][1][1][0][RTW89_IC][2][49] = 68,
[0][1][1][0][RTW89_KCC][1][49] = 12,
[0][1][1][0][RTW89_KCC][0][49] = 127,
[0][1][1][0][RTW89_ACMA][1][49] = 127,
@@ -40150,13 +39480,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][49] = 127,
[0][1][1][0][RTW89_THAILAND][0][49] = 127,
[0][1][1][0][RTW89_FCC][1][51] = -2,
- [0][1][1][0][RTW89_FCC][2][51] = 127,
[0][1][1][0][RTW89_ETSI][1][51] = 127,
[0][1][1][0][RTW89_ETSI][0][51] = 127,
[0][1][1][0][RTW89_MKK][1][51] = 127,
[0][1][1][0][RTW89_MKK][0][51] = 127,
[0][1][1][0][RTW89_IC][1][51] = -2,
- [0][1][1][0][RTW89_IC][2][51] = 68,
[0][1][1][0][RTW89_KCC][1][51] = 12,
[0][1][1][0][RTW89_KCC][0][51] = 127,
[0][1][1][0][RTW89_ACMA][1][51] = 127,
@@ -40169,13 +39497,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][51] = 127,
[0][1][1][0][RTW89_THAILAND][0][51] = 127,
[0][1][1][0][RTW89_FCC][1][53] = -2,
- [0][1][1][0][RTW89_FCC][2][53] = 127,
[0][1][1][0][RTW89_ETSI][1][53] = 127,
[0][1][1][0][RTW89_ETSI][0][53] = 127,
[0][1][1][0][RTW89_MKK][1][53] = 127,
[0][1][1][0][RTW89_MKK][0][53] = 127,
[0][1][1][0][RTW89_IC][1][53] = -2,
- [0][1][1][0][RTW89_IC][2][53] = 68,
[0][1][1][0][RTW89_KCC][1][53] = 12,
[0][1][1][0][RTW89_KCC][0][53] = 127,
[0][1][1][0][RTW89_ACMA][1][53] = 127,
@@ -40188,13 +39514,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][53] = 127,
[0][1][1][0][RTW89_THAILAND][0][53] = 127,
[0][1][1][0][RTW89_FCC][1][55] = -2,
- [0][1][1][0][RTW89_FCC][2][55] = 68,
[0][1][1][0][RTW89_ETSI][1][55] = 127,
[0][1][1][0][RTW89_ETSI][0][55] = 127,
[0][1][1][0][RTW89_MKK][1][55] = 127,
[0][1][1][0][RTW89_MKK][0][55] = 127,
[0][1][1][0][RTW89_IC][1][55] = -2,
- [0][1][1][0][RTW89_IC][2][55] = 68,
[0][1][1][0][RTW89_KCC][1][55] = 12,
[0][1][1][0][RTW89_KCC][0][55] = 127,
[0][1][1][0][RTW89_ACMA][1][55] = 127,
@@ -40207,13 +39531,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][55] = 127,
[0][1][1][0][RTW89_THAILAND][0][55] = 127,
[0][1][1][0][RTW89_FCC][1][57] = -2,
- [0][1][1][0][RTW89_FCC][2][57] = 68,
[0][1][1][0][RTW89_ETSI][1][57] = 127,
[0][1][1][0][RTW89_ETSI][0][57] = 127,
[0][1][1][0][RTW89_MKK][1][57] = 127,
[0][1][1][0][RTW89_MKK][0][57] = 127,
[0][1][1][0][RTW89_IC][1][57] = -2,
- [0][1][1][0][RTW89_IC][2][57] = 68,
[0][1][1][0][RTW89_KCC][1][57] = 12,
[0][1][1][0][RTW89_KCC][0][57] = 127,
[0][1][1][0][RTW89_ACMA][1][57] = 127,
@@ -40226,13 +39548,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][57] = 127,
[0][1][1][0][RTW89_THAILAND][0][57] = 127,
[0][1][1][0][RTW89_FCC][1][59] = -2,
- [0][1][1][0][RTW89_FCC][2][59] = 68,
[0][1][1][0][RTW89_ETSI][1][59] = 127,
[0][1][1][0][RTW89_ETSI][0][59] = 127,
[0][1][1][0][RTW89_MKK][1][59] = 127,
[0][1][1][0][RTW89_MKK][0][59] = 127,
[0][1][1][0][RTW89_IC][1][59] = -2,
- [0][1][1][0][RTW89_IC][2][59] = 68,
[0][1][1][0][RTW89_KCC][1][59] = 12,
[0][1][1][0][RTW89_KCC][0][59] = 127,
[0][1][1][0][RTW89_ACMA][1][59] = 127,
@@ -40245,13 +39565,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][59] = 127,
[0][1][1][0][RTW89_THAILAND][0][59] = 127,
[0][1][1][0][RTW89_FCC][1][60] = -2,
- [0][1][1][0][RTW89_FCC][2][60] = 68,
[0][1][1][0][RTW89_ETSI][1][60] = 127,
[0][1][1][0][RTW89_ETSI][0][60] = 127,
[0][1][1][0][RTW89_MKK][1][60] = 127,
[0][1][1][0][RTW89_MKK][0][60] = 127,
[0][1][1][0][RTW89_IC][1][60] = -2,
- [0][1][1][0][RTW89_IC][2][60] = 68,
[0][1][1][0][RTW89_KCC][1][60] = 12,
[0][1][1][0][RTW89_KCC][0][60] = 127,
[0][1][1][0][RTW89_ACMA][1][60] = 127,
@@ -40264,13 +39582,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][60] = 127,
[0][1][1][0][RTW89_THAILAND][0][60] = 127,
[0][1][1][0][RTW89_FCC][1][62] = -2,
- [0][1][1][0][RTW89_FCC][2][62] = 68,
[0][1][1][0][RTW89_ETSI][1][62] = 127,
[0][1][1][0][RTW89_ETSI][0][62] = 127,
[0][1][1][0][RTW89_MKK][1][62] = 127,
[0][1][1][0][RTW89_MKK][0][62] = 127,
[0][1][1][0][RTW89_IC][1][62] = -2,
- [0][1][1][0][RTW89_IC][2][62] = 68,
[0][1][1][0][RTW89_KCC][1][62] = 12,
[0][1][1][0][RTW89_KCC][0][62] = 127,
[0][1][1][0][RTW89_ACMA][1][62] = 127,
@@ -40283,13 +39599,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][62] = 127,
[0][1][1][0][RTW89_THAILAND][0][62] = 127,
[0][1][1][0][RTW89_FCC][1][64] = -2,
- [0][1][1][0][RTW89_FCC][2][64] = 68,
[0][1][1][0][RTW89_ETSI][1][64] = 127,
[0][1][1][0][RTW89_ETSI][0][64] = 127,
[0][1][1][0][RTW89_MKK][1][64] = 127,
[0][1][1][0][RTW89_MKK][0][64] = 127,
[0][1][1][0][RTW89_IC][1][64] = -2,
- [0][1][1][0][RTW89_IC][2][64] = 68,
[0][1][1][0][RTW89_KCC][1][64] = 12,
[0][1][1][0][RTW89_KCC][0][64] = 127,
[0][1][1][0][RTW89_ACMA][1][64] = 127,
@@ -40302,13 +39616,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][64] = 127,
[0][1][1][0][RTW89_THAILAND][0][64] = 127,
[0][1][1][0][RTW89_FCC][1][66] = -2,
- [0][1][1][0][RTW89_FCC][2][66] = 68,
[0][1][1][0][RTW89_ETSI][1][66] = 127,
[0][1][1][0][RTW89_ETSI][0][66] = 127,
[0][1][1][0][RTW89_MKK][1][66] = 127,
[0][1][1][0][RTW89_MKK][0][66] = 127,
[0][1][1][0][RTW89_IC][1][66] = -2,
- [0][1][1][0][RTW89_IC][2][66] = 68,
[0][1][1][0][RTW89_KCC][1][66] = 12,
[0][1][1][0][RTW89_KCC][0][66] = 127,
[0][1][1][0][RTW89_ACMA][1][66] = 127,
@@ -40321,13 +39633,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][66] = 127,
[0][1][1][0][RTW89_THAILAND][0][66] = 127,
[0][1][1][0][RTW89_FCC][1][68] = -2,
- [0][1][1][0][RTW89_FCC][2][68] = 68,
[0][1][1][0][RTW89_ETSI][1][68] = 127,
[0][1][1][0][RTW89_ETSI][0][68] = 127,
[0][1][1][0][RTW89_MKK][1][68] = 127,
[0][1][1][0][RTW89_MKK][0][68] = 127,
[0][1][1][0][RTW89_IC][1][68] = -2,
- [0][1][1][0][RTW89_IC][2][68] = 68,
[0][1][1][0][RTW89_KCC][1][68] = 12,
[0][1][1][0][RTW89_KCC][0][68] = 127,
[0][1][1][0][RTW89_ACMA][1][68] = 127,
@@ -40340,13 +39650,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][68] = 127,
[0][1][1][0][RTW89_THAILAND][0][68] = 127,
[0][1][1][0][RTW89_FCC][1][70] = -2,
- [0][1][1][0][RTW89_FCC][2][70] = 68,
[0][1][1][0][RTW89_ETSI][1][70] = 127,
[0][1][1][0][RTW89_ETSI][0][70] = 127,
[0][1][1][0][RTW89_MKK][1][70] = 127,
[0][1][1][0][RTW89_MKK][0][70] = 127,
[0][1][1][0][RTW89_IC][1][70] = -2,
- [0][1][1][0][RTW89_IC][2][70] = 68,
[0][1][1][0][RTW89_KCC][1][70] = 12,
[0][1][1][0][RTW89_KCC][0][70] = 127,
[0][1][1][0][RTW89_ACMA][1][70] = 127,
@@ -40359,13 +39667,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][70] = 127,
[0][1][1][0][RTW89_THAILAND][0][70] = 127,
[0][1][1][0][RTW89_FCC][1][72] = -2,
- [0][1][1][0][RTW89_FCC][2][72] = 68,
[0][1][1][0][RTW89_ETSI][1][72] = 127,
[0][1][1][0][RTW89_ETSI][0][72] = 127,
[0][1][1][0][RTW89_MKK][1][72] = 127,
[0][1][1][0][RTW89_MKK][0][72] = 127,
[0][1][1][0][RTW89_IC][1][72] = -2,
- [0][1][1][0][RTW89_IC][2][72] = 68,
[0][1][1][0][RTW89_KCC][1][72] = 12,
[0][1][1][0][RTW89_KCC][0][72] = 127,
[0][1][1][0][RTW89_ACMA][1][72] = 127,
@@ -40378,13 +39684,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][72] = 127,
[0][1][1][0][RTW89_THAILAND][0][72] = 127,
[0][1][1][0][RTW89_FCC][1][74] = -2,
- [0][1][1][0][RTW89_FCC][2][74] = 68,
[0][1][1][0][RTW89_ETSI][1][74] = 127,
[0][1][1][0][RTW89_ETSI][0][74] = 127,
[0][1][1][0][RTW89_MKK][1][74] = 127,
[0][1][1][0][RTW89_MKK][0][74] = 127,
[0][1][1][0][RTW89_IC][1][74] = -2,
- [0][1][1][0][RTW89_IC][2][74] = 68,
[0][1][1][0][RTW89_KCC][1][74] = 12,
[0][1][1][0][RTW89_KCC][0][74] = 127,
[0][1][1][0][RTW89_ACMA][1][74] = 127,
@@ -40397,13 +39701,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][74] = 127,
[0][1][1][0][RTW89_THAILAND][0][74] = 127,
[0][1][1][0][RTW89_FCC][1][75] = -2,
- [0][1][1][0][RTW89_FCC][2][75] = 68,
[0][1][1][0][RTW89_ETSI][1][75] = 127,
[0][1][1][0][RTW89_ETSI][0][75] = 127,
[0][1][1][0][RTW89_MKK][1][75] = 127,
[0][1][1][0][RTW89_MKK][0][75] = 127,
[0][1][1][0][RTW89_IC][1][75] = -2,
- [0][1][1][0][RTW89_IC][2][75] = 68,
[0][1][1][0][RTW89_KCC][1][75] = 12,
[0][1][1][0][RTW89_KCC][0][75] = 127,
[0][1][1][0][RTW89_ACMA][1][75] = 127,
@@ -40416,13 +39718,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][75] = 127,
[0][1][1][0][RTW89_THAILAND][0][75] = 127,
[0][1][1][0][RTW89_FCC][1][77] = -2,
- [0][1][1][0][RTW89_FCC][2][77] = 68,
[0][1][1][0][RTW89_ETSI][1][77] = 127,
[0][1][1][0][RTW89_ETSI][0][77] = 127,
[0][1][1][0][RTW89_MKK][1][77] = 127,
[0][1][1][0][RTW89_MKK][0][77] = 127,
[0][1][1][0][RTW89_IC][1][77] = -2,
- [0][1][1][0][RTW89_IC][2][77] = 68,
[0][1][1][0][RTW89_KCC][1][77] = 12,
[0][1][1][0][RTW89_KCC][0][77] = 127,
[0][1][1][0][RTW89_ACMA][1][77] = 127,
@@ -40435,13 +39735,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][77] = 127,
[0][1][1][0][RTW89_THAILAND][0][77] = 127,
[0][1][1][0][RTW89_FCC][1][79] = -2,
- [0][1][1][0][RTW89_FCC][2][79] = 68,
[0][1][1][0][RTW89_ETSI][1][79] = 127,
[0][1][1][0][RTW89_ETSI][0][79] = 127,
[0][1][1][0][RTW89_MKK][1][79] = 127,
[0][1][1][0][RTW89_MKK][0][79] = 127,
[0][1][1][0][RTW89_IC][1][79] = -2,
- [0][1][1][0][RTW89_IC][2][79] = 68,
[0][1][1][0][RTW89_KCC][1][79] = 12,
[0][1][1][0][RTW89_KCC][0][79] = 127,
[0][1][1][0][RTW89_ACMA][1][79] = 127,
@@ -40454,13 +39752,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][79] = 127,
[0][1][1][0][RTW89_THAILAND][0][79] = 127,
[0][1][1][0][RTW89_FCC][1][81] = -2,
- [0][1][1][0][RTW89_FCC][2][81] = 68,
[0][1][1][0][RTW89_ETSI][1][81] = 127,
[0][1][1][0][RTW89_ETSI][0][81] = 127,
[0][1][1][0][RTW89_MKK][1][81] = 127,
[0][1][1][0][RTW89_MKK][0][81] = 127,
[0][1][1][0][RTW89_IC][1][81] = -2,
- [0][1][1][0][RTW89_IC][2][81] = 68,
[0][1][1][0][RTW89_KCC][1][81] = 12,
[0][1][1][0][RTW89_KCC][0][81] = 127,
[0][1][1][0][RTW89_ACMA][1][81] = 127,
@@ -40473,13 +39769,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][81] = 127,
[0][1][1][0][RTW89_THAILAND][0][81] = 127,
[0][1][1][0][RTW89_FCC][1][83] = -2,
- [0][1][1][0][RTW89_FCC][2][83] = 68,
[0][1][1][0][RTW89_ETSI][1][83] = 127,
[0][1][1][0][RTW89_ETSI][0][83] = 127,
[0][1][1][0][RTW89_MKK][1][83] = 127,
[0][1][1][0][RTW89_MKK][0][83] = 127,
[0][1][1][0][RTW89_IC][1][83] = -2,
- [0][1][1][0][RTW89_IC][2][83] = 68,
[0][1][1][0][RTW89_KCC][1][83] = 20,
[0][1][1][0][RTW89_KCC][0][83] = 127,
[0][1][1][0][RTW89_ACMA][1][83] = 127,
@@ -40492,13 +39786,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][83] = 127,
[0][1][1][0][RTW89_THAILAND][0][83] = 127,
[0][1][1][0][RTW89_FCC][1][85] = -2,
- [0][1][1][0][RTW89_FCC][2][85] = 68,
[0][1][1][0][RTW89_ETSI][1][85] = 127,
[0][1][1][0][RTW89_ETSI][0][85] = 127,
[0][1][1][0][RTW89_MKK][1][85] = 127,
[0][1][1][0][RTW89_MKK][0][85] = 127,
[0][1][1][0][RTW89_IC][1][85] = -2,
- [0][1][1][0][RTW89_IC][2][85] = 68,
[0][1][1][0][RTW89_KCC][1][85] = 20,
[0][1][1][0][RTW89_KCC][0][85] = 127,
[0][1][1][0][RTW89_ACMA][1][85] = 127,
@@ -40511,13 +39803,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][85] = 127,
[0][1][1][0][RTW89_THAILAND][0][85] = 127,
[0][1][1][0][RTW89_FCC][1][87] = -2,
- [0][1][1][0][RTW89_FCC][2][87] = 127,
[0][1][1][0][RTW89_ETSI][1][87] = 127,
[0][1][1][0][RTW89_ETSI][0][87] = 127,
[0][1][1][0][RTW89_MKK][1][87] = 127,
[0][1][1][0][RTW89_MKK][0][87] = 127,
[0][1][1][0][RTW89_IC][1][87] = -2,
- [0][1][1][0][RTW89_IC][2][87] = 127,
[0][1][1][0][RTW89_KCC][1][87] = 20,
[0][1][1][0][RTW89_KCC][0][87] = 127,
[0][1][1][0][RTW89_ACMA][1][87] = 127,
@@ -40530,13 +39820,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][87] = 127,
[0][1][1][0][RTW89_THAILAND][0][87] = 127,
[0][1][1][0][RTW89_FCC][1][89] = -2,
- [0][1][1][0][RTW89_FCC][2][89] = 127,
[0][1][1][0][RTW89_ETSI][1][89] = 127,
[0][1][1][0][RTW89_ETSI][0][89] = 127,
[0][1][1][0][RTW89_MKK][1][89] = 127,
[0][1][1][0][RTW89_MKK][0][89] = 127,
[0][1][1][0][RTW89_IC][1][89] = -2,
- [0][1][1][0][RTW89_IC][2][89] = 127,
[0][1][1][0][RTW89_KCC][1][89] = 20,
[0][1][1][0][RTW89_KCC][0][89] = 127,
[0][1][1][0][RTW89_ACMA][1][89] = 127,
@@ -40549,13 +39837,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][89] = 127,
[0][1][1][0][RTW89_THAILAND][0][89] = 127,
[0][1][1][0][RTW89_FCC][1][90] = -2,
- [0][1][1][0][RTW89_FCC][2][90] = 127,
[0][1][1][0][RTW89_ETSI][1][90] = 127,
[0][1][1][0][RTW89_ETSI][0][90] = 127,
[0][1][1][0][RTW89_MKK][1][90] = 127,
[0][1][1][0][RTW89_MKK][0][90] = 127,
[0][1][1][0][RTW89_IC][1][90] = -2,
- [0][1][1][0][RTW89_IC][2][90] = 127,
[0][1][1][0][RTW89_KCC][1][90] = 20,
[0][1][1][0][RTW89_KCC][0][90] = 127,
[0][1][1][0][RTW89_ACMA][1][90] = 127,
@@ -40568,13 +39854,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][90] = 127,
[0][1][1][0][RTW89_THAILAND][0][90] = 127,
[0][1][1][0][RTW89_FCC][1][92] = -2,
- [0][1][1][0][RTW89_FCC][2][92] = 127,
[0][1][1][0][RTW89_ETSI][1][92] = 127,
[0][1][1][0][RTW89_ETSI][0][92] = 127,
[0][1][1][0][RTW89_MKK][1][92] = 127,
[0][1][1][0][RTW89_MKK][0][92] = 127,
[0][1][1][0][RTW89_IC][1][92] = -2,
- [0][1][1][0][RTW89_IC][2][92] = 127,
[0][1][1][0][RTW89_KCC][1][92] = 20,
[0][1][1][0][RTW89_KCC][0][92] = 127,
[0][1][1][0][RTW89_ACMA][1][92] = 127,
@@ -40587,13 +39871,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][92] = 127,
[0][1][1][0][RTW89_THAILAND][0][92] = 127,
[0][1][1][0][RTW89_FCC][1][94] = -2,
- [0][1][1][0][RTW89_FCC][2][94] = 127,
[0][1][1][0][RTW89_ETSI][1][94] = 127,
[0][1][1][0][RTW89_ETSI][0][94] = 127,
[0][1][1][0][RTW89_MKK][1][94] = 127,
[0][1][1][0][RTW89_MKK][0][94] = 127,
[0][1][1][0][RTW89_IC][1][94] = -2,
- [0][1][1][0][RTW89_IC][2][94] = 127,
[0][1][1][0][RTW89_KCC][1][94] = 20,
[0][1][1][0][RTW89_KCC][0][94] = 127,
[0][1][1][0][RTW89_ACMA][1][94] = 127,
@@ -40606,13 +39888,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][94] = 127,
[0][1][1][0][RTW89_THAILAND][0][94] = 127,
[0][1][1][0][RTW89_FCC][1][96] = -2,
- [0][1][1][0][RTW89_FCC][2][96] = 127,
[0][1][1][0][RTW89_ETSI][1][96] = 127,
[0][1][1][0][RTW89_ETSI][0][96] = 127,
[0][1][1][0][RTW89_MKK][1][96] = 127,
[0][1][1][0][RTW89_MKK][0][96] = 127,
[0][1][1][0][RTW89_IC][1][96] = -2,
- [0][1][1][0][RTW89_IC][2][96] = 127,
[0][1][1][0][RTW89_KCC][1][96] = 20,
[0][1][1][0][RTW89_KCC][0][96] = 127,
[0][1][1][0][RTW89_ACMA][1][96] = 127,
@@ -40625,13 +39905,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][96] = 127,
[0][1][1][0][RTW89_THAILAND][0][96] = 127,
[0][1][1][0][RTW89_FCC][1][98] = -2,
- [0][1][1][0][RTW89_FCC][2][98] = 127,
[0][1][1][0][RTW89_ETSI][1][98] = 127,
[0][1][1][0][RTW89_ETSI][0][98] = 127,
[0][1][1][0][RTW89_MKK][1][98] = 127,
[0][1][1][0][RTW89_MKK][0][98] = 127,
[0][1][1][0][RTW89_IC][1][98] = -2,
- [0][1][1][0][RTW89_IC][2][98] = 127,
[0][1][1][0][RTW89_KCC][1][98] = 20,
[0][1][1][0][RTW89_KCC][0][98] = 127,
[0][1][1][0][RTW89_ACMA][1][98] = 127,
@@ -40644,13 +39922,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][98] = 127,
[0][1][1][0][RTW89_THAILAND][0][98] = 127,
[0][1][1][0][RTW89_FCC][1][100] = -2,
- [0][1][1][0][RTW89_FCC][2][100] = 127,
[0][1][1][0][RTW89_ETSI][1][100] = 127,
[0][1][1][0][RTW89_ETSI][0][100] = 127,
[0][1][1][0][RTW89_MKK][1][100] = 127,
[0][1][1][0][RTW89_MKK][0][100] = 127,
[0][1][1][0][RTW89_IC][1][100] = -2,
- [0][1][1][0][RTW89_IC][2][100] = 127,
[0][1][1][0][RTW89_KCC][1][100] = 20,
[0][1][1][0][RTW89_KCC][0][100] = 127,
[0][1][1][0][RTW89_ACMA][1][100] = 127,
@@ -40663,13 +39939,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][100] = 127,
[0][1][1][0][RTW89_THAILAND][0][100] = 127,
[0][1][1][0][RTW89_FCC][1][102] = -2,
- [0][1][1][0][RTW89_FCC][2][102] = 127,
[0][1][1][0][RTW89_ETSI][1][102] = 127,
[0][1][1][0][RTW89_ETSI][0][102] = 127,
[0][1][1][0][RTW89_MKK][1][102] = 127,
[0][1][1][0][RTW89_MKK][0][102] = 127,
[0][1][1][0][RTW89_IC][1][102] = -2,
- [0][1][1][0][RTW89_IC][2][102] = 127,
[0][1][1][0][RTW89_KCC][1][102] = 20,
[0][1][1][0][RTW89_KCC][0][102] = 127,
[0][1][1][0][RTW89_ACMA][1][102] = 127,
@@ -40682,13 +39956,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][102] = 127,
[0][1][1][0][RTW89_THAILAND][0][102] = 127,
[0][1][1][0][RTW89_FCC][1][104] = -2,
- [0][1][1][0][RTW89_FCC][2][104] = 127,
[0][1][1][0][RTW89_ETSI][1][104] = 127,
[0][1][1][0][RTW89_ETSI][0][104] = 127,
[0][1][1][0][RTW89_MKK][1][104] = 127,
[0][1][1][0][RTW89_MKK][0][104] = 127,
[0][1][1][0][RTW89_IC][1][104] = -2,
- [0][1][1][0][RTW89_IC][2][104] = 127,
[0][1][1][0][RTW89_KCC][1][104] = 20,
[0][1][1][0][RTW89_KCC][0][104] = 127,
[0][1][1][0][RTW89_ACMA][1][104] = 127,
@@ -40701,13 +39973,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][104] = 127,
[0][1][1][0][RTW89_THAILAND][0][104] = 127,
[0][1][1][0][RTW89_FCC][1][105] = -2,
- [0][1][1][0][RTW89_FCC][2][105] = 127,
[0][1][1][0][RTW89_ETSI][1][105] = 127,
[0][1][1][0][RTW89_ETSI][0][105] = 127,
[0][1][1][0][RTW89_MKK][1][105] = 127,
[0][1][1][0][RTW89_MKK][0][105] = 127,
[0][1][1][0][RTW89_IC][1][105] = -2,
- [0][1][1][0][RTW89_IC][2][105] = 127,
[0][1][1][0][RTW89_KCC][1][105] = 20,
[0][1][1][0][RTW89_KCC][0][105] = 127,
[0][1][1][0][RTW89_ACMA][1][105] = 127,
@@ -40720,13 +39990,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][105] = 127,
[0][1][1][0][RTW89_THAILAND][0][105] = 127,
[0][1][1][0][RTW89_FCC][1][107] = 1,
- [0][1][1][0][RTW89_FCC][2][107] = 127,
[0][1][1][0][RTW89_ETSI][1][107] = 127,
[0][1][1][0][RTW89_ETSI][0][107] = 127,
[0][1][1][0][RTW89_MKK][1][107] = 127,
[0][1][1][0][RTW89_MKK][0][107] = 127,
[0][1][1][0][RTW89_IC][1][107] = 1,
- [0][1][1][0][RTW89_IC][2][107] = 127,
[0][1][1][0][RTW89_KCC][1][107] = 20,
[0][1][1][0][RTW89_KCC][0][107] = 127,
[0][1][1][0][RTW89_ACMA][1][107] = 127,
@@ -40739,13 +40007,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][107] = 127,
[0][1][1][0][RTW89_THAILAND][0][107] = 127,
[0][1][1][0][RTW89_FCC][1][109] = 1,
- [0][1][1][0][RTW89_FCC][2][109] = 127,
[0][1][1][0][RTW89_ETSI][1][109] = 127,
[0][1][1][0][RTW89_ETSI][0][109] = 127,
[0][1][1][0][RTW89_MKK][1][109] = 127,
[0][1][1][0][RTW89_MKK][0][109] = 127,
[0][1][1][0][RTW89_IC][1][109] = 1,
- [0][1][1][0][RTW89_IC][2][109] = 127,
[0][1][1][0][RTW89_KCC][1][109] = 20,
[0][1][1][0][RTW89_KCC][0][109] = 127,
[0][1][1][0][RTW89_ACMA][1][109] = 127,
@@ -40758,13 +40024,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][109] = 127,
[0][1][1][0][RTW89_THAILAND][0][109] = 127,
[0][1][1][0][RTW89_FCC][1][111] = 127,
- [0][1][1][0][RTW89_FCC][2][111] = 127,
[0][1][1][0][RTW89_ETSI][1][111] = 127,
[0][1][1][0][RTW89_ETSI][0][111] = 127,
[0][1][1][0][RTW89_MKK][1][111] = 127,
[0][1][1][0][RTW89_MKK][0][111] = 127,
[0][1][1][0][RTW89_IC][1][111] = 127,
- [0][1][1][0][RTW89_IC][2][111] = 127,
[0][1][1][0][RTW89_KCC][1][111] = 127,
[0][1][1][0][RTW89_KCC][0][111] = 127,
[0][1][1][0][RTW89_ACMA][1][111] = 127,
@@ -40777,13 +40041,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][111] = 127,
[0][1][1][0][RTW89_THAILAND][0][111] = 127,
[0][1][1][0][RTW89_FCC][1][113] = 127,
- [0][1][1][0][RTW89_FCC][2][113] = 127,
[0][1][1][0][RTW89_ETSI][1][113] = 127,
[0][1][1][0][RTW89_ETSI][0][113] = 127,
[0][1][1][0][RTW89_MKK][1][113] = 127,
[0][1][1][0][RTW89_MKK][0][113] = 127,
[0][1][1][0][RTW89_IC][1][113] = 127,
- [0][1][1][0][RTW89_IC][2][113] = 127,
[0][1][1][0][RTW89_KCC][1][113] = 127,
[0][1][1][0][RTW89_KCC][0][113] = 127,
[0][1][1][0][RTW89_ACMA][1][113] = 127,
@@ -40796,13 +40058,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][113] = 127,
[0][1][1][0][RTW89_THAILAND][0][113] = 127,
[0][1][1][0][RTW89_FCC][1][115] = 127,
- [0][1][1][0][RTW89_FCC][2][115] = 127,
[0][1][1][0][RTW89_ETSI][1][115] = 127,
[0][1][1][0][RTW89_ETSI][0][115] = 127,
[0][1][1][0][RTW89_MKK][1][115] = 127,
[0][1][1][0][RTW89_MKK][0][115] = 127,
[0][1][1][0][RTW89_IC][1][115] = 127,
- [0][1][1][0][RTW89_IC][2][115] = 127,
[0][1][1][0][RTW89_KCC][1][115] = 127,
[0][1][1][0][RTW89_KCC][0][115] = 127,
[0][1][1][0][RTW89_ACMA][1][115] = 127,
@@ -40815,13 +40075,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][115] = 127,
[0][1][1][0][RTW89_THAILAND][0][115] = 127,
[0][1][1][0][RTW89_FCC][1][117] = 127,
- [0][1][1][0][RTW89_FCC][2][117] = 127,
[0][1][1][0][RTW89_ETSI][1][117] = 127,
[0][1][1][0][RTW89_ETSI][0][117] = 127,
[0][1][1][0][RTW89_MKK][1][117] = 127,
[0][1][1][0][RTW89_MKK][0][117] = 127,
[0][1][1][0][RTW89_IC][1][117] = 127,
- [0][1][1][0][RTW89_IC][2][117] = 127,
[0][1][1][0][RTW89_KCC][1][117] = 127,
[0][1][1][0][RTW89_KCC][0][117] = 127,
[0][1][1][0][RTW89_ACMA][1][117] = 127,
@@ -40834,13 +40092,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][117] = 127,
[0][1][1][0][RTW89_THAILAND][0][117] = 127,
[0][1][1][0][RTW89_FCC][1][119] = 127,
- [0][1][1][0][RTW89_FCC][2][119] = 127,
[0][1][1][0][RTW89_ETSI][1][119] = 127,
[0][1][1][0][RTW89_ETSI][0][119] = 127,
[0][1][1][0][RTW89_MKK][1][119] = 127,
[0][1][1][0][RTW89_MKK][0][119] = 127,
[0][1][1][0][RTW89_IC][1][119] = 127,
- [0][1][1][0][RTW89_IC][2][119] = 127,
[0][1][1][0][RTW89_KCC][1][119] = 127,
[0][1][1][0][RTW89_KCC][0][119] = 127,
[0][1][1][0][RTW89_ACMA][1][119] = 127,
@@ -40853,13 +40109,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][1][0][RTW89_THAILAND][1][119] = 127,
[0][1][1][0][RTW89_THAILAND][0][119] = 127,
[0][0][2][0][RTW89_FCC][1][0] = 24,
- [0][0][2][0][RTW89_FCC][2][0] = 56,
[0][0][2][0][RTW89_ETSI][1][0] = 66,
[0][0][2][0][RTW89_ETSI][0][0] = 28,
[0][0][2][0][RTW89_MKK][1][0] = 66,
[0][0][2][0][RTW89_MKK][0][0] = 26,
[0][0][2][0][RTW89_IC][1][0] = 24,
- [0][0][2][0][RTW89_IC][2][0] = 56,
[0][0][2][0][RTW89_KCC][1][0] = 24,
[0][0][2][0][RTW89_KCC][0][0] = 24,
[0][0][2][0][RTW89_ACMA][1][0] = 66,
@@ -40872,13 +40126,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][0] = 56,
[0][0][2][0][RTW89_THAILAND][0][0] = 24,
[0][0][2][0][RTW89_FCC][1][2] = 22,
- [0][0][2][0][RTW89_FCC][2][2] = 56,
[0][0][2][0][RTW89_ETSI][1][2] = 66,
[0][0][2][0][RTW89_ETSI][0][2] = 28,
[0][0][2][0][RTW89_MKK][1][2] = 66,
[0][0][2][0][RTW89_MKK][0][2] = 26,
[0][0][2][0][RTW89_IC][1][2] = 22,
- [0][0][2][0][RTW89_IC][2][2] = 56,
[0][0][2][0][RTW89_KCC][1][2] = 24,
[0][0][2][0][RTW89_KCC][0][2] = 24,
[0][0][2][0][RTW89_ACMA][1][2] = 66,
@@ -40891,13 +40143,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][2] = 56,
[0][0][2][0][RTW89_THAILAND][0][2] = 22,
[0][0][2][0][RTW89_FCC][1][4] = 22,
- [0][0][2][0][RTW89_FCC][2][4] = 56,
[0][0][2][0][RTW89_ETSI][1][4] = 66,
[0][0][2][0][RTW89_ETSI][0][4] = 28,
[0][0][2][0][RTW89_MKK][1][4] = 66,
[0][0][2][0][RTW89_MKK][0][4] = 26,
[0][0][2][0][RTW89_IC][1][4] = 22,
- [0][0][2][0][RTW89_IC][2][4] = 56,
[0][0][2][0][RTW89_KCC][1][4] = 24,
[0][0][2][0][RTW89_KCC][0][4] = 24,
[0][0][2][0][RTW89_ACMA][1][4] = 66,
@@ -40910,13 +40160,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][4] = 56,
[0][0][2][0][RTW89_THAILAND][0][4] = 22,
[0][0][2][0][RTW89_FCC][1][6] = 22,
- [0][0][2][0][RTW89_FCC][2][6] = 56,
[0][0][2][0][RTW89_ETSI][1][6] = 66,
[0][0][2][0][RTW89_ETSI][0][6] = 28,
[0][0][2][0][RTW89_MKK][1][6] = 66,
[0][0][2][0][RTW89_MKK][0][6] = 26,
[0][0][2][0][RTW89_IC][1][6] = 22,
- [0][0][2][0][RTW89_IC][2][6] = 56,
[0][0][2][0][RTW89_KCC][1][6] = 24,
[0][0][2][0][RTW89_KCC][0][6] = 24,
[0][0][2][0][RTW89_ACMA][1][6] = 66,
@@ -40929,13 +40177,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][6] = 56,
[0][0][2][0][RTW89_THAILAND][0][6] = 22,
[0][0][2][0][RTW89_FCC][1][8] = 22,
- [0][0][2][0][RTW89_FCC][2][8] = 56,
[0][0][2][0][RTW89_ETSI][1][8] = 66,
[0][0][2][0][RTW89_ETSI][0][8] = 28,
[0][0][2][0][RTW89_MKK][1][8] = 66,
[0][0][2][0][RTW89_MKK][0][8] = 26,
[0][0][2][0][RTW89_IC][1][8] = 22,
- [0][0][2][0][RTW89_IC][2][8] = 56,
[0][0][2][0][RTW89_KCC][1][8] = 24,
[0][0][2][0][RTW89_KCC][0][8] = 24,
[0][0][2][0][RTW89_ACMA][1][8] = 66,
@@ -40948,13 +40194,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][8] = 56,
[0][0][2][0][RTW89_THAILAND][0][8] = 22,
[0][0][2][0][RTW89_FCC][1][10] = 22,
- [0][0][2][0][RTW89_FCC][2][10] = 56,
[0][0][2][0][RTW89_ETSI][1][10] = 66,
[0][0][2][0][RTW89_ETSI][0][10] = 28,
[0][0][2][0][RTW89_MKK][1][10] = 66,
[0][0][2][0][RTW89_MKK][0][10] = 26,
[0][0][2][0][RTW89_IC][1][10] = 22,
- [0][0][2][0][RTW89_IC][2][10] = 56,
[0][0][2][0][RTW89_KCC][1][10] = 24,
[0][0][2][0][RTW89_KCC][0][10] = 24,
[0][0][2][0][RTW89_ACMA][1][10] = 66,
@@ -40967,13 +40211,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][10] = 56,
[0][0][2][0][RTW89_THAILAND][0][10] = 22,
[0][0][2][0][RTW89_FCC][1][12] = 22,
- [0][0][2][0][RTW89_FCC][2][12] = 56,
[0][0][2][0][RTW89_ETSI][1][12] = 66,
[0][0][2][0][RTW89_ETSI][0][12] = 28,
[0][0][2][0][RTW89_MKK][1][12] = 66,
[0][0][2][0][RTW89_MKK][0][12] = 26,
[0][0][2][0][RTW89_IC][1][12] = 22,
- [0][0][2][0][RTW89_IC][2][12] = 56,
[0][0][2][0][RTW89_KCC][1][12] = 24,
[0][0][2][0][RTW89_KCC][0][12] = 24,
[0][0][2][0][RTW89_ACMA][1][12] = 66,
@@ -40986,13 +40228,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][12] = 56,
[0][0][2][0][RTW89_THAILAND][0][12] = 22,
[0][0][2][0][RTW89_FCC][1][14] = 22,
- [0][0][2][0][RTW89_FCC][2][14] = 56,
[0][0][2][0][RTW89_ETSI][1][14] = 66,
[0][0][2][0][RTW89_ETSI][0][14] = 28,
[0][0][2][0][RTW89_MKK][1][14] = 66,
[0][0][2][0][RTW89_MKK][0][14] = 26,
[0][0][2][0][RTW89_IC][1][14] = 22,
- [0][0][2][0][RTW89_IC][2][14] = 56,
[0][0][2][0][RTW89_KCC][1][14] = 24,
[0][0][2][0][RTW89_KCC][0][14] = 24,
[0][0][2][0][RTW89_ACMA][1][14] = 66,
@@ -41005,13 +40245,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][14] = 56,
[0][0][2][0][RTW89_THAILAND][0][14] = 22,
[0][0][2][0][RTW89_FCC][1][15] = 22,
- [0][0][2][0][RTW89_FCC][2][15] = 56,
[0][0][2][0][RTW89_ETSI][1][15] = 66,
[0][0][2][0][RTW89_ETSI][0][15] = 28,
[0][0][2][0][RTW89_MKK][1][15] = 66,
[0][0][2][0][RTW89_MKK][0][15] = 26,
[0][0][2][0][RTW89_IC][1][15] = 22,
- [0][0][2][0][RTW89_IC][2][15] = 56,
[0][0][2][0][RTW89_KCC][1][15] = 24,
[0][0][2][0][RTW89_KCC][0][15] = 24,
[0][0][2][0][RTW89_ACMA][1][15] = 66,
@@ -41024,13 +40262,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][15] = 56,
[0][0][2][0][RTW89_THAILAND][0][15] = 22,
[0][0][2][0][RTW89_FCC][1][17] = 22,
- [0][0][2][0][RTW89_FCC][2][17] = 56,
[0][0][2][0][RTW89_ETSI][1][17] = 66,
[0][0][2][0][RTW89_ETSI][0][17] = 28,
[0][0][2][0][RTW89_MKK][1][17] = 66,
[0][0][2][0][RTW89_MKK][0][17] = 26,
[0][0][2][0][RTW89_IC][1][17] = 22,
- [0][0][2][0][RTW89_IC][2][17] = 56,
[0][0][2][0][RTW89_KCC][1][17] = 24,
[0][0][2][0][RTW89_KCC][0][17] = 24,
[0][0][2][0][RTW89_ACMA][1][17] = 66,
@@ -41043,13 +40279,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][17] = 56,
[0][0][2][0][RTW89_THAILAND][0][17] = 22,
[0][0][2][0][RTW89_FCC][1][19] = 22,
- [0][0][2][0][RTW89_FCC][2][19] = 56,
[0][0][2][0][RTW89_ETSI][1][19] = 66,
[0][0][2][0][RTW89_ETSI][0][19] = 28,
[0][0][2][0][RTW89_MKK][1][19] = 66,
[0][0][2][0][RTW89_MKK][0][19] = 26,
[0][0][2][0][RTW89_IC][1][19] = 22,
- [0][0][2][0][RTW89_IC][2][19] = 56,
[0][0][2][0][RTW89_KCC][1][19] = 24,
[0][0][2][0][RTW89_KCC][0][19] = 24,
[0][0][2][0][RTW89_ACMA][1][19] = 66,
@@ -41062,13 +40296,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][19] = 56,
[0][0][2][0][RTW89_THAILAND][0][19] = 22,
[0][0][2][0][RTW89_FCC][1][21] = 22,
- [0][0][2][0][RTW89_FCC][2][21] = 56,
[0][0][2][0][RTW89_ETSI][1][21] = 66,
[0][0][2][0][RTW89_ETSI][0][21] = 28,
[0][0][2][0][RTW89_MKK][1][21] = 66,
[0][0][2][0][RTW89_MKK][0][21] = 26,
[0][0][2][0][RTW89_IC][1][21] = 22,
- [0][0][2][0][RTW89_IC][2][21] = 56,
[0][0][2][0][RTW89_KCC][1][21] = 24,
[0][0][2][0][RTW89_KCC][0][21] = 24,
[0][0][2][0][RTW89_ACMA][1][21] = 66,
@@ -41081,13 +40313,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][21] = 56,
[0][0][2][0][RTW89_THAILAND][0][21] = 22,
[0][0][2][0][RTW89_FCC][1][23] = 22,
- [0][0][2][0][RTW89_FCC][2][23] = 70,
[0][0][2][0][RTW89_ETSI][1][23] = 66,
[0][0][2][0][RTW89_ETSI][0][23] = 28,
[0][0][2][0][RTW89_MKK][1][23] = 66,
[0][0][2][0][RTW89_MKK][0][23] = 26,
[0][0][2][0][RTW89_IC][1][23] = 22,
- [0][0][2][0][RTW89_IC][2][23] = 70,
[0][0][2][0][RTW89_KCC][1][23] = 24,
[0][0][2][0][RTW89_KCC][0][23] = 26,
[0][0][2][0][RTW89_ACMA][1][23] = 66,
@@ -41100,13 +40330,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][23] = 66,
[0][0][2][0][RTW89_THAILAND][0][23] = 22,
[0][0][2][0][RTW89_FCC][1][25] = 22,
- [0][0][2][0][RTW89_FCC][2][25] = 70,
[0][0][2][0][RTW89_ETSI][1][25] = 66,
[0][0][2][0][RTW89_ETSI][0][25] = 28,
[0][0][2][0][RTW89_MKK][1][25] = 66,
[0][0][2][0][RTW89_MKK][0][25] = 26,
[0][0][2][0][RTW89_IC][1][25] = 22,
- [0][0][2][0][RTW89_IC][2][25] = 70,
[0][0][2][0][RTW89_KCC][1][25] = 24,
[0][0][2][0][RTW89_KCC][0][25] = 26,
[0][0][2][0][RTW89_ACMA][1][25] = 66,
@@ -41119,13 +40347,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][25] = 66,
[0][0][2][0][RTW89_THAILAND][0][25] = 22,
[0][0][2][0][RTW89_FCC][1][27] = 22,
- [0][0][2][0][RTW89_FCC][2][27] = 70,
[0][0][2][0][RTW89_ETSI][1][27] = 66,
[0][0][2][0][RTW89_ETSI][0][27] = 28,
[0][0][2][0][RTW89_MKK][1][27] = 66,
[0][0][2][0][RTW89_MKK][0][27] = 26,
[0][0][2][0][RTW89_IC][1][27] = 22,
- [0][0][2][0][RTW89_IC][2][27] = 70,
[0][0][2][0][RTW89_KCC][1][27] = 24,
[0][0][2][0][RTW89_KCC][0][27] = 26,
[0][0][2][0][RTW89_ACMA][1][27] = 66,
@@ -41138,13 +40364,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][27] = 66,
[0][0][2][0][RTW89_THAILAND][0][27] = 22,
[0][0][2][0][RTW89_FCC][1][29] = 22,
- [0][0][2][0][RTW89_FCC][2][29] = 70,
[0][0][2][0][RTW89_ETSI][1][29] = 66,
[0][0][2][0][RTW89_ETSI][0][29] = 28,
[0][0][2][0][RTW89_MKK][1][29] = 66,
[0][0][2][0][RTW89_MKK][0][29] = 26,
[0][0][2][0][RTW89_IC][1][29] = 22,
- [0][0][2][0][RTW89_IC][2][29] = 70,
[0][0][2][0][RTW89_KCC][1][29] = 24,
[0][0][2][0][RTW89_KCC][0][29] = 26,
[0][0][2][0][RTW89_ACMA][1][29] = 66,
@@ -41157,13 +40381,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][29] = 66,
[0][0][2][0][RTW89_THAILAND][0][29] = 22,
[0][0][2][0][RTW89_FCC][1][30] = 22,
- [0][0][2][0][RTW89_FCC][2][30] = 70,
[0][0][2][0][RTW89_ETSI][1][30] = 66,
[0][0][2][0][RTW89_ETSI][0][30] = 28,
[0][0][2][0][RTW89_MKK][1][30] = 66,
[0][0][2][0][RTW89_MKK][0][30] = 26,
[0][0][2][0][RTW89_IC][1][30] = 22,
- [0][0][2][0][RTW89_IC][2][30] = 70,
[0][0][2][0][RTW89_KCC][1][30] = 24,
[0][0][2][0][RTW89_KCC][0][30] = 26,
[0][0][2][0][RTW89_ACMA][1][30] = 66,
@@ -41176,13 +40398,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][30] = 66,
[0][0][2][0][RTW89_THAILAND][0][30] = 22,
[0][0][2][0][RTW89_FCC][1][32] = 22,
- [0][0][2][0][RTW89_FCC][2][32] = 70,
[0][0][2][0][RTW89_ETSI][1][32] = 66,
[0][0][2][0][RTW89_ETSI][0][32] = 28,
[0][0][2][0][RTW89_MKK][1][32] = 66,
[0][0][2][0][RTW89_MKK][0][32] = 26,
[0][0][2][0][RTW89_IC][1][32] = 22,
- [0][0][2][0][RTW89_IC][2][32] = 70,
[0][0][2][0][RTW89_KCC][1][32] = 24,
[0][0][2][0][RTW89_KCC][0][32] = 26,
[0][0][2][0][RTW89_ACMA][1][32] = 66,
@@ -41195,13 +40415,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][32] = 66,
[0][0][2][0][RTW89_THAILAND][0][32] = 22,
[0][0][2][0][RTW89_FCC][1][34] = 22,
- [0][0][2][0][RTW89_FCC][2][34] = 70,
[0][0][2][0][RTW89_ETSI][1][34] = 66,
[0][0][2][0][RTW89_ETSI][0][34] = 28,
[0][0][2][0][RTW89_MKK][1][34] = 66,
[0][0][2][0][RTW89_MKK][0][34] = 26,
[0][0][2][0][RTW89_IC][1][34] = 22,
- [0][0][2][0][RTW89_IC][2][34] = 70,
[0][0][2][0][RTW89_KCC][1][34] = 24,
[0][0][2][0][RTW89_KCC][0][34] = 26,
[0][0][2][0][RTW89_ACMA][1][34] = 66,
@@ -41214,13 +40432,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][34] = 66,
[0][0][2][0][RTW89_THAILAND][0][34] = 22,
[0][0][2][0][RTW89_FCC][1][36] = 22,
- [0][0][2][0][RTW89_FCC][2][36] = 70,
[0][0][2][0][RTW89_ETSI][1][36] = 66,
[0][0][2][0][RTW89_ETSI][0][36] = 28,
[0][0][2][0][RTW89_MKK][1][36] = 66,
[0][0][2][0][RTW89_MKK][0][36] = 26,
[0][0][2][0][RTW89_IC][1][36] = 22,
- [0][0][2][0][RTW89_IC][2][36] = 70,
[0][0][2][0][RTW89_KCC][1][36] = 24,
[0][0][2][0][RTW89_KCC][0][36] = 26,
[0][0][2][0][RTW89_ACMA][1][36] = 66,
@@ -41233,13 +40449,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][36] = 66,
[0][0][2][0][RTW89_THAILAND][0][36] = 22,
[0][0][2][0][RTW89_FCC][1][38] = 22,
- [0][0][2][0][RTW89_FCC][2][38] = 70,
[0][0][2][0][RTW89_ETSI][1][38] = 66,
[0][0][2][0][RTW89_ETSI][0][38] = 28,
[0][0][2][0][RTW89_MKK][1][38] = 66,
[0][0][2][0][RTW89_MKK][0][38] = 26,
[0][0][2][0][RTW89_IC][1][38] = 22,
- [0][0][2][0][RTW89_IC][2][38] = 70,
[0][0][2][0][RTW89_KCC][1][38] = 24,
[0][0][2][0][RTW89_KCC][0][38] = 26,
[0][0][2][0][RTW89_ACMA][1][38] = 66,
@@ -41252,13 +40466,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][38] = 66,
[0][0][2][0][RTW89_THAILAND][0][38] = 22,
[0][0][2][0][RTW89_FCC][1][40] = 22,
- [0][0][2][0][RTW89_FCC][2][40] = 70,
[0][0][2][0][RTW89_ETSI][1][40] = 66,
[0][0][2][0][RTW89_ETSI][0][40] = 28,
[0][0][2][0][RTW89_MKK][1][40] = 66,
[0][0][2][0][RTW89_MKK][0][40] = 26,
[0][0][2][0][RTW89_IC][1][40] = 22,
- [0][0][2][0][RTW89_IC][2][40] = 70,
[0][0][2][0][RTW89_KCC][1][40] = 24,
[0][0][2][0][RTW89_KCC][0][40] = 26,
[0][0][2][0][RTW89_ACMA][1][40] = 66,
@@ -41271,13 +40483,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][40] = 66,
[0][0][2][0][RTW89_THAILAND][0][40] = 22,
[0][0][2][0][RTW89_FCC][1][42] = 22,
- [0][0][2][0][RTW89_FCC][2][42] = 70,
[0][0][2][0][RTW89_ETSI][1][42] = 66,
[0][0][2][0][RTW89_ETSI][0][42] = 28,
[0][0][2][0][RTW89_MKK][1][42] = 66,
[0][0][2][0][RTW89_MKK][0][42] = 26,
[0][0][2][0][RTW89_IC][1][42] = 22,
- [0][0][2][0][RTW89_IC][2][42] = 70,
[0][0][2][0][RTW89_KCC][1][42] = 24,
[0][0][2][0][RTW89_KCC][0][42] = 26,
[0][0][2][0][RTW89_ACMA][1][42] = 66,
@@ -41290,13 +40500,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][42] = 66,
[0][0][2][0][RTW89_THAILAND][0][42] = 22,
[0][0][2][0][RTW89_FCC][1][44] = 22,
- [0][0][2][0][RTW89_FCC][2][44] = 70,
[0][0][2][0][RTW89_ETSI][1][44] = 66,
[0][0][2][0][RTW89_ETSI][0][44] = 30,
[0][0][2][0][RTW89_MKK][1][44] = 44,
[0][0][2][0][RTW89_MKK][0][44] = 28,
[0][0][2][0][RTW89_IC][1][44] = 22,
- [0][0][2][0][RTW89_IC][2][44] = 70,
[0][0][2][0][RTW89_KCC][1][44] = 24,
[0][0][2][0][RTW89_KCC][0][44] = 26,
[0][0][2][0][RTW89_ACMA][1][44] = 66,
@@ -41309,13 +40517,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][44] = 68,
[0][0][2][0][RTW89_THAILAND][0][44] = 22,
[0][0][2][0][RTW89_FCC][1][45] = 22,
- [0][0][2][0][RTW89_FCC][2][45] = 127,
[0][0][2][0][RTW89_ETSI][1][45] = 127,
[0][0][2][0][RTW89_ETSI][0][45] = 127,
[0][0][2][0][RTW89_MKK][1][45] = 127,
[0][0][2][0][RTW89_MKK][0][45] = 127,
[0][0][2][0][RTW89_IC][1][45] = 22,
- [0][0][2][0][RTW89_IC][2][45] = 70,
[0][0][2][0][RTW89_KCC][1][45] = 24,
[0][0][2][0][RTW89_KCC][0][45] = 127,
[0][0][2][0][RTW89_ACMA][1][45] = 127,
@@ -41328,13 +40534,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][45] = 127,
[0][0][2][0][RTW89_THAILAND][0][45] = 127,
[0][0][2][0][RTW89_FCC][1][47] = 22,
- [0][0][2][0][RTW89_FCC][2][47] = 127,
[0][0][2][0][RTW89_ETSI][1][47] = 127,
[0][0][2][0][RTW89_ETSI][0][47] = 127,
[0][0][2][0][RTW89_MKK][1][47] = 127,
[0][0][2][0][RTW89_MKK][0][47] = 127,
[0][0][2][0][RTW89_IC][1][47] = 22,
- [0][0][2][0][RTW89_IC][2][47] = 70,
[0][0][2][0][RTW89_KCC][1][47] = 24,
[0][0][2][0][RTW89_KCC][0][47] = 127,
[0][0][2][0][RTW89_ACMA][1][47] = 127,
@@ -41347,13 +40551,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][47] = 127,
[0][0][2][0][RTW89_THAILAND][0][47] = 127,
[0][0][2][0][RTW89_FCC][1][49] = 24,
- [0][0][2][0][RTW89_FCC][2][49] = 127,
[0][0][2][0][RTW89_ETSI][1][49] = 127,
[0][0][2][0][RTW89_ETSI][0][49] = 127,
[0][0][2][0][RTW89_MKK][1][49] = 127,
[0][0][2][0][RTW89_MKK][0][49] = 127,
[0][0][2][0][RTW89_IC][1][49] = 24,
- [0][0][2][0][RTW89_IC][2][49] = 70,
[0][0][2][0][RTW89_KCC][1][49] = 24,
[0][0][2][0][RTW89_KCC][0][49] = 127,
[0][0][2][0][RTW89_ACMA][1][49] = 127,
@@ -41366,13 +40568,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][49] = 127,
[0][0][2][0][RTW89_THAILAND][0][49] = 127,
[0][0][2][0][RTW89_FCC][1][51] = 22,
- [0][0][2][0][RTW89_FCC][2][51] = 127,
[0][0][2][0][RTW89_ETSI][1][51] = 127,
[0][0][2][0][RTW89_ETSI][0][51] = 127,
[0][0][2][0][RTW89_MKK][1][51] = 127,
[0][0][2][0][RTW89_MKK][0][51] = 127,
[0][0][2][0][RTW89_IC][1][51] = 22,
- [0][0][2][0][RTW89_IC][2][51] = 70,
[0][0][2][0][RTW89_KCC][1][51] = 24,
[0][0][2][0][RTW89_KCC][0][51] = 127,
[0][0][2][0][RTW89_ACMA][1][51] = 127,
@@ -41385,13 +40585,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][51] = 127,
[0][0][2][0][RTW89_THAILAND][0][51] = 127,
[0][0][2][0][RTW89_FCC][1][53] = 22,
- [0][0][2][0][RTW89_FCC][2][53] = 127,
[0][0][2][0][RTW89_ETSI][1][53] = 127,
[0][0][2][0][RTW89_ETSI][0][53] = 127,
[0][0][2][0][RTW89_MKK][1][53] = 127,
[0][0][2][0][RTW89_MKK][0][53] = 127,
[0][0][2][0][RTW89_IC][1][53] = 22,
- [0][0][2][0][RTW89_IC][2][53] = 70,
[0][0][2][0][RTW89_KCC][1][53] = 24,
[0][0][2][0][RTW89_KCC][0][53] = 127,
[0][0][2][0][RTW89_ACMA][1][53] = 127,
@@ -41404,13 +40602,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][53] = 127,
[0][0][2][0][RTW89_THAILAND][0][53] = 127,
[0][0][2][0][RTW89_FCC][1][55] = 22,
- [0][0][2][0][RTW89_FCC][2][55] = 68,
[0][0][2][0][RTW89_ETSI][1][55] = 127,
[0][0][2][0][RTW89_ETSI][0][55] = 127,
[0][0][2][0][RTW89_MKK][1][55] = 127,
[0][0][2][0][RTW89_MKK][0][55] = 127,
[0][0][2][0][RTW89_IC][1][55] = 22,
- [0][0][2][0][RTW89_IC][2][55] = 68,
[0][0][2][0][RTW89_KCC][1][55] = 26,
[0][0][2][0][RTW89_KCC][0][55] = 127,
[0][0][2][0][RTW89_ACMA][1][55] = 127,
@@ -41423,13 +40619,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][55] = 127,
[0][0][2][0][RTW89_THAILAND][0][55] = 127,
[0][0][2][0][RTW89_FCC][1][57] = 22,
- [0][0][2][0][RTW89_FCC][2][57] = 68,
[0][0][2][0][RTW89_ETSI][1][57] = 127,
[0][0][2][0][RTW89_ETSI][0][57] = 127,
[0][0][2][0][RTW89_MKK][1][57] = 127,
[0][0][2][0][RTW89_MKK][0][57] = 127,
[0][0][2][0][RTW89_IC][1][57] = 22,
- [0][0][2][0][RTW89_IC][2][57] = 68,
[0][0][2][0][RTW89_KCC][1][57] = 26,
[0][0][2][0][RTW89_KCC][0][57] = 127,
[0][0][2][0][RTW89_ACMA][1][57] = 127,
@@ -41442,13 +40636,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][57] = 127,
[0][0][2][0][RTW89_THAILAND][0][57] = 127,
[0][0][2][0][RTW89_FCC][1][59] = 22,
- [0][0][2][0][RTW89_FCC][2][59] = 68,
[0][0][2][0][RTW89_ETSI][1][59] = 127,
[0][0][2][0][RTW89_ETSI][0][59] = 127,
[0][0][2][0][RTW89_MKK][1][59] = 127,
[0][0][2][0][RTW89_MKK][0][59] = 127,
[0][0][2][0][RTW89_IC][1][59] = 22,
- [0][0][2][0][RTW89_IC][2][59] = 68,
[0][0][2][0][RTW89_KCC][1][59] = 26,
[0][0][2][0][RTW89_KCC][0][59] = 127,
[0][0][2][0][RTW89_ACMA][1][59] = 127,
@@ -41461,13 +40653,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][59] = 127,
[0][0][2][0][RTW89_THAILAND][0][59] = 127,
[0][0][2][0][RTW89_FCC][1][60] = 22,
- [0][0][2][0][RTW89_FCC][2][60] = 68,
[0][0][2][0][RTW89_ETSI][1][60] = 127,
[0][0][2][0][RTW89_ETSI][0][60] = 127,
[0][0][2][0][RTW89_MKK][1][60] = 127,
[0][0][2][0][RTW89_MKK][0][60] = 127,
[0][0][2][0][RTW89_IC][1][60] = 22,
- [0][0][2][0][RTW89_IC][2][60] = 68,
[0][0][2][0][RTW89_KCC][1][60] = 26,
[0][0][2][0][RTW89_KCC][0][60] = 127,
[0][0][2][0][RTW89_ACMA][1][60] = 127,
@@ -41480,13 +40670,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][60] = 127,
[0][0][2][0][RTW89_THAILAND][0][60] = 127,
[0][0][2][0][RTW89_FCC][1][62] = 22,
- [0][0][2][0][RTW89_FCC][2][62] = 68,
[0][0][2][0][RTW89_ETSI][1][62] = 127,
[0][0][2][0][RTW89_ETSI][0][62] = 127,
[0][0][2][0][RTW89_MKK][1][62] = 127,
[0][0][2][0][RTW89_MKK][0][62] = 127,
[0][0][2][0][RTW89_IC][1][62] = 22,
- [0][0][2][0][RTW89_IC][2][62] = 68,
[0][0][2][0][RTW89_KCC][1][62] = 26,
[0][0][2][0][RTW89_KCC][0][62] = 127,
[0][0][2][0][RTW89_ACMA][1][62] = 127,
@@ -41499,13 +40687,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][62] = 127,
[0][0][2][0][RTW89_THAILAND][0][62] = 127,
[0][0][2][0][RTW89_FCC][1][64] = 22,
- [0][0][2][0][RTW89_FCC][2][64] = 68,
[0][0][2][0][RTW89_ETSI][1][64] = 127,
[0][0][2][0][RTW89_ETSI][0][64] = 127,
[0][0][2][0][RTW89_MKK][1][64] = 127,
[0][0][2][0][RTW89_MKK][0][64] = 127,
[0][0][2][0][RTW89_IC][1][64] = 22,
- [0][0][2][0][RTW89_IC][2][64] = 68,
[0][0][2][0][RTW89_KCC][1][64] = 26,
[0][0][2][0][RTW89_KCC][0][64] = 127,
[0][0][2][0][RTW89_ACMA][1][64] = 127,
@@ -41518,13 +40704,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][64] = 127,
[0][0][2][0][RTW89_THAILAND][0][64] = 127,
[0][0][2][0][RTW89_FCC][1][66] = 22,
- [0][0][2][0][RTW89_FCC][2][66] = 68,
[0][0][2][0][RTW89_ETSI][1][66] = 127,
[0][0][2][0][RTW89_ETSI][0][66] = 127,
[0][0][2][0][RTW89_MKK][1][66] = 127,
[0][0][2][0][RTW89_MKK][0][66] = 127,
[0][0][2][0][RTW89_IC][1][66] = 22,
- [0][0][2][0][RTW89_IC][2][66] = 68,
[0][0][2][0][RTW89_KCC][1][66] = 26,
[0][0][2][0][RTW89_KCC][0][66] = 127,
[0][0][2][0][RTW89_ACMA][1][66] = 127,
@@ -41537,13 +40721,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][66] = 127,
[0][0][2][0][RTW89_THAILAND][0][66] = 127,
[0][0][2][0][RTW89_FCC][1][68] = 22,
- [0][0][2][0][RTW89_FCC][2][68] = 68,
[0][0][2][0][RTW89_ETSI][1][68] = 127,
[0][0][2][0][RTW89_ETSI][0][68] = 127,
[0][0][2][0][RTW89_MKK][1][68] = 127,
[0][0][2][0][RTW89_MKK][0][68] = 127,
[0][0][2][0][RTW89_IC][1][68] = 22,
- [0][0][2][0][RTW89_IC][2][68] = 68,
[0][0][2][0][RTW89_KCC][1][68] = 26,
[0][0][2][0][RTW89_KCC][0][68] = 127,
[0][0][2][0][RTW89_ACMA][1][68] = 127,
@@ -41556,13 +40738,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][68] = 127,
[0][0][2][0][RTW89_THAILAND][0][68] = 127,
[0][0][2][0][RTW89_FCC][1][70] = 24,
- [0][0][2][0][RTW89_FCC][2][70] = 68,
[0][0][2][0][RTW89_ETSI][1][70] = 127,
[0][0][2][0][RTW89_ETSI][0][70] = 127,
[0][0][2][0][RTW89_MKK][1][70] = 127,
[0][0][2][0][RTW89_MKK][0][70] = 127,
[0][0][2][0][RTW89_IC][1][70] = 24,
- [0][0][2][0][RTW89_IC][2][70] = 68,
[0][0][2][0][RTW89_KCC][1][70] = 26,
[0][0][2][0][RTW89_KCC][0][70] = 127,
[0][0][2][0][RTW89_ACMA][1][70] = 127,
@@ -41575,13 +40755,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][70] = 127,
[0][0][2][0][RTW89_THAILAND][0][70] = 127,
[0][0][2][0][RTW89_FCC][1][72] = 22,
- [0][0][2][0][RTW89_FCC][2][72] = 68,
[0][0][2][0][RTW89_ETSI][1][72] = 127,
[0][0][2][0][RTW89_ETSI][0][72] = 127,
[0][0][2][0][RTW89_MKK][1][72] = 127,
[0][0][2][0][RTW89_MKK][0][72] = 127,
[0][0][2][0][RTW89_IC][1][72] = 22,
- [0][0][2][0][RTW89_IC][2][72] = 68,
[0][0][2][0][RTW89_KCC][1][72] = 26,
[0][0][2][0][RTW89_KCC][0][72] = 127,
[0][0][2][0][RTW89_ACMA][1][72] = 127,
@@ -41594,13 +40772,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][72] = 127,
[0][0][2][0][RTW89_THAILAND][0][72] = 127,
[0][0][2][0][RTW89_FCC][1][74] = 22,
- [0][0][2][0][RTW89_FCC][2][74] = 68,
[0][0][2][0][RTW89_ETSI][1][74] = 127,
[0][0][2][0][RTW89_ETSI][0][74] = 127,
[0][0][2][0][RTW89_MKK][1][74] = 127,
[0][0][2][0][RTW89_MKK][0][74] = 127,
[0][0][2][0][RTW89_IC][1][74] = 22,
- [0][0][2][0][RTW89_IC][2][74] = 68,
[0][0][2][0][RTW89_KCC][1][74] = 26,
[0][0][2][0][RTW89_KCC][0][74] = 127,
[0][0][2][0][RTW89_ACMA][1][74] = 127,
@@ -41613,13 +40789,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][74] = 127,
[0][0][2][0][RTW89_THAILAND][0][74] = 127,
[0][0][2][0][RTW89_FCC][1][75] = 22,
- [0][0][2][0][RTW89_FCC][2][75] = 68,
[0][0][2][0][RTW89_ETSI][1][75] = 127,
[0][0][2][0][RTW89_ETSI][0][75] = 127,
[0][0][2][0][RTW89_MKK][1][75] = 127,
[0][0][2][0][RTW89_MKK][0][75] = 127,
[0][0][2][0][RTW89_IC][1][75] = 22,
- [0][0][2][0][RTW89_IC][2][75] = 68,
[0][0][2][0][RTW89_KCC][1][75] = 26,
[0][0][2][0][RTW89_KCC][0][75] = 127,
[0][0][2][0][RTW89_ACMA][1][75] = 127,
@@ -41632,13 +40806,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][75] = 127,
[0][0][2][0][RTW89_THAILAND][0][75] = 127,
[0][0][2][0][RTW89_FCC][1][77] = 22,
- [0][0][2][0][RTW89_FCC][2][77] = 68,
[0][0][2][0][RTW89_ETSI][1][77] = 127,
[0][0][2][0][RTW89_ETSI][0][77] = 127,
[0][0][2][0][RTW89_MKK][1][77] = 127,
[0][0][2][0][RTW89_MKK][0][77] = 127,
[0][0][2][0][RTW89_IC][1][77] = 22,
- [0][0][2][0][RTW89_IC][2][77] = 68,
[0][0][2][0][RTW89_KCC][1][77] = 26,
[0][0][2][0][RTW89_KCC][0][77] = 127,
[0][0][2][0][RTW89_ACMA][1][77] = 127,
@@ -41651,13 +40823,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][77] = 127,
[0][0][2][0][RTW89_THAILAND][0][77] = 127,
[0][0][2][0][RTW89_FCC][1][79] = 22,
- [0][0][2][0][RTW89_FCC][2][79] = 68,
[0][0][2][0][RTW89_ETSI][1][79] = 127,
[0][0][2][0][RTW89_ETSI][0][79] = 127,
[0][0][2][0][RTW89_MKK][1][79] = 127,
[0][0][2][0][RTW89_MKK][0][79] = 127,
[0][0][2][0][RTW89_IC][1][79] = 22,
- [0][0][2][0][RTW89_IC][2][79] = 68,
[0][0][2][0][RTW89_KCC][1][79] = 26,
[0][0][2][0][RTW89_KCC][0][79] = 127,
[0][0][2][0][RTW89_ACMA][1][79] = 127,
@@ -41670,13 +40840,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][79] = 127,
[0][0][2][0][RTW89_THAILAND][0][79] = 127,
[0][0][2][0][RTW89_FCC][1][81] = 22,
- [0][0][2][0][RTW89_FCC][2][81] = 68,
[0][0][2][0][RTW89_ETSI][1][81] = 127,
[0][0][2][0][RTW89_ETSI][0][81] = 127,
[0][0][2][0][RTW89_MKK][1][81] = 127,
[0][0][2][0][RTW89_MKK][0][81] = 127,
[0][0][2][0][RTW89_IC][1][81] = 22,
- [0][0][2][0][RTW89_IC][2][81] = 68,
[0][0][2][0][RTW89_KCC][1][81] = 26,
[0][0][2][0][RTW89_KCC][0][81] = 127,
[0][0][2][0][RTW89_ACMA][1][81] = 127,
@@ -41689,13 +40857,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][81] = 127,
[0][0][2][0][RTW89_THAILAND][0][81] = 127,
[0][0][2][0][RTW89_FCC][1][83] = 22,
- [0][0][2][0][RTW89_FCC][2][83] = 68,
[0][0][2][0][RTW89_ETSI][1][83] = 127,
[0][0][2][0][RTW89_ETSI][0][83] = 127,
[0][0][2][0][RTW89_MKK][1][83] = 127,
[0][0][2][0][RTW89_MKK][0][83] = 127,
[0][0][2][0][RTW89_IC][1][83] = 22,
- [0][0][2][0][RTW89_IC][2][83] = 68,
[0][0][2][0][RTW89_KCC][1][83] = 32,
[0][0][2][0][RTW89_KCC][0][83] = 127,
[0][0][2][0][RTW89_ACMA][1][83] = 127,
@@ -41708,13 +40874,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][83] = 127,
[0][0][2][0][RTW89_THAILAND][0][83] = 127,
[0][0][2][0][RTW89_FCC][1][85] = 22,
- [0][0][2][0][RTW89_FCC][2][85] = 68,
[0][0][2][0][RTW89_ETSI][1][85] = 127,
[0][0][2][0][RTW89_ETSI][0][85] = 127,
[0][0][2][0][RTW89_MKK][1][85] = 127,
[0][0][2][0][RTW89_MKK][0][85] = 127,
[0][0][2][0][RTW89_IC][1][85] = 22,
- [0][0][2][0][RTW89_IC][2][85] = 68,
[0][0][2][0][RTW89_KCC][1][85] = 32,
[0][0][2][0][RTW89_KCC][0][85] = 127,
[0][0][2][0][RTW89_ACMA][1][85] = 127,
@@ -41727,13 +40891,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][85] = 127,
[0][0][2][0][RTW89_THAILAND][0][85] = 127,
[0][0][2][0][RTW89_FCC][1][87] = 22,
- [0][0][2][0][RTW89_FCC][2][87] = 127,
[0][0][2][0][RTW89_ETSI][1][87] = 127,
[0][0][2][0][RTW89_ETSI][0][87] = 127,
[0][0][2][0][RTW89_MKK][1][87] = 127,
[0][0][2][0][RTW89_MKK][0][87] = 127,
[0][0][2][0][RTW89_IC][1][87] = 22,
- [0][0][2][0][RTW89_IC][2][87] = 127,
[0][0][2][0][RTW89_KCC][1][87] = 32,
[0][0][2][0][RTW89_KCC][0][87] = 127,
[0][0][2][0][RTW89_ACMA][1][87] = 127,
@@ -41746,13 +40908,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][87] = 127,
[0][0][2][0][RTW89_THAILAND][0][87] = 127,
[0][0][2][0][RTW89_FCC][1][89] = 22,
- [0][0][2][0][RTW89_FCC][2][89] = 127,
[0][0][2][0][RTW89_ETSI][1][89] = 127,
[0][0][2][0][RTW89_ETSI][0][89] = 127,
[0][0][2][0][RTW89_MKK][1][89] = 127,
[0][0][2][0][RTW89_MKK][0][89] = 127,
[0][0][2][0][RTW89_IC][1][89] = 22,
- [0][0][2][0][RTW89_IC][2][89] = 127,
[0][0][2][0][RTW89_KCC][1][89] = 32,
[0][0][2][0][RTW89_KCC][0][89] = 127,
[0][0][2][0][RTW89_ACMA][1][89] = 127,
@@ -41765,13 +40925,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][89] = 127,
[0][0][2][0][RTW89_THAILAND][0][89] = 127,
[0][0][2][0][RTW89_FCC][1][90] = 22,
- [0][0][2][0][RTW89_FCC][2][90] = 127,
[0][0][2][0][RTW89_ETSI][1][90] = 127,
[0][0][2][0][RTW89_ETSI][0][90] = 127,
[0][0][2][0][RTW89_MKK][1][90] = 127,
[0][0][2][0][RTW89_MKK][0][90] = 127,
[0][0][2][0][RTW89_IC][1][90] = 22,
- [0][0][2][0][RTW89_IC][2][90] = 127,
[0][0][2][0][RTW89_KCC][1][90] = 32,
[0][0][2][0][RTW89_KCC][0][90] = 127,
[0][0][2][0][RTW89_ACMA][1][90] = 127,
@@ -41784,13 +40942,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][90] = 127,
[0][0][2][0][RTW89_THAILAND][0][90] = 127,
[0][0][2][0][RTW89_FCC][1][92] = 22,
- [0][0][2][0][RTW89_FCC][2][92] = 127,
[0][0][2][0][RTW89_ETSI][1][92] = 127,
[0][0][2][0][RTW89_ETSI][0][92] = 127,
[0][0][2][0][RTW89_MKK][1][92] = 127,
[0][0][2][0][RTW89_MKK][0][92] = 127,
[0][0][2][0][RTW89_IC][1][92] = 22,
- [0][0][2][0][RTW89_IC][2][92] = 127,
[0][0][2][0][RTW89_KCC][1][92] = 32,
[0][0][2][0][RTW89_KCC][0][92] = 127,
[0][0][2][0][RTW89_ACMA][1][92] = 127,
@@ -41803,13 +40959,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][92] = 127,
[0][0][2][0][RTW89_THAILAND][0][92] = 127,
[0][0][2][0][RTW89_FCC][1][94] = 22,
- [0][0][2][0][RTW89_FCC][2][94] = 127,
[0][0][2][0][RTW89_ETSI][1][94] = 127,
[0][0][2][0][RTW89_ETSI][0][94] = 127,
[0][0][2][0][RTW89_MKK][1][94] = 127,
[0][0][2][0][RTW89_MKK][0][94] = 127,
[0][0][2][0][RTW89_IC][1][94] = 22,
- [0][0][2][0][RTW89_IC][2][94] = 127,
[0][0][2][0][RTW89_KCC][1][94] = 32,
[0][0][2][0][RTW89_KCC][0][94] = 127,
[0][0][2][0][RTW89_ACMA][1][94] = 127,
@@ -41822,13 +40976,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][94] = 127,
[0][0][2][0][RTW89_THAILAND][0][94] = 127,
[0][0][2][0][RTW89_FCC][1][96] = 22,
- [0][0][2][0][RTW89_FCC][2][96] = 127,
[0][0][2][0][RTW89_ETSI][1][96] = 127,
[0][0][2][0][RTW89_ETSI][0][96] = 127,
[0][0][2][0][RTW89_MKK][1][96] = 127,
[0][0][2][0][RTW89_MKK][0][96] = 127,
[0][0][2][0][RTW89_IC][1][96] = 22,
- [0][0][2][0][RTW89_IC][2][96] = 127,
[0][0][2][0][RTW89_KCC][1][96] = 32,
[0][0][2][0][RTW89_KCC][0][96] = 127,
[0][0][2][0][RTW89_ACMA][1][96] = 127,
@@ -41841,13 +40993,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][96] = 127,
[0][0][2][0][RTW89_THAILAND][0][96] = 127,
[0][0][2][0][RTW89_FCC][1][98] = 22,
- [0][0][2][0][RTW89_FCC][2][98] = 127,
[0][0][2][0][RTW89_ETSI][1][98] = 127,
[0][0][2][0][RTW89_ETSI][0][98] = 127,
[0][0][2][0][RTW89_MKK][1][98] = 127,
[0][0][2][0][RTW89_MKK][0][98] = 127,
[0][0][2][0][RTW89_IC][1][98] = 22,
- [0][0][2][0][RTW89_IC][2][98] = 127,
[0][0][2][0][RTW89_KCC][1][98] = 32,
[0][0][2][0][RTW89_KCC][0][98] = 127,
[0][0][2][0][RTW89_ACMA][1][98] = 127,
@@ -41860,13 +41010,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][98] = 127,
[0][0][2][0][RTW89_THAILAND][0][98] = 127,
[0][0][2][0][RTW89_FCC][1][100] = 22,
- [0][0][2][0][RTW89_FCC][2][100] = 127,
[0][0][2][0][RTW89_ETSI][1][100] = 127,
[0][0][2][0][RTW89_ETSI][0][100] = 127,
[0][0][2][0][RTW89_MKK][1][100] = 127,
[0][0][2][0][RTW89_MKK][0][100] = 127,
[0][0][2][0][RTW89_IC][1][100] = 22,
- [0][0][2][0][RTW89_IC][2][100] = 127,
[0][0][2][0][RTW89_KCC][1][100] = 32,
[0][0][2][0][RTW89_KCC][0][100] = 127,
[0][0][2][0][RTW89_ACMA][1][100] = 127,
@@ -41879,13 +41027,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][100] = 127,
[0][0][2][0][RTW89_THAILAND][0][100] = 127,
[0][0][2][0][RTW89_FCC][1][102] = 22,
- [0][0][2][0][RTW89_FCC][2][102] = 127,
[0][0][2][0][RTW89_ETSI][1][102] = 127,
[0][0][2][0][RTW89_ETSI][0][102] = 127,
[0][0][2][0][RTW89_MKK][1][102] = 127,
[0][0][2][0][RTW89_MKK][0][102] = 127,
[0][0][2][0][RTW89_IC][1][102] = 22,
- [0][0][2][0][RTW89_IC][2][102] = 127,
[0][0][2][0][RTW89_KCC][1][102] = 32,
[0][0][2][0][RTW89_KCC][0][102] = 127,
[0][0][2][0][RTW89_ACMA][1][102] = 127,
@@ -41898,13 +41044,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][102] = 127,
[0][0][2][0][RTW89_THAILAND][0][102] = 127,
[0][0][2][0][RTW89_FCC][1][104] = 22,
- [0][0][2][0][RTW89_FCC][2][104] = 127,
[0][0][2][0][RTW89_ETSI][1][104] = 127,
[0][0][2][0][RTW89_ETSI][0][104] = 127,
[0][0][2][0][RTW89_MKK][1][104] = 127,
[0][0][2][0][RTW89_MKK][0][104] = 127,
[0][0][2][0][RTW89_IC][1][104] = 22,
- [0][0][2][0][RTW89_IC][2][104] = 127,
[0][0][2][0][RTW89_KCC][1][104] = 32,
[0][0][2][0][RTW89_KCC][0][104] = 127,
[0][0][2][0][RTW89_ACMA][1][104] = 127,
@@ -41917,13 +41061,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][104] = 127,
[0][0][2][0][RTW89_THAILAND][0][104] = 127,
[0][0][2][0][RTW89_FCC][1][105] = 22,
- [0][0][2][0][RTW89_FCC][2][105] = 127,
[0][0][2][0][RTW89_ETSI][1][105] = 127,
[0][0][2][0][RTW89_ETSI][0][105] = 127,
[0][0][2][0][RTW89_MKK][1][105] = 127,
[0][0][2][0][RTW89_MKK][0][105] = 127,
[0][0][2][0][RTW89_IC][1][105] = 22,
- [0][0][2][0][RTW89_IC][2][105] = 127,
[0][0][2][0][RTW89_KCC][1][105] = 32,
[0][0][2][0][RTW89_KCC][0][105] = 127,
[0][0][2][0][RTW89_ACMA][1][105] = 127,
@@ -41936,13 +41078,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][105] = 127,
[0][0][2][0][RTW89_THAILAND][0][105] = 127,
[0][0][2][0][RTW89_FCC][1][107] = 24,
- [0][0][2][0][RTW89_FCC][2][107] = 127,
[0][0][2][0][RTW89_ETSI][1][107] = 127,
[0][0][2][0][RTW89_ETSI][0][107] = 127,
[0][0][2][0][RTW89_MKK][1][107] = 127,
[0][0][2][0][RTW89_MKK][0][107] = 127,
[0][0][2][0][RTW89_IC][1][107] = 24,
- [0][0][2][0][RTW89_IC][2][107] = 127,
[0][0][2][0][RTW89_KCC][1][107] = 32,
[0][0][2][0][RTW89_KCC][0][107] = 127,
[0][0][2][0][RTW89_ACMA][1][107] = 127,
@@ -41955,13 +41095,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][107] = 127,
[0][0][2][0][RTW89_THAILAND][0][107] = 127,
[0][0][2][0][RTW89_FCC][1][109] = 24,
- [0][0][2][0][RTW89_FCC][2][109] = 127,
[0][0][2][0][RTW89_ETSI][1][109] = 127,
[0][0][2][0][RTW89_ETSI][0][109] = 127,
[0][0][2][0][RTW89_MKK][1][109] = 127,
[0][0][2][0][RTW89_MKK][0][109] = 127,
[0][0][2][0][RTW89_IC][1][109] = 24,
- [0][0][2][0][RTW89_IC][2][109] = 127,
[0][0][2][0][RTW89_KCC][1][109] = 32,
[0][0][2][0][RTW89_KCC][0][109] = 127,
[0][0][2][0][RTW89_ACMA][1][109] = 127,
@@ -41974,13 +41112,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][109] = 127,
[0][0][2][0][RTW89_THAILAND][0][109] = 127,
[0][0][2][0][RTW89_FCC][1][111] = 127,
- [0][0][2][0][RTW89_FCC][2][111] = 127,
[0][0][2][0][RTW89_ETSI][1][111] = 127,
[0][0][2][0][RTW89_ETSI][0][111] = 127,
[0][0][2][0][RTW89_MKK][1][111] = 127,
[0][0][2][0][RTW89_MKK][0][111] = 127,
[0][0][2][0][RTW89_IC][1][111] = 127,
- [0][0][2][0][RTW89_IC][2][111] = 127,
[0][0][2][0][RTW89_KCC][1][111] = 127,
[0][0][2][0][RTW89_KCC][0][111] = 127,
[0][0][2][0][RTW89_ACMA][1][111] = 127,
@@ -41993,13 +41129,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][111] = 127,
[0][0][2][0][RTW89_THAILAND][0][111] = 127,
[0][0][2][0][RTW89_FCC][1][113] = 127,
- [0][0][2][0][RTW89_FCC][2][113] = 127,
[0][0][2][0][RTW89_ETSI][1][113] = 127,
[0][0][2][0][RTW89_ETSI][0][113] = 127,
[0][0][2][0][RTW89_MKK][1][113] = 127,
[0][0][2][0][RTW89_MKK][0][113] = 127,
[0][0][2][0][RTW89_IC][1][113] = 127,
- [0][0][2][0][RTW89_IC][2][113] = 127,
[0][0][2][0][RTW89_KCC][1][113] = 127,
[0][0][2][0][RTW89_KCC][0][113] = 127,
[0][0][2][0][RTW89_ACMA][1][113] = 127,
@@ -42012,13 +41146,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][113] = 127,
[0][0][2][0][RTW89_THAILAND][0][113] = 127,
[0][0][2][0][RTW89_FCC][1][115] = 127,
- [0][0][2][0][RTW89_FCC][2][115] = 127,
[0][0][2][0][RTW89_ETSI][1][115] = 127,
[0][0][2][0][RTW89_ETSI][0][115] = 127,
[0][0][2][0][RTW89_MKK][1][115] = 127,
[0][0][2][0][RTW89_MKK][0][115] = 127,
[0][0][2][0][RTW89_IC][1][115] = 127,
- [0][0][2][0][RTW89_IC][2][115] = 127,
[0][0][2][0][RTW89_KCC][1][115] = 127,
[0][0][2][0][RTW89_KCC][0][115] = 127,
[0][0][2][0][RTW89_ACMA][1][115] = 127,
@@ -42031,13 +41163,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][115] = 127,
[0][0][2][0][RTW89_THAILAND][0][115] = 127,
[0][0][2][0][RTW89_FCC][1][117] = 127,
- [0][0][2][0][RTW89_FCC][2][117] = 127,
[0][0][2][0][RTW89_ETSI][1][117] = 127,
[0][0][2][0][RTW89_ETSI][0][117] = 127,
[0][0][2][0][RTW89_MKK][1][117] = 127,
[0][0][2][0][RTW89_MKK][0][117] = 127,
[0][0][2][0][RTW89_IC][1][117] = 127,
- [0][0][2][0][RTW89_IC][2][117] = 127,
[0][0][2][0][RTW89_KCC][1][117] = 127,
[0][0][2][0][RTW89_KCC][0][117] = 127,
[0][0][2][0][RTW89_ACMA][1][117] = 127,
@@ -42050,13 +41180,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][117] = 127,
[0][0][2][0][RTW89_THAILAND][0][117] = 127,
[0][0][2][0][RTW89_FCC][1][119] = 127,
- [0][0][2][0][RTW89_FCC][2][119] = 127,
[0][0][2][0][RTW89_ETSI][1][119] = 127,
[0][0][2][0][RTW89_ETSI][0][119] = 127,
[0][0][2][0][RTW89_MKK][1][119] = 127,
[0][0][2][0][RTW89_MKK][0][119] = 127,
[0][0][2][0][RTW89_IC][1][119] = 127,
- [0][0][2][0][RTW89_IC][2][119] = 127,
[0][0][2][0][RTW89_KCC][1][119] = 127,
[0][0][2][0][RTW89_KCC][0][119] = 127,
[0][0][2][0][RTW89_ACMA][1][119] = 127,
@@ -42069,13 +41197,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][0][2][0][RTW89_THAILAND][1][119] = 127,
[0][0][2][0][RTW89_THAILAND][0][119] = 127,
[0][1][2][0][RTW89_FCC][1][0] = -2,
- [0][1][2][0][RTW89_FCC][2][0] = 54,
[0][1][2][0][RTW89_ETSI][1][0] = 54,
[0][1][2][0][RTW89_ETSI][0][0] = 18,
[0][1][2][0][RTW89_MKK][1][0] = 56,
[0][1][2][0][RTW89_MKK][0][0] = 16,
[0][1][2][0][RTW89_IC][1][0] = -2,
- [0][1][2][0][RTW89_IC][2][0] = 54,
[0][1][2][0][RTW89_KCC][1][0] = 12,
[0][1][2][0][RTW89_KCC][0][0] = 10,
[0][1][2][0][RTW89_ACMA][1][0] = 54,
@@ -42088,13 +41214,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][0] = 44,
[0][1][2][0][RTW89_THAILAND][0][0] = -2,
[0][1][2][0][RTW89_FCC][1][2] = -4,
- [0][1][2][0][RTW89_FCC][2][2] = 54,
[0][1][2][0][RTW89_ETSI][1][2] = 54,
[0][1][2][0][RTW89_ETSI][0][2] = 18,
[0][1][2][0][RTW89_MKK][1][2] = 54,
[0][1][2][0][RTW89_MKK][0][2] = 16,
[0][1][2][0][RTW89_IC][1][2] = -4,
- [0][1][2][0][RTW89_IC][2][2] = 54,
[0][1][2][0][RTW89_KCC][1][2] = 12,
[0][1][2][0][RTW89_KCC][0][2] = 12,
[0][1][2][0][RTW89_ACMA][1][2] = 54,
@@ -42107,13 +41231,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][2] = 44,
[0][1][2][0][RTW89_THAILAND][0][2] = -4,
[0][1][2][0][RTW89_FCC][1][4] = -4,
- [0][1][2][0][RTW89_FCC][2][4] = 54,
[0][1][2][0][RTW89_ETSI][1][4] = 54,
[0][1][2][0][RTW89_ETSI][0][4] = 18,
[0][1][2][0][RTW89_MKK][1][4] = 54,
[0][1][2][0][RTW89_MKK][0][4] = 16,
[0][1][2][0][RTW89_IC][1][4] = -4,
- [0][1][2][0][RTW89_IC][2][4] = 54,
[0][1][2][0][RTW89_KCC][1][4] = 12,
[0][1][2][0][RTW89_KCC][0][4] = 12,
[0][1][2][0][RTW89_ACMA][1][4] = 54,
@@ -42126,13 +41248,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][4] = 44,
[0][1][2][0][RTW89_THAILAND][0][4] = -4,
[0][1][2][0][RTW89_FCC][1][6] = -4,
- [0][1][2][0][RTW89_FCC][2][6] = 54,
[0][1][2][0][RTW89_ETSI][1][6] = 54,
[0][1][2][0][RTW89_ETSI][0][6] = 18,
[0][1][2][0][RTW89_MKK][1][6] = 54,
[0][1][2][0][RTW89_MKK][0][6] = 16,
[0][1][2][0][RTW89_IC][1][6] = -4,
- [0][1][2][0][RTW89_IC][2][6] = 54,
[0][1][2][0][RTW89_KCC][1][6] = 12,
[0][1][2][0][RTW89_KCC][0][6] = 12,
[0][1][2][0][RTW89_ACMA][1][6] = 54,
@@ -42145,13 +41265,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][6] = 44,
[0][1][2][0][RTW89_THAILAND][0][6] = -4,
[0][1][2][0][RTW89_FCC][1][8] = -4,
- [0][1][2][0][RTW89_FCC][2][8] = 54,
[0][1][2][0][RTW89_ETSI][1][8] = 54,
[0][1][2][0][RTW89_ETSI][0][8] = 18,
[0][1][2][0][RTW89_MKK][1][8] = 54,
[0][1][2][0][RTW89_MKK][0][8] = 16,
[0][1][2][0][RTW89_IC][1][8] = -4,
- [0][1][2][0][RTW89_IC][2][8] = 54,
[0][1][2][0][RTW89_KCC][1][8] = 12,
[0][1][2][0][RTW89_KCC][0][8] = 12,
[0][1][2][0][RTW89_ACMA][1][8] = 54,
@@ -42164,13 +41282,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][8] = 44,
[0][1][2][0][RTW89_THAILAND][0][8] = -4,
[0][1][2][0][RTW89_FCC][1][10] = -4,
- [0][1][2][0][RTW89_FCC][2][10] = 54,
[0][1][2][0][RTW89_ETSI][1][10] = 54,
[0][1][2][0][RTW89_ETSI][0][10] = 18,
[0][1][2][0][RTW89_MKK][1][10] = 54,
[0][1][2][0][RTW89_MKK][0][10] = 16,
[0][1][2][0][RTW89_IC][1][10] = -4,
- [0][1][2][0][RTW89_IC][2][10] = 54,
[0][1][2][0][RTW89_KCC][1][10] = 12,
[0][1][2][0][RTW89_KCC][0][10] = 12,
[0][1][2][0][RTW89_ACMA][1][10] = 54,
@@ -42183,13 +41299,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][10] = 44,
[0][1][2][0][RTW89_THAILAND][0][10] = -4,
[0][1][2][0][RTW89_FCC][1][12] = -4,
- [0][1][2][0][RTW89_FCC][2][12] = 54,
[0][1][2][0][RTW89_ETSI][1][12] = 54,
[0][1][2][0][RTW89_ETSI][0][12] = 18,
[0][1][2][0][RTW89_MKK][1][12] = 54,
[0][1][2][0][RTW89_MKK][0][12] = 16,
[0][1][2][0][RTW89_IC][1][12] = -4,
- [0][1][2][0][RTW89_IC][2][12] = 54,
[0][1][2][0][RTW89_KCC][1][12] = 12,
[0][1][2][0][RTW89_KCC][0][12] = 12,
[0][1][2][0][RTW89_ACMA][1][12] = 54,
@@ -42202,13 +41316,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][12] = 44,
[0][1][2][0][RTW89_THAILAND][0][12] = -4,
[0][1][2][0][RTW89_FCC][1][14] = -4,
- [0][1][2][0][RTW89_FCC][2][14] = 54,
[0][1][2][0][RTW89_ETSI][1][14] = 54,
[0][1][2][0][RTW89_ETSI][0][14] = 18,
[0][1][2][0][RTW89_MKK][1][14] = 54,
[0][1][2][0][RTW89_MKK][0][14] = 16,
[0][1][2][0][RTW89_IC][1][14] = -4,
- [0][1][2][0][RTW89_IC][2][14] = 54,
[0][1][2][0][RTW89_KCC][1][14] = 12,
[0][1][2][0][RTW89_KCC][0][14] = 12,
[0][1][2][0][RTW89_ACMA][1][14] = 54,
@@ -42221,13 +41333,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][14] = 44,
[0][1][2][0][RTW89_THAILAND][0][14] = -4,
[0][1][2][0][RTW89_FCC][1][15] = -4,
- [0][1][2][0][RTW89_FCC][2][15] = 54,
[0][1][2][0][RTW89_ETSI][1][15] = 54,
[0][1][2][0][RTW89_ETSI][0][15] = 18,
[0][1][2][0][RTW89_MKK][1][15] = 54,
[0][1][2][0][RTW89_MKK][0][15] = 16,
[0][1][2][0][RTW89_IC][1][15] = -4,
- [0][1][2][0][RTW89_IC][2][15] = 54,
[0][1][2][0][RTW89_KCC][1][15] = 12,
[0][1][2][0][RTW89_KCC][0][15] = 12,
[0][1][2][0][RTW89_ACMA][1][15] = 54,
@@ -42240,13 +41350,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][15] = 44,
[0][1][2][0][RTW89_THAILAND][0][15] = -4,
[0][1][2][0][RTW89_FCC][1][17] = -4,
- [0][1][2][0][RTW89_FCC][2][17] = 54,
[0][1][2][0][RTW89_ETSI][1][17] = 54,
[0][1][2][0][RTW89_ETSI][0][17] = 18,
[0][1][2][0][RTW89_MKK][1][17] = 54,
[0][1][2][0][RTW89_MKK][0][17] = 16,
[0][1][2][0][RTW89_IC][1][17] = -4,
- [0][1][2][0][RTW89_IC][2][17] = 54,
[0][1][2][0][RTW89_KCC][1][17] = 12,
[0][1][2][0][RTW89_KCC][0][17] = 12,
[0][1][2][0][RTW89_ACMA][1][17] = 54,
@@ -42259,13 +41367,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][17] = 44,
[0][1][2][0][RTW89_THAILAND][0][17] = -4,
[0][1][2][0][RTW89_FCC][1][19] = -4,
- [0][1][2][0][RTW89_FCC][2][19] = 54,
[0][1][2][0][RTW89_ETSI][1][19] = 54,
[0][1][2][0][RTW89_ETSI][0][19] = 18,
[0][1][2][0][RTW89_MKK][1][19] = 54,
[0][1][2][0][RTW89_MKK][0][19] = 16,
[0][1][2][0][RTW89_IC][1][19] = -4,
- [0][1][2][0][RTW89_IC][2][19] = 54,
[0][1][2][0][RTW89_KCC][1][19] = 12,
[0][1][2][0][RTW89_KCC][0][19] = 12,
[0][1][2][0][RTW89_ACMA][1][19] = 54,
@@ -42278,13 +41384,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][19] = 44,
[0][1][2][0][RTW89_THAILAND][0][19] = -4,
[0][1][2][0][RTW89_FCC][1][21] = -4,
- [0][1][2][0][RTW89_FCC][2][21] = 54,
[0][1][2][0][RTW89_ETSI][1][21] = 54,
[0][1][2][0][RTW89_ETSI][0][21] = 18,
[0][1][2][0][RTW89_MKK][1][21] = 54,
[0][1][2][0][RTW89_MKK][0][21] = 16,
[0][1][2][0][RTW89_IC][1][21] = -4,
- [0][1][2][0][RTW89_IC][2][21] = 54,
[0][1][2][0][RTW89_KCC][1][21] = 12,
[0][1][2][0][RTW89_KCC][0][21] = 12,
[0][1][2][0][RTW89_ACMA][1][21] = 54,
@@ -42297,13 +41401,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][21] = 44,
[0][1][2][0][RTW89_THAILAND][0][21] = -4,
[0][1][2][0][RTW89_FCC][1][23] = -4,
- [0][1][2][0][RTW89_FCC][2][23] = 68,
[0][1][2][0][RTW89_ETSI][1][23] = 54,
[0][1][2][0][RTW89_ETSI][0][23] = 18,
[0][1][2][0][RTW89_MKK][1][23] = 54,
[0][1][2][0][RTW89_MKK][0][23] = 16,
[0][1][2][0][RTW89_IC][1][23] = -4,
- [0][1][2][0][RTW89_IC][2][23] = 68,
[0][1][2][0][RTW89_KCC][1][23] = 12,
[0][1][2][0][RTW89_KCC][0][23] = 10,
[0][1][2][0][RTW89_ACMA][1][23] = 54,
@@ -42316,13 +41418,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][23] = 44,
[0][1][2][0][RTW89_THAILAND][0][23] = -4,
[0][1][2][0][RTW89_FCC][1][25] = -4,
- [0][1][2][0][RTW89_FCC][2][25] = 68,
[0][1][2][0][RTW89_ETSI][1][25] = 54,
[0][1][2][0][RTW89_ETSI][0][25] = 18,
[0][1][2][0][RTW89_MKK][1][25] = 54,
[0][1][2][0][RTW89_MKK][0][25] = 16,
[0][1][2][0][RTW89_IC][1][25] = -4,
- [0][1][2][0][RTW89_IC][2][25] = 68,
[0][1][2][0][RTW89_KCC][1][25] = 12,
[0][1][2][0][RTW89_KCC][0][25] = 14,
[0][1][2][0][RTW89_ACMA][1][25] = 54,
@@ -42335,13 +41435,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][25] = 42,
[0][1][2][0][RTW89_THAILAND][0][25] = -4,
[0][1][2][0][RTW89_FCC][1][27] = -4,
- [0][1][2][0][RTW89_FCC][2][27] = 68,
[0][1][2][0][RTW89_ETSI][1][27] = 54,
[0][1][2][0][RTW89_ETSI][0][27] = 18,
[0][1][2][0][RTW89_MKK][1][27] = 54,
[0][1][2][0][RTW89_MKK][0][27] = 16,
[0][1][2][0][RTW89_IC][1][27] = -4,
- [0][1][2][0][RTW89_IC][2][27] = 68,
[0][1][2][0][RTW89_KCC][1][27] = 12,
[0][1][2][0][RTW89_KCC][0][27] = 14,
[0][1][2][0][RTW89_ACMA][1][27] = 54,
@@ -42354,13 +41452,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][27] = 42,
[0][1][2][0][RTW89_THAILAND][0][27] = -4,
[0][1][2][0][RTW89_FCC][1][29] = -4,
- [0][1][2][0][RTW89_FCC][2][29] = 68,
[0][1][2][0][RTW89_ETSI][1][29] = 54,
[0][1][2][0][RTW89_ETSI][0][29] = 18,
[0][1][2][0][RTW89_MKK][1][29] = 54,
[0][1][2][0][RTW89_MKK][0][29] = 16,
[0][1][2][0][RTW89_IC][1][29] = -4,
- [0][1][2][0][RTW89_IC][2][29] = 68,
[0][1][2][0][RTW89_KCC][1][29] = 12,
[0][1][2][0][RTW89_KCC][0][29] = 14,
[0][1][2][0][RTW89_ACMA][1][29] = 54,
@@ -42373,13 +41469,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][29] = 42,
[0][1][2][0][RTW89_THAILAND][0][29] = -4,
[0][1][2][0][RTW89_FCC][1][30] = -4,
- [0][1][2][0][RTW89_FCC][2][30] = 68,
[0][1][2][0][RTW89_ETSI][1][30] = 54,
[0][1][2][0][RTW89_ETSI][0][30] = 18,
[0][1][2][0][RTW89_MKK][1][30] = 54,
[0][1][2][0][RTW89_MKK][0][30] = 16,
[0][1][2][0][RTW89_IC][1][30] = -4,
- [0][1][2][0][RTW89_IC][2][30] = 68,
[0][1][2][0][RTW89_KCC][1][30] = 12,
[0][1][2][0][RTW89_KCC][0][30] = 14,
[0][1][2][0][RTW89_ACMA][1][30] = 54,
@@ -42392,13 +41486,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][30] = 42,
[0][1][2][0][RTW89_THAILAND][0][30] = -4,
[0][1][2][0][RTW89_FCC][1][32] = -4,
- [0][1][2][0][RTW89_FCC][2][32] = 68,
[0][1][2][0][RTW89_ETSI][1][32] = 54,
[0][1][2][0][RTW89_ETSI][0][32] = 18,
[0][1][2][0][RTW89_MKK][1][32] = 54,
[0][1][2][0][RTW89_MKK][0][32] = 16,
[0][1][2][0][RTW89_IC][1][32] = -4,
- [0][1][2][0][RTW89_IC][2][32] = 68,
[0][1][2][0][RTW89_KCC][1][32] = 12,
[0][1][2][0][RTW89_KCC][0][32] = 14,
[0][1][2][0][RTW89_ACMA][1][32] = 54,
@@ -42411,13 +41503,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][32] = 42,
[0][1][2][0][RTW89_THAILAND][0][32] = -4,
[0][1][2][0][RTW89_FCC][1][34] = -4,
- [0][1][2][0][RTW89_FCC][2][34] = 68,
[0][1][2][0][RTW89_ETSI][1][34] = 54,
[0][1][2][0][RTW89_ETSI][0][34] = 18,
[0][1][2][0][RTW89_MKK][1][34] = 54,
[0][1][2][0][RTW89_MKK][0][34] = 16,
[0][1][2][0][RTW89_IC][1][34] = -4,
- [0][1][2][0][RTW89_IC][2][34] = 68,
[0][1][2][0][RTW89_KCC][1][34] = 12,
[0][1][2][0][RTW89_KCC][0][34] = 14,
[0][1][2][0][RTW89_ACMA][1][34] = 54,
@@ -42430,13 +41520,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][34] = 42,
[0][1][2][0][RTW89_THAILAND][0][34] = -4,
[0][1][2][0][RTW89_FCC][1][36] = -4,
- [0][1][2][0][RTW89_FCC][2][36] = 68,
[0][1][2][0][RTW89_ETSI][1][36] = 54,
[0][1][2][0][RTW89_ETSI][0][36] = 18,
[0][1][2][0][RTW89_MKK][1][36] = 54,
[0][1][2][0][RTW89_MKK][0][36] = 16,
[0][1][2][0][RTW89_IC][1][36] = -4,
- [0][1][2][0][RTW89_IC][2][36] = 68,
[0][1][2][0][RTW89_KCC][1][36] = 12,
[0][1][2][0][RTW89_KCC][0][36] = 14,
[0][1][2][0][RTW89_ACMA][1][36] = 54,
@@ -42449,13 +41537,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][36] = 42,
[0][1][2][0][RTW89_THAILAND][0][36] = -4,
[0][1][2][0][RTW89_FCC][1][38] = -4,
- [0][1][2][0][RTW89_FCC][2][38] = 68,
[0][1][2][0][RTW89_ETSI][1][38] = 54,
[0][1][2][0][RTW89_ETSI][0][38] = 18,
[0][1][2][0][RTW89_MKK][1][38] = 54,
[0][1][2][0][RTW89_MKK][0][38] = 16,
[0][1][2][0][RTW89_IC][1][38] = -4,
- [0][1][2][0][RTW89_IC][2][38] = 68,
[0][1][2][0][RTW89_KCC][1][38] = 12,
[0][1][2][0][RTW89_KCC][0][38] = 14,
[0][1][2][0][RTW89_ACMA][1][38] = 54,
@@ -42468,13 +41554,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][38] = 42,
[0][1][2][0][RTW89_THAILAND][0][38] = -4,
[0][1][2][0][RTW89_FCC][1][40] = -4,
- [0][1][2][0][RTW89_FCC][2][40] = 68,
[0][1][2][0][RTW89_ETSI][1][40] = 54,
[0][1][2][0][RTW89_ETSI][0][40] = 18,
[0][1][2][0][RTW89_MKK][1][40] = 54,
[0][1][2][0][RTW89_MKK][0][40] = 16,
[0][1][2][0][RTW89_IC][1][40] = -4,
- [0][1][2][0][RTW89_IC][2][40] = 68,
[0][1][2][0][RTW89_KCC][1][40] = 12,
[0][1][2][0][RTW89_KCC][0][40] = 14,
[0][1][2][0][RTW89_ACMA][1][40] = 54,
@@ -42487,13 +41571,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][40] = 42,
[0][1][2][0][RTW89_THAILAND][0][40] = -4,
[0][1][2][0][RTW89_FCC][1][42] = -4,
- [0][1][2][0][RTW89_FCC][2][42] = 68,
[0][1][2][0][RTW89_ETSI][1][42] = 54,
[0][1][2][0][RTW89_ETSI][0][42] = 18,
[0][1][2][0][RTW89_MKK][1][42] = 54,
[0][1][2][0][RTW89_MKK][0][42] = 16,
[0][1][2][0][RTW89_IC][1][42] = -4,
- [0][1][2][0][RTW89_IC][2][42] = 68,
[0][1][2][0][RTW89_KCC][1][42] = 12,
[0][1][2][0][RTW89_KCC][0][42] = 14,
[0][1][2][0][RTW89_ACMA][1][42] = 54,
@@ -42506,13 +41588,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][42] = 42,
[0][1][2][0][RTW89_THAILAND][0][42] = -4,
[0][1][2][0][RTW89_FCC][1][44] = -2,
- [0][1][2][0][RTW89_FCC][2][44] = 68,
[0][1][2][0][RTW89_ETSI][1][44] = 54,
[0][1][2][0][RTW89_ETSI][0][44] = 18,
[0][1][2][0][RTW89_MKK][1][44] = 34,
[0][1][2][0][RTW89_MKK][0][44] = 16,
[0][1][2][0][RTW89_IC][1][44] = -2,
- [0][1][2][0][RTW89_IC][2][44] = 68,
[0][1][2][0][RTW89_KCC][1][44] = 12,
[0][1][2][0][RTW89_KCC][0][44] = 12,
[0][1][2][0][RTW89_ACMA][1][44] = 54,
@@ -42525,13 +41605,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][44] = 42,
[0][1][2][0][RTW89_THAILAND][0][44] = -2,
[0][1][2][0][RTW89_FCC][1][45] = -2,
- [0][1][2][0][RTW89_FCC][2][45] = 127,
[0][1][2][0][RTW89_ETSI][1][45] = 127,
[0][1][2][0][RTW89_ETSI][0][45] = 127,
[0][1][2][0][RTW89_MKK][1][45] = 127,
[0][1][2][0][RTW89_MKK][0][45] = 127,
[0][1][2][0][RTW89_IC][1][45] = -2,
- [0][1][2][0][RTW89_IC][2][45] = 70,
[0][1][2][0][RTW89_KCC][1][45] = 12,
[0][1][2][0][RTW89_KCC][0][45] = 127,
[0][1][2][0][RTW89_ACMA][1][45] = 127,
@@ -42544,13 +41622,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][45] = 127,
[0][1][2][0][RTW89_THAILAND][0][45] = 127,
[0][1][2][0][RTW89_FCC][1][47] = -2,
- [0][1][2][0][RTW89_FCC][2][47] = 127,
[0][1][2][0][RTW89_ETSI][1][47] = 127,
[0][1][2][0][RTW89_ETSI][0][47] = 127,
[0][1][2][0][RTW89_MKK][1][47] = 127,
[0][1][2][0][RTW89_MKK][0][47] = 127,
[0][1][2][0][RTW89_IC][1][47] = -2,
- [0][1][2][0][RTW89_IC][2][47] = 68,
[0][1][2][0][RTW89_KCC][1][47] = 12,
[0][1][2][0][RTW89_KCC][0][47] = 127,
[0][1][2][0][RTW89_ACMA][1][47] = 127,
@@ -42563,13 +41639,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][47] = 127,
[0][1][2][0][RTW89_THAILAND][0][47] = 127,
[0][1][2][0][RTW89_FCC][1][49] = -2,
- [0][1][2][0][RTW89_FCC][2][49] = 127,
[0][1][2][0][RTW89_ETSI][1][49] = 127,
[0][1][2][0][RTW89_ETSI][0][49] = 127,
[0][1][2][0][RTW89_MKK][1][49] = 127,
[0][1][2][0][RTW89_MKK][0][49] = 127,
[0][1][2][0][RTW89_IC][1][49] = -2,
- [0][1][2][0][RTW89_IC][2][49] = 68,
[0][1][2][0][RTW89_KCC][1][49] = 12,
[0][1][2][0][RTW89_KCC][0][49] = 127,
[0][1][2][0][RTW89_ACMA][1][49] = 127,
@@ -42582,13 +41656,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][49] = 127,
[0][1][2][0][RTW89_THAILAND][0][49] = 127,
[0][1][2][0][RTW89_FCC][1][51] = -2,
- [0][1][2][0][RTW89_FCC][2][51] = 127,
[0][1][2][0][RTW89_ETSI][1][51] = 127,
[0][1][2][0][RTW89_ETSI][0][51] = 127,
[0][1][2][0][RTW89_MKK][1][51] = 127,
[0][1][2][0][RTW89_MKK][0][51] = 127,
[0][1][2][0][RTW89_IC][1][51] = -2,
- [0][1][2][0][RTW89_IC][2][51] = 68,
[0][1][2][0][RTW89_KCC][1][51] = 12,
[0][1][2][0][RTW89_KCC][0][51] = 127,
[0][1][2][0][RTW89_ACMA][1][51] = 127,
@@ -42601,13 +41673,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][51] = 127,
[0][1][2][0][RTW89_THAILAND][0][51] = 127,
[0][1][2][0][RTW89_FCC][1][53] = -2,
- [0][1][2][0][RTW89_FCC][2][53] = 127,
[0][1][2][0][RTW89_ETSI][1][53] = 127,
[0][1][2][0][RTW89_ETSI][0][53] = 127,
[0][1][2][0][RTW89_MKK][1][53] = 127,
[0][1][2][0][RTW89_MKK][0][53] = 127,
[0][1][2][0][RTW89_IC][1][53] = -2,
- [0][1][2][0][RTW89_IC][2][53] = 68,
[0][1][2][0][RTW89_KCC][1][53] = 12,
[0][1][2][0][RTW89_KCC][0][53] = 127,
[0][1][2][0][RTW89_ACMA][1][53] = 127,
@@ -42620,13 +41690,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][53] = 127,
[0][1][2][0][RTW89_THAILAND][0][53] = 127,
[0][1][2][0][RTW89_FCC][1][55] = -2,
- [0][1][2][0][RTW89_FCC][2][55] = 68,
[0][1][2][0][RTW89_ETSI][1][55] = 127,
[0][1][2][0][RTW89_ETSI][0][55] = 127,
[0][1][2][0][RTW89_MKK][1][55] = 127,
[0][1][2][0][RTW89_MKK][0][55] = 127,
[0][1][2][0][RTW89_IC][1][55] = -2,
- [0][1][2][0][RTW89_IC][2][55] = 68,
[0][1][2][0][RTW89_KCC][1][55] = 12,
[0][1][2][0][RTW89_KCC][0][55] = 127,
[0][1][2][0][RTW89_ACMA][1][55] = 127,
@@ -42639,13 +41707,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][55] = 127,
[0][1][2][0][RTW89_THAILAND][0][55] = 127,
[0][1][2][0][RTW89_FCC][1][57] = -2,
- [0][1][2][0][RTW89_FCC][2][57] = 68,
[0][1][2][0][RTW89_ETSI][1][57] = 127,
[0][1][2][0][RTW89_ETSI][0][57] = 127,
[0][1][2][0][RTW89_MKK][1][57] = 127,
[0][1][2][0][RTW89_MKK][0][57] = 127,
[0][1][2][0][RTW89_IC][1][57] = -2,
- [0][1][2][0][RTW89_IC][2][57] = 68,
[0][1][2][0][RTW89_KCC][1][57] = 12,
[0][1][2][0][RTW89_KCC][0][57] = 127,
[0][1][2][0][RTW89_ACMA][1][57] = 127,
@@ -42658,13 +41724,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][57] = 127,
[0][1][2][0][RTW89_THAILAND][0][57] = 127,
[0][1][2][0][RTW89_FCC][1][59] = -2,
- [0][1][2][0][RTW89_FCC][2][59] = 68,
[0][1][2][0][RTW89_ETSI][1][59] = 127,
[0][1][2][0][RTW89_ETSI][0][59] = 127,
[0][1][2][0][RTW89_MKK][1][59] = 127,
[0][1][2][0][RTW89_MKK][0][59] = 127,
[0][1][2][0][RTW89_IC][1][59] = -2,
- [0][1][2][0][RTW89_IC][2][59] = 68,
[0][1][2][0][RTW89_KCC][1][59] = 12,
[0][1][2][0][RTW89_KCC][0][59] = 127,
[0][1][2][0][RTW89_ACMA][1][59] = 127,
@@ -42677,13 +41741,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][59] = 127,
[0][1][2][0][RTW89_THAILAND][0][59] = 127,
[0][1][2][0][RTW89_FCC][1][60] = -2,
- [0][1][2][0][RTW89_FCC][2][60] = 68,
[0][1][2][0][RTW89_ETSI][1][60] = 127,
[0][1][2][0][RTW89_ETSI][0][60] = 127,
[0][1][2][0][RTW89_MKK][1][60] = 127,
[0][1][2][0][RTW89_MKK][0][60] = 127,
[0][1][2][0][RTW89_IC][1][60] = -2,
- [0][1][2][0][RTW89_IC][2][60] = 68,
[0][1][2][0][RTW89_KCC][1][60] = 12,
[0][1][2][0][RTW89_KCC][0][60] = 127,
[0][1][2][0][RTW89_ACMA][1][60] = 127,
@@ -42696,13 +41758,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][60] = 127,
[0][1][2][0][RTW89_THAILAND][0][60] = 127,
[0][1][2][0][RTW89_FCC][1][62] = -2,
- [0][1][2][0][RTW89_FCC][2][62] = 68,
[0][1][2][0][RTW89_ETSI][1][62] = 127,
[0][1][2][0][RTW89_ETSI][0][62] = 127,
[0][1][2][0][RTW89_MKK][1][62] = 127,
[0][1][2][0][RTW89_MKK][0][62] = 127,
[0][1][2][0][RTW89_IC][1][62] = -2,
- [0][1][2][0][RTW89_IC][2][62] = 68,
[0][1][2][0][RTW89_KCC][1][62] = 12,
[0][1][2][0][RTW89_KCC][0][62] = 127,
[0][1][2][0][RTW89_ACMA][1][62] = 127,
@@ -42715,13 +41775,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][62] = 127,
[0][1][2][0][RTW89_THAILAND][0][62] = 127,
[0][1][2][0][RTW89_FCC][1][64] = -2,
- [0][1][2][0][RTW89_FCC][2][64] = 68,
[0][1][2][0][RTW89_ETSI][1][64] = 127,
[0][1][2][0][RTW89_ETSI][0][64] = 127,
[0][1][2][0][RTW89_MKK][1][64] = 127,
[0][1][2][0][RTW89_MKK][0][64] = 127,
[0][1][2][0][RTW89_IC][1][64] = -2,
- [0][1][2][0][RTW89_IC][2][64] = 68,
[0][1][2][0][RTW89_KCC][1][64] = 12,
[0][1][2][0][RTW89_KCC][0][64] = 127,
[0][1][2][0][RTW89_ACMA][1][64] = 127,
@@ -42734,13 +41792,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][64] = 127,
[0][1][2][0][RTW89_THAILAND][0][64] = 127,
[0][1][2][0][RTW89_FCC][1][66] = -2,
- [0][1][2][0][RTW89_FCC][2][66] = 68,
[0][1][2][0][RTW89_ETSI][1][66] = 127,
[0][1][2][0][RTW89_ETSI][0][66] = 127,
[0][1][2][0][RTW89_MKK][1][66] = 127,
[0][1][2][0][RTW89_MKK][0][66] = 127,
[0][1][2][0][RTW89_IC][1][66] = -2,
- [0][1][2][0][RTW89_IC][2][66] = 68,
[0][1][2][0][RTW89_KCC][1][66] = 12,
[0][1][2][0][RTW89_KCC][0][66] = 127,
[0][1][2][0][RTW89_ACMA][1][66] = 127,
@@ -42753,13 +41809,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][66] = 127,
[0][1][2][0][RTW89_THAILAND][0][66] = 127,
[0][1][2][0][RTW89_FCC][1][68] = -2,
- [0][1][2][0][RTW89_FCC][2][68] = 68,
[0][1][2][0][RTW89_ETSI][1][68] = 127,
[0][1][2][0][RTW89_ETSI][0][68] = 127,
[0][1][2][0][RTW89_MKK][1][68] = 127,
[0][1][2][0][RTW89_MKK][0][68] = 127,
[0][1][2][0][RTW89_IC][1][68] = -2,
- [0][1][2][0][RTW89_IC][2][68] = 68,
[0][1][2][0][RTW89_KCC][1][68] = 12,
[0][1][2][0][RTW89_KCC][0][68] = 127,
[0][1][2][0][RTW89_ACMA][1][68] = 127,
@@ -42772,13 +41826,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][68] = 127,
[0][1][2][0][RTW89_THAILAND][0][68] = 127,
[0][1][2][0][RTW89_FCC][1][70] = -2,
- [0][1][2][0][RTW89_FCC][2][70] = 68,
[0][1][2][0][RTW89_ETSI][1][70] = 127,
[0][1][2][0][RTW89_ETSI][0][70] = 127,
[0][1][2][0][RTW89_MKK][1][70] = 127,
[0][1][2][0][RTW89_MKK][0][70] = 127,
[0][1][2][0][RTW89_IC][1][70] = -2,
- [0][1][2][0][RTW89_IC][2][70] = 68,
[0][1][2][0][RTW89_KCC][1][70] = 12,
[0][1][2][0][RTW89_KCC][0][70] = 127,
[0][1][2][0][RTW89_ACMA][1][70] = 127,
@@ -42791,13 +41843,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][70] = 127,
[0][1][2][0][RTW89_THAILAND][0][70] = 127,
[0][1][2][0][RTW89_FCC][1][72] = -2,
- [0][1][2][0][RTW89_FCC][2][72] = 68,
[0][1][2][0][RTW89_ETSI][1][72] = 127,
[0][1][2][0][RTW89_ETSI][0][72] = 127,
[0][1][2][0][RTW89_MKK][1][72] = 127,
[0][1][2][0][RTW89_MKK][0][72] = 127,
[0][1][2][0][RTW89_IC][1][72] = -2,
- [0][1][2][0][RTW89_IC][2][72] = 68,
[0][1][2][0][RTW89_KCC][1][72] = 12,
[0][1][2][0][RTW89_KCC][0][72] = 127,
[0][1][2][0][RTW89_ACMA][1][72] = 127,
@@ -42810,13 +41860,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][72] = 127,
[0][1][2][0][RTW89_THAILAND][0][72] = 127,
[0][1][2][0][RTW89_FCC][1][74] = -2,
- [0][1][2][0][RTW89_FCC][2][74] = 68,
[0][1][2][0][RTW89_ETSI][1][74] = 127,
[0][1][2][0][RTW89_ETSI][0][74] = 127,
[0][1][2][0][RTW89_MKK][1][74] = 127,
[0][1][2][0][RTW89_MKK][0][74] = 127,
[0][1][2][0][RTW89_IC][1][74] = -2,
- [0][1][2][0][RTW89_IC][2][74] = 68,
[0][1][2][0][RTW89_KCC][1][74] = 12,
[0][1][2][0][RTW89_KCC][0][74] = 127,
[0][1][2][0][RTW89_ACMA][1][74] = 127,
@@ -42829,13 +41877,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][74] = 127,
[0][1][2][0][RTW89_THAILAND][0][74] = 127,
[0][1][2][0][RTW89_FCC][1][75] = -2,
- [0][1][2][0][RTW89_FCC][2][75] = 68,
[0][1][2][0][RTW89_ETSI][1][75] = 127,
[0][1][2][0][RTW89_ETSI][0][75] = 127,
[0][1][2][0][RTW89_MKK][1][75] = 127,
[0][1][2][0][RTW89_MKK][0][75] = 127,
[0][1][2][0][RTW89_IC][1][75] = -2,
- [0][1][2][0][RTW89_IC][2][75] = 68,
[0][1][2][0][RTW89_KCC][1][75] = 12,
[0][1][2][0][RTW89_KCC][0][75] = 127,
[0][1][2][0][RTW89_ACMA][1][75] = 127,
@@ -42848,13 +41894,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][75] = 127,
[0][1][2][0][RTW89_THAILAND][0][75] = 127,
[0][1][2][0][RTW89_FCC][1][77] = -2,
- [0][1][2][0][RTW89_FCC][2][77] = 68,
[0][1][2][0][RTW89_ETSI][1][77] = 127,
[0][1][2][0][RTW89_ETSI][0][77] = 127,
[0][1][2][0][RTW89_MKK][1][77] = 127,
[0][1][2][0][RTW89_MKK][0][77] = 127,
[0][1][2][0][RTW89_IC][1][77] = -2,
- [0][1][2][0][RTW89_IC][2][77] = 68,
[0][1][2][0][RTW89_KCC][1][77] = 12,
[0][1][2][0][RTW89_KCC][0][77] = 127,
[0][1][2][0][RTW89_ACMA][1][77] = 127,
@@ -42867,13 +41911,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][77] = 127,
[0][1][2][0][RTW89_THAILAND][0][77] = 127,
[0][1][2][0][RTW89_FCC][1][79] = -2,
- [0][1][2][0][RTW89_FCC][2][79] = 68,
[0][1][2][0][RTW89_ETSI][1][79] = 127,
[0][1][2][0][RTW89_ETSI][0][79] = 127,
[0][1][2][0][RTW89_MKK][1][79] = 127,
[0][1][2][0][RTW89_MKK][0][79] = 127,
[0][1][2][0][RTW89_IC][1][79] = -2,
- [0][1][2][0][RTW89_IC][2][79] = 68,
[0][1][2][0][RTW89_KCC][1][79] = 12,
[0][1][2][0][RTW89_KCC][0][79] = 127,
[0][1][2][0][RTW89_ACMA][1][79] = 127,
@@ -42886,13 +41928,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][79] = 127,
[0][1][2][0][RTW89_THAILAND][0][79] = 127,
[0][1][2][0][RTW89_FCC][1][81] = -2,
- [0][1][2][0][RTW89_FCC][2][81] = 68,
[0][1][2][0][RTW89_ETSI][1][81] = 127,
[0][1][2][0][RTW89_ETSI][0][81] = 127,
[0][1][2][0][RTW89_MKK][1][81] = 127,
[0][1][2][0][RTW89_MKK][0][81] = 127,
[0][1][2][0][RTW89_IC][1][81] = -2,
- [0][1][2][0][RTW89_IC][2][81] = 68,
[0][1][2][0][RTW89_KCC][1][81] = 12,
[0][1][2][0][RTW89_KCC][0][81] = 127,
[0][1][2][0][RTW89_ACMA][1][81] = 127,
@@ -42905,13 +41945,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][81] = 127,
[0][1][2][0][RTW89_THAILAND][0][81] = 127,
[0][1][2][0][RTW89_FCC][1][83] = -2,
- [0][1][2][0][RTW89_FCC][2][83] = 68,
[0][1][2][0][RTW89_ETSI][1][83] = 127,
[0][1][2][0][RTW89_ETSI][0][83] = 127,
[0][1][2][0][RTW89_MKK][1][83] = 127,
[0][1][2][0][RTW89_MKK][0][83] = 127,
[0][1][2][0][RTW89_IC][1][83] = -2,
- [0][1][2][0][RTW89_IC][2][83] = 68,
[0][1][2][0][RTW89_KCC][1][83] = 20,
[0][1][2][0][RTW89_KCC][0][83] = 127,
[0][1][2][0][RTW89_ACMA][1][83] = 127,
@@ -42924,13 +41962,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][83] = 127,
[0][1][2][0][RTW89_THAILAND][0][83] = 127,
[0][1][2][0][RTW89_FCC][1][85] = -2,
- [0][1][2][0][RTW89_FCC][2][85] = 68,
[0][1][2][0][RTW89_ETSI][1][85] = 127,
[0][1][2][0][RTW89_ETSI][0][85] = 127,
[0][1][2][0][RTW89_MKK][1][85] = 127,
[0][1][2][0][RTW89_MKK][0][85] = 127,
[0][1][2][0][RTW89_IC][1][85] = -2,
- [0][1][2][0][RTW89_IC][2][85] = 68,
[0][1][2][0][RTW89_KCC][1][85] = 20,
[0][1][2][0][RTW89_KCC][0][85] = 127,
[0][1][2][0][RTW89_ACMA][1][85] = 127,
@@ -42943,13 +41979,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][85] = 127,
[0][1][2][0][RTW89_THAILAND][0][85] = 127,
[0][1][2][0][RTW89_FCC][1][87] = -2,
- [0][1][2][0][RTW89_FCC][2][87] = 127,
[0][1][2][0][RTW89_ETSI][1][87] = 127,
[0][1][2][0][RTW89_ETSI][0][87] = 127,
[0][1][2][0][RTW89_MKK][1][87] = 127,
[0][1][2][0][RTW89_MKK][0][87] = 127,
[0][1][2][0][RTW89_IC][1][87] = -2,
- [0][1][2][0][RTW89_IC][2][87] = 127,
[0][1][2][0][RTW89_KCC][1][87] = 20,
[0][1][2][0][RTW89_KCC][0][87] = 127,
[0][1][2][0][RTW89_ACMA][1][87] = 127,
@@ -42962,13 +41996,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][87] = 127,
[0][1][2][0][RTW89_THAILAND][0][87] = 127,
[0][1][2][0][RTW89_FCC][1][89] = -2,
- [0][1][2][0][RTW89_FCC][2][89] = 127,
[0][1][2][0][RTW89_ETSI][1][89] = 127,
[0][1][2][0][RTW89_ETSI][0][89] = 127,
[0][1][2][0][RTW89_MKK][1][89] = 127,
[0][1][2][0][RTW89_MKK][0][89] = 127,
[0][1][2][0][RTW89_IC][1][89] = -2,
- [0][1][2][0][RTW89_IC][2][89] = 127,
[0][1][2][0][RTW89_KCC][1][89] = 20,
[0][1][2][0][RTW89_KCC][0][89] = 127,
[0][1][2][0][RTW89_ACMA][1][89] = 127,
@@ -42981,13 +42013,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][89] = 127,
[0][1][2][0][RTW89_THAILAND][0][89] = 127,
[0][1][2][0][RTW89_FCC][1][90] = -2,
- [0][1][2][0][RTW89_FCC][2][90] = 127,
[0][1][2][0][RTW89_ETSI][1][90] = 127,
[0][1][2][0][RTW89_ETSI][0][90] = 127,
[0][1][2][0][RTW89_MKK][1][90] = 127,
[0][1][2][0][RTW89_MKK][0][90] = 127,
[0][1][2][0][RTW89_IC][1][90] = -2,
- [0][1][2][0][RTW89_IC][2][90] = 127,
[0][1][2][0][RTW89_KCC][1][90] = 20,
[0][1][2][0][RTW89_KCC][0][90] = 127,
[0][1][2][0][RTW89_ACMA][1][90] = 127,
@@ -43000,13 +42030,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][90] = 127,
[0][1][2][0][RTW89_THAILAND][0][90] = 127,
[0][1][2][0][RTW89_FCC][1][92] = -2,
- [0][1][2][0][RTW89_FCC][2][92] = 127,
[0][1][2][0][RTW89_ETSI][1][92] = 127,
[0][1][2][0][RTW89_ETSI][0][92] = 127,
[0][1][2][0][RTW89_MKK][1][92] = 127,
[0][1][2][0][RTW89_MKK][0][92] = 127,
[0][1][2][0][RTW89_IC][1][92] = -2,
- [0][1][2][0][RTW89_IC][2][92] = 127,
[0][1][2][0][RTW89_KCC][1][92] = 20,
[0][1][2][0][RTW89_KCC][0][92] = 127,
[0][1][2][0][RTW89_ACMA][1][92] = 127,
@@ -43019,13 +42047,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][92] = 127,
[0][1][2][0][RTW89_THAILAND][0][92] = 127,
[0][1][2][0][RTW89_FCC][1][94] = -2,
- [0][1][2][0][RTW89_FCC][2][94] = 127,
[0][1][2][0][RTW89_ETSI][1][94] = 127,
[0][1][2][0][RTW89_ETSI][0][94] = 127,
[0][1][2][0][RTW89_MKK][1][94] = 127,
[0][1][2][0][RTW89_MKK][0][94] = 127,
[0][1][2][0][RTW89_IC][1][94] = -2,
- [0][1][2][0][RTW89_IC][2][94] = 127,
[0][1][2][0][RTW89_KCC][1][94] = 20,
[0][1][2][0][RTW89_KCC][0][94] = 127,
[0][1][2][0][RTW89_ACMA][1][94] = 127,
@@ -43038,13 +42064,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][94] = 127,
[0][1][2][0][RTW89_THAILAND][0][94] = 127,
[0][1][2][0][RTW89_FCC][1][96] = -2,
- [0][1][2][0][RTW89_FCC][2][96] = 127,
[0][1][2][0][RTW89_ETSI][1][96] = 127,
[0][1][2][0][RTW89_ETSI][0][96] = 127,
[0][1][2][0][RTW89_MKK][1][96] = 127,
[0][1][2][0][RTW89_MKK][0][96] = 127,
[0][1][2][0][RTW89_IC][1][96] = -2,
- [0][1][2][0][RTW89_IC][2][96] = 127,
[0][1][2][0][RTW89_KCC][1][96] = 20,
[0][1][2][0][RTW89_KCC][0][96] = 127,
[0][1][2][0][RTW89_ACMA][1][96] = 127,
@@ -43057,13 +42081,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][96] = 127,
[0][1][2][0][RTW89_THAILAND][0][96] = 127,
[0][1][2][0][RTW89_FCC][1][98] = -2,
- [0][1][2][0][RTW89_FCC][2][98] = 127,
[0][1][2][0][RTW89_ETSI][1][98] = 127,
[0][1][2][0][RTW89_ETSI][0][98] = 127,
[0][1][2][0][RTW89_MKK][1][98] = 127,
[0][1][2][0][RTW89_MKK][0][98] = 127,
[0][1][2][0][RTW89_IC][1][98] = -2,
- [0][1][2][0][RTW89_IC][2][98] = 127,
[0][1][2][0][RTW89_KCC][1][98] = 20,
[0][1][2][0][RTW89_KCC][0][98] = 127,
[0][1][2][0][RTW89_ACMA][1][98] = 127,
@@ -43076,13 +42098,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][98] = 127,
[0][1][2][0][RTW89_THAILAND][0][98] = 127,
[0][1][2][0][RTW89_FCC][1][100] = -2,
- [0][1][2][0][RTW89_FCC][2][100] = 127,
[0][1][2][0][RTW89_ETSI][1][100] = 127,
[0][1][2][0][RTW89_ETSI][0][100] = 127,
[0][1][2][0][RTW89_MKK][1][100] = 127,
[0][1][2][0][RTW89_MKK][0][100] = 127,
[0][1][2][0][RTW89_IC][1][100] = -2,
- [0][1][2][0][RTW89_IC][2][100] = 127,
[0][1][2][0][RTW89_KCC][1][100] = 20,
[0][1][2][0][RTW89_KCC][0][100] = 127,
[0][1][2][0][RTW89_ACMA][1][100] = 127,
@@ -43095,13 +42115,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][100] = 127,
[0][1][2][0][RTW89_THAILAND][0][100] = 127,
[0][1][2][0][RTW89_FCC][1][102] = -2,
- [0][1][2][0][RTW89_FCC][2][102] = 127,
[0][1][2][0][RTW89_ETSI][1][102] = 127,
[0][1][2][0][RTW89_ETSI][0][102] = 127,
[0][1][2][0][RTW89_MKK][1][102] = 127,
[0][1][2][0][RTW89_MKK][0][102] = 127,
[0][1][2][0][RTW89_IC][1][102] = -2,
- [0][1][2][0][RTW89_IC][2][102] = 127,
[0][1][2][0][RTW89_KCC][1][102] = 20,
[0][1][2][0][RTW89_KCC][0][102] = 127,
[0][1][2][0][RTW89_ACMA][1][102] = 127,
@@ -43114,13 +42132,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][102] = 127,
[0][1][2][0][RTW89_THAILAND][0][102] = 127,
[0][1][2][0][RTW89_FCC][1][104] = -2,
- [0][1][2][0][RTW89_FCC][2][104] = 127,
[0][1][2][0][RTW89_ETSI][1][104] = 127,
[0][1][2][0][RTW89_ETSI][0][104] = 127,
[0][1][2][0][RTW89_MKK][1][104] = 127,
[0][1][2][0][RTW89_MKK][0][104] = 127,
[0][1][2][0][RTW89_IC][1][104] = -2,
- [0][1][2][0][RTW89_IC][2][104] = 127,
[0][1][2][0][RTW89_KCC][1][104] = 20,
[0][1][2][0][RTW89_KCC][0][104] = 127,
[0][1][2][0][RTW89_ACMA][1][104] = 127,
@@ -43133,13 +42149,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][104] = 127,
[0][1][2][0][RTW89_THAILAND][0][104] = 127,
[0][1][2][0][RTW89_FCC][1][105] = -2,
- [0][1][2][0][RTW89_FCC][2][105] = 127,
[0][1][2][0][RTW89_ETSI][1][105] = 127,
[0][1][2][0][RTW89_ETSI][0][105] = 127,
[0][1][2][0][RTW89_MKK][1][105] = 127,
[0][1][2][0][RTW89_MKK][0][105] = 127,
[0][1][2][0][RTW89_IC][1][105] = -2,
- [0][1][2][0][RTW89_IC][2][105] = 127,
[0][1][2][0][RTW89_KCC][1][105] = 20,
[0][1][2][0][RTW89_KCC][0][105] = 127,
[0][1][2][0][RTW89_ACMA][1][105] = 127,
@@ -43152,13 +42166,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][105] = 127,
[0][1][2][0][RTW89_THAILAND][0][105] = 127,
[0][1][2][0][RTW89_FCC][1][107] = 1,
- [0][1][2][0][RTW89_FCC][2][107] = 127,
[0][1][2][0][RTW89_ETSI][1][107] = 127,
[0][1][2][0][RTW89_ETSI][0][107] = 127,
[0][1][2][0][RTW89_MKK][1][107] = 127,
[0][1][2][0][RTW89_MKK][0][107] = 127,
[0][1][2][0][RTW89_IC][1][107] = 1,
- [0][1][2][0][RTW89_IC][2][107] = 127,
[0][1][2][0][RTW89_KCC][1][107] = 20,
[0][1][2][0][RTW89_KCC][0][107] = 127,
[0][1][2][0][RTW89_ACMA][1][107] = 127,
@@ -43171,13 +42183,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][107] = 127,
[0][1][2][0][RTW89_THAILAND][0][107] = 127,
[0][1][2][0][RTW89_FCC][1][109] = 1,
- [0][1][2][0][RTW89_FCC][2][109] = 127,
[0][1][2][0][RTW89_ETSI][1][109] = 127,
[0][1][2][0][RTW89_ETSI][0][109] = 127,
[0][1][2][0][RTW89_MKK][1][109] = 127,
[0][1][2][0][RTW89_MKK][0][109] = 127,
[0][1][2][0][RTW89_IC][1][109] = 1,
- [0][1][2][0][RTW89_IC][2][109] = 127,
[0][1][2][0][RTW89_KCC][1][109] = 20,
[0][1][2][0][RTW89_KCC][0][109] = 127,
[0][1][2][0][RTW89_ACMA][1][109] = 127,
@@ -43190,13 +42200,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][109] = 127,
[0][1][2][0][RTW89_THAILAND][0][109] = 127,
[0][1][2][0][RTW89_FCC][1][111] = 127,
- [0][1][2][0][RTW89_FCC][2][111] = 127,
[0][1][2][0][RTW89_ETSI][1][111] = 127,
[0][1][2][0][RTW89_ETSI][0][111] = 127,
[0][1][2][0][RTW89_MKK][1][111] = 127,
[0][1][2][0][RTW89_MKK][0][111] = 127,
[0][1][2][0][RTW89_IC][1][111] = 127,
- [0][1][2][0][RTW89_IC][2][111] = 127,
[0][1][2][0][RTW89_KCC][1][111] = 127,
[0][1][2][0][RTW89_KCC][0][111] = 127,
[0][1][2][0][RTW89_ACMA][1][111] = 127,
@@ -43209,13 +42217,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][111] = 127,
[0][1][2][0][RTW89_THAILAND][0][111] = 127,
[0][1][2][0][RTW89_FCC][1][113] = 127,
- [0][1][2][0][RTW89_FCC][2][113] = 127,
[0][1][2][0][RTW89_ETSI][1][113] = 127,
[0][1][2][0][RTW89_ETSI][0][113] = 127,
[0][1][2][0][RTW89_MKK][1][113] = 127,
[0][1][2][0][RTW89_MKK][0][113] = 127,
[0][1][2][0][RTW89_IC][1][113] = 127,
- [0][1][2][0][RTW89_IC][2][113] = 127,
[0][1][2][0][RTW89_KCC][1][113] = 127,
[0][1][2][0][RTW89_KCC][0][113] = 127,
[0][1][2][0][RTW89_ACMA][1][113] = 127,
@@ -43228,13 +42234,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][113] = 127,
[0][1][2][0][RTW89_THAILAND][0][113] = 127,
[0][1][2][0][RTW89_FCC][1][115] = 127,
- [0][1][2][0][RTW89_FCC][2][115] = 127,
[0][1][2][0][RTW89_ETSI][1][115] = 127,
[0][1][2][0][RTW89_ETSI][0][115] = 127,
[0][1][2][0][RTW89_MKK][1][115] = 127,
[0][1][2][0][RTW89_MKK][0][115] = 127,
[0][1][2][0][RTW89_IC][1][115] = 127,
- [0][1][2][0][RTW89_IC][2][115] = 127,
[0][1][2][0][RTW89_KCC][1][115] = 127,
[0][1][2][0][RTW89_KCC][0][115] = 127,
[0][1][2][0][RTW89_ACMA][1][115] = 127,
@@ -43247,13 +42251,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][115] = 127,
[0][1][2][0][RTW89_THAILAND][0][115] = 127,
[0][1][2][0][RTW89_FCC][1][117] = 127,
- [0][1][2][0][RTW89_FCC][2][117] = 127,
[0][1][2][0][RTW89_ETSI][1][117] = 127,
[0][1][2][0][RTW89_ETSI][0][117] = 127,
[0][1][2][0][RTW89_MKK][1][117] = 127,
[0][1][2][0][RTW89_MKK][0][117] = 127,
[0][1][2][0][RTW89_IC][1][117] = 127,
- [0][1][2][0][RTW89_IC][2][117] = 127,
[0][1][2][0][RTW89_KCC][1][117] = 127,
[0][1][2][0][RTW89_KCC][0][117] = 127,
[0][1][2][0][RTW89_ACMA][1][117] = 127,
@@ -43266,13 +42268,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][117] = 127,
[0][1][2][0][RTW89_THAILAND][0][117] = 127,
[0][1][2][0][RTW89_FCC][1][119] = 127,
- [0][1][2][0][RTW89_FCC][2][119] = 127,
[0][1][2][0][RTW89_ETSI][1][119] = 127,
[0][1][2][0][RTW89_ETSI][0][119] = 127,
[0][1][2][0][RTW89_MKK][1][119] = 127,
[0][1][2][0][RTW89_MKK][0][119] = 127,
[0][1][2][0][RTW89_IC][1][119] = 127,
- [0][1][2][0][RTW89_IC][2][119] = 127,
[0][1][2][0][RTW89_KCC][1][119] = 127,
[0][1][2][0][RTW89_KCC][0][119] = 127,
[0][1][2][0][RTW89_ACMA][1][119] = 127,
@@ -43285,13 +42285,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][0][RTW89_THAILAND][1][119] = 127,
[0][1][2][0][RTW89_THAILAND][0][119] = 127,
[0][1][2][1][RTW89_FCC][1][0] = -2,
- [0][1][2][1][RTW89_FCC][2][0] = 54,
[0][1][2][1][RTW89_ETSI][1][0] = 42,
[0][1][2][1][RTW89_ETSI][0][0] = 6,
[0][1][2][1][RTW89_MKK][1][0] = 56,
[0][1][2][1][RTW89_MKK][0][0] = 16,
[0][1][2][1][RTW89_IC][1][0] = -2,
- [0][1][2][1][RTW89_IC][2][0] = 54,
[0][1][2][1][RTW89_KCC][1][0] = 12,
[0][1][2][1][RTW89_KCC][0][0] = 10,
[0][1][2][1][RTW89_ACMA][1][0] = 42,
@@ -43304,13 +42302,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][0] = 44,
[0][1][2][1][RTW89_THAILAND][0][0] = -2,
[0][1][2][1][RTW89_FCC][1][2] = -4,
- [0][1][2][1][RTW89_FCC][2][2] = 54,
[0][1][2][1][RTW89_ETSI][1][2] = 42,
[0][1][2][1][RTW89_ETSI][0][2] = 6,
[0][1][2][1][RTW89_MKK][1][2] = 54,
[0][1][2][1][RTW89_MKK][0][2] = 16,
[0][1][2][1][RTW89_IC][1][2] = -4,
- [0][1][2][1][RTW89_IC][2][2] = 54,
[0][1][2][1][RTW89_KCC][1][2] = 12,
[0][1][2][1][RTW89_KCC][0][2] = 12,
[0][1][2][1][RTW89_ACMA][1][2] = 42,
@@ -43323,13 +42319,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][2] = 44,
[0][1][2][1][RTW89_THAILAND][0][2] = -4,
[0][1][2][1][RTW89_FCC][1][4] = -4,
- [0][1][2][1][RTW89_FCC][2][4] = 54,
[0][1][2][1][RTW89_ETSI][1][4] = 42,
[0][1][2][1][RTW89_ETSI][0][4] = 6,
[0][1][2][1][RTW89_MKK][1][4] = 54,
[0][1][2][1][RTW89_MKK][0][4] = 16,
[0][1][2][1][RTW89_IC][1][4] = -4,
- [0][1][2][1][RTW89_IC][2][4] = 54,
[0][1][2][1][RTW89_KCC][1][4] = 12,
[0][1][2][1][RTW89_KCC][0][4] = 12,
[0][1][2][1][RTW89_ACMA][1][4] = 42,
@@ -43342,13 +42336,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][4] = 44,
[0][1][2][1][RTW89_THAILAND][0][4] = -4,
[0][1][2][1][RTW89_FCC][1][6] = -4,
- [0][1][2][1][RTW89_FCC][2][6] = 54,
[0][1][2][1][RTW89_ETSI][1][6] = 42,
[0][1][2][1][RTW89_ETSI][0][6] = 6,
[0][1][2][1][RTW89_MKK][1][6] = 54,
[0][1][2][1][RTW89_MKK][0][6] = 16,
[0][1][2][1][RTW89_IC][1][6] = -4,
- [0][1][2][1][RTW89_IC][2][6] = 54,
[0][1][2][1][RTW89_KCC][1][6] = 12,
[0][1][2][1][RTW89_KCC][0][6] = 12,
[0][1][2][1][RTW89_ACMA][1][6] = 42,
@@ -43361,13 +42353,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][6] = 44,
[0][1][2][1][RTW89_THAILAND][0][6] = -4,
[0][1][2][1][RTW89_FCC][1][8] = -4,
- [0][1][2][1][RTW89_FCC][2][8] = 54,
[0][1][2][1][RTW89_ETSI][1][8] = 42,
[0][1][2][1][RTW89_ETSI][0][8] = 6,
[0][1][2][1][RTW89_MKK][1][8] = 54,
[0][1][2][1][RTW89_MKK][0][8] = 16,
[0][1][2][1][RTW89_IC][1][8] = -4,
- [0][1][2][1][RTW89_IC][2][8] = 54,
[0][1][2][1][RTW89_KCC][1][8] = 12,
[0][1][2][1][RTW89_KCC][0][8] = 12,
[0][1][2][1][RTW89_ACMA][1][8] = 42,
@@ -43380,13 +42370,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][8] = 44,
[0][1][2][1][RTW89_THAILAND][0][8] = -4,
[0][1][2][1][RTW89_FCC][1][10] = -4,
- [0][1][2][1][RTW89_FCC][2][10] = 54,
[0][1][2][1][RTW89_ETSI][1][10] = 42,
[0][1][2][1][RTW89_ETSI][0][10] = 6,
[0][1][2][1][RTW89_MKK][1][10] = 54,
[0][1][2][1][RTW89_MKK][0][10] = 16,
[0][1][2][1][RTW89_IC][1][10] = -4,
- [0][1][2][1][RTW89_IC][2][10] = 54,
[0][1][2][1][RTW89_KCC][1][10] = 12,
[0][1][2][1][RTW89_KCC][0][10] = 12,
[0][1][2][1][RTW89_ACMA][1][10] = 42,
@@ -43399,13 +42387,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][10] = 44,
[0][1][2][1][RTW89_THAILAND][0][10] = -4,
[0][1][2][1][RTW89_FCC][1][12] = -4,
- [0][1][2][1][RTW89_FCC][2][12] = 54,
[0][1][2][1][RTW89_ETSI][1][12] = 42,
[0][1][2][1][RTW89_ETSI][0][12] = 6,
[0][1][2][1][RTW89_MKK][1][12] = 54,
[0][1][2][1][RTW89_MKK][0][12] = 16,
[0][1][2][1][RTW89_IC][1][12] = -4,
- [0][1][2][1][RTW89_IC][2][12] = 54,
[0][1][2][1][RTW89_KCC][1][12] = 12,
[0][1][2][1][RTW89_KCC][0][12] = 12,
[0][1][2][1][RTW89_ACMA][1][12] = 42,
@@ -43418,13 +42404,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][12] = 44,
[0][1][2][1][RTW89_THAILAND][0][12] = -4,
[0][1][2][1][RTW89_FCC][1][14] = -4,
- [0][1][2][1][RTW89_FCC][2][14] = 54,
[0][1][2][1][RTW89_ETSI][1][14] = 42,
[0][1][2][1][RTW89_ETSI][0][14] = 6,
[0][1][2][1][RTW89_MKK][1][14] = 54,
[0][1][2][1][RTW89_MKK][0][14] = 16,
[0][1][2][1][RTW89_IC][1][14] = -4,
- [0][1][2][1][RTW89_IC][2][14] = 54,
[0][1][2][1][RTW89_KCC][1][14] = 12,
[0][1][2][1][RTW89_KCC][0][14] = 12,
[0][1][2][1][RTW89_ACMA][1][14] = 42,
@@ -43437,13 +42421,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][14] = 44,
[0][1][2][1][RTW89_THAILAND][0][14] = -4,
[0][1][2][1][RTW89_FCC][1][15] = -4,
- [0][1][2][1][RTW89_FCC][2][15] = 54,
[0][1][2][1][RTW89_ETSI][1][15] = 42,
[0][1][2][1][RTW89_ETSI][0][15] = 6,
[0][1][2][1][RTW89_MKK][1][15] = 54,
[0][1][2][1][RTW89_MKK][0][15] = 16,
[0][1][2][1][RTW89_IC][1][15] = -4,
- [0][1][2][1][RTW89_IC][2][15] = 54,
[0][1][2][1][RTW89_KCC][1][15] = 12,
[0][1][2][1][RTW89_KCC][0][15] = 12,
[0][1][2][1][RTW89_ACMA][1][15] = 42,
@@ -43456,13 +42438,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][15] = 44,
[0][1][2][1][RTW89_THAILAND][0][15] = -4,
[0][1][2][1][RTW89_FCC][1][17] = -4,
- [0][1][2][1][RTW89_FCC][2][17] = 54,
[0][1][2][1][RTW89_ETSI][1][17] = 42,
[0][1][2][1][RTW89_ETSI][0][17] = 6,
[0][1][2][1][RTW89_MKK][1][17] = 54,
[0][1][2][1][RTW89_MKK][0][17] = 16,
[0][1][2][1][RTW89_IC][1][17] = -4,
- [0][1][2][1][RTW89_IC][2][17] = 54,
[0][1][2][1][RTW89_KCC][1][17] = 12,
[0][1][2][1][RTW89_KCC][0][17] = 12,
[0][1][2][1][RTW89_ACMA][1][17] = 42,
@@ -43475,13 +42455,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][17] = 44,
[0][1][2][1][RTW89_THAILAND][0][17] = -4,
[0][1][2][1][RTW89_FCC][1][19] = -4,
- [0][1][2][1][RTW89_FCC][2][19] = 54,
[0][1][2][1][RTW89_ETSI][1][19] = 42,
[0][1][2][1][RTW89_ETSI][0][19] = 6,
[0][1][2][1][RTW89_MKK][1][19] = 54,
[0][1][2][1][RTW89_MKK][0][19] = 16,
[0][1][2][1][RTW89_IC][1][19] = -4,
- [0][1][2][1][RTW89_IC][2][19] = 54,
[0][1][2][1][RTW89_KCC][1][19] = 12,
[0][1][2][1][RTW89_KCC][0][19] = 12,
[0][1][2][1][RTW89_ACMA][1][19] = 42,
@@ -43494,13 +42472,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][19] = 44,
[0][1][2][1][RTW89_THAILAND][0][19] = -4,
[0][1][2][1][RTW89_FCC][1][21] = -4,
- [0][1][2][1][RTW89_FCC][2][21] = 54,
[0][1][2][1][RTW89_ETSI][1][21] = 42,
[0][1][2][1][RTW89_ETSI][0][21] = 6,
[0][1][2][1][RTW89_MKK][1][21] = 54,
[0][1][2][1][RTW89_MKK][0][21] = 16,
[0][1][2][1][RTW89_IC][1][21] = -4,
- [0][1][2][1][RTW89_IC][2][21] = 54,
[0][1][2][1][RTW89_KCC][1][21] = 12,
[0][1][2][1][RTW89_KCC][0][21] = 12,
[0][1][2][1][RTW89_ACMA][1][21] = 42,
@@ -43513,13 +42489,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][21] = 44,
[0][1][2][1][RTW89_THAILAND][0][21] = -4,
[0][1][2][1][RTW89_FCC][1][23] = -4,
- [0][1][2][1][RTW89_FCC][2][23] = 68,
[0][1][2][1][RTW89_ETSI][1][23] = 42,
[0][1][2][1][RTW89_ETSI][0][23] = 6,
[0][1][2][1][RTW89_MKK][1][23] = 54,
[0][1][2][1][RTW89_MKK][0][23] = 16,
[0][1][2][1][RTW89_IC][1][23] = -4,
- [0][1][2][1][RTW89_IC][2][23] = 68,
[0][1][2][1][RTW89_KCC][1][23] = 12,
[0][1][2][1][RTW89_KCC][0][23] = 10,
[0][1][2][1][RTW89_ACMA][1][23] = 42,
@@ -43532,13 +42506,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][23] = 44,
[0][1][2][1][RTW89_THAILAND][0][23] = -4,
[0][1][2][1][RTW89_FCC][1][25] = -4,
- [0][1][2][1][RTW89_FCC][2][25] = 68,
[0][1][2][1][RTW89_ETSI][1][25] = 42,
[0][1][2][1][RTW89_ETSI][0][25] = 6,
[0][1][2][1][RTW89_MKK][1][25] = 54,
[0][1][2][1][RTW89_MKK][0][25] = 16,
[0][1][2][1][RTW89_IC][1][25] = -4,
- [0][1][2][1][RTW89_IC][2][25] = 68,
[0][1][2][1][RTW89_KCC][1][25] = 12,
[0][1][2][1][RTW89_KCC][0][25] = 14,
[0][1][2][1][RTW89_ACMA][1][25] = 42,
@@ -43551,13 +42523,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][25] = 42,
[0][1][2][1][RTW89_THAILAND][0][25] = -4,
[0][1][2][1][RTW89_FCC][1][27] = -4,
- [0][1][2][1][RTW89_FCC][2][27] = 68,
[0][1][2][1][RTW89_ETSI][1][27] = 42,
[0][1][2][1][RTW89_ETSI][0][27] = 6,
[0][1][2][1][RTW89_MKK][1][27] = 54,
[0][1][2][1][RTW89_MKK][0][27] = 16,
[0][1][2][1][RTW89_IC][1][27] = -4,
- [0][1][2][1][RTW89_IC][2][27] = 68,
[0][1][2][1][RTW89_KCC][1][27] = 12,
[0][1][2][1][RTW89_KCC][0][27] = 14,
[0][1][2][1][RTW89_ACMA][1][27] = 42,
@@ -43570,13 +42540,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][27] = 42,
[0][1][2][1][RTW89_THAILAND][0][27] = -4,
[0][1][2][1][RTW89_FCC][1][29] = -4,
- [0][1][2][1][RTW89_FCC][2][29] = 68,
[0][1][2][1][RTW89_ETSI][1][29] = 42,
[0][1][2][1][RTW89_ETSI][0][29] = 6,
[0][1][2][1][RTW89_MKK][1][29] = 54,
[0][1][2][1][RTW89_MKK][0][29] = 16,
[0][1][2][1][RTW89_IC][1][29] = -4,
- [0][1][2][1][RTW89_IC][2][29] = 68,
[0][1][2][1][RTW89_KCC][1][29] = 12,
[0][1][2][1][RTW89_KCC][0][29] = 14,
[0][1][2][1][RTW89_ACMA][1][29] = 42,
@@ -43589,13 +42557,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][29] = 42,
[0][1][2][1][RTW89_THAILAND][0][29] = -4,
[0][1][2][1][RTW89_FCC][1][30] = -4,
- [0][1][2][1][RTW89_FCC][2][30] = 68,
[0][1][2][1][RTW89_ETSI][1][30] = 42,
[0][1][2][1][RTW89_ETSI][0][30] = 6,
[0][1][2][1][RTW89_MKK][1][30] = 54,
[0][1][2][1][RTW89_MKK][0][30] = 16,
[0][1][2][1][RTW89_IC][1][30] = -4,
- [0][1][2][1][RTW89_IC][2][30] = 68,
[0][1][2][1][RTW89_KCC][1][30] = 12,
[0][1][2][1][RTW89_KCC][0][30] = 14,
[0][1][2][1][RTW89_ACMA][1][30] = 42,
@@ -43608,13 +42574,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][30] = 42,
[0][1][2][1][RTW89_THAILAND][0][30] = -4,
[0][1][2][1][RTW89_FCC][1][32] = -4,
- [0][1][2][1][RTW89_FCC][2][32] = 68,
[0][1][2][1][RTW89_ETSI][1][32] = 42,
[0][1][2][1][RTW89_ETSI][0][32] = 6,
[0][1][2][1][RTW89_MKK][1][32] = 54,
[0][1][2][1][RTW89_MKK][0][32] = 16,
[0][1][2][1][RTW89_IC][1][32] = -4,
- [0][1][2][1][RTW89_IC][2][32] = 68,
[0][1][2][1][RTW89_KCC][1][32] = 12,
[0][1][2][1][RTW89_KCC][0][32] = 14,
[0][1][2][1][RTW89_ACMA][1][32] = 42,
@@ -43627,13 +42591,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][32] = 42,
[0][1][2][1][RTW89_THAILAND][0][32] = -4,
[0][1][2][1][RTW89_FCC][1][34] = -4,
- [0][1][2][1][RTW89_FCC][2][34] = 68,
[0][1][2][1][RTW89_ETSI][1][34] = 42,
[0][1][2][1][RTW89_ETSI][0][34] = 6,
[0][1][2][1][RTW89_MKK][1][34] = 54,
[0][1][2][1][RTW89_MKK][0][34] = 16,
[0][1][2][1][RTW89_IC][1][34] = -4,
- [0][1][2][1][RTW89_IC][2][34] = 68,
[0][1][2][1][RTW89_KCC][1][34] = 12,
[0][1][2][1][RTW89_KCC][0][34] = 14,
[0][1][2][1][RTW89_ACMA][1][34] = 42,
@@ -43646,13 +42608,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][34] = 42,
[0][1][2][1][RTW89_THAILAND][0][34] = -4,
[0][1][2][1][RTW89_FCC][1][36] = -4,
- [0][1][2][1][RTW89_FCC][2][36] = 68,
[0][1][2][1][RTW89_ETSI][1][36] = 42,
[0][1][2][1][RTW89_ETSI][0][36] = 6,
[0][1][2][1][RTW89_MKK][1][36] = 54,
[0][1][2][1][RTW89_MKK][0][36] = 16,
[0][1][2][1][RTW89_IC][1][36] = -4,
- [0][1][2][1][RTW89_IC][2][36] = 68,
[0][1][2][1][RTW89_KCC][1][36] = 12,
[0][1][2][1][RTW89_KCC][0][36] = 14,
[0][1][2][1][RTW89_ACMA][1][36] = 42,
@@ -43665,13 +42625,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][36] = 42,
[0][1][2][1][RTW89_THAILAND][0][36] = -4,
[0][1][2][1][RTW89_FCC][1][38] = -4,
- [0][1][2][1][RTW89_FCC][2][38] = 68,
[0][1][2][1][RTW89_ETSI][1][38] = 42,
[0][1][2][1][RTW89_ETSI][0][38] = 6,
[0][1][2][1][RTW89_MKK][1][38] = 54,
[0][1][2][1][RTW89_MKK][0][38] = 16,
[0][1][2][1][RTW89_IC][1][38] = -4,
- [0][1][2][1][RTW89_IC][2][38] = 68,
[0][1][2][1][RTW89_KCC][1][38] = 12,
[0][1][2][1][RTW89_KCC][0][38] = 14,
[0][1][2][1][RTW89_ACMA][1][38] = 42,
@@ -43684,13 +42642,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][38] = 42,
[0][1][2][1][RTW89_THAILAND][0][38] = -4,
[0][1][2][1][RTW89_FCC][1][40] = -4,
- [0][1][2][1][RTW89_FCC][2][40] = 68,
[0][1][2][1][RTW89_ETSI][1][40] = 42,
[0][1][2][1][RTW89_ETSI][0][40] = 6,
[0][1][2][1][RTW89_MKK][1][40] = 54,
[0][1][2][1][RTW89_MKK][0][40] = 16,
[0][1][2][1][RTW89_IC][1][40] = -4,
- [0][1][2][1][RTW89_IC][2][40] = 68,
[0][1][2][1][RTW89_KCC][1][40] = 12,
[0][1][2][1][RTW89_KCC][0][40] = 14,
[0][1][2][1][RTW89_ACMA][1][40] = 42,
@@ -43703,13 +42659,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][40] = 42,
[0][1][2][1][RTW89_THAILAND][0][40] = -4,
[0][1][2][1][RTW89_FCC][1][42] = -4,
- [0][1][2][1][RTW89_FCC][2][42] = 68,
[0][1][2][1][RTW89_ETSI][1][42] = 42,
[0][1][2][1][RTW89_ETSI][0][42] = 6,
[0][1][2][1][RTW89_MKK][1][42] = 54,
[0][1][2][1][RTW89_MKK][0][42] = 16,
[0][1][2][1][RTW89_IC][1][42] = -4,
- [0][1][2][1][RTW89_IC][2][42] = 68,
[0][1][2][1][RTW89_KCC][1][42] = 12,
[0][1][2][1][RTW89_KCC][0][42] = 14,
[0][1][2][1][RTW89_ACMA][1][42] = 42,
@@ -43722,13 +42676,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][42] = 42,
[0][1][2][1][RTW89_THAILAND][0][42] = -4,
[0][1][2][1][RTW89_FCC][1][44] = -2,
- [0][1][2][1][RTW89_FCC][2][44] = 68,
[0][1][2][1][RTW89_ETSI][1][44] = 42,
[0][1][2][1][RTW89_ETSI][0][44] = 6,
[0][1][2][1][RTW89_MKK][1][44] = 34,
[0][1][2][1][RTW89_MKK][0][44] = 16,
[0][1][2][1][RTW89_IC][1][44] = -2,
- [0][1][2][1][RTW89_IC][2][44] = 68,
[0][1][2][1][RTW89_KCC][1][44] = 12,
[0][1][2][1][RTW89_KCC][0][44] = 12,
[0][1][2][1][RTW89_ACMA][1][44] = 42,
@@ -43741,13 +42693,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][44] = 42,
[0][1][2][1][RTW89_THAILAND][0][44] = -2,
[0][1][2][1][RTW89_FCC][1][45] = -2,
- [0][1][2][1][RTW89_FCC][2][45] = 127,
[0][1][2][1][RTW89_ETSI][1][45] = 127,
[0][1][2][1][RTW89_ETSI][0][45] = 127,
[0][1][2][1][RTW89_MKK][1][45] = 127,
[0][1][2][1][RTW89_MKK][0][45] = 127,
[0][1][2][1][RTW89_IC][1][45] = -2,
- [0][1][2][1][RTW89_IC][2][45] = 70,
[0][1][2][1][RTW89_KCC][1][45] = 12,
[0][1][2][1][RTW89_KCC][0][45] = 127,
[0][1][2][1][RTW89_ACMA][1][45] = 127,
@@ -43760,13 +42710,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][45] = 127,
[0][1][2][1][RTW89_THAILAND][0][45] = 127,
[0][1][2][1][RTW89_FCC][1][47] = -2,
- [0][1][2][1][RTW89_FCC][2][47] = 127,
[0][1][2][1][RTW89_ETSI][1][47] = 127,
[0][1][2][1][RTW89_ETSI][0][47] = 127,
[0][1][2][1][RTW89_MKK][1][47] = 127,
[0][1][2][1][RTW89_MKK][0][47] = 127,
[0][1][2][1][RTW89_IC][1][47] = -2,
- [0][1][2][1][RTW89_IC][2][47] = 68,
[0][1][2][1][RTW89_KCC][1][47] = 12,
[0][1][2][1][RTW89_KCC][0][47] = 127,
[0][1][2][1][RTW89_ACMA][1][47] = 127,
@@ -43779,13 +42727,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][47] = 127,
[0][1][2][1][RTW89_THAILAND][0][47] = 127,
[0][1][2][1][RTW89_FCC][1][49] = -2,
- [0][1][2][1][RTW89_FCC][2][49] = 127,
[0][1][2][1][RTW89_ETSI][1][49] = 127,
[0][1][2][1][RTW89_ETSI][0][49] = 127,
[0][1][2][1][RTW89_MKK][1][49] = 127,
[0][1][2][1][RTW89_MKK][0][49] = 127,
[0][1][2][1][RTW89_IC][1][49] = -2,
- [0][1][2][1][RTW89_IC][2][49] = 68,
[0][1][2][1][RTW89_KCC][1][49] = 12,
[0][1][2][1][RTW89_KCC][0][49] = 127,
[0][1][2][1][RTW89_ACMA][1][49] = 127,
@@ -43798,13 +42744,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][49] = 127,
[0][1][2][1][RTW89_THAILAND][0][49] = 127,
[0][1][2][1][RTW89_FCC][1][51] = -2,
- [0][1][2][1][RTW89_FCC][2][51] = 127,
[0][1][2][1][RTW89_ETSI][1][51] = 127,
[0][1][2][1][RTW89_ETSI][0][51] = 127,
[0][1][2][1][RTW89_MKK][1][51] = 127,
[0][1][2][1][RTW89_MKK][0][51] = 127,
[0][1][2][1][RTW89_IC][1][51] = -2,
- [0][1][2][1][RTW89_IC][2][51] = 68,
[0][1][2][1][RTW89_KCC][1][51] = 12,
[0][1][2][1][RTW89_KCC][0][51] = 127,
[0][1][2][1][RTW89_ACMA][1][51] = 127,
@@ -43817,13 +42761,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][51] = 127,
[0][1][2][1][RTW89_THAILAND][0][51] = 127,
[0][1][2][1][RTW89_FCC][1][53] = -2,
- [0][1][2][1][RTW89_FCC][2][53] = 127,
[0][1][2][1][RTW89_ETSI][1][53] = 127,
[0][1][2][1][RTW89_ETSI][0][53] = 127,
[0][1][2][1][RTW89_MKK][1][53] = 127,
[0][1][2][1][RTW89_MKK][0][53] = 127,
[0][1][2][1][RTW89_IC][1][53] = -2,
- [0][1][2][1][RTW89_IC][2][53] = 68,
[0][1][2][1][RTW89_KCC][1][53] = 12,
[0][1][2][1][RTW89_KCC][0][53] = 127,
[0][1][2][1][RTW89_ACMA][1][53] = 127,
@@ -43836,13 +42778,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][53] = 127,
[0][1][2][1][RTW89_THAILAND][0][53] = 127,
[0][1][2][1][RTW89_FCC][1][55] = -2,
- [0][1][2][1][RTW89_FCC][2][55] = 68,
[0][1][2][1][RTW89_ETSI][1][55] = 127,
[0][1][2][1][RTW89_ETSI][0][55] = 127,
[0][1][2][1][RTW89_MKK][1][55] = 127,
[0][1][2][1][RTW89_MKK][0][55] = 127,
[0][1][2][1][RTW89_IC][1][55] = -2,
- [0][1][2][1][RTW89_IC][2][55] = 68,
[0][1][2][1][RTW89_KCC][1][55] = 12,
[0][1][2][1][RTW89_KCC][0][55] = 127,
[0][1][2][1][RTW89_ACMA][1][55] = 127,
@@ -43855,13 +42795,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][55] = 127,
[0][1][2][1][RTW89_THAILAND][0][55] = 127,
[0][1][2][1][RTW89_FCC][1][57] = -2,
- [0][1][2][1][RTW89_FCC][2][57] = 68,
[0][1][2][1][RTW89_ETSI][1][57] = 127,
[0][1][2][1][RTW89_ETSI][0][57] = 127,
[0][1][2][1][RTW89_MKK][1][57] = 127,
[0][1][2][1][RTW89_MKK][0][57] = 127,
[0][1][2][1][RTW89_IC][1][57] = -2,
- [0][1][2][1][RTW89_IC][2][57] = 68,
[0][1][2][1][RTW89_KCC][1][57] = 12,
[0][1][2][1][RTW89_KCC][0][57] = 127,
[0][1][2][1][RTW89_ACMA][1][57] = 127,
@@ -43874,13 +42812,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][57] = 127,
[0][1][2][1][RTW89_THAILAND][0][57] = 127,
[0][1][2][1][RTW89_FCC][1][59] = -2,
- [0][1][2][1][RTW89_FCC][2][59] = 68,
[0][1][2][1][RTW89_ETSI][1][59] = 127,
[0][1][2][1][RTW89_ETSI][0][59] = 127,
[0][1][2][1][RTW89_MKK][1][59] = 127,
[0][1][2][1][RTW89_MKK][0][59] = 127,
[0][1][2][1][RTW89_IC][1][59] = -2,
- [0][1][2][1][RTW89_IC][2][59] = 68,
[0][1][2][1][RTW89_KCC][1][59] = 12,
[0][1][2][1][RTW89_KCC][0][59] = 127,
[0][1][2][1][RTW89_ACMA][1][59] = 127,
@@ -43893,13 +42829,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][59] = 127,
[0][1][2][1][RTW89_THAILAND][0][59] = 127,
[0][1][2][1][RTW89_FCC][1][60] = -2,
- [0][1][2][1][RTW89_FCC][2][60] = 68,
[0][1][2][1][RTW89_ETSI][1][60] = 127,
[0][1][2][1][RTW89_ETSI][0][60] = 127,
[0][1][2][1][RTW89_MKK][1][60] = 127,
[0][1][2][1][RTW89_MKK][0][60] = 127,
[0][1][2][1][RTW89_IC][1][60] = -2,
- [0][1][2][1][RTW89_IC][2][60] = 68,
[0][1][2][1][RTW89_KCC][1][60] = 12,
[0][1][2][1][RTW89_KCC][0][60] = 127,
[0][1][2][1][RTW89_ACMA][1][60] = 127,
@@ -43912,13 +42846,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][60] = 127,
[0][1][2][1][RTW89_THAILAND][0][60] = 127,
[0][1][2][1][RTW89_FCC][1][62] = -2,
- [0][1][2][1][RTW89_FCC][2][62] = 68,
[0][1][2][1][RTW89_ETSI][1][62] = 127,
[0][1][2][1][RTW89_ETSI][0][62] = 127,
[0][1][2][1][RTW89_MKK][1][62] = 127,
[0][1][2][1][RTW89_MKK][0][62] = 127,
[0][1][2][1][RTW89_IC][1][62] = -2,
- [0][1][2][1][RTW89_IC][2][62] = 68,
[0][1][2][1][RTW89_KCC][1][62] = 12,
[0][1][2][1][RTW89_KCC][0][62] = 127,
[0][1][2][1][RTW89_ACMA][1][62] = 127,
@@ -43931,13 +42863,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][62] = 127,
[0][1][2][1][RTW89_THAILAND][0][62] = 127,
[0][1][2][1][RTW89_FCC][1][64] = -2,
- [0][1][2][1][RTW89_FCC][2][64] = 68,
[0][1][2][1][RTW89_ETSI][1][64] = 127,
[0][1][2][1][RTW89_ETSI][0][64] = 127,
[0][1][2][1][RTW89_MKK][1][64] = 127,
[0][1][2][1][RTW89_MKK][0][64] = 127,
[0][1][2][1][RTW89_IC][1][64] = -2,
- [0][1][2][1][RTW89_IC][2][64] = 68,
[0][1][2][1][RTW89_KCC][1][64] = 12,
[0][1][2][1][RTW89_KCC][0][64] = 127,
[0][1][2][1][RTW89_ACMA][1][64] = 127,
@@ -43950,13 +42880,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][64] = 127,
[0][1][2][1][RTW89_THAILAND][0][64] = 127,
[0][1][2][1][RTW89_FCC][1][66] = -2,
- [0][1][2][1][RTW89_FCC][2][66] = 68,
[0][1][2][1][RTW89_ETSI][1][66] = 127,
[0][1][2][1][RTW89_ETSI][0][66] = 127,
[0][1][2][1][RTW89_MKK][1][66] = 127,
[0][1][2][1][RTW89_MKK][0][66] = 127,
[0][1][2][1][RTW89_IC][1][66] = -2,
- [0][1][2][1][RTW89_IC][2][66] = 68,
[0][1][2][1][RTW89_KCC][1][66] = 12,
[0][1][2][1][RTW89_KCC][0][66] = 127,
[0][1][2][1][RTW89_ACMA][1][66] = 127,
@@ -43969,13 +42897,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][66] = 127,
[0][1][2][1][RTW89_THAILAND][0][66] = 127,
[0][1][2][1][RTW89_FCC][1][68] = -2,
- [0][1][2][1][RTW89_FCC][2][68] = 68,
[0][1][2][1][RTW89_ETSI][1][68] = 127,
[0][1][2][1][RTW89_ETSI][0][68] = 127,
[0][1][2][1][RTW89_MKK][1][68] = 127,
[0][1][2][1][RTW89_MKK][0][68] = 127,
[0][1][2][1][RTW89_IC][1][68] = -2,
- [0][1][2][1][RTW89_IC][2][68] = 68,
[0][1][2][1][RTW89_KCC][1][68] = 12,
[0][1][2][1][RTW89_KCC][0][68] = 127,
[0][1][2][1][RTW89_ACMA][1][68] = 127,
@@ -43988,13 +42914,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][68] = 127,
[0][1][2][1][RTW89_THAILAND][0][68] = 127,
[0][1][2][1][RTW89_FCC][1][70] = -2,
- [0][1][2][1][RTW89_FCC][2][70] = 68,
[0][1][2][1][RTW89_ETSI][1][70] = 127,
[0][1][2][1][RTW89_ETSI][0][70] = 127,
[0][1][2][1][RTW89_MKK][1][70] = 127,
[0][1][2][1][RTW89_MKK][0][70] = 127,
[0][1][2][1][RTW89_IC][1][70] = -2,
- [0][1][2][1][RTW89_IC][2][70] = 68,
[0][1][2][1][RTW89_KCC][1][70] = 12,
[0][1][2][1][RTW89_KCC][0][70] = 127,
[0][1][2][1][RTW89_ACMA][1][70] = 127,
@@ -44007,13 +42931,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][70] = 127,
[0][1][2][1][RTW89_THAILAND][0][70] = 127,
[0][1][2][1][RTW89_FCC][1][72] = -2,
- [0][1][2][1][RTW89_FCC][2][72] = 68,
[0][1][2][1][RTW89_ETSI][1][72] = 127,
[0][1][2][1][RTW89_ETSI][0][72] = 127,
[0][1][2][1][RTW89_MKK][1][72] = 127,
[0][1][2][1][RTW89_MKK][0][72] = 127,
[0][1][2][1][RTW89_IC][1][72] = -2,
- [0][1][2][1][RTW89_IC][2][72] = 68,
[0][1][2][1][RTW89_KCC][1][72] = 12,
[0][1][2][1][RTW89_KCC][0][72] = 127,
[0][1][2][1][RTW89_ACMA][1][72] = 127,
@@ -44026,13 +42948,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][72] = 127,
[0][1][2][1][RTW89_THAILAND][0][72] = 127,
[0][1][2][1][RTW89_FCC][1][74] = -2,
- [0][1][2][1][RTW89_FCC][2][74] = 68,
[0][1][2][1][RTW89_ETSI][1][74] = 127,
[0][1][2][1][RTW89_ETSI][0][74] = 127,
[0][1][2][1][RTW89_MKK][1][74] = 127,
[0][1][2][1][RTW89_MKK][0][74] = 127,
[0][1][2][1][RTW89_IC][1][74] = -2,
- [0][1][2][1][RTW89_IC][2][74] = 68,
[0][1][2][1][RTW89_KCC][1][74] = 12,
[0][1][2][1][RTW89_KCC][0][74] = 127,
[0][1][2][1][RTW89_ACMA][1][74] = 127,
@@ -44045,13 +42965,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][74] = 127,
[0][1][2][1][RTW89_THAILAND][0][74] = 127,
[0][1][2][1][RTW89_FCC][1][75] = -2,
- [0][1][2][1][RTW89_FCC][2][75] = 68,
[0][1][2][1][RTW89_ETSI][1][75] = 127,
[0][1][2][1][RTW89_ETSI][0][75] = 127,
[0][1][2][1][RTW89_MKK][1][75] = 127,
[0][1][2][1][RTW89_MKK][0][75] = 127,
[0][1][2][1][RTW89_IC][1][75] = -2,
- [0][1][2][1][RTW89_IC][2][75] = 68,
[0][1][2][1][RTW89_KCC][1][75] = 12,
[0][1][2][1][RTW89_KCC][0][75] = 127,
[0][1][2][1][RTW89_ACMA][1][75] = 127,
@@ -44064,13 +42982,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][75] = 127,
[0][1][2][1][RTW89_THAILAND][0][75] = 127,
[0][1][2][1][RTW89_FCC][1][77] = -2,
- [0][1][2][1][RTW89_FCC][2][77] = 68,
[0][1][2][1][RTW89_ETSI][1][77] = 127,
[0][1][2][1][RTW89_ETSI][0][77] = 127,
[0][1][2][1][RTW89_MKK][1][77] = 127,
[0][1][2][1][RTW89_MKK][0][77] = 127,
[0][1][2][1][RTW89_IC][1][77] = -2,
- [0][1][2][1][RTW89_IC][2][77] = 68,
[0][1][2][1][RTW89_KCC][1][77] = 12,
[0][1][2][1][RTW89_KCC][0][77] = 127,
[0][1][2][1][RTW89_ACMA][1][77] = 127,
@@ -44083,13 +42999,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][77] = 127,
[0][1][2][1][RTW89_THAILAND][0][77] = 127,
[0][1][2][1][RTW89_FCC][1][79] = -2,
- [0][1][2][1][RTW89_FCC][2][79] = 68,
[0][1][2][1][RTW89_ETSI][1][79] = 127,
[0][1][2][1][RTW89_ETSI][0][79] = 127,
[0][1][2][1][RTW89_MKK][1][79] = 127,
[0][1][2][1][RTW89_MKK][0][79] = 127,
[0][1][2][1][RTW89_IC][1][79] = -2,
- [0][1][2][1][RTW89_IC][2][79] = 68,
[0][1][2][1][RTW89_KCC][1][79] = 12,
[0][1][2][1][RTW89_KCC][0][79] = 127,
[0][1][2][1][RTW89_ACMA][1][79] = 127,
@@ -44102,13 +43016,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][79] = 127,
[0][1][2][1][RTW89_THAILAND][0][79] = 127,
[0][1][2][1][RTW89_FCC][1][81] = -2,
- [0][1][2][1][RTW89_FCC][2][81] = 68,
[0][1][2][1][RTW89_ETSI][1][81] = 127,
[0][1][2][1][RTW89_ETSI][0][81] = 127,
[0][1][2][1][RTW89_MKK][1][81] = 127,
[0][1][2][1][RTW89_MKK][0][81] = 127,
[0][1][2][1][RTW89_IC][1][81] = -2,
- [0][1][2][1][RTW89_IC][2][81] = 68,
[0][1][2][1][RTW89_KCC][1][81] = 12,
[0][1][2][1][RTW89_KCC][0][81] = 127,
[0][1][2][1][RTW89_ACMA][1][81] = 127,
@@ -44121,13 +43033,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][81] = 127,
[0][1][2][1][RTW89_THAILAND][0][81] = 127,
[0][1][2][1][RTW89_FCC][1][83] = -2,
- [0][1][2][1][RTW89_FCC][2][83] = 68,
[0][1][2][1][RTW89_ETSI][1][83] = 127,
[0][1][2][1][RTW89_ETSI][0][83] = 127,
[0][1][2][1][RTW89_MKK][1][83] = 127,
[0][1][2][1][RTW89_MKK][0][83] = 127,
[0][1][2][1][RTW89_IC][1][83] = -2,
- [0][1][2][1][RTW89_IC][2][83] = 68,
[0][1][2][1][RTW89_KCC][1][83] = 20,
[0][1][2][1][RTW89_KCC][0][83] = 127,
[0][1][2][1][RTW89_ACMA][1][83] = 127,
@@ -44140,13 +43050,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][83] = 127,
[0][1][2][1][RTW89_THAILAND][0][83] = 127,
[0][1][2][1][RTW89_FCC][1][85] = -2,
- [0][1][2][1][RTW89_FCC][2][85] = 68,
[0][1][2][1][RTW89_ETSI][1][85] = 127,
[0][1][2][1][RTW89_ETSI][0][85] = 127,
[0][1][2][1][RTW89_MKK][1][85] = 127,
[0][1][2][1][RTW89_MKK][0][85] = 127,
[0][1][2][1][RTW89_IC][1][85] = -2,
- [0][1][2][1][RTW89_IC][2][85] = 68,
[0][1][2][1][RTW89_KCC][1][85] = 20,
[0][1][2][1][RTW89_KCC][0][85] = 127,
[0][1][2][1][RTW89_ACMA][1][85] = 127,
@@ -44159,13 +43067,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][85] = 127,
[0][1][2][1][RTW89_THAILAND][0][85] = 127,
[0][1][2][1][RTW89_FCC][1][87] = -2,
- [0][1][2][1][RTW89_FCC][2][87] = 127,
[0][1][2][1][RTW89_ETSI][1][87] = 127,
[0][1][2][1][RTW89_ETSI][0][87] = 127,
[0][1][2][1][RTW89_MKK][1][87] = 127,
[0][1][2][1][RTW89_MKK][0][87] = 127,
[0][1][2][1][RTW89_IC][1][87] = -2,
- [0][1][2][1][RTW89_IC][2][87] = 127,
[0][1][2][1][RTW89_KCC][1][87] = 20,
[0][1][2][1][RTW89_KCC][0][87] = 127,
[0][1][2][1][RTW89_ACMA][1][87] = 127,
@@ -44178,13 +43084,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][87] = 127,
[0][1][2][1][RTW89_THAILAND][0][87] = 127,
[0][1][2][1][RTW89_FCC][1][89] = -2,
- [0][1][2][1][RTW89_FCC][2][89] = 127,
[0][1][2][1][RTW89_ETSI][1][89] = 127,
[0][1][2][1][RTW89_ETSI][0][89] = 127,
[0][1][2][1][RTW89_MKK][1][89] = 127,
[0][1][2][1][RTW89_MKK][0][89] = 127,
[0][1][2][1][RTW89_IC][1][89] = -2,
- [0][1][2][1][RTW89_IC][2][89] = 127,
[0][1][2][1][RTW89_KCC][1][89] = 20,
[0][1][2][1][RTW89_KCC][0][89] = 127,
[0][1][2][1][RTW89_ACMA][1][89] = 127,
@@ -44197,13 +43101,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][89] = 127,
[0][1][2][1][RTW89_THAILAND][0][89] = 127,
[0][1][2][1][RTW89_FCC][1][90] = -2,
- [0][1][2][1][RTW89_FCC][2][90] = 127,
[0][1][2][1][RTW89_ETSI][1][90] = 127,
[0][1][2][1][RTW89_ETSI][0][90] = 127,
[0][1][2][1][RTW89_MKK][1][90] = 127,
[0][1][2][1][RTW89_MKK][0][90] = 127,
[0][1][2][1][RTW89_IC][1][90] = -2,
- [0][1][2][1][RTW89_IC][2][90] = 127,
[0][1][2][1][RTW89_KCC][1][90] = 20,
[0][1][2][1][RTW89_KCC][0][90] = 127,
[0][1][2][1][RTW89_ACMA][1][90] = 127,
@@ -44216,13 +43118,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][90] = 127,
[0][1][2][1][RTW89_THAILAND][0][90] = 127,
[0][1][2][1][RTW89_FCC][1][92] = -2,
- [0][1][2][1][RTW89_FCC][2][92] = 127,
[0][1][2][1][RTW89_ETSI][1][92] = 127,
[0][1][2][1][RTW89_ETSI][0][92] = 127,
[0][1][2][1][RTW89_MKK][1][92] = 127,
[0][1][2][1][RTW89_MKK][0][92] = 127,
[0][1][2][1][RTW89_IC][1][92] = -2,
- [0][1][2][1][RTW89_IC][2][92] = 127,
[0][1][2][1][RTW89_KCC][1][92] = 20,
[0][1][2][1][RTW89_KCC][0][92] = 127,
[0][1][2][1][RTW89_ACMA][1][92] = 127,
@@ -44235,13 +43135,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][92] = 127,
[0][1][2][1][RTW89_THAILAND][0][92] = 127,
[0][1][2][1][RTW89_FCC][1][94] = -2,
- [0][1][2][1][RTW89_FCC][2][94] = 127,
[0][1][2][1][RTW89_ETSI][1][94] = 127,
[0][1][2][1][RTW89_ETSI][0][94] = 127,
[0][1][2][1][RTW89_MKK][1][94] = 127,
[0][1][2][1][RTW89_MKK][0][94] = 127,
[0][1][2][1][RTW89_IC][1][94] = -2,
- [0][1][2][1][RTW89_IC][2][94] = 127,
[0][1][2][1][RTW89_KCC][1][94] = 20,
[0][1][2][1][RTW89_KCC][0][94] = 127,
[0][1][2][1][RTW89_ACMA][1][94] = 127,
@@ -44254,13 +43152,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][94] = 127,
[0][1][2][1][RTW89_THAILAND][0][94] = 127,
[0][1][2][1][RTW89_FCC][1][96] = -2,
- [0][1][2][1][RTW89_FCC][2][96] = 127,
[0][1][2][1][RTW89_ETSI][1][96] = 127,
[0][1][2][1][RTW89_ETSI][0][96] = 127,
[0][1][2][1][RTW89_MKK][1][96] = 127,
[0][1][2][1][RTW89_MKK][0][96] = 127,
[0][1][2][1][RTW89_IC][1][96] = -2,
- [0][1][2][1][RTW89_IC][2][96] = 127,
[0][1][2][1][RTW89_KCC][1][96] = 20,
[0][1][2][1][RTW89_KCC][0][96] = 127,
[0][1][2][1][RTW89_ACMA][1][96] = 127,
@@ -44273,13 +43169,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][96] = 127,
[0][1][2][1][RTW89_THAILAND][0][96] = 127,
[0][1][2][1][RTW89_FCC][1][98] = -2,
- [0][1][2][1][RTW89_FCC][2][98] = 127,
[0][1][2][1][RTW89_ETSI][1][98] = 127,
[0][1][2][1][RTW89_ETSI][0][98] = 127,
[0][1][2][1][RTW89_MKK][1][98] = 127,
[0][1][2][1][RTW89_MKK][0][98] = 127,
[0][1][2][1][RTW89_IC][1][98] = -2,
- [0][1][2][1][RTW89_IC][2][98] = 127,
[0][1][2][1][RTW89_KCC][1][98] = 20,
[0][1][2][1][RTW89_KCC][0][98] = 127,
[0][1][2][1][RTW89_ACMA][1][98] = 127,
@@ -44292,13 +43186,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][98] = 127,
[0][1][2][1][RTW89_THAILAND][0][98] = 127,
[0][1][2][1][RTW89_FCC][1][100] = -2,
- [0][1][2][1][RTW89_FCC][2][100] = 127,
[0][1][2][1][RTW89_ETSI][1][100] = 127,
[0][1][2][1][RTW89_ETSI][0][100] = 127,
[0][1][2][1][RTW89_MKK][1][100] = 127,
[0][1][2][1][RTW89_MKK][0][100] = 127,
[0][1][2][1][RTW89_IC][1][100] = -2,
- [0][1][2][1][RTW89_IC][2][100] = 127,
[0][1][2][1][RTW89_KCC][1][100] = 20,
[0][1][2][1][RTW89_KCC][0][100] = 127,
[0][1][2][1][RTW89_ACMA][1][100] = 127,
@@ -44311,13 +43203,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][100] = 127,
[0][1][2][1][RTW89_THAILAND][0][100] = 127,
[0][1][2][1][RTW89_FCC][1][102] = -2,
- [0][1][2][1][RTW89_FCC][2][102] = 127,
[0][1][2][1][RTW89_ETSI][1][102] = 127,
[0][1][2][1][RTW89_ETSI][0][102] = 127,
[0][1][2][1][RTW89_MKK][1][102] = 127,
[0][1][2][1][RTW89_MKK][0][102] = 127,
[0][1][2][1][RTW89_IC][1][102] = -2,
- [0][1][2][1][RTW89_IC][2][102] = 127,
[0][1][2][1][RTW89_KCC][1][102] = 20,
[0][1][2][1][RTW89_KCC][0][102] = 127,
[0][1][2][1][RTW89_ACMA][1][102] = 127,
@@ -44330,13 +43220,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][102] = 127,
[0][1][2][1][RTW89_THAILAND][0][102] = 127,
[0][1][2][1][RTW89_FCC][1][104] = -2,
- [0][1][2][1][RTW89_FCC][2][104] = 127,
[0][1][2][1][RTW89_ETSI][1][104] = 127,
[0][1][2][1][RTW89_ETSI][0][104] = 127,
[0][1][2][1][RTW89_MKK][1][104] = 127,
[0][1][2][1][RTW89_MKK][0][104] = 127,
[0][1][2][1][RTW89_IC][1][104] = -2,
- [0][1][2][1][RTW89_IC][2][104] = 127,
[0][1][2][1][RTW89_KCC][1][104] = 20,
[0][1][2][1][RTW89_KCC][0][104] = 127,
[0][1][2][1][RTW89_ACMA][1][104] = 127,
@@ -44349,13 +43237,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][104] = 127,
[0][1][2][1][RTW89_THAILAND][0][104] = 127,
[0][1][2][1][RTW89_FCC][1][105] = -2,
- [0][1][2][1][RTW89_FCC][2][105] = 127,
[0][1][2][1][RTW89_ETSI][1][105] = 127,
[0][1][2][1][RTW89_ETSI][0][105] = 127,
[0][1][2][1][RTW89_MKK][1][105] = 127,
[0][1][2][1][RTW89_MKK][0][105] = 127,
[0][1][2][1][RTW89_IC][1][105] = -2,
- [0][1][2][1][RTW89_IC][2][105] = 127,
[0][1][2][1][RTW89_KCC][1][105] = 20,
[0][1][2][1][RTW89_KCC][0][105] = 127,
[0][1][2][1][RTW89_ACMA][1][105] = 127,
@@ -44368,13 +43254,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][105] = 127,
[0][1][2][1][RTW89_THAILAND][0][105] = 127,
[0][1][2][1][RTW89_FCC][1][107] = 1,
- [0][1][2][1][RTW89_FCC][2][107] = 127,
[0][1][2][1][RTW89_ETSI][1][107] = 127,
[0][1][2][1][RTW89_ETSI][0][107] = 127,
[0][1][2][1][RTW89_MKK][1][107] = 127,
[0][1][2][1][RTW89_MKK][0][107] = 127,
[0][1][2][1][RTW89_IC][1][107] = 1,
- [0][1][2][1][RTW89_IC][2][107] = 127,
[0][1][2][1][RTW89_KCC][1][107] = 20,
[0][1][2][1][RTW89_KCC][0][107] = 127,
[0][1][2][1][RTW89_ACMA][1][107] = 127,
@@ -44387,13 +43271,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][107] = 127,
[0][1][2][1][RTW89_THAILAND][0][107] = 127,
[0][1][2][1][RTW89_FCC][1][109] = 1,
- [0][1][2][1][RTW89_FCC][2][109] = 127,
[0][1][2][1][RTW89_ETSI][1][109] = 127,
[0][1][2][1][RTW89_ETSI][0][109] = 127,
[0][1][2][1][RTW89_MKK][1][109] = 127,
[0][1][2][1][RTW89_MKK][0][109] = 127,
[0][1][2][1][RTW89_IC][1][109] = 1,
- [0][1][2][1][RTW89_IC][2][109] = 127,
[0][1][2][1][RTW89_KCC][1][109] = 20,
[0][1][2][1][RTW89_KCC][0][109] = 127,
[0][1][2][1][RTW89_ACMA][1][109] = 127,
@@ -44406,13 +43288,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][109] = 127,
[0][1][2][1][RTW89_THAILAND][0][109] = 127,
[0][1][2][1][RTW89_FCC][1][111] = 127,
- [0][1][2][1][RTW89_FCC][2][111] = 127,
[0][1][2][1][RTW89_ETSI][1][111] = 127,
[0][1][2][1][RTW89_ETSI][0][111] = 127,
[0][1][2][1][RTW89_MKK][1][111] = 127,
[0][1][2][1][RTW89_MKK][0][111] = 127,
[0][1][2][1][RTW89_IC][1][111] = 127,
- [0][1][2][1][RTW89_IC][2][111] = 127,
[0][1][2][1][RTW89_KCC][1][111] = 127,
[0][1][2][1][RTW89_KCC][0][111] = 127,
[0][1][2][1][RTW89_ACMA][1][111] = 127,
@@ -44425,13 +43305,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][111] = 127,
[0][1][2][1][RTW89_THAILAND][0][111] = 127,
[0][1][2][1][RTW89_FCC][1][113] = 127,
- [0][1][2][1][RTW89_FCC][2][113] = 127,
[0][1][2][1][RTW89_ETSI][1][113] = 127,
[0][1][2][1][RTW89_ETSI][0][113] = 127,
[0][1][2][1][RTW89_MKK][1][113] = 127,
[0][1][2][1][RTW89_MKK][0][113] = 127,
[0][1][2][1][RTW89_IC][1][113] = 127,
- [0][1][2][1][RTW89_IC][2][113] = 127,
[0][1][2][1][RTW89_KCC][1][113] = 127,
[0][1][2][1][RTW89_KCC][0][113] = 127,
[0][1][2][1][RTW89_ACMA][1][113] = 127,
@@ -44444,13 +43322,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][113] = 127,
[0][1][2][1][RTW89_THAILAND][0][113] = 127,
[0][1][2][1][RTW89_FCC][1][115] = 127,
- [0][1][2][1][RTW89_FCC][2][115] = 127,
[0][1][2][1][RTW89_ETSI][1][115] = 127,
[0][1][2][1][RTW89_ETSI][0][115] = 127,
[0][1][2][1][RTW89_MKK][1][115] = 127,
[0][1][2][1][RTW89_MKK][0][115] = 127,
[0][1][2][1][RTW89_IC][1][115] = 127,
- [0][1][2][1][RTW89_IC][2][115] = 127,
[0][1][2][1][RTW89_KCC][1][115] = 127,
[0][1][2][1][RTW89_KCC][0][115] = 127,
[0][1][2][1][RTW89_ACMA][1][115] = 127,
@@ -44463,13 +43339,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][115] = 127,
[0][1][2][1][RTW89_THAILAND][0][115] = 127,
[0][1][2][1][RTW89_FCC][1][117] = 127,
- [0][1][2][1][RTW89_FCC][2][117] = 127,
[0][1][2][1][RTW89_ETSI][1][117] = 127,
[0][1][2][1][RTW89_ETSI][0][117] = 127,
[0][1][2][1][RTW89_MKK][1][117] = 127,
[0][1][2][1][RTW89_MKK][0][117] = 127,
[0][1][2][1][RTW89_IC][1][117] = 127,
- [0][1][2][1][RTW89_IC][2][117] = 127,
[0][1][2][1][RTW89_KCC][1][117] = 127,
[0][1][2][1][RTW89_KCC][0][117] = 127,
[0][1][2][1][RTW89_ACMA][1][117] = 127,
@@ -44482,13 +43356,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][117] = 127,
[0][1][2][1][RTW89_THAILAND][0][117] = 127,
[0][1][2][1][RTW89_FCC][1][119] = 127,
- [0][1][2][1][RTW89_FCC][2][119] = 127,
[0][1][2][1][RTW89_ETSI][1][119] = 127,
[0][1][2][1][RTW89_ETSI][0][119] = 127,
[0][1][2][1][RTW89_MKK][1][119] = 127,
[0][1][2][1][RTW89_MKK][0][119] = 127,
[0][1][2][1][RTW89_IC][1][119] = 127,
- [0][1][2][1][RTW89_IC][2][119] = 127,
[0][1][2][1][RTW89_KCC][1][119] = 127,
[0][1][2][1][RTW89_KCC][0][119] = 127,
[0][1][2][1][RTW89_ACMA][1][119] = 127,
@@ -44501,13 +43373,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[0][1][2][1][RTW89_THAILAND][1][119] = 127,
[0][1][2][1][RTW89_THAILAND][0][119] = 127,
[1][0][2][0][RTW89_FCC][1][1] = 34,
- [1][0][2][0][RTW89_FCC][2][1] = 70,
[1][0][2][0][RTW89_ETSI][1][1] = 66,
[1][0][2][0][RTW89_ETSI][0][1] = 30,
[1][0][2][0][RTW89_MKK][1][1] = 62,
[1][0][2][0][RTW89_MKK][0][1] = 26,
[1][0][2][0][RTW89_IC][1][1] = 34,
- [1][0][2][0][RTW89_IC][2][1] = 70,
[1][0][2][0][RTW89_KCC][1][1] = 40,
[1][0][2][0][RTW89_KCC][0][1] = 24,
[1][0][2][0][RTW89_ACMA][1][1] = 66,
@@ -44520,13 +43390,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][1] = 68,
[1][0][2][0][RTW89_THAILAND][0][1] = 30,
[1][0][2][0][RTW89_FCC][1][5] = 34,
- [1][0][2][0][RTW89_FCC][2][5] = 70,
[1][0][2][0][RTW89_ETSI][1][5] = 66,
[1][0][2][0][RTW89_ETSI][0][5] = 30,
[1][0][2][0][RTW89_MKK][1][5] = 62,
[1][0][2][0][RTW89_MKK][0][5] = 26,
[1][0][2][0][RTW89_IC][1][5] = 34,
- [1][0][2][0][RTW89_IC][2][5] = 70,
[1][0][2][0][RTW89_KCC][1][5] = 40,
[1][0][2][0][RTW89_KCC][0][5] = 24,
[1][0][2][0][RTW89_ACMA][1][5] = 66,
@@ -44539,13 +43407,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][5] = 68,
[1][0][2][0][RTW89_THAILAND][0][5] = 30,
[1][0][2][0][RTW89_FCC][1][9] = 34,
- [1][0][2][0][RTW89_FCC][2][9] = 70,
[1][0][2][0][RTW89_ETSI][1][9] = 66,
[1][0][2][0][RTW89_ETSI][0][9] = 30,
[1][0][2][0][RTW89_MKK][1][9] = 62,
[1][0][2][0][RTW89_MKK][0][9] = 26,
[1][0][2][0][RTW89_IC][1][9] = 34,
- [1][0][2][0][RTW89_IC][2][9] = 70,
[1][0][2][0][RTW89_KCC][1][9] = 40,
[1][0][2][0][RTW89_KCC][0][9] = 24,
[1][0][2][0][RTW89_ACMA][1][9] = 66,
@@ -44558,13 +43424,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][9] = 68,
[1][0][2][0][RTW89_THAILAND][0][9] = 30,
[1][0][2][0][RTW89_FCC][1][13] = 34,
- [1][0][2][0][RTW89_FCC][2][13] = 70,
[1][0][2][0][RTW89_ETSI][1][13] = 66,
[1][0][2][0][RTW89_ETSI][0][13] = 30,
[1][0][2][0][RTW89_MKK][1][13] = 62,
[1][0][2][0][RTW89_MKK][0][13] = 26,
[1][0][2][0][RTW89_IC][1][13] = 34,
- [1][0][2][0][RTW89_IC][2][13] = 70,
[1][0][2][0][RTW89_KCC][1][13] = 40,
[1][0][2][0][RTW89_KCC][0][13] = 24,
[1][0][2][0][RTW89_ACMA][1][13] = 66,
@@ -44577,13 +43441,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][13] = 68,
[1][0][2][0][RTW89_THAILAND][0][13] = 30,
[1][0][2][0][RTW89_FCC][1][16] = 34,
- [1][0][2][0][RTW89_FCC][2][16] = 70,
[1][0][2][0][RTW89_ETSI][1][16] = 66,
[1][0][2][0][RTW89_ETSI][0][16] = 30,
[1][0][2][0][RTW89_MKK][1][16] = 62,
[1][0][2][0][RTW89_MKK][0][16] = 26,
[1][0][2][0][RTW89_IC][1][16] = 34,
- [1][0][2][0][RTW89_IC][2][16] = 70,
[1][0][2][0][RTW89_KCC][1][16] = 40,
[1][0][2][0][RTW89_KCC][0][16] = 24,
[1][0][2][0][RTW89_ACMA][1][16] = 66,
@@ -44596,13 +43458,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][16] = 68,
[1][0][2][0][RTW89_THAILAND][0][16] = 30,
[1][0][2][0][RTW89_FCC][1][20] = 34,
- [1][0][2][0][RTW89_FCC][2][20] = 70,
[1][0][2][0][RTW89_ETSI][1][20] = 66,
[1][0][2][0][RTW89_ETSI][0][20] = 30,
[1][0][2][0][RTW89_MKK][1][20] = 62,
[1][0][2][0][RTW89_MKK][0][20] = 26,
[1][0][2][0][RTW89_IC][1][20] = 34,
- [1][0][2][0][RTW89_IC][2][20] = 70,
[1][0][2][0][RTW89_KCC][1][20] = 40,
[1][0][2][0][RTW89_KCC][0][20] = 24,
[1][0][2][0][RTW89_ACMA][1][20] = 66,
@@ -44615,13 +43475,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][20] = 68,
[1][0][2][0][RTW89_THAILAND][0][20] = 30,
[1][0][2][0][RTW89_FCC][1][24] = 36,
- [1][0][2][0][RTW89_FCC][2][24] = 70,
[1][0][2][0][RTW89_ETSI][1][24] = 66,
[1][0][2][0][RTW89_ETSI][0][24] = 30,
[1][0][2][0][RTW89_MKK][1][24] = 64,
[1][0][2][0][RTW89_MKK][0][24] = 28,
[1][0][2][0][RTW89_IC][1][24] = 36,
- [1][0][2][0][RTW89_IC][2][24] = 70,
[1][0][2][0][RTW89_KCC][1][24] = 40,
[1][0][2][0][RTW89_KCC][0][24] = 26,
[1][0][2][0][RTW89_ACMA][1][24] = 66,
@@ -44634,13 +43492,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][24] = 68,
[1][0][2][0][RTW89_THAILAND][0][24] = 30,
[1][0][2][0][RTW89_FCC][1][28] = 34,
- [1][0][2][0][RTW89_FCC][2][28] = 70,
[1][0][2][0][RTW89_ETSI][1][28] = 66,
[1][0][2][0][RTW89_ETSI][0][28] = 30,
[1][0][2][0][RTW89_MKK][1][28] = 64,
[1][0][2][0][RTW89_MKK][0][28] = 26,
[1][0][2][0][RTW89_IC][1][28] = 34,
- [1][0][2][0][RTW89_IC][2][28] = 70,
[1][0][2][0][RTW89_KCC][1][28] = 40,
[1][0][2][0][RTW89_KCC][0][28] = 26,
[1][0][2][0][RTW89_ACMA][1][28] = 66,
@@ -44653,13 +43509,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][28] = 68,
[1][0][2][0][RTW89_THAILAND][0][28] = 30,
[1][0][2][0][RTW89_FCC][1][31] = 34,
- [1][0][2][0][RTW89_FCC][2][31] = 70,
[1][0][2][0][RTW89_ETSI][1][31] = 66,
[1][0][2][0][RTW89_ETSI][0][31] = 30,
[1][0][2][0][RTW89_MKK][1][31] = 64,
[1][0][2][0][RTW89_MKK][0][31] = 26,
[1][0][2][0][RTW89_IC][1][31] = 34,
- [1][0][2][0][RTW89_IC][2][31] = 70,
[1][0][2][0][RTW89_KCC][1][31] = 40,
[1][0][2][0][RTW89_KCC][0][31] = 26,
[1][0][2][0][RTW89_ACMA][1][31] = 66,
@@ -44672,13 +43526,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][31] = 68,
[1][0][2][0][RTW89_THAILAND][0][31] = 30,
[1][0][2][0][RTW89_FCC][1][35] = 34,
- [1][0][2][0][RTW89_FCC][2][35] = 70,
[1][0][2][0][RTW89_ETSI][1][35] = 66,
[1][0][2][0][RTW89_ETSI][0][35] = 30,
[1][0][2][0][RTW89_MKK][1][35] = 64,
[1][0][2][0][RTW89_MKK][0][35] = 26,
[1][0][2][0][RTW89_IC][1][35] = 34,
- [1][0][2][0][RTW89_IC][2][35] = 70,
[1][0][2][0][RTW89_KCC][1][35] = 40,
[1][0][2][0][RTW89_KCC][0][35] = 26,
[1][0][2][0][RTW89_ACMA][1][35] = 66,
@@ -44691,13 +43543,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][35] = 68,
[1][0][2][0][RTW89_THAILAND][0][35] = 30,
[1][0][2][0][RTW89_FCC][1][39] = 34,
- [1][0][2][0][RTW89_FCC][2][39] = 70,
[1][0][2][0][RTW89_ETSI][1][39] = 66,
[1][0][2][0][RTW89_ETSI][0][39] = 30,
[1][0][2][0][RTW89_MKK][1][39] = 64,
[1][0][2][0][RTW89_MKK][0][39] = 26,
[1][0][2][0][RTW89_IC][1][39] = 34,
- [1][0][2][0][RTW89_IC][2][39] = 70,
[1][0][2][0][RTW89_KCC][1][39] = 40,
[1][0][2][0][RTW89_KCC][0][39] = 26,
[1][0][2][0][RTW89_ACMA][1][39] = 66,
@@ -44710,13 +43560,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][39] = 68,
[1][0][2][0][RTW89_THAILAND][0][39] = 30,
[1][0][2][0][RTW89_FCC][1][43] = 34,
- [1][0][2][0][RTW89_FCC][2][43] = 70,
[1][0][2][0][RTW89_ETSI][1][43] = 66,
[1][0][2][0][RTW89_ETSI][0][43] = 30,
[1][0][2][0][RTW89_MKK][1][43] = 64,
[1][0][2][0][RTW89_MKK][0][43] = 26,
[1][0][2][0][RTW89_IC][1][43] = 34,
- [1][0][2][0][RTW89_IC][2][43] = 70,
[1][0][2][0][RTW89_KCC][1][43] = 40,
[1][0][2][0][RTW89_KCC][0][43] = 26,
[1][0][2][0][RTW89_ACMA][1][43] = 66,
@@ -44729,13 +43577,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][43] = 68,
[1][0][2][0][RTW89_THAILAND][0][43] = 30,
[1][0][2][0][RTW89_FCC][1][46] = 34,
- [1][0][2][0][RTW89_FCC][2][46] = 127,
[1][0][2][0][RTW89_ETSI][1][46] = 127,
[1][0][2][0][RTW89_ETSI][0][46] = 127,
[1][0][2][0][RTW89_MKK][1][46] = 127,
[1][0][2][0][RTW89_MKK][0][46] = 127,
[1][0][2][0][RTW89_IC][1][46] = 34,
- [1][0][2][0][RTW89_IC][2][46] = 68,
[1][0][2][0][RTW89_KCC][1][46] = 40,
[1][0][2][0][RTW89_KCC][0][46] = 127,
[1][0][2][0][RTW89_ACMA][1][46] = 127,
@@ -44748,13 +43594,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][46] = 127,
[1][0][2][0][RTW89_THAILAND][0][46] = 127,
[1][0][2][0][RTW89_FCC][1][50] = 34,
- [1][0][2][0][RTW89_FCC][2][50] = 127,
[1][0][2][0][RTW89_ETSI][1][50] = 127,
[1][0][2][0][RTW89_ETSI][0][50] = 127,
[1][0][2][0][RTW89_MKK][1][50] = 127,
[1][0][2][0][RTW89_MKK][0][50] = 127,
[1][0][2][0][RTW89_IC][1][50] = 34,
- [1][0][2][0][RTW89_IC][2][50] = 68,
[1][0][2][0][RTW89_KCC][1][50] = 40,
[1][0][2][0][RTW89_KCC][0][50] = 127,
[1][0][2][0][RTW89_ACMA][1][50] = 127,
@@ -44767,13 +43611,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][50] = 127,
[1][0][2][0][RTW89_THAILAND][0][50] = 127,
[1][0][2][0][RTW89_FCC][1][54] = 36,
- [1][0][2][0][RTW89_FCC][2][54] = 127,
[1][0][2][0][RTW89_ETSI][1][54] = 127,
[1][0][2][0][RTW89_ETSI][0][54] = 127,
[1][0][2][0][RTW89_MKK][1][54] = 127,
[1][0][2][0][RTW89_MKK][0][54] = 127,
[1][0][2][0][RTW89_IC][1][54] = 36,
- [1][0][2][0][RTW89_IC][2][54] = 127,
[1][0][2][0][RTW89_KCC][1][54] = 40,
[1][0][2][0][RTW89_KCC][0][54] = 127,
[1][0][2][0][RTW89_ACMA][1][54] = 127,
@@ -44786,13 +43628,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][54] = 127,
[1][0][2][0][RTW89_THAILAND][0][54] = 127,
[1][0][2][0][RTW89_FCC][1][58] = 36,
- [1][0][2][0][RTW89_FCC][2][58] = 66,
[1][0][2][0][RTW89_ETSI][1][58] = 127,
[1][0][2][0][RTW89_ETSI][0][58] = 127,
[1][0][2][0][RTW89_MKK][1][58] = 127,
[1][0][2][0][RTW89_MKK][0][58] = 127,
[1][0][2][0][RTW89_IC][1][58] = 36,
- [1][0][2][0][RTW89_IC][2][58] = 66,
[1][0][2][0][RTW89_KCC][1][58] = 40,
[1][0][2][0][RTW89_KCC][0][58] = 127,
[1][0][2][0][RTW89_ACMA][1][58] = 127,
@@ -44805,13 +43645,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][58] = 127,
[1][0][2][0][RTW89_THAILAND][0][58] = 127,
[1][0][2][0][RTW89_FCC][1][61] = 34,
- [1][0][2][0][RTW89_FCC][2][61] = 66,
[1][0][2][0][RTW89_ETSI][1][61] = 127,
[1][0][2][0][RTW89_ETSI][0][61] = 127,
[1][0][2][0][RTW89_MKK][1][61] = 127,
[1][0][2][0][RTW89_MKK][0][61] = 127,
[1][0][2][0][RTW89_IC][1][61] = 34,
- [1][0][2][0][RTW89_IC][2][61] = 66,
[1][0][2][0][RTW89_KCC][1][61] = 40,
[1][0][2][0][RTW89_KCC][0][61] = 127,
[1][0][2][0][RTW89_ACMA][1][61] = 127,
@@ -44824,13 +43662,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][61] = 127,
[1][0][2][0][RTW89_THAILAND][0][61] = 127,
[1][0][2][0][RTW89_FCC][1][65] = 34,
- [1][0][2][0][RTW89_FCC][2][65] = 66,
[1][0][2][0][RTW89_ETSI][1][65] = 127,
[1][0][2][0][RTW89_ETSI][0][65] = 127,
[1][0][2][0][RTW89_MKK][1][65] = 127,
[1][0][2][0][RTW89_MKK][0][65] = 127,
[1][0][2][0][RTW89_IC][1][65] = 34,
- [1][0][2][0][RTW89_IC][2][65] = 66,
[1][0][2][0][RTW89_KCC][1][65] = 40,
[1][0][2][0][RTW89_KCC][0][65] = 127,
[1][0][2][0][RTW89_ACMA][1][65] = 127,
@@ -44843,13 +43679,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][65] = 127,
[1][0][2][0][RTW89_THAILAND][0][65] = 127,
[1][0][2][0][RTW89_FCC][1][69] = 34,
- [1][0][2][0][RTW89_FCC][2][69] = 66,
[1][0][2][0][RTW89_ETSI][1][69] = 127,
[1][0][2][0][RTW89_ETSI][0][69] = 127,
[1][0][2][0][RTW89_MKK][1][69] = 127,
[1][0][2][0][RTW89_MKK][0][69] = 127,
[1][0][2][0][RTW89_IC][1][69] = 34,
- [1][0][2][0][RTW89_IC][2][69] = 66,
[1][0][2][0][RTW89_KCC][1][69] = 40,
[1][0][2][0][RTW89_KCC][0][69] = 127,
[1][0][2][0][RTW89_ACMA][1][69] = 127,
@@ -44862,13 +43696,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][69] = 127,
[1][0][2][0][RTW89_THAILAND][0][69] = 127,
[1][0][2][0][RTW89_FCC][1][73] = 34,
- [1][0][2][0][RTW89_FCC][2][73] = 66,
[1][0][2][0][RTW89_ETSI][1][73] = 127,
[1][0][2][0][RTW89_ETSI][0][73] = 127,
[1][0][2][0][RTW89_MKK][1][73] = 127,
[1][0][2][0][RTW89_MKK][0][73] = 127,
[1][0][2][0][RTW89_IC][1][73] = 34,
- [1][0][2][0][RTW89_IC][2][73] = 66,
[1][0][2][0][RTW89_KCC][1][73] = 40,
[1][0][2][0][RTW89_KCC][0][73] = 127,
[1][0][2][0][RTW89_ACMA][1][73] = 127,
@@ -44881,13 +43713,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][73] = 127,
[1][0][2][0][RTW89_THAILAND][0][73] = 127,
[1][0][2][0][RTW89_FCC][1][76] = 34,
- [1][0][2][0][RTW89_FCC][2][76] = 66,
[1][0][2][0][RTW89_ETSI][1][76] = 127,
[1][0][2][0][RTW89_ETSI][0][76] = 127,
[1][0][2][0][RTW89_MKK][1][76] = 127,
[1][0][2][0][RTW89_MKK][0][76] = 127,
[1][0][2][0][RTW89_IC][1][76] = 34,
- [1][0][2][0][RTW89_IC][2][76] = 66,
[1][0][2][0][RTW89_KCC][1][76] = 40,
[1][0][2][0][RTW89_KCC][0][76] = 127,
[1][0][2][0][RTW89_ACMA][1][76] = 127,
@@ -44900,13 +43730,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][76] = 127,
[1][0][2][0][RTW89_THAILAND][0][76] = 127,
[1][0][2][0][RTW89_FCC][1][80] = 34,
- [1][0][2][0][RTW89_FCC][2][80] = 66,
[1][0][2][0][RTW89_ETSI][1][80] = 127,
[1][0][2][0][RTW89_ETSI][0][80] = 127,
[1][0][2][0][RTW89_MKK][1][80] = 127,
[1][0][2][0][RTW89_MKK][0][80] = 127,
[1][0][2][0][RTW89_IC][1][80] = 34,
- [1][0][2][0][RTW89_IC][2][80] = 66,
[1][0][2][0][RTW89_KCC][1][80] = 42,
[1][0][2][0][RTW89_KCC][0][80] = 127,
[1][0][2][0][RTW89_ACMA][1][80] = 127,
@@ -44919,13 +43747,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][80] = 127,
[1][0][2][0][RTW89_THAILAND][0][80] = 127,
[1][0][2][0][RTW89_FCC][1][84] = 34,
- [1][0][2][0][RTW89_FCC][2][84] = 66,
[1][0][2][0][RTW89_ETSI][1][84] = 127,
[1][0][2][0][RTW89_ETSI][0][84] = 127,
[1][0][2][0][RTW89_MKK][1][84] = 127,
[1][0][2][0][RTW89_MKK][0][84] = 127,
[1][0][2][0][RTW89_IC][1][84] = 34,
- [1][0][2][0][RTW89_IC][2][84] = 66,
[1][0][2][0][RTW89_KCC][1][84] = 42,
[1][0][2][0][RTW89_KCC][0][84] = 127,
[1][0][2][0][RTW89_ACMA][1][84] = 127,
@@ -44938,13 +43764,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][84] = 127,
[1][0][2][0][RTW89_THAILAND][0][84] = 127,
[1][0][2][0][RTW89_FCC][1][88] = 34,
- [1][0][2][0][RTW89_FCC][2][88] = 127,
[1][0][2][0][RTW89_ETSI][1][88] = 127,
[1][0][2][0][RTW89_ETSI][0][88] = 127,
[1][0][2][0][RTW89_MKK][1][88] = 127,
[1][0][2][0][RTW89_MKK][0][88] = 127,
[1][0][2][0][RTW89_IC][1][88] = 34,
- [1][0][2][0][RTW89_IC][2][88] = 127,
[1][0][2][0][RTW89_KCC][1][88] = 42,
[1][0][2][0][RTW89_KCC][0][88] = 127,
[1][0][2][0][RTW89_ACMA][1][88] = 127,
@@ -44957,13 +43781,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][88] = 127,
[1][0][2][0][RTW89_THAILAND][0][88] = 127,
[1][0][2][0][RTW89_FCC][1][91] = 36,
- [1][0][2][0][RTW89_FCC][2][91] = 127,
[1][0][2][0][RTW89_ETSI][1][91] = 127,
[1][0][2][0][RTW89_ETSI][0][91] = 127,
[1][0][2][0][RTW89_MKK][1][91] = 127,
[1][0][2][0][RTW89_MKK][0][91] = 127,
[1][0][2][0][RTW89_IC][1][91] = 36,
- [1][0][2][0][RTW89_IC][2][91] = 127,
[1][0][2][0][RTW89_KCC][1][91] = 42,
[1][0][2][0][RTW89_KCC][0][91] = 127,
[1][0][2][0][RTW89_ACMA][1][91] = 127,
@@ -44976,13 +43798,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][91] = 127,
[1][0][2][0][RTW89_THAILAND][0][91] = 127,
[1][0][2][0][RTW89_FCC][1][95] = 34,
- [1][0][2][0][RTW89_FCC][2][95] = 127,
[1][0][2][0][RTW89_ETSI][1][95] = 127,
[1][0][2][0][RTW89_ETSI][0][95] = 127,
[1][0][2][0][RTW89_MKK][1][95] = 127,
[1][0][2][0][RTW89_MKK][0][95] = 127,
[1][0][2][0][RTW89_IC][1][95] = 34,
- [1][0][2][0][RTW89_IC][2][95] = 127,
[1][0][2][0][RTW89_KCC][1][95] = 42,
[1][0][2][0][RTW89_KCC][0][95] = 127,
[1][0][2][0][RTW89_ACMA][1][95] = 127,
@@ -44995,13 +43815,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][95] = 127,
[1][0][2][0][RTW89_THAILAND][0][95] = 127,
[1][0][2][0][RTW89_FCC][1][99] = 34,
- [1][0][2][0][RTW89_FCC][2][99] = 127,
[1][0][2][0][RTW89_ETSI][1][99] = 127,
[1][0][2][0][RTW89_ETSI][0][99] = 127,
[1][0][2][0][RTW89_MKK][1][99] = 127,
[1][0][2][0][RTW89_MKK][0][99] = 127,
[1][0][2][0][RTW89_IC][1][99] = 34,
- [1][0][2][0][RTW89_IC][2][99] = 127,
[1][0][2][0][RTW89_KCC][1][99] = 42,
[1][0][2][0][RTW89_KCC][0][99] = 127,
[1][0][2][0][RTW89_ACMA][1][99] = 127,
@@ -45014,13 +43832,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][99] = 127,
[1][0][2][0][RTW89_THAILAND][0][99] = 127,
[1][0][2][0][RTW89_FCC][1][103] = 34,
- [1][0][2][0][RTW89_FCC][2][103] = 127,
[1][0][2][0][RTW89_ETSI][1][103] = 127,
[1][0][2][0][RTW89_ETSI][0][103] = 127,
[1][0][2][0][RTW89_MKK][1][103] = 127,
[1][0][2][0][RTW89_MKK][0][103] = 127,
[1][0][2][0][RTW89_IC][1][103] = 34,
- [1][0][2][0][RTW89_IC][2][103] = 127,
[1][0][2][0][RTW89_KCC][1][103] = 42,
[1][0][2][0][RTW89_KCC][0][103] = 127,
[1][0][2][0][RTW89_ACMA][1][103] = 127,
@@ -45033,13 +43849,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][103] = 127,
[1][0][2][0][RTW89_THAILAND][0][103] = 127,
[1][0][2][0][RTW89_FCC][1][106] = 36,
- [1][0][2][0][RTW89_FCC][2][106] = 127,
[1][0][2][0][RTW89_ETSI][1][106] = 127,
[1][0][2][0][RTW89_ETSI][0][106] = 127,
[1][0][2][0][RTW89_MKK][1][106] = 127,
[1][0][2][0][RTW89_MKK][0][106] = 127,
[1][0][2][0][RTW89_IC][1][106] = 36,
- [1][0][2][0][RTW89_IC][2][106] = 127,
[1][0][2][0][RTW89_KCC][1][106] = 42,
[1][0][2][0][RTW89_KCC][0][106] = 127,
[1][0][2][0][RTW89_ACMA][1][106] = 127,
@@ -45052,13 +43866,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][106] = 127,
[1][0][2][0][RTW89_THAILAND][0][106] = 127,
[1][0][2][0][RTW89_FCC][1][110] = 127,
- [1][0][2][0][RTW89_FCC][2][110] = 127,
[1][0][2][0][RTW89_ETSI][1][110] = 127,
[1][0][2][0][RTW89_ETSI][0][110] = 127,
[1][0][2][0][RTW89_MKK][1][110] = 127,
[1][0][2][0][RTW89_MKK][0][110] = 127,
[1][0][2][0][RTW89_IC][1][110] = 127,
- [1][0][2][0][RTW89_IC][2][110] = 127,
[1][0][2][0][RTW89_KCC][1][110] = 127,
[1][0][2][0][RTW89_KCC][0][110] = 127,
[1][0][2][0][RTW89_ACMA][1][110] = 127,
@@ -45071,13 +43883,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][110] = 127,
[1][0][2][0][RTW89_THAILAND][0][110] = 127,
[1][0][2][0][RTW89_FCC][1][114] = 127,
- [1][0][2][0][RTW89_FCC][2][114] = 127,
[1][0][2][0][RTW89_ETSI][1][114] = 127,
[1][0][2][0][RTW89_ETSI][0][114] = 127,
[1][0][2][0][RTW89_MKK][1][114] = 127,
[1][0][2][0][RTW89_MKK][0][114] = 127,
[1][0][2][0][RTW89_IC][1][114] = 127,
- [1][0][2][0][RTW89_IC][2][114] = 127,
[1][0][2][0][RTW89_KCC][1][114] = 127,
[1][0][2][0][RTW89_KCC][0][114] = 127,
[1][0][2][0][RTW89_ACMA][1][114] = 127,
@@ -45090,13 +43900,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][114] = 127,
[1][0][2][0][RTW89_THAILAND][0][114] = 127,
[1][0][2][0][RTW89_FCC][1][118] = 127,
- [1][0][2][0][RTW89_FCC][2][118] = 127,
[1][0][2][0][RTW89_ETSI][1][118] = 127,
[1][0][2][0][RTW89_ETSI][0][118] = 127,
[1][0][2][0][RTW89_MKK][1][118] = 127,
[1][0][2][0][RTW89_MKK][0][118] = 127,
[1][0][2][0][RTW89_IC][1][118] = 127,
- [1][0][2][0][RTW89_IC][2][118] = 127,
[1][0][2][0][RTW89_KCC][1][118] = 127,
[1][0][2][0][RTW89_KCC][0][118] = 127,
[1][0][2][0][RTW89_ACMA][1][118] = 127,
@@ -45109,13 +43917,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][0][2][0][RTW89_THAILAND][1][118] = 127,
[1][0][2][0][RTW89_THAILAND][0][118] = 127,
[1][1][2][0][RTW89_FCC][1][1] = 10,
- [1][1][2][0][RTW89_FCC][2][1] = 58,
[1][1][2][0][RTW89_ETSI][1][1] = 54,
[1][1][2][0][RTW89_ETSI][0][1] = 18,
[1][1][2][0][RTW89_MKK][1][1] = 52,
[1][1][2][0][RTW89_MKK][0][1] = 12,
[1][1][2][0][RTW89_IC][1][1] = 10,
- [1][1][2][0][RTW89_IC][2][1] = 58,
[1][1][2][0][RTW89_KCC][1][1] = 28,
[1][1][2][0][RTW89_KCC][0][1] = 12,
[1][1][2][0][RTW89_ACMA][1][1] = 54,
@@ -45128,13 +43934,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][1] = 46,
[1][1][2][0][RTW89_THAILAND][0][1] = 10,
[1][1][2][0][RTW89_FCC][1][5] = 10,
- [1][1][2][0][RTW89_FCC][2][5] = 58,
[1][1][2][0][RTW89_ETSI][1][5] = 54,
[1][1][2][0][RTW89_ETSI][0][5] = 16,
[1][1][2][0][RTW89_MKK][1][5] = 52,
[1][1][2][0][RTW89_MKK][0][5] = 12,
[1][1][2][0][RTW89_IC][1][5] = 10,
- [1][1][2][0][RTW89_IC][2][5] = 58,
[1][1][2][0][RTW89_KCC][1][5] = 28,
[1][1][2][0][RTW89_KCC][0][5] = 12,
[1][1][2][0][RTW89_ACMA][1][5] = 54,
@@ -45147,13 +43951,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][5] = 46,
[1][1][2][0][RTW89_THAILAND][0][5] = 10,
[1][1][2][0][RTW89_FCC][1][9] = 10,
- [1][1][2][0][RTW89_FCC][2][9] = 58,
[1][1][2][0][RTW89_ETSI][1][9] = 54,
[1][1][2][0][RTW89_ETSI][0][9] = 16,
[1][1][2][0][RTW89_MKK][1][9] = 52,
[1][1][2][0][RTW89_MKK][0][9] = 12,
[1][1][2][0][RTW89_IC][1][9] = 10,
- [1][1][2][0][RTW89_IC][2][9] = 58,
[1][1][2][0][RTW89_KCC][1][9] = 28,
[1][1][2][0][RTW89_KCC][0][9] = 12,
[1][1][2][0][RTW89_ACMA][1][9] = 54,
@@ -45166,13 +43968,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][9] = 46,
[1][1][2][0][RTW89_THAILAND][0][9] = 10,
[1][1][2][0][RTW89_FCC][1][13] = 10,
- [1][1][2][0][RTW89_FCC][2][13] = 58,
[1][1][2][0][RTW89_ETSI][1][13] = 54,
[1][1][2][0][RTW89_ETSI][0][13] = 16,
[1][1][2][0][RTW89_MKK][1][13] = 52,
[1][1][2][0][RTW89_MKK][0][13] = 12,
[1][1][2][0][RTW89_IC][1][13] = 10,
- [1][1][2][0][RTW89_IC][2][13] = 58,
[1][1][2][0][RTW89_KCC][1][13] = 28,
[1][1][2][0][RTW89_KCC][0][13] = 12,
[1][1][2][0][RTW89_ACMA][1][13] = 54,
@@ -45185,13 +43985,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][13] = 46,
[1][1][2][0][RTW89_THAILAND][0][13] = 10,
[1][1][2][0][RTW89_FCC][1][16] = 10,
- [1][1][2][0][RTW89_FCC][2][16] = 58,
[1][1][2][0][RTW89_ETSI][1][16] = 54,
[1][1][2][0][RTW89_ETSI][0][16] = 16,
[1][1][2][0][RTW89_MKK][1][16] = 52,
[1][1][2][0][RTW89_MKK][0][16] = 12,
[1][1][2][0][RTW89_IC][1][16] = 10,
- [1][1][2][0][RTW89_IC][2][16] = 58,
[1][1][2][0][RTW89_KCC][1][16] = 28,
[1][1][2][0][RTW89_KCC][0][16] = 12,
[1][1][2][0][RTW89_ACMA][1][16] = 54,
@@ -45204,13 +44002,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][16] = 46,
[1][1][2][0][RTW89_THAILAND][0][16] = 10,
[1][1][2][0][RTW89_FCC][1][20] = 10,
- [1][1][2][0][RTW89_FCC][2][20] = 58,
[1][1][2][0][RTW89_ETSI][1][20] = 54,
[1][1][2][0][RTW89_ETSI][0][20] = 16,
[1][1][2][0][RTW89_MKK][1][20] = 52,
[1][1][2][0][RTW89_MKK][0][20] = 12,
[1][1][2][0][RTW89_IC][1][20] = 10,
- [1][1][2][0][RTW89_IC][2][20] = 58,
[1][1][2][0][RTW89_KCC][1][20] = 28,
[1][1][2][0][RTW89_KCC][0][20] = 12,
[1][1][2][0][RTW89_ACMA][1][20] = 54,
@@ -45223,13 +44019,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][20] = 46,
[1][1][2][0][RTW89_THAILAND][0][20] = 10,
[1][1][2][0][RTW89_FCC][1][24] = 10,
- [1][1][2][0][RTW89_FCC][2][24] = 70,
[1][1][2][0][RTW89_ETSI][1][24] = 54,
[1][1][2][0][RTW89_ETSI][0][24] = 16,
[1][1][2][0][RTW89_MKK][1][24] = 54,
[1][1][2][0][RTW89_MKK][0][24] = 14,
[1][1][2][0][RTW89_IC][1][24] = 10,
- [1][1][2][0][RTW89_IC][2][24] = 70,
[1][1][2][0][RTW89_KCC][1][24] = 28,
[1][1][2][0][RTW89_KCC][0][24] = 12,
[1][1][2][0][RTW89_ACMA][1][24] = 54,
@@ -45242,13 +44036,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][24] = 46,
[1][1][2][0][RTW89_THAILAND][0][24] = 10,
[1][1][2][0][RTW89_FCC][1][28] = 10,
- [1][1][2][0][RTW89_FCC][2][28] = 70,
[1][1][2][0][RTW89_ETSI][1][28] = 54,
[1][1][2][0][RTW89_ETSI][0][28] = 16,
[1][1][2][0][RTW89_MKK][1][28] = 52,
[1][1][2][0][RTW89_MKK][0][28] = 14,
[1][1][2][0][RTW89_IC][1][28] = 10,
- [1][1][2][0][RTW89_IC][2][28] = 70,
[1][1][2][0][RTW89_KCC][1][28] = 28,
[1][1][2][0][RTW89_KCC][0][28] = 14,
[1][1][2][0][RTW89_ACMA][1][28] = 54,
@@ -45261,13 +44053,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][28] = 46,
[1][1][2][0][RTW89_THAILAND][0][28] = 10,
[1][1][2][0][RTW89_FCC][1][31] = 10,
- [1][1][2][0][RTW89_FCC][2][31] = 70,
[1][1][2][0][RTW89_ETSI][1][31] = 54,
[1][1][2][0][RTW89_ETSI][0][31] = 16,
[1][1][2][0][RTW89_MKK][1][31] = 52,
[1][1][2][0][RTW89_MKK][0][31] = 14,
[1][1][2][0][RTW89_IC][1][31] = 10,
- [1][1][2][0][RTW89_IC][2][31] = 70,
[1][1][2][0][RTW89_KCC][1][31] = 28,
[1][1][2][0][RTW89_KCC][0][31] = 14,
[1][1][2][0][RTW89_ACMA][1][31] = 54,
@@ -45280,13 +44070,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][31] = 46,
[1][1][2][0][RTW89_THAILAND][0][31] = 10,
[1][1][2][0][RTW89_FCC][1][35] = 10,
- [1][1][2][0][RTW89_FCC][2][35] = 70,
[1][1][2][0][RTW89_ETSI][1][35] = 54,
[1][1][2][0][RTW89_ETSI][0][35] = 16,
[1][1][2][0][RTW89_MKK][1][35] = 52,
[1][1][2][0][RTW89_MKK][0][35] = 14,
[1][1][2][0][RTW89_IC][1][35] = 10,
- [1][1][2][0][RTW89_IC][2][35] = 70,
[1][1][2][0][RTW89_KCC][1][35] = 28,
[1][1][2][0][RTW89_KCC][0][35] = 14,
[1][1][2][0][RTW89_ACMA][1][35] = 54,
@@ -45299,13 +44087,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][35] = 46,
[1][1][2][0][RTW89_THAILAND][0][35] = 10,
[1][1][2][0][RTW89_FCC][1][39] = 10,
- [1][1][2][0][RTW89_FCC][2][39] = 70,
[1][1][2][0][RTW89_ETSI][1][39] = 54,
[1][1][2][0][RTW89_ETSI][0][39] = 16,
[1][1][2][0][RTW89_MKK][1][39] = 52,
[1][1][2][0][RTW89_MKK][0][39] = 14,
[1][1][2][0][RTW89_IC][1][39] = 10,
- [1][1][2][0][RTW89_IC][2][39] = 70,
[1][1][2][0][RTW89_KCC][1][39] = 28,
[1][1][2][0][RTW89_KCC][0][39] = 14,
[1][1][2][0][RTW89_ACMA][1][39] = 54,
@@ -45318,13 +44104,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][39] = 46,
[1][1][2][0][RTW89_THAILAND][0][39] = 10,
[1][1][2][0][RTW89_FCC][1][43] = 10,
- [1][1][2][0][RTW89_FCC][2][43] = 70,
[1][1][2][0][RTW89_ETSI][1][43] = 54,
[1][1][2][0][RTW89_ETSI][0][43] = 16,
[1][1][2][0][RTW89_MKK][1][43] = 52,
[1][1][2][0][RTW89_MKK][0][43] = 14,
[1][1][2][0][RTW89_IC][1][43] = 10,
- [1][1][2][0][RTW89_IC][2][43] = 70,
[1][1][2][0][RTW89_KCC][1][43] = 28,
[1][1][2][0][RTW89_KCC][0][43] = 14,
[1][1][2][0][RTW89_ACMA][1][43] = 54,
@@ -45337,13 +44121,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][43] = 46,
[1][1][2][0][RTW89_THAILAND][0][43] = 10,
[1][1][2][0][RTW89_FCC][1][46] = 12,
- [1][1][2][0][RTW89_FCC][2][46] = 127,
[1][1][2][0][RTW89_ETSI][1][46] = 127,
[1][1][2][0][RTW89_ETSI][0][46] = 127,
[1][1][2][0][RTW89_MKK][1][46] = 127,
[1][1][2][0][RTW89_MKK][0][46] = 127,
[1][1][2][0][RTW89_IC][1][46] = 12,
- [1][1][2][0][RTW89_IC][2][46] = 68,
[1][1][2][0][RTW89_KCC][1][46] = 28,
[1][1][2][0][RTW89_KCC][0][46] = 127,
[1][1][2][0][RTW89_ACMA][1][46] = 127,
@@ -45356,13 +44138,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][46] = 127,
[1][1][2][0][RTW89_THAILAND][0][46] = 127,
[1][1][2][0][RTW89_FCC][1][50] = 12,
- [1][1][2][0][RTW89_FCC][2][50] = 127,
[1][1][2][0][RTW89_ETSI][1][50] = 127,
[1][1][2][0][RTW89_ETSI][0][50] = 127,
[1][1][2][0][RTW89_MKK][1][50] = 127,
[1][1][2][0][RTW89_MKK][0][50] = 127,
[1][1][2][0][RTW89_IC][1][50] = 12,
- [1][1][2][0][RTW89_IC][2][50] = 68,
[1][1][2][0][RTW89_KCC][1][50] = 28,
[1][1][2][0][RTW89_KCC][0][50] = 127,
[1][1][2][0][RTW89_ACMA][1][50] = 127,
@@ -45375,13 +44155,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][50] = 127,
[1][1][2][0][RTW89_THAILAND][0][50] = 127,
[1][1][2][0][RTW89_FCC][1][54] = 10,
- [1][1][2][0][RTW89_FCC][2][54] = 127,
[1][1][2][0][RTW89_ETSI][1][54] = 127,
[1][1][2][0][RTW89_ETSI][0][54] = 127,
[1][1][2][0][RTW89_MKK][1][54] = 127,
[1][1][2][0][RTW89_MKK][0][54] = 127,
[1][1][2][0][RTW89_IC][1][54] = 10,
- [1][1][2][0][RTW89_IC][2][54] = 127,
[1][1][2][0][RTW89_KCC][1][54] = 28,
[1][1][2][0][RTW89_KCC][0][54] = 127,
[1][1][2][0][RTW89_ACMA][1][54] = 127,
@@ -45394,13 +44172,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][54] = 127,
[1][1][2][0][RTW89_THAILAND][0][54] = 127,
[1][1][2][0][RTW89_FCC][1][58] = 10,
- [1][1][2][0][RTW89_FCC][2][58] = 66,
[1][1][2][0][RTW89_ETSI][1][58] = 127,
[1][1][2][0][RTW89_ETSI][0][58] = 127,
[1][1][2][0][RTW89_MKK][1][58] = 127,
[1][1][2][0][RTW89_MKK][0][58] = 127,
[1][1][2][0][RTW89_IC][1][58] = 10,
- [1][1][2][0][RTW89_IC][2][58] = 66,
[1][1][2][0][RTW89_KCC][1][58] = 28,
[1][1][2][0][RTW89_KCC][0][58] = 127,
[1][1][2][0][RTW89_ACMA][1][58] = 127,
@@ -45413,13 +44189,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][58] = 127,
[1][1][2][0][RTW89_THAILAND][0][58] = 127,
[1][1][2][0][RTW89_FCC][1][61] = 10,
- [1][1][2][0][RTW89_FCC][2][61] = 66,
[1][1][2][0][RTW89_ETSI][1][61] = 127,
[1][1][2][0][RTW89_ETSI][0][61] = 127,
[1][1][2][0][RTW89_MKK][1][61] = 127,
[1][1][2][0][RTW89_MKK][0][61] = 127,
[1][1][2][0][RTW89_IC][1][61] = 10,
- [1][1][2][0][RTW89_IC][2][61] = 66,
[1][1][2][0][RTW89_KCC][1][61] = 28,
[1][1][2][0][RTW89_KCC][0][61] = 127,
[1][1][2][0][RTW89_ACMA][1][61] = 127,
@@ -45432,13 +44206,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][61] = 127,
[1][1][2][0][RTW89_THAILAND][0][61] = 127,
[1][1][2][0][RTW89_FCC][1][65] = 10,
- [1][1][2][0][RTW89_FCC][2][65] = 66,
[1][1][2][0][RTW89_ETSI][1][65] = 127,
[1][1][2][0][RTW89_ETSI][0][65] = 127,
[1][1][2][0][RTW89_MKK][1][65] = 127,
[1][1][2][0][RTW89_MKK][0][65] = 127,
[1][1][2][0][RTW89_IC][1][65] = 10,
- [1][1][2][0][RTW89_IC][2][65] = 66,
[1][1][2][0][RTW89_KCC][1][65] = 28,
[1][1][2][0][RTW89_KCC][0][65] = 127,
[1][1][2][0][RTW89_ACMA][1][65] = 127,
@@ -45451,13 +44223,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][65] = 127,
[1][1][2][0][RTW89_THAILAND][0][65] = 127,
[1][1][2][0][RTW89_FCC][1][69] = 10,
- [1][1][2][0][RTW89_FCC][2][69] = 66,
[1][1][2][0][RTW89_ETSI][1][69] = 127,
[1][1][2][0][RTW89_ETSI][0][69] = 127,
[1][1][2][0][RTW89_MKK][1][69] = 127,
[1][1][2][0][RTW89_MKK][0][69] = 127,
[1][1][2][0][RTW89_IC][1][69] = 10,
- [1][1][2][0][RTW89_IC][2][69] = 66,
[1][1][2][0][RTW89_KCC][1][69] = 28,
[1][1][2][0][RTW89_KCC][0][69] = 127,
[1][1][2][0][RTW89_ACMA][1][69] = 127,
@@ -45470,13 +44240,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][69] = 127,
[1][1][2][0][RTW89_THAILAND][0][69] = 127,
[1][1][2][0][RTW89_FCC][1][73] = 10,
- [1][1][2][0][RTW89_FCC][2][73] = 66,
[1][1][2][0][RTW89_ETSI][1][73] = 127,
[1][1][2][0][RTW89_ETSI][0][73] = 127,
[1][1][2][0][RTW89_MKK][1][73] = 127,
[1][1][2][0][RTW89_MKK][0][73] = 127,
[1][1][2][0][RTW89_IC][1][73] = 10,
- [1][1][2][0][RTW89_IC][2][73] = 66,
[1][1][2][0][RTW89_KCC][1][73] = 28,
[1][1][2][0][RTW89_KCC][0][73] = 127,
[1][1][2][0][RTW89_ACMA][1][73] = 127,
@@ -45489,13 +44257,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][73] = 127,
[1][1][2][0][RTW89_THAILAND][0][73] = 127,
[1][1][2][0][RTW89_FCC][1][76] = 10,
- [1][1][2][0][RTW89_FCC][2][76] = 66,
[1][1][2][0][RTW89_ETSI][1][76] = 127,
[1][1][2][0][RTW89_ETSI][0][76] = 127,
[1][1][2][0][RTW89_MKK][1][76] = 127,
[1][1][2][0][RTW89_MKK][0][76] = 127,
[1][1][2][0][RTW89_IC][1][76] = 10,
- [1][1][2][0][RTW89_IC][2][76] = 66,
[1][1][2][0][RTW89_KCC][1][76] = 28,
[1][1][2][0][RTW89_KCC][0][76] = 127,
[1][1][2][0][RTW89_ACMA][1][76] = 127,
@@ -45508,13 +44274,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][76] = 127,
[1][1][2][0][RTW89_THAILAND][0][76] = 127,
[1][1][2][0][RTW89_FCC][1][80] = 10,
- [1][1][2][0][RTW89_FCC][2][80] = 66,
[1][1][2][0][RTW89_ETSI][1][80] = 127,
[1][1][2][0][RTW89_ETSI][0][80] = 127,
[1][1][2][0][RTW89_MKK][1][80] = 127,
[1][1][2][0][RTW89_MKK][0][80] = 127,
[1][1][2][0][RTW89_IC][1][80] = 10,
- [1][1][2][0][RTW89_IC][2][80] = 66,
[1][1][2][0][RTW89_KCC][1][80] = 32,
[1][1][2][0][RTW89_KCC][0][80] = 127,
[1][1][2][0][RTW89_ACMA][1][80] = 127,
@@ -45527,13 +44291,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][80] = 127,
[1][1][2][0][RTW89_THAILAND][0][80] = 127,
[1][1][2][0][RTW89_FCC][1][84] = 10,
- [1][1][2][0][RTW89_FCC][2][84] = 66,
[1][1][2][0][RTW89_ETSI][1][84] = 127,
[1][1][2][0][RTW89_ETSI][0][84] = 127,
[1][1][2][0][RTW89_MKK][1][84] = 127,
[1][1][2][0][RTW89_MKK][0][84] = 127,
[1][1][2][0][RTW89_IC][1][84] = 10,
- [1][1][2][0][RTW89_IC][2][84] = 66,
[1][1][2][0][RTW89_KCC][1][84] = 32,
[1][1][2][0][RTW89_KCC][0][84] = 127,
[1][1][2][0][RTW89_ACMA][1][84] = 127,
@@ -45546,13 +44308,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][84] = 127,
[1][1][2][0][RTW89_THAILAND][0][84] = 127,
[1][1][2][0][RTW89_FCC][1][88] = 10,
- [1][1][2][0][RTW89_FCC][2][88] = 127,
[1][1][2][0][RTW89_ETSI][1][88] = 127,
[1][1][2][0][RTW89_ETSI][0][88] = 127,
[1][1][2][0][RTW89_MKK][1][88] = 127,
[1][1][2][0][RTW89_MKK][0][88] = 127,
[1][1][2][0][RTW89_IC][1][88] = 10,
- [1][1][2][0][RTW89_IC][2][88] = 127,
[1][1][2][0][RTW89_KCC][1][88] = 32,
[1][1][2][0][RTW89_KCC][0][88] = 127,
[1][1][2][0][RTW89_ACMA][1][88] = 127,
@@ -45565,13 +44325,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][88] = 127,
[1][1][2][0][RTW89_THAILAND][0][88] = 127,
[1][1][2][0][RTW89_FCC][1][91] = 12,
- [1][1][2][0][RTW89_FCC][2][91] = 127,
[1][1][2][0][RTW89_ETSI][1][91] = 127,
[1][1][2][0][RTW89_ETSI][0][91] = 127,
[1][1][2][0][RTW89_MKK][1][91] = 127,
[1][1][2][0][RTW89_MKK][0][91] = 127,
[1][1][2][0][RTW89_IC][1][91] = 12,
- [1][1][2][0][RTW89_IC][2][91] = 127,
[1][1][2][0][RTW89_KCC][1][91] = 32,
[1][1][2][0][RTW89_KCC][0][91] = 127,
[1][1][2][0][RTW89_ACMA][1][91] = 127,
@@ -45584,13 +44342,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][91] = 127,
[1][1][2][0][RTW89_THAILAND][0][91] = 127,
[1][1][2][0][RTW89_FCC][1][95] = 10,
- [1][1][2][0][RTW89_FCC][2][95] = 127,
[1][1][2][0][RTW89_ETSI][1][95] = 127,
[1][1][2][0][RTW89_ETSI][0][95] = 127,
[1][1][2][0][RTW89_MKK][1][95] = 127,
[1][1][2][0][RTW89_MKK][0][95] = 127,
[1][1][2][0][RTW89_IC][1][95] = 10,
- [1][1][2][0][RTW89_IC][2][95] = 127,
[1][1][2][0][RTW89_KCC][1][95] = 32,
[1][1][2][0][RTW89_KCC][0][95] = 127,
[1][1][2][0][RTW89_ACMA][1][95] = 127,
@@ -45603,13 +44359,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][95] = 127,
[1][1][2][0][RTW89_THAILAND][0][95] = 127,
[1][1][2][0][RTW89_FCC][1][99] = 10,
- [1][1][2][0][RTW89_FCC][2][99] = 127,
[1][1][2][0][RTW89_ETSI][1][99] = 127,
[1][1][2][0][RTW89_ETSI][0][99] = 127,
[1][1][2][0][RTW89_MKK][1][99] = 127,
[1][1][2][0][RTW89_MKK][0][99] = 127,
[1][1][2][0][RTW89_IC][1][99] = 10,
- [1][1][2][0][RTW89_IC][2][99] = 127,
[1][1][2][0][RTW89_KCC][1][99] = 32,
[1][1][2][0][RTW89_KCC][0][99] = 127,
[1][1][2][0][RTW89_ACMA][1][99] = 127,
@@ -45622,13 +44376,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][99] = 127,
[1][1][2][0][RTW89_THAILAND][0][99] = 127,
[1][1][2][0][RTW89_FCC][1][103] = 10,
- [1][1][2][0][RTW89_FCC][2][103] = 127,
[1][1][2][0][RTW89_ETSI][1][103] = 127,
[1][1][2][0][RTW89_ETSI][0][103] = 127,
[1][1][2][0][RTW89_MKK][1][103] = 127,
[1][1][2][0][RTW89_MKK][0][103] = 127,
[1][1][2][0][RTW89_IC][1][103] = 10,
- [1][1][2][0][RTW89_IC][2][103] = 127,
[1][1][2][0][RTW89_KCC][1][103] = 32,
[1][1][2][0][RTW89_KCC][0][103] = 127,
[1][1][2][0][RTW89_ACMA][1][103] = 127,
@@ -45641,13 +44393,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][103] = 127,
[1][1][2][0][RTW89_THAILAND][0][103] = 127,
[1][1][2][0][RTW89_FCC][1][106] = 12,
- [1][1][2][0][RTW89_FCC][2][106] = 127,
[1][1][2][0][RTW89_ETSI][1][106] = 127,
[1][1][2][0][RTW89_ETSI][0][106] = 127,
[1][1][2][0][RTW89_MKK][1][106] = 127,
[1][1][2][0][RTW89_MKK][0][106] = 127,
[1][1][2][0][RTW89_IC][1][106] = 12,
- [1][1][2][0][RTW89_IC][2][106] = 127,
[1][1][2][0][RTW89_KCC][1][106] = 32,
[1][1][2][0][RTW89_KCC][0][106] = 127,
[1][1][2][0][RTW89_ACMA][1][106] = 127,
@@ -45660,13 +44410,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][106] = 127,
[1][1][2][0][RTW89_THAILAND][0][106] = 127,
[1][1][2][0][RTW89_FCC][1][110] = 127,
- [1][1][2][0][RTW89_FCC][2][110] = 127,
[1][1][2][0][RTW89_ETSI][1][110] = 127,
[1][1][2][0][RTW89_ETSI][0][110] = 127,
[1][1][2][0][RTW89_MKK][1][110] = 127,
[1][1][2][0][RTW89_MKK][0][110] = 127,
[1][1][2][0][RTW89_IC][1][110] = 127,
- [1][1][2][0][RTW89_IC][2][110] = 127,
[1][1][2][0][RTW89_KCC][1][110] = 127,
[1][1][2][0][RTW89_KCC][0][110] = 127,
[1][1][2][0][RTW89_ACMA][1][110] = 127,
@@ -45679,13 +44427,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][110] = 127,
[1][1][2][0][RTW89_THAILAND][0][110] = 127,
[1][1][2][0][RTW89_FCC][1][114] = 127,
- [1][1][2][0][RTW89_FCC][2][114] = 127,
[1][1][2][0][RTW89_ETSI][1][114] = 127,
[1][1][2][0][RTW89_ETSI][0][114] = 127,
[1][1][2][0][RTW89_MKK][1][114] = 127,
[1][1][2][0][RTW89_MKK][0][114] = 127,
[1][1][2][0][RTW89_IC][1][114] = 127,
- [1][1][2][0][RTW89_IC][2][114] = 127,
[1][1][2][0][RTW89_KCC][1][114] = 127,
[1][1][2][0][RTW89_KCC][0][114] = 127,
[1][1][2][0][RTW89_ACMA][1][114] = 127,
@@ -45698,13 +44444,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][114] = 127,
[1][1][2][0][RTW89_THAILAND][0][114] = 127,
[1][1][2][0][RTW89_FCC][1][118] = 127,
- [1][1][2][0][RTW89_FCC][2][118] = 127,
[1][1][2][0][RTW89_ETSI][1][118] = 127,
[1][1][2][0][RTW89_ETSI][0][118] = 127,
[1][1][2][0][RTW89_MKK][1][118] = 127,
[1][1][2][0][RTW89_MKK][0][118] = 127,
[1][1][2][0][RTW89_IC][1][118] = 127,
- [1][1][2][0][RTW89_IC][2][118] = 127,
[1][1][2][0][RTW89_KCC][1][118] = 127,
[1][1][2][0][RTW89_KCC][0][118] = 127,
[1][1][2][0][RTW89_ACMA][1][118] = 127,
@@ -45717,13 +44461,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][0][RTW89_THAILAND][1][118] = 127,
[1][1][2][0][RTW89_THAILAND][0][118] = 127,
[1][1][2][1][RTW89_FCC][1][1] = 10,
- [1][1][2][1][RTW89_FCC][2][1] = 58,
[1][1][2][1][RTW89_ETSI][1][1] = 42,
[1][1][2][1][RTW89_ETSI][0][1] = 6,
[1][1][2][1][RTW89_MKK][1][1] = 52,
[1][1][2][1][RTW89_MKK][0][1] = 12,
[1][1][2][1][RTW89_IC][1][1] = 10,
- [1][1][2][1][RTW89_IC][2][1] = 58,
[1][1][2][1][RTW89_KCC][1][1] = 28,
[1][1][2][1][RTW89_KCC][0][1] = 12,
[1][1][2][1][RTW89_ACMA][1][1] = 42,
@@ -45736,13 +44478,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][1] = 46,
[1][1][2][1][RTW89_THAILAND][0][1] = 6,
[1][1][2][1][RTW89_FCC][1][5] = 10,
- [1][1][2][1][RTW89_FCC][2][5] = 58,
[1][1][2][1][RTW89_ETSI][1][5] = 42,
[1][1][2][1][RTW89_ETSI][0][5] = 6,
[1][1][2][1][RTW89_MKK][1][5] = 52,
[1][1][2][1][RTW89_MKK][0][5] = 12,
[1][1][2][1][RTW89_IC][1][5] = 10,
- [1][1][2][1][RTW89_IC][2][5] = 58,
[1][1][2][1][RTW89_KCC][1][5] = 28,
[1][1][2][1][RTW89_KCC][0][5] = 12,
[1][1][2][1][RTW89_ACMA][1][5] = 42,
@@ -45755,13 +44495,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][5] = 46,
[1][1][2][1][RTW89_THAILAND][0][5] = 6,
[1][1][2][1][RTW89_FCC][1][9] = 10,
- [1][1][2][1][RTW89_FCC][2][9] = 58,
[1][1][2][1][RTW89_ETSI][1][9] = 42,
[1][1][2][1][RTW89_ETSI][0][9] = 6,
[1][1][2][1][RTW89_MKK][1][9] = 52,
[1][1][2][1][RTW89_MKK][0][9] = 12,
[1][1][2][1][RTW89_IC][1][9] = 10,
- [1][1][2][1][RTW89_IC][2][9] = 58,
[1][1][2][1][RTW89_KCC][1][9] = 28,
[1][1][2][1][RTW89_KCC][0][9] = 12,
[1][1][2][1][RTW89_ACMA][1][9] = 42,
@@ -45774,13 +44512,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][9] = 46,
[1][1][2][1][RTW89_THAILAND][0][9] = 6,
[1][1][2][1][RTW89_FCC][1][13] = 10,
- [1][1][2][1][RTW89_FCC][2][13] = 58,
[1][1][2][1][RTW89_ETSI][1][13] = 42,
[1][1][2][1][RTW89_ETSI][0][13] = 6,
[1][1][2][1][RTW89_MKK][1][13] = 52,
[1][1][2][1][RTW89_MKK][0][13] = 12,
[1][1][2][1][RTW89_IC][1][13] = 10,
- [1][1][2][1][RTW89_IC][2][13] = 58,
[1][1][2][1][RTW89_KCC][1][13] = 28,
[1][1][2][1][RTW89_KCC][0][13] = 12,
[1][1][2][1][RTW89_ACMA][1][13] = 42,
@@ -45793,13 +44529,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][13] = 46,
[1][1][2][1][RTW89_THAILAND][0][13] = 6,
[1][1][2][1][RTW89_FCC][1][16] = 10,
- [1][1][2][1][RTW89_FCC][2][16] = 58,
[1][1][2][1][RTW89_ETSI][1][16] = 42,
[1][1][2][1][RTW89_ETSI][0][16] = 6,
[1][1][2][1][RTW89_MKK][1][16] = 52,
[1][1][2][1][RTW89_MKK][0][16] = 12,
[1][1][2][1][RTW89_IC][1][16] = 10,
- [1][1][2][1][RTW89_IC][2][16] = 58,
[1][1][2][1][RTW89_KCC][1][16] = 28,
[1][1][2][1][RTW89_KCC][0][16] = 12,
[1][1][2][1][RTW89_ACMA][1][16] = 42,
@@ -45812,13 +44546,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][16] = 46,
[1][1][2][1][RTW89_THAILAND][0][16] = 6,
[1][1][2][1][RTW89_FCC][1][20] = 10,
- [1][1][2][1][RTW89_FCC][2][20] = 58,
[1][1][2][1][RTW89_ETSI][1][20] = 42,
[1][1][2][1][RTW89_ETSI][0][20] = 6,
[1][1][2][1][RTW89_MKK][1][20] = 52,
[1][1][2][1][RTW89_MKK][0][20] = 12,
[1][1][2][1][RTW89_IC][1][20] = 10,
- [1][1][2][1][RTW89_IC][2][20] = 58,
[1][1][2][1][RTW89_KCC][1][20] = 28,
[1][1][2][1][RTW89_KCC][0][20] = 12,
[1][1][2][1][RTW89_ACMA][1][20] = 42,
@@ -45831,13 +44563,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][20] = 46,
[1][1][2][1][RTW89_THAILAND][0][20] = 6,
[1][1][2][1][RTW89_FCC][1][24] = 10,
- [1][1][2][1][RTW89_FCC][2][24] = 70,
[1][1][2][1][RTW89_ETSI][1][24] = 42,
[1][1][2][1][RTW89_ETSI][0][24] = 6,
[1][1][2][1][RTW89_MKK][1][24] = 54,
[1][1][2][1][RTW89_MKK][0][24] = 14,
[1][1][2][1][RTW89_IC][1][24] = 10,
- [1][1][2][1][RTW89_IC][2][24] = 70,
[1][1][2][1][RTW89_KCC][1][24] = 28,
[1][1][2][1][RTW89_KCC][0][24] = 12,
[1][1][2][1][RTW89_ACMA][1][24] = 42,
@@ -45850,13 +44580,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][24] = 46,
[1][1][2][1][RTW89_THAILAND][0][24] = 6,
[1][1][2][1][RTW89_FCC][1][28] = 10,
- [1][1][2][1][RTW89_FCC][2][28] = 70,
[1][1][2][1][RTW89_ETSI][1][28] = 42,
[1][1][2][1][RTW89_ETSI][0][28] = 6,
[1][1][2][1][RTW89_MKK][1][28] = 52,
[1][1][2][1][RTW89_MKK][0][28] = 14,
[1][1][2][1][RTW89_IC][1][28] = 10,
- [1][1][2][1][RTW89_IC][2][28] = 70,
[1][1][2][1][RTW89_KCC][1][28] = 28,
[1][1][2][1][RTW89_KCC][0][28] = 14,
[1][1][2][1][RTW89_ACMA][1][28] = 42,
@@ -45869,13 +44597,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][28] = 46,
[1][1][2][1][RTW89_THAILAND][0][28] = 6,
[1][1][2][1][RTW89_FCC][1][31] = 10,
- [1][1][2][1][RTW89_FCC][2][31] = 70,
[1][1][2][1][RTW89_ETSI][1][31] = 42,
[1][1][2][1][RTW89_ETSI][0][31] = 6,
[1][1][2][1][RTW89_MKK][1][31] = 52,
[1][1][2][1][RTW89_MKK][0][31] = 14,
[1][1][2][1][RTW89_IC][1][31] = 10,
- [1][1][2][1][RTW89_IC][2][31] = 70,
[1][1][2][1][RTW89_KCC][1][31] = 28,
[1][1][2][1][RTW89_KCC][0][31] = 14,
[1][1][2][1][RTW89_ACMA][1][31] = 42,
@@ -45888,13 +44614,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][31] = 46,
[1][1][2][1][RTW89_THAILAND][0][31] = 6,
[1][1][2][1][RTW89_FCC][1][35] = 10,
- [1][1][2][1][RTW89_FCC][2][35] = 70,
[1][1][2][1][RTW89_ETSI][1][35] = 42,
[1][1][2][1][RTW89_ETSI][0][35] = 6,
[1][1][2][1][RTW89_MKK][1][35] = 52,
[1][1][2][1][RTW89_MKK][0][35] = 14,
[1][1][2][1][RTW89_IC][1][35] = 10,
- [1][1][2][1][RTW89_IC][2][35] = 70,
[1][1][2][1][RTW89_KCC][1][35] = 28,
[1][1][2][1][RTW89_KCC][0][35] = 14,
[1][1][2][1][RTW89_ACMA][1][35] = 42,
@@ -45907,13 +44631,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][35] = 46,
[1][1][2][1][RTW89_THAILAND][0][35] = 6,
[1][1][2][1][RTW89_FCC][1][39] = 10,
- [1][1][2][1][RTW89_FCC][2][39] = 70,
[1][1][2][1][RTW89_ETSI][1][39] = 42,
[1][1][2][1][RTW89_ETSI][0][39] = 6,
[1][1][2][1][RTW89_MKK][1][39] = 52,
[1][1][2][1][RTW89_MKK][0][39] = 14,
[1][1][2][1][RTW89_IC][1][39] = 10,
- [1][1][2][1][RTW89_IC][2][39] = 70,
[1][1][2][1][RTW89_KCC][1][39] = 28,
[1][1][2][1][RTW89_KCC][0][39] = 14,
[1][1][2][1][RTW89_ACMA][1][39] = 42,
@@ -45926,13 +44648,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][39] = 46,
[1][1][2][1][RTW89_THAILAND][0][39] = 6,
[1][1][2][1][RTW89_FCC][1][43] = 10,
- [1][1][2][1][RTW89_FCC][2][43] = 70,
[1][1][2][1][RTW89_ETSI][1][43] = 42,
[1][1][2][1][RTW89_ETSI][0][43] = 6,
[1][1][2][1][RTW89_MKK][1][43] = 52,
[1][1][2][1][RTW89_MKK][0][43] = 14,
[1][1][2][1][RTW89_IC][1][43] = 10,
- [1][1][2][1][RTW89_IC][2][43] = 70,
[1][1][2][1][RTW89_KCC][1][43] = 28,
[1][1][2][1][RTW89_KCC][0][43] = 14,
[1][1][2][1][RTW89_ACMA][1][43] = 42,
@@ -45945,13 +44665,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][43] = 46,
[1][1][2][1][RTW89_THAILAND][0][43] = 6,
[1][1][2][1][RTW89_FCC][1][46] = 12,
- [1][1][2][1][RTW89_FCC][2][46] = 127,
[1][1][2][1][RTW89_ETSI][1][46] = 127,
[1][1][2][1][RTW89_ETSI][0][46] = 127,
[1][1][2][1][RTW89_MKK][1][46] = 127,
[1][1][2][1][RTW89_MKK][0][46] = 127,
[1][1][2][1][RTW89_IC][1][46] = 12,
- [1][1][2][1][RTW89_IC][2][46] = 68,
[1][1][2][1][RTW89_KCC][1][46] = 28,
[1][1][2][1][RTW89_KCC][0][46] = 127,
[1][1][2][1][RTW89_ACMA][1][46] = 127,
@@ -45964,13 +44682,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][46] = 127,
[1][1][2][1][RTW89_THAILAND][0][46] = 127,
[1][1][2][1][RTW89_FCC][1][50] = 12,
- [1][1][2][1][RTW89_FCC][2][50] = 127,
[1][1][2][1][RTW89_ETSI][1][50] = 127,
[1][1][2][1][RTW89_ETSI][0][50] = 127,
[1][1][2][1][RTW89_MKK][1][50] = 127,
[1][1][2][1][RTW89_MKK][0][50] = 127,
[1][1][2][1][RTW89_IC][1][50] = 12,
- [1][1][2][1][RTW89_IC][2][50] = 68,
[1][1][2][1][RTW89_KCC][1][50] = 28,
[1][1][2][1][RTW89_KCC][0][50] = 127,
[1][1][2][1][RTW89_ACMA][1][50] = 127,
@@ -45983,13 +44699,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][50] = 127,
[1][1][2][1][RTW89_THAILAND][0][50] = 127,
[1][1][2][1][RTW89_FCC][1][54] = 10,
- [1][1][2][1][RTW89_FCC][2][54] = 127,
[1][1][2][1][RTW89_ETSI][1][54] = 127,
[1][1][2][1][RTW89_ETSI][0][54] = 127,
[1][1][2][1][RTW89_MKK][1][54] = 127,
[1][1][2][1][RTW89_MKK][0][54] = 127,
[1][1][2][1][RTW89_IC][1][54] = 10,
- [1][1][2][1][RTW89_IC][2][54] = 127,
[1][1][2][1][RTW89_KCC][1][54] = 28,
[1][1][2][1][RTW89_KCC][0][54] = 127,
[1][1][2][1][RTW89_ACMA][1][54] = 127,
@@ -46002,13 +44716,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][54] = 127,
[1][1][2][1][RTW89_THAILAND][0][54] = 127,
[1][1][2][1][RTW89_FCC][1][58] = 10,
- [1][1][2][1][RTW89_FCC][2][58] = 66,
[1][1][2][1][RTW89_ETSI][1][58] = 127,
[1][1][2][1][RTW89_ETSI][0][58] = 127,
[1][1][2][1][RTW89_MKK][1][58] = 127,
[1][1][2][1][RTW89_MKK][0][58] = 127,
[1][1][2][1][RTW89_IC][1][58] = 10,
- [1][1][2][1][RTW89_IC][2][58] = 66,
[1][1][2][1][RTW89_KCC][1][58] = 28,
[1][1][2][1][RTW89_KCC][0][58] = 127,
[1][1][2][1][RTW89_ACMA][1][58] = 127,
@@ -46021,13 +44733,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][58] = 127,
[1][1][2][1][RTW89_THAILAND][0][58] = 127,
[1][1][2][1][RTW89_FCC][1][61] = 10,
- [1][1][2][1][RTW89_FCC][2][61] = 66,
[1][1][2][1][RTW89_ETSI][1][61] = 127,
[1][1][2][1][RTW89_ETSI][0][61] = 127,
[1][1][2][1][RTW89_MKK][1][61] = 127,
[1][1][2][1][RTW89_MKK][0][61] = 127,
[1][1][2][1][RTW89_IC][1][61] = 10,
- [1][1][2][1][RTW89_IC][2][61] = 66,
[1][1][2][1][RTW89_KCC][1][61] = 28,
[1][1][2][1][RTW89_KCC][0][61] = 127,
[1][1][2][1][RTW89_ACMA][1][61] = 127,
@@ -46040,13 +44750,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][61] = 127,
[1][1][2][1][RTW89_THAILAND][0][61] = 127,
[1][1][2][1][RTW89_FCC][1][65] = 10,
- [1][1][2][1][RTW89_FCC][2][65] = 66,
[1][1][2][1][RTW89_ETSI][1][65] = 127,
[1][1][2][1][RTW89_ETSI][0][65] = 127,
[1][1][2][1][RTW89_MKK][1][65] = 127,
[1][1][2][1][RTW89_MKK][0][65] = 127,
[1][1][2][1][RTW89_IC][1][65] = 10,
- [1][1][2][1][RTW89_IC][2][65] = 66,
[1][1][2][1][RTW89_KCC][1][65] = 28,
[1][1][2][1][RTW89_KCC][0][65] = 127,
[1][1][2][1][RTW89_ACMA][1][65] = 127,
@@ -46059,13 +44767,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][65] = 127,
[1][1][2][1][RTW89_THAILAND][0][65] = 127,
[1][1][2][1][RTW89_FCC][1][69] = 10,
- [1][1][2][1][RTW89_FCC][2][69] = 66,
[1][1][2][1][RTW89_ETSI][1][69] = 127,
[1][1][2][1][RTW89_ETSI][0][69] = 127,
[1][1][2][1][RTW89_MKK][1][69] = 127,
[1][1][2][1][RTW89_MKK][0][69] = 127,
[1][1][2][1][RTW89_IC][1][69] = 10,
- [1][1][2][1][RTW89_IC][2][69] = 66,
[1][1][2][1][RTW89_KCC][1][69] = 28,
[1][1][2][1][RTW89_KCC][0][69] = 127,
[1][1][2][1][RTW89_ACMA][1][69] = 127,
@@ -46078,13 +44784,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][69] = 127,
[1][1][2][1][RTW89_THAILAND][0][69] = 127,
[1][1][2][1][RTW89_FCC][1][73] = 10,
- [1][1][2][1][RTW89_FCC][2][73] = 66,
[1][1][2][1][RTW89_ETSI][1][73] = 127,
[1][1][2][1][RTW89_ETSI][0][73] = 127,
[1][1][2][1][RTW89_MKK][1][73] = 127,
[1][1][2][1][RTW89_MKK][0][73] = 127,
[1][1][2][1][RTW89_IC][1][73] = 10,
- [1][1][2][1][RTW89_IC][2][73] = 66,
[1][1][2][1][RTW89_KCC][1][73] = 28,
[1][1][2][1][RTW89_KCC][0][73] = 127,
[1][1][2][1][RTW89_ACMA][1][73] = 127,
@@ -46097,13 +44801,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][73] = 127,
[1][1][2][1][RTW89_THAILAND][0][73] = 127,
[1][1][2][1][RTW89_FCC][1][76] = 10,
- [1][1][2][1][RTW89_FCC][2][76] = 66,
[1][1][2][1][RTW89_ETSI][1][76] = 127,
[1][1][2][1][RTW89_ETSI][0][76] = 127,
[1][1][2][1][RTW89_MKK][1][76] = 127,
[1][1][2][1][RTW89_MKK][0][76] = 127,
[1][1][2][1][RTW89_IC][1][76] = 10,
- [1][1][2][1][RTW89_IC][2][76] = 66,
[1][1][2][1][RTW89_KCC][1][76] = 28,
[1][1][2][1][RTW89_KCC][0][76] = 127,
[1][1][2][1][RTW89_ACMA][1][76] = 127,
@@ -46116,13 +44818,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][76] = 127,
[1][1][2][1][RTW89_THAILAND][0][76] = 127,
[1][1][2][1][RTW89_FCC][1][80] = 10,
- [1][1][2][1][RTW89_FCC][2][80] = 66,
[1][1][2][1][RTW89_ETSI][1][80] = 127,
[1][1][2][1][RTW89_ETSI][0][80] = 127,
[1][1][2][1][RTW89_MKK][1][80] = 127,
[1][1][2][1][RTW89_MKK][0][80] = 127,
[1][1][2][1][RTW89_IC][1][80] = 10,
- [1][1][2][1][RTW89_IC][2][80] = 66,
[1][1][2][1][RTW89_KCC][1][80] = 32,
[1][1][2][1][RTW89_KCC][0][80] = 127,
[1][1][2][1][RTW89_ACMA][1][80] = 127,
@@ -46135,13 +44835,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][80] = 127,
[1][1][2][1][RTW89_THAILAND][0][80] = 127,
[1][1][2][1][RTW89_FCC][1][84] = 10,
- [1][1][2][1][RTW89_FCC][2][84] = 66,
[1][1][2][1][RTW89_ETSI][1][84] = 127,
[1][1][2][1][RTW89_ETSI][0][84] = 127,
[1][1][2][1][RTW89_MKK][1][84] = 127,
[1][1][2][1][RTW89_MKK][0][84] = 127,
[1][1][2][1][RTW89_IC][1][84] = 10,
- [1][1][2][1][RTW89_IC][2][84] = 66,
[1][1][2][1][RTW89_KCC][1][84] = 32,
[1][1][2][1][RTW89_KCC][0][84] = 127,
[1][1][2][1][RTW89_ACMA][1][84] = 127,
@@ -46154,13 +44852,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][84] = 127,
[1][1][2][1][RTW89_THAILAND][0][84] = 127,
[1][1][2][1][RTW89_FCC][1][88] = 10,
- [1][1][2][1][RTW89_FCC][2][88] = 127,
[1][1][2][1][RTW89_ETSI][1][88] = 127,
[1][1][2][1][RTW89_ETSI][0][88] = 127,
[1][1][2][1][RTW89_MKK][1][88] = 127,
[1][1][2][1][RTW89_MKK][0][88] = 127,
[1][1][2][1][RTW89_IC][1][88] = 10,
- [1][1][2][1][RTW89_IC][2][88] = 127,
[1][1][2][1][RTW89_KCC][1][88] = 32,
[1][1][2][1][RTW89_KCC][0][88] = 127,
[1][1][2][1][RTW89_ACMA][1][88] = 127,
@@ -46173,13 +44869,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][88] = 127,
[1][1][2][1][RTW89_THAILAND][0][88] = 127,
[1][1][2][1][RTW89_FCC][1][91] = 12,
- [1][1][2][1][RTW89_FCC][2][91] = 127,
[1][1][2][1][RTW89_ETSI][1][91] = 127,
[1][1][2][1][RTW89_ETSI][0][91] = 127,
[1][1][2][1][RTW89_MKK][1][91] = 127,
[1][1][2][1][RTW89_MKK][0][91] = 127,
[1][1][2][1][RTW89_IC][1][91] = 12,
- [1][1][2][1][RTW89_IC][2][91] = 127,
[1][1][2][1][RTW89_KCC][1][91] = 32,
[1][1][2][1][RTW89_KCC][0][91] = 127,
[1][1][2][1][RTW89_ACMA][1][91] = 127,
@@ -46192,13 +44886,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][91] = 127,
[1][1][2][1][RTW89_THAILAND][0][91] = 127,
[1][1][2][1][RTW89_FCC][1][95] = 10,
- [1][1][2][1][RTW89_FCC][2][95] = 127,
[1][1][2][1][RTW89_ETSI][1][95] = 127,
[1][1][2][1][RTW89_ETSI][0][95] = 127,
[1][1][2][1][RTW89_MKK][1][95] = 127,
[1][1][2][1][RTW89_MKK][0][95] = 127,
[1][1][2][1][RTW89_IC][1][95] = 10,
- [1][1][2][1][RTW89_IC][2][95] = 127,
[1][1][2][1][RTW89_KCC][1][95] = 32,
[1][1][2][1][RTW89_KCC][0][95] = 127,
[1][1][2][1][RTW89_ACMA][1][95] = 127,
@@ -46211,13 +44903,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][95] = 127,
[1][1][2][1][RTW89_THAILAND][0][95] = 127,
[1][1][2][1][RTW89_FCC][1][99] = 10,
- [1][1][2][1][RTW89_FCC][2][99] = 127,
[1][1][2][1][RTW89_ETSI][1][99] = 127,
[1][1][2][1][RTW89_ETSI][0][99] = 127,
[1][1][2][1][RTW89_MKK][1][99] = 127,
[1][1][2][1][RTW89_MKK][0][99] = 127,
[1][1][2][1][RTW89_IC][1][99] = 10,
- [1][1][2][1][RTW89_IC][2][99] = 127,
[1][1][2][1][RTW89_KCC][1][99] = 32,
[1][1][2][1][RTW89_KCC][0][99] = 127,
[1][1][2][1][RTW89_ACMA][1][99] = 127,
@@ -46230,13 +44920,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][99] = 127,
[1][1][2][1][RTW89_THAILAND][0][99] = 127,
[1][1][2][1][RTW89_FCC][1][103] = 10,
- [1][1][2][1][RTW89_FCC][2][103] = 127,
[1][1][2][1][RTW89_ETSI][1][103] = 127,
[1][1][2][1][RTW89_ETSI][0][103] = 127,
[1][1][2][1][RTW89_MKK][1][103] = 127,
[1][1][2][1][RTW89_MKK][0][103] = 127,
[1][1][2][1][RTW89_IC][1][103] = 10,
- [1][1][2][1][RTW89_IC][2][103] = 127,
[1][1][2][1][RTW89_KCC][1][103] = 32,
[1][1][2][1][RTW89_KCC][0][103] = 127,
[1][1][2][1][RTW89_ACMA][1][103] = 127,
@@ -46249,13 +44937,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][103] = 127,
[1][1][2][1][RTW89_THAILAND][0][103] = 127,
[1][1][2][1][RTW89_FCC][1][106] = 12,
- [1][1][2][1][RTW89_FCC][2][106] = 127,
[1][1][2][1][RTW89_ETSI][1][106] = 127,
[1][1][2][1][RTW89_ETSI][0][106] = 127,
[1][1][2][1][RTW89_MKK][1][106] = 127,
[1][1][2][1][RTW89_MKK][0][106] = 127,
[1][1][2][1][RTW89_IC][1][106] = 12,
- [1][1][2][1][RTW89_IC][2][106] = 127,
[1][1][2][1][RTW89_KCC][1][106] = 32,
[1][1][2][1][RTW89_KCC][0][106] = 127,
[1][1][2][1][RTW89_ACMA][1][106] = 127,
@@ -46268,13 +44954,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][106] = 127,
[1][1][2][1][RTW89_THAILAND][0][106] = 127,
[1][1][2][1][RTW89_FCC][1][110] = 127,
- [1][1][2][1][RTW89_FCC][2][110] = 127,
[1][1][2][1][RTW89_ETSI][1][110] = 127,
[1][1][2][1][RTW89_ETSI][0][110] = 127,
[1][1][2][1][RTW89_MKK][1][110] = 127,
[1][1][2][1][RTW89_MKK][0][110] = 127,
[1][1][2][1][RTW89_IC][1][110] = 127,
- [1][1][2][1][RTW89_IC][2][110] = 127,
[1][1][2][1][RTW89_KCC][1][110] = 127,
[1][1][2][1][RTW89_KCC][0][110] = 127,
[1][1][2][1][RTW89_ACMA][1][110] = 127,
@@ -46287,13 +44971,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][110] = 127,
[1][1][2][1][RTW89_THAILAND][0][110] = 127,
[1][1][2][1][RTW89_FCC][1][114] = 127,
- [1][1][2][1][RTW89_FCC][2][114] = 127,
[1][1][2][1][RTW89_ETSI][1][114] = 127,
[1][1][2][1][RTW89_ETSI][0][114] = 127,
[1][1][2][1][RTW89_MKK][1][114] = 127,
[1][1][2][1][RTW89_MKK][0][114] = 127,
[1][1][2][1][RTW89_IC][1][114] = 127,
- [1][1][2][1][RTW89_IC][2][114] = 127,
[1][1][2][1][RTW89_KCC][1][114] = 127,
[1][1][2][1][RTW89_KCC][0][114] = 127,
[1][1][2][1][RTW89_ACMA][1][114] = 127,
@@ -46306,13 +44988,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][114] = 127,
[1][1][2][1][RTW89_THAILAND][0][114] = 127,
[1][1][2][1][RTW89_FCC][1][118] = 127,
- [1][1][2][1][RTW89_FCC][2][118] = 127,
[1][1][2][1][RTW89_ETSI][1][118] = 127,
[1][1][2][1][RTW89_ETSI][0][118] = 127,
[1][1][2][1][RTW89_MKK][1][118] = 127,
[1][1][2][1][RTW89_MKK][0][118] = 127,
[1][1][2][1][RTW89_IC][1][118] = 127,
- [1][1][2][1][RTW89_IC][2][118] = 127,
[1][1][2][1][RTW89_KCC][1][118] = 127,
[1][1][2][1][RTW89_KCC][0][118] = 127,
[1][1][2][1][RTW89_ACMA][1][118] = 127,
@@ -46325,13 +45005,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[1][1][2][1][RTW89_THAILAND][1][118] = 127,
[1][1][2][1][RTW89_THAILAND][0][118] = 127,
[2][0][2][0][RTW89_FCC][1][3] = 46,
- [2][0][2][0][RTW89_FCC][2][3] = 60,
[2][0][2][0][RTW89_ETSI][1][3] = 58,
[2][0][2][0][RTW89_ETSI][0][3] = 30,
[2][0][2][0][RTW89_MKK][1][3] = 58,
[2][0][2][0][RTW89_MKK][0][3] = 26,
[2][0][2][0][RTW89_IC][1][3] = 46,
- [2][0][2][0][RTW89_IC][2][3] = 60,
[2][0][2][0][RTW89_KCC][1][3] = 50,
[2][0][2][0][RTW89_KCC][0][3] = 24,
[2][0][2][0][RTW89_ACMA][1][3] = 58,
@@ -46344,13 +45022,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][3] = 58,
[2][0][2][0][RTW89_THAILAND][0][3] = 30,
[2][0][2][0][RTW89_FCC][1][11] = 46,
- [2][0][2][0][RTW89_FCC][2][11] = 60,
[2][0][2][0][RTW89_ETSI][1][11] = 58,
[2][0][2][0][RTW89_ETSI][0][11] = 30,
[2][0][2][0][RTW89_MKK][1][11] = 58,
[2][0][2][0][RTW89_MKK][0][11] = 24,
[2][0][2][0][RTW89_IC][1][11] = 46,
- [2][0][2][0][RTW89_IC][2][11] = 60,
[2][0][2][0][RTW89_KCC][1][11] = 50,
[2][0][2][0][RTW89_KCC][0][11] = 24,
[2][0][2][0][RTW89_ACMA][1][11] = 58,
@@ -46363,13 +45039,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][11] = 58,
[2][0][2][0][RTW89_THAILAND][0][11] = 30,
[2][0][2][0][RTW89_FCC][1][18] = 46,
- [2][0][2][0][RTW89_FCC][2][18] = 60,
[2][0][2][0][RTW89_ETSI][1][18] = 58,
[2][0][2][0][RTW89_ETSI][0][18] = 30,
[2][0][2][0][RTW89_MKK][1][18] = 58,
[2][0][2][0][RTW89_MKK][0][18] = 24,
[2][0][2][0][RTW89_IC][1][18] = 46,
- [2][0][2][0][RTW89_IC][2][18] = 60,
[2][0][2][0][RTW89_KCC][1][18] = 50,
[2][0][2][0][RTW89_KCC][0][18] = 24,
[2][0][2][0][RTW89_ACMA][1][18] = 58,
@@ -46382,13 +45056,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][18] = 58,
[2][0][2][0][RTW89_THAILAND][0][18] = 30,
[2][0][2][0][RTW89_FCC][1][26] = 46,
- [2][0][2][0][RTW89_FCC][2][26] = 60,
[2][0][2][0][RTW89_ETSI][1][26] = 58,
[2][0][2][0][RTW89_ETSI][0][26] = 30,
[2][0][2][0][RTW89_MKK][1][26] = 58,
[2][0][2][0][RTW89_MKK][0][26] = 24,
[2][0][2][0][RTW89_IC][1][26] = 46,
- [2][0][2][0][RTW89_IC][2][26] = 60,
[2][0][2][0][RTW89_KCC][1][26] = 50,
[2][0][2][0][RTW89_KCC][0][26] = 26,
[2][0][2][0][RTW89_ACMA][1][26] = 58,
@@ -46401,13 +45073,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][26] = 58,
[2][0][2][0][RTW89_THAILAND][0][26] = 30,
[2][0][2][0][RTW89_FCC][1][33] = 46,
- [2][0][2][0][RTW89_FCC][2][33] = 60,
[2][0][2][0][RTW89_ETSI][1][33] = 58,
[2][0][2][0][RTW89_ETSI][0][33] = 30,
[2][0][2][0][RTW89_MKK][1][33] = 58,
[2][0][2][0][RTW89_MKK][0][33] = 24,
[2][0][2][0][RTW89_IC][1][33] = 46,
- [2][0][2][0][RTW89_IC][2][33] = 60,
[2][0][2][0][RTW89_KCC][1][33] = 50,
[2][0][2][0][RTW89_KCC][0][33] = 24,
[2][0][2][0][RTW89_ACMA][1][33] = 58,
@@ -46420,13 +45090,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][33] = 58,
[2][0][2][0][RTW89_THAILAND][0][33] = 30,
[2][0][2][0][RTW89_FCC][1][41] = 46,
- [2][0][2][0][RTW89_FCC][2][41] = 60,
[2][0][2][0][RTW89_ETSI][1][41] = 58,
[2][0][2][0][RTW89_ETSI][0][41] = 30,
[2][0][2][0][RTW89_MKK][1][41] = 58,
[2][0][2][0][RTW89_MKK][0][41] = 24,
[2][0][2][0][RTW89_IC][1][41] = 46,
- [2][0][2][0][RTW89_IC][2][41] = 60,
[2][0][2][0][RTW89_KCC][1][41] = 50,
[2][0][2][0][RTW89_KCC][0][41] = 24,
[2][0][2][0][RTW89_ACMA][1][41] = 58,
@@ -46439,13 +45107,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][41] = 58,
[2][0][2][0][RTW89_THAILAND][0][41] = 30,
[2][0][2][0][RTW89_FCC][1][48] = 46,
- [2][0][2][0][RTW89_FCC][2][48] = 127,
[2][0][2][0][RTW89_ETSI][1][48] = 127,
[2][0][2][0][RTW89_ETSI][0][48] = 127,
[2][0][2][0][RTW89_MKK][1][48] = 127,
[2][0][2][0][RTW89_MKK][0][48] = 127,
[2][0][2][0][RTW89_IC][1][48] = 46,
- [2][0][2][0][RTW89_IC][2][48] = 60,
[2][0][2][0][RTW89_KCC][1][48] = 48,
[2][0][2][0][RTW89_KCC][0][48] = 127,
[2][0][2][0][RTW89_ACMA][1][48] = 127,
@@ -46458,13 +45124,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][48] = 127,
[2][0][2][0][RTW89_THAILAND][0][48] = 127,
[2][0][2][0][RTW89_FCC][1][56] = 46,
- [2][0][2][0][RTW89_FCC][2][56] = 127,
[2][0][2][0][RTW89_ETSI][1][56] = 127,
[2][0][2][0][RTW89_ETSI][0][56] = 127,
[2][0][2][0][RTW89_MKK][1][56] = 127,
[2][0][2][0][RTW89_MKK][0][56] = 127,
[2][0][2][0][RTW89_IC][1][56] = 46,
- [2][0][2][0][RTW89_IC][2][56] = 58,
[2][0][2][0][RTW89_KCC][1][56] = 48,
[2][0][2][0][RTW89_KCC][0][56] = 127,
[2][0][2][0][RTW89_ACMA][1][56] = 127,
@@ -46477,13 +45141,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][56] = 127,
[2][0][2][0][RTW89_THAILAND][0][56] = 127,
[2][0][2][0][RTW89_FCC][1][63] = 46,
- [2][0][2][0][RTW89_FCC][2][63] = 58,
[2][0][2][0][RTW89_ETSI][1][63] = 127,
[2][0][2][0][RTW89_ETSI][0][63] = 127,
[2][0][2][0][RTW89_MKK][1][63] = 127,
[2][0][2][0][RTW89_MKK][0][63] = 127,
[2][0][2][0][RTW89_IC][1][63] = 46,
- [2][0][2][0][RTW89_IC][2][63] = 58,
[2][0][2][0][RTW89_KCC][1][63] = 48,
[2][0][2][0][RTW89_KCC][0][63] = 127,
[2][0][2][0][RTW89_ACMA][1][63] = 127,
@@ -46496,13 +45158,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][63] = 127,
[2][0][2][0][RTW89_THAILAND][0][63] = 127,
[2][0][2][0][RTW89_FCC][1][71] = 46,
- [2][0][2][0][RTW89_FCC][2][71] = 58,
[2][0][2][0][RTW89_ETSI][1][71] = 127,
[2][0][2][0][RTW89_ETSI][0][71] = 127,
[2][0][2][0][RTW89_MKK][1][71] = 127,
[2][0][2][0][RTW89_MKK][0][71] = 127,
[2][0][2][0][RTW89_IC][1][71] = 46,
- [2][0][2][0][RTW89_IC][2][71] = 58,
[2][0][2][0][RTW89_KCC][1][71] = 48,
[2][0][2][0][RTW89_KCC][0][71] = 127,
[2][0][2][0][RTW89_ACMA][1][71] = 127,
@@ -46515,13 +45175,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][71] = 127,
[2][0][2][0][RTW89_THAILAND][0][71] = 127,
[2][0][2][0][RTW89_FCC][1][78] = 46,
- [2][0][2][0][RTW89_FCC][2][78] = 58,
[2][0][2][0][RTW89_ETSI][1][78] = 127,
[2][0][2][0][RTW89_ETSI][0][78] = 127,
[2][0][2][0][RTW89_MKK][1][78] = 127,
[2][0][2][0][RTW89_MKK][0][78] = 127,
[2][0][2][0][RTW89_IC][1][78] = 46,
- [2][0][2][0][RTW89_IC][2][78] = 58,
[2][0][2][0][RTW89_KCC][1][78] = 52,
[2][0][2][0][RTW89_KCC][0][78] = 127,
[2][0][2][0][RTW89_ACMA][1][78] = 127,
@@ -46534,13 +45192,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][78] = 127,
[2][0][2][0][RTW89_THAILAND][0][78] = 127,
[2][0][2][0][RTW89_FCC][1][86] = 46,
- [2][0][2][0][RTW89_FCC][2][86] = 127,
[2][0][2][0][RTW89_ETSI][1][86] = 127,
[2][0][2][0][RTW89_ETSI][0][86] = 127,
[2][0][2][0][RTW89_MKK][1][86] = 127,
[2][0][2][0][RTW89_MKK][0][86] = 127,
[2][0][2][0][RTW89_IC][1][86] = 46,
- [2][0][2][0][RTW89_IC][2][86] = 127,
[2][0][2][0][RTW89_KCC][1][86] = 52,
[2][0][2][0][RTW89_KCC][0][86] = 127,
[2][0][2][0][RTW89_ACMA][1][86] = 127,
@@ -46553,13 +45209,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][86] = 127,
[2][0][2][0][RTW89_THAILAND][0][86] = 127,
[2][0][2][0][RTW89_FCC][1][93] = 46,
- [2][0][2][0][RTW89_FCC][2][93] = 127,
[2][0][2][0][RTW89_ETSI][1][93] = 127,
[2][0][2][0][RTW89_ETSI][0][93] = 127,
[2][0][2][0][RTW89_MKK][1][93] = 127,
[2][0][2][0][RTW89_MKK][0][93] = 127,
[2][0][2][0][RTW89_IC][1][93] = 46,
- [2][0][2][0][RTW89_IC][2][93] = 127,
[2][0][2][0][RTW89_KCC][1][93] = 50,
[2][0][2][0][RTW89_KCC][0][93] = 127,
[2][0][2][0][RTW89_ACMA][1][93] = 127,
@@ -46572,13 +45226,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][93] = 127,
[2][0][2][0][RTW89_THAILAND][0][93] = 127,
[2][0][2][0][RTW89_FCC][1][101] = 44,
- [2][0][2][0][RTW89_FCC][2][101] = 127,
[2][0][2][0][RTW89_ETSI][1][101] = 127,
[2][0][2][0][RTW89_ETSI][0][101] = 127,
[2][0][2][0][RTW89_MKK][1][101] = 127,
[2][0][2][0][RTW89_MKK][0][101] = 127,
[2][0][2][0][RTW89_IC][1][101] = 44,
- [2][0][2][0][RTW89_IC][2][101] = 127,
[2][0][2][0][RTW89_KCC][1][101] = 50,
[2][0][2][0][RTW89_KCC][0][101] = 127,
[2][0][2][0][RTW89_ACMA][1][101] = 127,
@@ -46591,13 +45243,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][101] = 127,
[2][0][2][0][RTW89_THAILAND][0][101] = 127,
[2][0][2][0][RTW89_FCC][1][108] = 127,
- [2][0][2][0][RTW89_FCC][2][108] = 127,
[2][0][2][0][RTW89_ETSI][1][108] = 127,
[2][0][2][0][RTW89_ETSI][0][108] = 127,
[2][0][2][0][RTW89_MKK][1][108] = 127,
[2][0][2][0][RTW89_MKK][0][108] = 127,
[2][0][2][0][RTW89_IC][1][108] = 127,
- [2][0][2][0][RTW89_IC][2][108] = 127,
[2][0][2][0][RTW89_KCC][1][108] = 127,
[2][0][2][0][RTW89_KCC][0][108] = 127,
[2][0][2][0][RTW89_ACMA][1][108] = 127,
@@ -46610,13 +45260,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][108] = 127,
[2][0][2][0][RTW89_THAILAND][0][108] = 127,
[2][0][2][0][RTW89_FCC][1][116] = 127,
- [2][0][2][0][RTW89_FCC][2][116] = 127,
[2][0][2][0][RTW89_ETSI][1][116] = 127,
[2][0][2][0][RTW89_ETSI][0][116] = 127,
[2][0][2][0][RTW89_MKK][1][116] = 127,
[2][0][2][0][RTW89_MKK][0][116] = 127,
[2][0][2][0][RTW89_IC][1][116] = 127,
- [2][0][2][0][RTW89_IC][2][116] = 127,
[2][0][2][0][RTW89_KCC][1][116] = 127,
[2][0][2][0][RTW89_KCC][0][116] = 127,
[2][0][2][0][RTW89_ACMA][1][116] = 127,
@@ -46629,13 +45277,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][0][2][0][RTW89_THAILAND][1][116] = 127,
[2][0][2][0][RTW89_THAILAND][0][116] = 127,
[2][1][2][0][RTW89_FCC][1][3] = 22,
- [2][1][2][0][RTW89_FCC][2][3] = 50,
[2][1][2][0][RTW89_ETSI][1][3] = 54,
[2][1][2][0][RTW89_ETSI][0][3] = 16,
[2][1][2][0][RTW89_MKK][1][3] = 52,
[2][1][2][0][RTW89_MKK][0][3] = 14,
[2][1][2][0][RTW89_IC][1][3] = 22,
- [2][1][2][0][RTW89_IC][2][3] = 50,
[2][1][2][0][RTW89_KCC][1][3] = 38,
[2][1][2][0][RTW89_KCC][0][3] = 12,
[2][1][2][0][RTW89_ACMA][1][3] = 54,
@@ -46648,13 +45294,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][3] = 46,
[2][1][2][0][RTW89_THAILAND][0][3] = 18,
[2][1][2][0][RTW89_FCC][1][11] = 20,
- [2][1][2][0][RTW89_FCC][2][11] = 50,
[2][1][2][0][RTW89_ETSI][1][11] = 54,
[2][1][2][0][RTW89_ETSI][0][11] = 16,
[2][1][2][0][RTW89_MKK][1][11] = 52,
[2][1][2][0][RTW89_MKK][0][11] = 12,
[2][1][2][0][RTW89_IC][1][11] = 20,
- [2][1][2][0][RTW89_IC][2][11] = 50,
[2][1][2][0][RTW89_KCC][1][11] = 38,
[2][1][2][0][RTW89_KCC][0][11] = 12,
[2][1][2][0][RTW89_ACMA][1][11] = 54,
@@ -46667,13 +45311,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][11] = 46,
[2][1][2][0][RTW89_THAILAND][0][11] = 18,
[2][1][2][0][RTW89_FCC][1][18] = 20,
- [2][1][2][0][RTW89_FCC][2][18] = 50,
[2][1][2][0][RTW89_ETSI][1][18] = 54,
[2][1][2][0][RTW89_ETSI][0][18] = 16,
[2][1][2][0][RTW89_MKK][1][18] = 52,
[2][1][2][0][RTW89_MKK][0][18] = 12,
[2][1][2][0][RTW89_IC][1][18] = 20,
- [2][1][2][0][RTW89_IC][2][18] = 50,
[2][1][2][0][RTW89_KCC][1][18] = 38,
[2][1][2][0][RTW89_KCC][0][18] = 12,
[2][1][2][0][RTW89_ACMA][1][18] = 54,
@@ -46686,13 +45328,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][18] = 46,
[2][1][2][0][RTW89_THAILAND][0][18] = 18,
[2][1][2][0][RTW89_FCC][1][26] = 20,
- [2][1][2][0][RTW89_FCC][2][26] = 60,
[2][1][2][0][RTW89_ETSI][1][26] = 54,
[2][1][2][0][RTW89_ETSI][0][26] = 16,
[2][1][2][0][RTW89_MKK][1][26] = 52,
[2][1][2][0][RTW89_MKK][0][26] = 12,
[2][1][2][0][RTW89_IC][1][26] = 20,
- [2][1][2][0][RTW89_IC][2][26] = 60,
[2][1][2][0][RTW89_KCC][1][26] = 38,
[2][1][2][0][RTW89_KCC][0][26] = 12,
[2][1][2][0][RTW89_ACMA][1][26] = 54,
@@ -46705,13 +45345,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][26] = 46,
[2][1][2][0][RTW89_THAILAND][0][26] = 18,
[2][1][2][0][RTW89_FCC][1][33] = 20,
- [2][1][2][0][RTW89_FCC][2][33] = 60,
[2][1][2][0][RTW89_ETSI][1][33] = 54,
[2][1][2][0][RTW89_ETSI][0][33] = 16,
[2][1][2][0][RTW89_MKK][1][33] = 48,
[2][1][2][0][RTW89_MKK][0][33] = 12,
[2][1][2][0][RTW89_IC][1][33] = 20,
- [2][1][2][0][RTW89_IC][2][33] = 60,
[2][1][2][0][RTW89_KCC][1][33] = 38,
[2][1][2][0][RTW89_KCC][0][33] = 12,
[2][1][2][0][RTW89_ACMA][1][33] = 54,
@@ -46724,13 +45362,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][33] = 46,
[2][1][2][0][RTW89_THAILAND][0][33] = 18,
[2][1][2][0][RTW89_FCC][1][41] = 22,
- [2][1][2][0][RTW89_FCC][2][41] = 60,
[2][1][2][0][RTW89_ETSI][1][41] = 54,
[2][1][2][0][RTW89_ETSI][0][41] = 18,
[2][1][2][0][RTW89_MKK][1][41] = 48,
[2][1][2][0][RTW89_MKK][0][41] = 12,
[2][1][2][0][RTW89_IC][1][41] = 22,
- [2][1][2][0][RTW89_IC][2][41] = 60,
[2][1][2][0][RTW89_KCC][1][41] = 38,
[2][1][2][0][RTW89_KCC][0][41] = 12,
[2][1][2][0][RTW89_ACMA][1][41] = 54,
@@ -46743,13 +45379,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][41] = 46,
[2][1][2][0][RTW89_THAILAND][0][41] = 18,
[2][1][2][0][RTW89_FCC][1][48] = 22,
- [2][1][2][0][RTW89_FCC][2][48] = 127,
[2][1][2][0][RTW89_ETSI][1][48] = 127,
[2][1][2][0][RTW89_ETSI][0][48] = 127,
[2][1][2][0][RTW89_MKK][1][48] = 127,
[2][1][2][0][RTW89_MKK][0][48] = 127,
[2][1][2][0][RTW89_IC][1][48] = 22,
- [2][1][2][0][RTW89_IC][2][48] = 60,
[2][1][2][0][RTW89_KCC][1][48] = 38,
[2][1][2][0][RTW89_KCC][0][48] = 127,
[2][1][2][0][RTW89_ACMA][1][48] = 127,
@@ -46762,13 +45396,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][48] = 127,
[2][1][2][0][RTW89_THAILAND][0][48] = 127,
[2][1][2][0][RTW89_FCC][1][56] = 20,
- [2][1][2][0][RTW89_FCC][2][56] = 127,
[2][1][2][0][RTW89_ETSI][1][56] = 127,
[2][1][2][0][RTW89_ETSI][0][56] = 127,
[2][1][2][0][RTW89_MKK][1][56] = 127,
[2][1][2][0][RTW89_MKK][0][56] = 127,
[2][1][2][0][RTW89_IC][1][56] = 20,
- [2][1][2][0][RTW89_IC][2][56] = 56,
[2][1][2][0][RTW89_KCC][1][56] = 38,
[2][1][2][0][RTW89_KCC][0][56] = 127,
[2][1][2][0][RTW89_ACMA][1][56] = 127,
@@ -46781,13 +45413,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][56] = 127,
[2][1][2][0][RTW89_THAILAND][0][56] = 127,
[2][1][2][0][RTW89_FCC][1][63] = 22,
- [2][1][2][0][RTW89_FCC][2][63] = 58,
[2][1][2][0][RTW89_ETSI][1][63] = 127,
[2][1][2][0][RTW89_ETSI][0][63] = 127,
[2][1][2][0][RTW89_MKK][1][63] = 127,
[2][1][2][0][RTW89_MKK][0][63] = 127,
[2][1][2][0][RTW89_IC][1][63] = 22,
- [2][1][2][0][RTW89_IC][2][63] = 58,
[2][1][2][0][RTW89_KCC][1][63] = 38,
[2][1][2][0][RTW89_KCC][0][63] = 127,
[2][1][2][0][RTW89_ACMA][1][63] = 127,
@@ -46800,13 +45430,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][63] = 127,
[2][1][2][0][RTW89_THAILAND][0][63] = 127,
[2][1][2][0][RTW89_FCC][1][71] = 20,
- [2][1][2][0][RTW89_FCC][2][71] = 58,
[2][1][2][0][RTW89_ETSI][1][71] = 127,
[2][1][2][0][RTW89_ETSI][0][71] = 127,
[2][1][2][0][RTW89_MKK][1][71] = 127,
[2][1][2][0][RTW89_MKK][0][71] = 127,
[2][1][2][0][RTW89_IC][1][71] = 20,
- [2][1][2][0][RTW89_IC][2][71] = 58,
[2][1][2][0][RTW89_KCC][1][71] = 38,
[2][1][2][0][RTW89_KCC][0][71] = 127,
[2][1][2][0][RTW89_ACMA][1][71] = 127,
@@ -46819,13 +45447,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][71] = 127,
[2][1][2][0][RTW89_THAILAND][0][71] = 127,
[2][1][2][0][RTW89_FCC][1][78] = 20,
- [2][1][2][0][RTW89_FCC][2][78] = 58,
[2][1][2][0][RTW89_ETSI][1][78] = 127,
[2][1][2][0][RTW89_ETSI][0][78] = 127,
[2][1][2][0][RTW89_MKK][1][78] = 127,
[2][1][2][0][RTW89_MKK][0][78] = 127,
[2][1][2][0][RTW89_IC][1][78] = 20,
- [2][1][2][0][RTW89_IC][2][78] = 58,
[2][1][2][0][RTW89_KCC][1][78] = 38,
[2][1][2][0][RTW89_KCC][0][78] = 127,
[2][1][2][0][RTW89_ACMA][1][78] = 127,
@@ -46838,13 +45464,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][78] = 127,
[2][1][2][0][RTW89_THAILAND][0][78] = 127,
[2][1][2][0][RTW89_FCC][1][86] = 20,
- [2][1][2][0][RTW89_FCC][2][86] = 127,
[2][1][2][0][RTW89_ETSI][1][86] = 127,
[2][1][2][0][RTW89_ETSI][0][86] = 127,
[2][1][2][0][RTW89_MKK][1][86] = 127,
[2][1][2][0][RTW89_MKK][0][86] = 127,
[2][1][2][0][RTW89_IC][1][86] = 20,
- [2][1][2][0][RTW89_IC][2][86] = 127,
[2][1][2][0][RTW89_KCC][1][86] = 38,
[2][1][2][0][RTW89_KCC][0][86] = 127,
[2][1][2][0][RTW89_ACMA][1][86] = 127,
@@ -46857,13 +45481,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][86] = 127,
[2][1][2][0][RTW89_THAILAND][0][86] = 127,
[2][1][2][0][RTW89_FCC][1][93] = 22,
- [2][1][2][0][RTW89_FCC][2][93] = 127,
[2][1][2][0][RTW89_ETSI][1][93] = 127,
[2][1][2][0][RTW89_ETSI][0][93] = 127,
[2][1][2][0][RTW89_MKK][1][93] = 127,
[2][1][2][0][RTW89_MKK][0][93] = 127,
[2][1][2][0][RTW89_IC][1][93] = 22,
- [2][1][2][0][RTW89_IC][2][93] = 127,
[2][1][2][0][RTW89_KCC][1][93] = 38,
[2][1][2][0][RTW89_KCC][0][93] = 127,
[2][1][2][0][RTW89_ACMA][1][93] = 127,
@@ -46876,13 +45498,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][93] = 127,
[2][1][2][0][RTW89_THAILAND][0][93] = 127,
[2][1][2][0][RTW89_FCC][1][101] = 22,
- [2][1][2][0][RTW89_FCC][2][101] = 127,
[2][1][2][0][RTW89_ETSI][1][101] = 127,
[2][1][2][0][RTW89_ETSI][0][101] = 127,
[2][1][2][0][RTW89_MKK][1][101] = 127,
[2][1][2][0][RTW89_MKK][0][101] = 127,
[2][1][2][0][RTW89_IC][1][101] = 22,
- [2][1][2][0][RTW89_IC][2][101] = 127,
[2][1][2][0][RTW89_KCC][1][101] = 38,
[2][1][2][0][RTW89_KCC][0][101] = 127,
[2][1][2][0][RTW89_ACMA][1][101] = 127,
@@ -46895,13 +45515,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][101] = 127,
[2][1][2][0][RTW89_THAILAND][0][101] = 127,
[2][1][2][0][RTW89_FCC][1][108] = 127,
- [2][1][2][0][RTW89_FCC][2][108] = 127,
[2][1][2][0][RTW89_ETSI][1][108] = 127,
[2][1][2][0][RTW89_ETSI][0][108] = 127,
[2][1][2][0][RTW89_MKK][1][108] = 127,
[2][1][2][0][RTW89_MKK][0][108] = 127,
[2][1][2][0][RTW89_IC][1][108] = 127,
- [2][1][2][0][RTW89_IC][2][108] = 127,
[2][1][2][0][RTW89_KCC][1][108] = 127,
[2][1][2][0][RTW89_KCC][0][108] = 127,
[2][1][2][0][RTW89_ACMA][1][108] = 127,
@@ -46914,13 +45532,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][108] = 127,
[2][1][2][0][RTW89_THAILAND][0][108] = 127,
[2][1][2][0][RTW89_FCC][1][116] = 127,
- [2][1][2][0][RTW89_FCC][2][116] = 127,
[2][1][2][0][RTW89_ETSI][1][116] = 127,
[2][1][2][0][RTW89_ETSI][0][116] = 127,
[2][1][2][0][RTW89_MKK][1][116] = 127,
[2][1][2][0][RTW89_MKK][0][116] = 127,
[2][1][2][0][RTW89_IC][1][116] = 127,
- [2][1][2][0][RTW89_IC][2][116] = 127,
[2][1][2][0][RTW89_KCC][1][116] = 127,
[2][1][2][0][RTW89_KCC][0][116] = 127,
[2][1][2][0][RTW89_ACMA][1][116] = 127,
@@ -46933,13 +45549,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][0][RTW89_THAILAND][1][116] = 127,
[2][1][2][0][RTW89_THAILAND][0][116] = 127,
[2][1][2][1][RTW89_FCC][1][3] = 22,
- [2][1][2][1][RTW89_FCC][2][3] = 50,
[2][1][2][1][RTW89_ETSI][1][3] = 42,
[2][1][2][1][RTW89_ETSI][0][3] = 6,
[2][1][2][1][RTW89_MKK][1][3] = 52,
[2][1][2][1][RTW89_MKK][0][3] = 14,
[2][1][2][1][RTW89_IC][1][3] = 22,
- [2][1][2][1][RTW89_IC][2][3] = 50,
[2][1][2][1][RTW89_KCC][1][3] = 38,
[2][1][2][1][RTW89_KCC][0][3] = 12,
[2][1][2][1][RTW89_ACMA][1][3] = 42,
@@ -46952,13 +45566,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][3] = 46,
[2][1][2][1][RTW89_THAILAND][0][3] = 6,
[2][1][2][1][RTW89_FCC][1][11] = 20,
- [2][1][2][1][RTW89_FCC][2][11] = 50,
[2][1][2][1][RTW89_ETSI][1][11] = 42,
[2][1][2][1][RTW89_ETSI][0][11] = 6,
[2][1][2][1][RTW89_MKK][1][11] = 52,
[2][1][2][1][RTW89_MKK][0][11] = 12,
[2][1][2][1][RTW89_IC][1][11] = 20,
- [2][1][2][1][RTW89_IC][2][11] = 50,
[2][1][2][1][RTW89_KCC][1][11] = 38,
[2][1][2][1][RTW89_KCC][0][11] = 12,
[2][1][2][1][RTW89_ACMA][1][11] = 42,
@@ -46971,13 +45583,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][11] = 46,
[2][1][2][1][RTW89_THAILAND][0][11] = 6,
[2][1][2][1][RTW89_FCC][1][18] = 20,
- [2][1][2][1][RTW89_FCC][2][18] = 50,
[2][1][2][1][RTW89_ETSI][1][18] = 42,
[2][1][2][1][RTW89_ETSI][0][18] = 6,
[2][1][2][1][RTW89_MKK][1][18] = 52,
[2][1][2][1][RTW89_MKK][0][18] = 12,
[2][1][2][1][RTW89_IC][1][18] = 20,
- [2][1][2][1][RTW89_IC][2][18] = 50,
[2][1][2][1][RTW89_KCC][1][18] = 38,
[2][1][2][1][RTW89_KCC][0][18] = 12,
[2][1][2][1][RTW89_ACMA][1][18] = 42,
@@ -46990,13 +45600,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][18] = 46,
[2][1][2][1][RTW89_THAILAND][0][18] = 6,
[2][1][2][1][RTW89_FCC][1][26] = 20,
- [2][1][2][1][RTW89_FCC][2][26] = 60,
[2][1][2][1][RTW89_ETSI][1][26] = 42,
[2][1][2][1][RTW89_ETSI][0][26] = 6,
[2][1][2][1][RTW89_MKK][1][26] = 52,
[2][1][2][1][RTW89_MKK][0][26] = 12,
[2][1][2][1][RTW89_IC][1][26] = 20,
- [2][1][2][1][RTW89_IC][2][26] = 60,
[2][1][2][1][RTW89_KCC][1][26] = 38,
[2][1][2][1][RTW89_KCC][0][26] = 12,
[2][1][2][1][RTW89_ACMA][1][26] = 42,
@@ -47009,13 +45617,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][26] = 46,
[2][1][2][1][RTW89_THAILAND][0][26] = 6,
[2][1][2][1][RTW89_FCC][1][33] = 20,
- [2][1][2][1][RTW89_FCC][2][33] = 60,
[2][1][2][1][RTW89_ETSI][1][33] = 42,
[2][1][2][1][RTW89_ETSI][0][33] = 6,
[2][1][2][1][RTW89_MKK][1][33] = 48,
[2][1][2][1][RTW89_MKK][0][33] = 12,
[2][1][2][1][RTW89_IC][1][33] = 20,
- [2][1][2][1][RTW89_IC][2][33] = 60,
[2][1][2][1][RTW89_KCC][1][33] = 38,
[2][1][2][1][RTW89_KCC][0][33] = 12,
[2][1][2][1][RTW89_ACMA][1][33] = 42,
@@ -47028,13 +45634,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][33] = 46,
[2][1][2][1][RTW89_THAILAND][0][33] = 6,
[2][1][2][1][RTW89_FCC][1][41] = 22,
- [2][1][2][1][RTW89_FCC][2][41] = 60,
[2][1][2][1][RTW89_ETSI][1][41] = 42,
[2][1][2][1][RTW89_ETSI][0][41] = 6,
[2][1][2][1][RTW89_MKK][1][41] = 48,
[2][1][2][1][RTW89_MKK][0][41] = 12,
[2][1][2][1][RTW89_IC][1][41] = 22,
- [2][1][2][1][RTW89_IC][2][41] = 60,
[2][1][2][1][RTW89_KCC][1][41] = 38,
[2][1][2][1][RTW89_KCC][0][41] = 12,
[2][1][2][1][RTW89_ACMA][1][41] = 42,
@@ -47047,13 +45651,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][41] = 46,
[2][1][2][1][RTW89_THAILAND][0][41] = 6,
[2][1][2][1][RTW89_FCC][1][48] = 22,
- [2][1][2][1][RTW89_FCC][2][48] = 127,
[2][1][2][1][RTW89_ETSI][1][48] = 127,
[2][1][2][1][RTW89_ETSI][0][48] = 127,
[2][1][2][1][RTW89_MKK][1][48] = 127,
[2][1][2][1][RTW89_MKK][0][48] = 127,
[2][1][2][1][RTW89_IC][1][48] = 22,
- [2][1][2][1][RTW89_IC][2][48] = 60,
[2][1][2][1][RTW89_KCC][1][48] = 38,
[2][1][2][1][RTW89_KCC][0][48] = 127,
[2][1][2][1][RTW89_ACMA][1][48] = 127,
@@ -47066,13 +45668,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][48] = 127,
[2][1][2][1][RTW89_THAILAND][0][48] = 127,
[2][1][2][1][RTW89_FCC][1][56] = 20,
- [2][1][2][1][RTW89_FCC][2][56] = 127,
[2][1][2][1][RTW89_ETSI][1][56] = 127,
[2][1][2][1][RTW89_ETSI][0][56] = 127,
[2][1][2][1][RTW89_MKK][1][56] = 127,
[2][1][2][1][RTW89_MKK][0][56] = 127,
[2][1][2][1][RTW89_IC][1][56] = 20,
- [2][1][2][1][RTW89_IC][2][56] = 56,
[2][1][2][1][RTW89_KCC][1][56] = 38,
[2][1][2][1][RTW89_KCC][0][56] = 127,
[2][1][2][1][RTW89_ACMA][1][56] = 127,
@@ -47085,13 +45685,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][56] = 127,
[2][1][2][1][RTW89_THAILAND][0][56] = 127,
[2][1][2][1][RTW89_FCC][1][63] = 22,
- [2][1][2][1][RTW89_FCC][2][63] = 58,
[2][1][2][1][RTW89_ETSI][1][63] = 127,
[2][1][2][1][RTW89_ETSI][0][63] = 127,
[2][1][2][1][RTW89_MKK][1][63] = 127,
[2][1][2][1][RTW89_MKK][0][63] = 127,
[2][1][2][1][RTW89_IC][1][63] = 22,
- [2][1][2][1][RTW89_IC][2][63] = 58,
[2][1][2][1][RTW89_KCC][1][63] = 38,
[2][1][2][1][RTW89_KCC][0][63] = 127,
[2][1][2][1][RTW89_ACMA][1][63] = 127,
@@ -47104,13 +45702,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][63] = 127,
[2][1][2][1][RTW89_THAILAND][0][63] = 127,
[2][1][2][1][RTW89_FCC][1][71] = 20,
- [2][1][2][1][RTW89_FCC][2][71] = 58,
[2][1][2][1][RTW89_ETSI][1][71] = 127,
[2][1][2][1][RTW89_ETSI][0][71] = 127,
[2][1][2][1][RTW89_MKK][1][71] = 127,
[2][1][2][1][RTW89_MKK][0][71] = 127,
[2][1][2][1][RTW89_IC][1][71] = 20,
- [2][1][2][1][RTW89_IC][2][71] = 58,
[2][1][2][1][RTW89_KCC][1][71] = 38,
[2][1][2][1][RTW89_KCC][0][71] = 127,
[2][1][2][1][RTW89_ACMA][1][71] = 127,
@@ -47123,13 +45719,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][71] = 127,
[2][1][2][1][RTW89_THAILAND][0][71] = 127,
[2][1][2][1][RTW89_FCC][1][78] = 20,
- [2][1][2][1][RTW89_FCC][2][78] = 58,
[2][1][2][1][RTW89_ETSI][1][78] = 127,
[2][1][2][1][RTW89_ETSI][0][78] = 127,
[2][1][2][1][RTW89_MKK][1][78] = 127,
[2][1][2][1][RTW89_MKK][0][78] = 127,
[2][1][2][1][RTW89_IC][1][78] = 20,
- [2][1][2][1][RTW89_IC][2][78] = 58,
[2][1][2][1][RTW89_KCC][1][78] = 38,
[2][1][2][1][RTW89_KCC][0][78] = 127,
[2][1][2][1][RTW89_ACMA][1][78] = 127,
@@ -47142,13 +45736,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][78] = 127,
[2][1][2][1][RTW89_THAILAND][0][78] = 127,
[2][1][2][1][RTW89_FCC][1][86] = 20,
- [2][1][2][1][RTW89_FCC][2][86] = 127,
[2][1][2][1][RTW89_ETSI][1][86] = 127,
[2][1][2][1][RTW89_ETSI][0][86] = 127,
[2][1][2][1][RTW89_MKK][1][86] = 127,
[2][1][2][1][RTW89_MKK][0][86] = 127,
[2][1][2][1][RTW89_IC][1][86] = 20,
- [2][1][2][1][RTW89_IC][2][86] = 127,
[2][1][2][1][RTW89_KCC][1][86] = 38,
[2][1][2][1][RTW89_KCC][0][86] = 127,
[2][1][2][1][RTW89_ACMA][1][86] = 127,
@@ -47161,13 +45753,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][86] = 127,
[2][1][2][1][RTW89_THAILAND][0][86] = 127,
[2][1][2][1][RTW89_FCC][1][93] = 22,
- [2][1][2][1][RTW89_FCC][2][93] = 127,
[2][1][2][1][RTW89_ETSI][1][93] = 127,
[2][1][2][1][RTW89_ETSI][0][93] = 127,
[2][1][2][1][RTW89_MKK][1][93] = 127,
[2][1][2][1][RTW89_MKK][0][93] = 127,
[2][1][2][1][RTW89_IC][1][93] = 22,
- [2][1][2][1][RTW89_IC][2][93] = 127,
[2][1][2][1][RTW89_KCC][1][93] = 38,
[2][1][2][1][RTW89_KCC][0][93] = 127,
[2][1][2][1][RTW89_ACMA][1][93] = 127,
@@ -47180,13 +45770,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][93] = 127,
[2][1][2][1][RTW89_THAILAND][0][93] = 127,
[2][1][2][1][RTW89_FCC][1][101] = 22,
- [2][1][2][1][RTW89_FCC][2][101] = 127,
[2][1][2][1][RTW89_ETSI][1][101] = 127,
[2][1][2][1][RTW89_ETSI][0][101] = 127,
[2][1][2][1][RTW89_MKK][1][101] = 127,
[2][1][2][1][RTW89_MKK][0][101] = 127,
[2][1][2][1][RTW89_IC][1][101] = 22,
- [2][1][2][1][RTW89_IC][2][101] = 127,
[2][1][2][1][RTW89_KCC][1][101] = 38,
[2][1][2][1][RTW89_KCC][0][101] = 127,
[2][1][2][1][RTW89_ACMA][1][101] = 127,
@@ -47199,13 +45787,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][101] = 127,
[2][1][2][1][RTW89_THAILAND][0][101] = 127,
[2][1][2][1][RTW89_FCC][1][108] = 127,
- [2][1][2][1][RTW89_FCC][2][108] = 127,
[2][1][2][1][RTW89_ETSI][1][108] = 127,
[2][1][2][1][RTW89_ETSI][0][108] = 127,
[2][1][2][1][RTW89_MKK][1][108] = 127,
[2][1][2][1][RTW89_MKK][0][108] = 127,
[2][1][2][1][RTW89_IC][1][108] = 127,
- [2][1][2][1][RTW89_IC][2][108] = 127,
[2][1][2][1][RTW89_KCC][1][108] = 127,
[2][1][2][1][RTW89_KCC][0][108] = 127,
[2][1][2][1][RTW89_ACMA][1][108] = 127,
@@ -47218,13 +45804,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][108] = 127,
[2][1][2][1][RTW89_THAILAND][0][108] = 127,
[2][1][2][1][RTW89_FCC][1][116] = 127,
- [2][1][2][1][RTW89_FCC][2][116] = 127,
[2][1][2][1][RTW89_ETSI][1][116] = 127,
[2][1][2][1][RTW89_ETSI][0][116] = 127,
[2][1][2][1][RTW89_MKK][1][116] = 127,
[2][1][2][1][RTW89_MKK][0][116] = 127,
[2][1][2][1][RTW89_IC][1][116] = 127,
- [2][1][2][1][RTW89_IC][2][116] = 127,
[2][1][2][1][RTW89_KCC][1][116] = 127,
[2][1][2][1][RTW89_KCC][0][116] = 127,
[2][1][2][1][RTW89_ACMA][1][116] = 127,
@@ -47237,13 +45821,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[2][1][2][1][RTW89_THAILAND][1][116] = 127,
[2][1][2][1][RTW89_THAILAND][0][116] = 127,
[3][0][2][0][RTW89_FCC][1][7] = 52,
- [3][0][2][0][RTW89_FCC][2][7] = 52,
[3][0][2][0][RTW89_ETSI][1][7] = 50,
[3][0][2][0][RTW89_ETSI][0][7] = 30,
[3][0][2][0][RTW89_MKK][1][7] = 50,
[3][0][2][0][RTW89_MKK][0][7] = 22,
[3][0][2][0][RTW89_IC][1][7] = 52,
- [3][0][2][0][RTW89_IC][2][7] = 52,
[3][0][2][0][RTW89_KCC][1][7] = 42,
[3][0][2][0][RTW89_KCC][0][7] = 24,
[3][0][2][0][RTW89_ACMA][1][7] = 50,
@@ -47256,13 +45838,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][0][2][0][RTW89_THAILAND][1][7] = 50,
[3][0][2][0][RTW89_THAILAND][0][7] = 30,
[3][0][2][0][RTW89_FCC][1][22] = 52,
- [3][0][2][0][RTW89_FCC][2][22] = 52,
[3][0][2][0][RTW89_ETSI][1][22] = 50,
[3][0][2][0][RTW89_ETSI][0][22] = 30,
[3][0][2][0][RTW89_MKK][1][22] = 50,
[3][0][2][0][RTW89_MKK][0][22] = 20,
[3][0][2][0][RTW89_IC][1][22] = 52,
- [3][0][2][0][RTW89_IC][2][22] = 52,
[3][0][2][0][RTW89_KCC][1][22] = 42,
[3][0][2][0][RTW89_KCC][0][22] = 24,
[3][0][2][0][RTW89_ACMA][1][22] = 50,
@@ -47275,13 +45855,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][0][2][0][RTW89_THAILAND][1][22] = 50,
[3][0][2][0][RTW89_THAILAND][0][22] = 30,
[3][0][2][0][RTW89_FCC][1][37] = 52,
- [3][0][2][0][RTW89_FCC][2][37] = 52,
[3][0][2][0][RTW89_ETSI][1][37] = 50,
[3][0][2][0][RTW89_ETSI][0][37] = 30,
[3][0][2][0][RTW89_MKK][1][37] = 50,
[3][0][2][0][RTW89_MKK][0][37] = 20,
[3][0][2][0][RTW89_IC][1][37] = 52,
- [3][0][2][0][RTW89_IC][2][37] = 52,
[3][0][2][0][RTW89_KCC][1][37] = 42,
[3][0][2][0][RTW89_KCC][0][37] = 24,
[3][0][2][0][RTW89_ACMA][1][37] = 50,
@@ -47294,13 +45872,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][0][2][0][RTW89_THAILAND][1][37] = 50,
[3][0][2][0][RTW89_THAILAND][0][37] = 30,
[3][0][2][0][RTW89_FCC][1][52] = 54,
- [3][0][2][0][RTW89_FCC][2][52] = 127,
[3][0][2][0][RTW89_ETSI][1][52] = 127,
[3][0][2][0][RTW89_ETSI][0][52] = 127,
[3][0][2][0][RTW89_MKK][1][52] = 127,
[3][0][2][0][RTW89_MKK][0][52] = 127,
[3][0][2][0][RTW89_IC][1][52] = 54,
- [3][0][2][0][RTW89_IC][2][52] = 56,
[3][0][2][0][RTW89_KCC][1][52] = 56,
[3][0][2][0][RTW89_KCC][0][52] = 127,
[3][0][2][0][RTW89_ACMA][1][52] = 127,
@@ -47313,13 +45889,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][0][2][0][RTW89_THAILAND][1][52] = 127,
[3][0][2][0][RTW89_THAILAND][0][52] = 127,
[3][0][2][0][RTW89_FCC][1][67] = 54,
- [3][0][2][0][RTW89_FCC][2][67] = 54,
[3][0][2][0][RTW89_ETSI][1][67] = 127,
[3][0][2][0][RTW89_ETSI][0][67] = 127,
[3][0][2][0][RTW89_MKK][1][67] = 127,
[3][0][2][0][RTW89_MKK][0][67] = 127,
[3][0][2][0][RTW89_IC][1][67] = 54,
- [3][0][2][0][RTW89_IC][2][67] = 54,
[3][0][2][0][RTW89_KCC][1][67] = 54,
[3][0][2][0][RTW89_KCC][0][67] = 127,
[3][0][2][0][RTW89_ACMA][1][67] = 127,
@@ -47332,13 +45906,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][0][2][0][RTW89_THAILAND][1][67] = 127,
[3][0][2][0][RTW89_THAILAND][0][67] = 127,
[3][0][2][0][RTW89_FCC][1][82] = 46,
- [3][0][2][0][RTW89_FCC][2][82] = 127,
[3][0][2][0][RTW89_ETSI][1][82] = 127,
[3][0][2][0][RTW89_ETSI][0][82] = 127,
[3][0][2][0][RTW89_MKK][1][82] = 127,
[3][0][2][0][RTW89_MKK][0][82] = 127,
[3][0][2][0][RTW89_IC][1][82] = 46,
- [3][0][2][0][RTW89_IC][2][82] = 127,
[3][0][2][0][RTW89_KCC][1][82] = 26,
[3][0][2][0][RTW89_KCC][0][82] = 127,
[3][0][2][0][RTW89_ACMA][1][82] = 127,
@@ -47351,13 +45923,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][0][2][0][RTW89_THAILAND][1][82] = 127,
[3][0][2][0][RTW89_THAILAND][0][82] = 127,
[3][0][2][0][RTW89_FCC][1][97] = 40,
- [3][0][2][0][RTW89_FCC][2][97] = 127,
[3][0][2][0][RTW89_ETSI][1][97] = 127,
[3][0][2][0][RTW89_ETSI][0][97] = 127,
[3][0][2][0][RTW89_MKK][1][97] = 127,
[3][0][2][0][RTW89_MKK][0][97] = 127,
[3][0][2][0][RTW89_IC][1][97] = 40,
- [3][0][2][0][RTW89_IC][2][97] = 127,
[3][0][2][0][RTW89_KCC][1][97] = 26,
[3][0][2][0][RTW89_KCC][0][97] = 127,
[3][0][2][0][RTW89_ACMA][1][97] = 127,
@@ -47370,13 +45940,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][0][2][0][RTW89_THAILAND][1][97] = 127,
[3][0][2][0][RTW89_THAILAND][0][97] = 127,
[3][0][2][0][RTW89_FCC][1][112] = 127,
- [3][0][2][0][RTW89_FCC][2][112] = 127,
[3][0][2][0][RTW89_ETSI][1][112] = 127,
[3][0][2][0][RTW89_ETSI][0][112] = 127,
[3][0][2][0][RTW89_MKK][1][112] = 127,
[3][0][2][0][RTW89_MKK][0][112] = 127,
[3][0][2][0][RTW89_IC][1][112] = 127,
- [3][0][2][0][RTW89_IC][2][112] = 127,
[3][0][2][0][RTW89_KCC][1][112] = 127,
[3][0][2][0][RTW89_KCC][0][112] = 127,
[3][0][2][0][RTW89_ACMA][1][112] = 127,
@@ -47389,13 +45957,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][0][2][0][RTW89_THAILAND][1][112] = 127,
[3][0][2][0][RTW89_THAILAND][0][112] = 127,
[3][1][2][0][RTW89_FCC][1][7] = 32,
- [3][1][2][0][RTW89_FCC][2][7] = 46,
[3][1][2][0][RTW89_ETSI][1][7] = 50,
[3][1][2][0][RTW89_ETSI][0][7] = 18,
[3][1][2][0][RTW89_MKK][1][7] = 38,
[3][1][2][0][RTW89_MKK][0][7] = 10,
[3][1][2][0][RTW89_IC][1][7] = 32,
- [3][1][2][0][RTW89_IC][2][7] = 46,
[3][1][2][0][RTW89_KCC][1][7] = 40,
[3][1][2][0][RTW89_KCC][0][7] = 12,
[3][1][2][0][RTW89_ACMA][1][7] = 50,
@@ -47408,13 +45974,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][0][RTW89_THAILAND][1][7] = 46,
[3][1][2][0][RTW89_THAILAND][0][7] = 18,
[3][1][2][0][RTW89_FCC][1][22] = 30,
- [3][1][2][0][RTW89_FCC][2][22] = 52,
[3][1][2][0][RTW89_ETSI][1][22] = 46,
[3][1][2][0][RTW89_ETSI][0][22] = 16,
[3][1][2][0][RTW89_MKK][1][22] = 48,
[3][1][2][0][RTW89_MKK][0][22] = 8,
[3][1][2][0][RTW89_IC][1][22] = 30,
- [3][1][2][0][RTW89_IC][2][22] = 52,
[3][1][2][0][RTW89_KCC][1][22] = 40,
[3][1][2][0][RTW89_KCC][0][22] = 12,
[3][1][2][0][RTW89_ACMA][1][22] = 46,
@@ -47427,13 +45991,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][0][RTW89_THAILAND][1][22] = 46,
[3][1][2][0][RTW89_THAILAND][0][22] = 18,
[3][1][2][0][RTW89_FCC][1][37] = 30,
- [3][1][2][0][RTW89_FCC][2][37] = 52,
[3][1][2][0][RTW89_ETSI][1][37] = 46,
[3][1][2][0][RTW89_ETSI][0][37] = 16,
[3][1][2][0][RTW89_MKK][1][37] = 48,
[3][1][2][0][RTW89_MKK][0][37] = 8,
[3][1][2][0][RTW89_IC][1][37] = 30,
- [3][1][2][0][RTW89_IC][2][37] = 52,
[3][1][2][0][RTW89_KCC][1][37] = 40,
[3][1][2][0][RTW89_KCC][0][37] = 12,
[3][1][2][0][RTW89_ACMA][1][37] = 46,
@@ -47446,13 +46008,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][0][RTW89_THAILAND][1][37] = 46,
[3][1][2][0][RTW89_THAILAND][0][37] = 18,
[3][1][2][0][RTW89_FCC][1][52] = 30,
- [3][1][2][0][RTW89_FCC][2][52] = 127,
[3][1][2][0][RTW89_ETSI][1][52] = 127,
[3][1][2][0][RTW89_ETSI][0][52] = 127,
[3][1][2][0][RTW89_MKK][1][52] = 127,
[3][1][2][0][RTW89_MKK][0][52] = 127,
[3][1][2][0][RTW89_IC][1][52] = 30,
- [3][1][2][0][RTW89_IC][2][52] = 56,
[3][1][2][0][RTW89_KCC][1][52] = 48,
[3][1][2][0][RTW89_KCC][0][52] = 127,
[3][1][2][0][RTW89_ACMA][1][52] = 127,
@@ -47465,13 +46025,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][0][RTW89_THAILAND][1][52] = 127,
[3][1][2][0][RTW89_THAILAND][0][52] = 127,
[3][1][2][0][RTW89_FCC][1][67] = 32,
- [3][1][2][0][RTW89_FCC][2][67] = 54,
[3][1][2][0][RTW89_ETSI][1][67] = 127,
[3][1][2][0][RTW89_ETSI][0][67] = 127,
[3][1][2][0][RTW89_MKK][1][67] = 127,
[3][1][2][0][RTW89_MKK][0][67] = 127,
[3][1][2][0][RTW89_IC][1][67] = 32,
- [3][1][2][0][RTW89_IC][2][67] = 54,
[3][1][2][0][RTW89_KCC][1][67] = 48,
[3][1][2][0][RTW89_KCC][0][67] = 127,
[3][1][2][0][RTW89_ACMA][1][67] = 127,
@@ -47484,13 +46042,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][0][RTW89_THAILAND][1][67] = 127,
[3][1][2][0][RTW89_THAILAND][0][67] = 127,
[3][1][2][0][RTW89_FCC][1][82] = 32,
- [3][1][2][0][RTW89_FCC][2][82] = 127,
[3][1][2][0][RTW89_ETSI][1][82] = 127,
[3][1][2][0][RTW89_ETSI][0][82] = 127,
[3][1][2][0][RTW89_MKK][1][82] = 127,
[3][1][2][0][RTW89_MKK][0][82] = 127,
[3][1][2][0][RTW89_IC][1][82] = 32,
- [3][1][2][0][RTW89_IC][2][82] = 127,
[3][1][2][0][RTW89_KCC][1][82] = 24,
[3][1][2][0][RTW89_KCC][0][82] = 127,
[3][1][2][0][RTW89_ACMA][1][82] = 127,
@@ -47503,13 +46059,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][0][RTW89_THAILAND][1][82] = 127,
[3][1][2][0][RTW89_THAILAND][0][82] = 127,
[3][1][2][0][RTW89_FCC][1][97] = 32,
- [3][1][2][0][RTW89_FCC][2][97] = 127,
[3][1][2][0][RTW89_ETSI][1][97] = 127,
[3][1][2][0][RTW89_ETSI][0][97] = 127,
[3][1][2][0][RTW89_MKK][1][97] = 127,
[3][1][2][0][RTW89_MKK][0][97] = 127,
[3][1][2][0][RTW89_IC][1][97] = 32,
- [3][1][2][0][RTW89_IC][2][97] = 127,
[3][1][2][0][RTW89_KCC][1][97] = 24,
[3][1][2][0][RTW89_KCC][0][97] = 127,
[3][1][2][0][RTW89_ACMA][1][97] = 127,
@@ -47522,13 +46076,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][0][RTW89_THAILAND][1][97] = 127,
[3][1][2][0][RTW89_THAILAND][0][97] = 127,
[3][1][2][0][RTW89_FCC][1][112] = 127,
- [3][1][2][0][RTW89_FCC][2][112] = 127,
[3][1][2][0][RTW89_ETSI][1][112] = 127,
[3][1][2][0][RTW89_ETSI][0][112] = 127,
[3][1][2][0][RTW89_MKK][1][112] = 127,
[3][1][2][0][RTW89_MKK][0][112] = 127,
[3][1][2][0][RTW89_IC][1][112] = 127,
- [3][1][2][0][RTW89_IC][2][112] = 127,
[3][1][2][0][RTW89_KCC][1][112] = 127,
[3][1][2][0][RTW89_KCC][0][112] = 127,
[3][1][2][0][RTW89_ACMA][1][112] = 127,
@@ -47541,13 +46093,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][0][RTW89_THAILAND][1][112] = 127,
[3][1][2][0][RTW89_THAILAND][0][112] = 127,
[3][1][2][1][RTW89_FCC][1][7] = 32,
- [3][1][2][1][RTW89_FCC][2][7] = 46,
[3][1][2][1][RTW89_ETSI][1][7] = 42,
[3][1][2][1][RTW89_ETSI][0][7] = 6,
[3][1][2][1][RTW89_MKK][1][7] = 38,
[3][1][2][1][RTW89_MKK][0][7] = 10,
[3][1][2][1][RTW89_IC][1][7] = 32,
- [3][1][2][1][RTW89_IC][2][7] = 46,
[3][1][2][1][RTW89_KCC][1][7] = 40,
[3][1][2][1][RTW89_KCC][0][7] = 12,
[3][1][2][1][RTW89_ACMA][1][7] = 42,
@@ -47560,13 +46110,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][1][RTW89_THAILAND][1][7] = 46,
[3][1][2][1][RTW89_THAILAND][0][7] = 6,
[3][1][2][1][RTW89_FCC][1][22] = 30,
- [3][1][2][1][RTW89_FCC][2][22] = 52,
[3][1][2][1][RTW89_ETSI][1][22] = 42,
[3][1][2][1][RTW89_ETSI][0][22] = 6,
[3][1][2][1][RTW89_MKK][1][22] = 48,
[3][1][2][1][RTW89_MKK][0][22] = 8,
[3][1][2][1][RTW89_IC][1][22] = 30,
- [3][1][2][1][RTW89_IC][2][22] = 52,
[3][1][2][1][RTW89_KCC][1][22] = 40,
[3][1][2][1][RTW89_KCC][0][22] = 12,
[3][1][2][1][RTW89_ACMA][1][22] = 42,
@@ -47579,13 +46127,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][1][RTW89_THAILAND][1][22] = 46,
[3][1][2][1][RTW89_THAILAND][0][22] = 6,
[3][1][2][1][RTW89_FCC][1][37] = 30,
- [3][1][2][1][RTW89_FCC][2][37] = 52,
[3][1][2][1][RTW89_ETSI][1][37] = 42,
[3][1][2][1][RTW89_ETSI][0][37] = 6,
[3][1][2][1][RTW89_MKK][1][37] = 48,
[3][1][2][1][RTW89_MKK][0][37] = 8,
[3][1][2][1][RTW89_IC][1][37] = 30,
- [3][1][2][1][RTW89_IC][2][37] = 52,
[3][1][2][1][RTW89_KCC][1][37] = 40,
[3][1][2][1][RTW89_KCC][0][37] = 12,
[3][1][2][1][RTW89_ACMA][1][37] = 42,
@@ -47598,13 +46144,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][1][RTW89_THAILAND][1][37] = 46,
[3][1][2][1][RTW89_THAILAND][0][37] = 6,
[3][1][2][1][RTW89_FCC][1][52] = 30,
- [3][1][2][1][RTW89_FCC][2][52] = 127,
[3][1][2][1][RTW89_ETSI][1][52] = 127,
[3][1][2][1][RTW89_ETSI][0][52] = 127,
[3][1][2][1][RTW89_MKK][1][52] = 127,
[3][1][2][1][RTW89_MKK][0][52] = 127,
[3][1][2][1][RTW89_IC][1][52] = 30,
- [3][1][2][1][RTW89_IC][2][52] = 56,
[3][1][2][1][RTW89_KCC][1][52] = 48,
[3][1][2][1][RTW89_KCC][0][52] = 127,
[3][1][2][1][RTW89_ACMA][1][52] = 127,
@@ -47617,13 +46161,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][1][RTW89_THAILAND][1][52] = 127,
[3][1][2][1][RTW89_THAILAND][0][52] = 127,
[3][1][2][1][RTW89_FCC][1][67] = 32,
- [3][1][2][1][RTW89_FCC][2][67] = 54,
[3][1][2][1][RTW89_ETSI][1][67] = 127,
[3][1][2][1][RTW89_ETSI][0][67] = 127,
[3][1][2][1][RTW89_MKK][1][67] = 127,
[3][1][2][1][RTW89_MKK][0][67] = 127,
[3][1][2][1][RTW89_IC][1][67] = 32,
- [3][1][2][1][RTW89_IC][2][67] = 54,
[3][1][2][1][RTW89_KCC][1][67] = 48,
[3][1][2][1][RTW89_KCC][0][67] = 127,
[3][1][2][1][RTW89_ACMA][1][67] = 127,
@@ -47636,13 +46178,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][1][RTW89_THAILAND][1][67] = 127,
[3][1][2][1][RTW89_THAILAND][0][67] = 127,
[3][1][2][1][RTW89_FCC][1][82] = 32,
- [3][1][2][1][RTW89_FCC][2][82] = 127,
[3][1][2][1][RTW89_ETSI][1][82] = 127,
[3][1][2][1][RTW89_ETSI][0][82] = 127,
[3][1][2][1][RTW89_MKK][1][82] = 127,
[3][1][2][1][RTW89_MKK][0][82] = 127,
[3][1][2][1][RTW89_IC][1][82] = 32,
- [3][1][2][1][RTW89_IC][2][82] = 127,
[3][1][2][1][RTW89_KCC][1][82] = 24,
[3][1][2][1][RTW89_KCC][0][82] = 127,
[3][1][2][1][RTW89_ACMA][1][82] = 127,
@@ -47655,13 +46195,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][1][RTW89_THAILAND][1][82] = 127,
[3][1][2][1][RTW89_THAILAND][0][82] = 127,
[3][1][2][1][RTW89_FCC][1][97] = 32,
- [3][1][2][1][RTW89_FCC][2][97] = 127,
[3][1][2][1][RTW89_ETSI][1][97] = 127,
[3][1][2][1][RTW89_ETSI][0][97] = 127,
[3][1][2][1][RTW89_MKK][1][97] = 127,
[3][1][2][1][RTW89_MKK][0][97] = 127,
[3][1][2][1][RTW89_IC][1][97] = 32,
- [3][1][2][1][RTW89_IC][2][97] = 127,
[3][1][2][1][RTW89_KCC][1][97] = 24,
[3][1][2][1][RTW89_KCC][0][97] = 127,
[3][1][2][1][RTW89_ACMA][1][97] = 127,
@@ -47674,13 +46212,11 @@ const s8 rtw89_8852c_txpwr_lmt_6g[RTW89_6G_BW_NUM][RTW89_NTX_NUM]
[3][1][2][1][RTW89_THAILAND][1][97] = 127,
[3][1][2][1][RTW89_THAILAND][0][97] = 127,
[3][1][2][1][RTW89_FCC][1][112] = 127,
- [3][1][2][1][RTW89_FCC][2][112] = 127,
[3][1][2][1][RTW89_ETSI][1][112] = 127,
[3][1][2][1][RTW89_ETSI][0][112] = 127,
[3][1][2][1][RTW89_MKK][1][112] = 127,
[3][1][2][1][RTW89_MKK][0][112] = 127,
[3][1][2][1][RTW89_IC][1][112] = 127,
- [3][1][2][1][RTW89_IC][2][112] = 127,
[3][1][2][1][RTW89_KCC][1][112] = 127,
[3][1][2][1][RTW89_KCC][0][112] = 127,
[3][1][2][1][RTW89_ACMA][1][112] = 127,
@@ -49374,7 +47910,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_FCC][48] = 46,
[0][0][RTW89_ETSI][48] = 127,
[0][0][RTW89_MKK][48] = 127,
- [0][0][RTW89_IC][48] = 127,
+ [0][0][RTW89_IC][48] = 46,
[0][0][RTW89_KCC][48] = 127,
[0][0][RTW89_ACMA][48] = 127,
[0][0][RTW89_CN][48] = 127,
@@ -49387,7 +47923,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_FCC][50] = 44,
[0][0][RTW89_ETSI][50] = 127,
[0][0][RTW89_MKK][50] = 127,
- [0][0][RTW89_IC][50] = 127,
+ [0][0][RTW89_IC][50] = 44,
[0][0][RTW89_KCC][50] = 127,
[0][0][RTW89_ACMA][50] = 127,
[0][0][RTW89_CN][50] = 127,
@@ -49400,7 +47936,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_FCC][52] = 34,
[0][0][RTW89_ETSI][52] = 127,
[0][0][RTW89_MKK][52] = 127,
- [0][0][RTW89_IC][52] = 127,
+ [0][0][RTW89_IC][52] = 34,
[0][0][RTW89_KCC][52] = 127,
[0][0][RTW89_ACMA][52] = 127,
[0][0][RTW89_CN][52] = 127,
@@ -49738,7 +48274,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_FCC][48] = 20,
[0][1][RTW89_ETSI][48] = 127,
[0][1][RTW89_MKK][48] = 127,
- [0][1][RTW89_IC][48] = 127,
+ [0][1][RTW89_IC][48] = 20,
[0][1][RTW89_KCC][48] = 127,
[0][1][RTW89_ACMA][48] = 127,
[0][1][RTW89_CN][48] = 127,
@@ -49751,7 +48287,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_FCC][50] = 20,
[0][1][RTW89_ETSI][50] = 127,
[0][1][RTW89_MKK][50] = 127,
- [0][1][RTW89_IC][50] = 127,
+ [0][1][RTW89_IC][50] = 20,
[0][1][RTW89_KCC][50] = 127,
[0][1][RTW89_ACMA][50] = 127,
[0][1][RTW89_CN][50] = 127,
@@ -49764,7 +48300,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_FCC][52] = 8,
[0][1][RTW89_ETSI][52] = 127,
[0][1][RTW89_MKK][52] = 127,
- [0][1][RTW89_IC][52] = 127,
+ [0][1][RTW89_IC][52] = 8,
[0][1][RTW89_KCC][52] = 127,
[0][1][RTW89_ACMA][52] = 127,
[0][1][RTW89_CN][52] = 127,
@@ -50102,7 +48638,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_FCC][48] = 56,
[1][0][RTW89_ETSI][48] = 127,
[1][0][RTW89_MKK][48] = 127,
- [1][0][RTW89_IC][48] = 127,
+ [1][0][RTW89_IC][48] = 56,
[1][0][RTW89_KCC][48] = 127,
[1][0][RTW89_ACMA][48] = 127,
[1][0][RTW89_CN][48] = 127,
@@ -50115,7 +48651,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_FCC][50] = 58,
[1][0][RTW89_ETSI][50] = 127,
[1][0][RTW89_MKK][50] = 127,
- [1][0][RTW89_IC][50] = 127,
+ [1][0][RTW89_IC][50] = 58,
[1][0][RTW89_KCC][50] = 127,
[1][0][RTW89_ACMA][50] = 127,
[1][0][RTW89_CN][50] = 127,
@@ -50128,7 +48664,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_FCC][52] = 56,
[1][0][RTW89_ETSI][52] = 127,
[1][0][RTW89_MKK][52] = 127,
- [1][0][RTW89_IC][52] = 127,
+ [1][0][RTW89_IC][52] = 56,
[1][0][RTW89_KCC][52] = 127,
[1][0][RTW89_ACMA][52] = 127,
[1][0][RTW89_CN][52] = 127,
@@ -50466,7 +49002,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_FCC][48] = 34,
[1][1][RTW89_ETSI][48] = 127,
[1][1][RTW89_MKK][48] = 127,
- [1][1][RTW89_IC][48] = 127,
+ [1][1][RTW89_IC][48] = 34,
[1][1][RTW89_KCC][48] = 127,
[1][1][RTW89_ACMA][48] = 127,
[1][1][RTW89_CN][48] = 127,
@@ -50479,7 +49015,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_FCC][50] = 34,
[1][1][RTW89_ETSI][50] = 127,
[1][1][RTW89_MKK][50] = 127,
- [1][1][RTW89_IC][50] = 127,
+ [1][1][RTW89_IC][50] = 34,
[1][1][RTW89_KCC][50] = 127,
[1][1][RTW89_ACMA][50] = 127,
[1][1][RTW89_CN][50] = 127,
@@ -50492,7 +49028,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_FCC][52] = 30,
[1][1][RTW89_ETSI][52] = 127,
[1][1][RTW89_MKK][52] = 127,
- [1][1][RTW89_IC][52] = 127,
+ [1][1][RTW89_IC][52] = 30,
[1][1][RTW89_KCC][52] = 127,
[1][1][RTW89_ACMA][52] = 127,
[1][1][RTW89_CN][52] = 127,
@@ -50830,7 +49366,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_FCC][48] = 64,
[2][0][RTW89_ETSI][48] = 127,
[2][0][RTW89_MKK][48] = 127,
- [2][0][RTW89_IC][48] = 127,
+ [2][0][RTW89_IC][48] = 64,
[2][0][RTW89_KCC][48] = 127,
[2][0][RTW89_ACMA][48] = 127,
[2][0][RTW89_CN][48] = 127,
@@ -50843,7 +49379,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_FCC][50] = 64,
[2][0][RTW89_ETSI][50] = 127,
[2][0][RTW89_MKK][50] = 127,
- [2][0][RTW89_IC][50] = 127,
+ [2][0][RTW89_IC][50] = 64,
[2][0][RTW89_KCC][50] = 127,
[2][0][RTW89_ACMA][50] = 127,
[2][0][RTW89_CN][50] = 127,
@@ -50856,7 +49392,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_FCC][52] = 64,
[2][0][RTW89_ETSI][52] = 127,
[2][0][RTW89_MKK][52] = 127,
- [2][0][RTW89_IC][52] = 127,
+ [2][0][RTW89_IC][52] = 64,
[2][0][RTW89_KCC][52] = 127,
[2][0][RTW89_ACMA][52] = 127,
[2][0][RTW89_CN][52] = 127,
@@ -51194,7 +49730,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_FCC][48] = 40,
[2][1][RTW89_ETSI][48] = 127,
[2][1][RTW89_MKK][48] = 127,
- [2][1][RTW89_IC][48] = 127,
+ [2][1][RTW89_IC][48] = 40,
[2][1][RTW89_KCC][48] = 127,
[2][1][RTW89_ACMA][48] = 127,
[2][1][RTW89_CN][48] = 127,
@@ -51207,7 +49743,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_FCC][50] = 40,
[2][1][RTW89_ETSI][50] = 127,
[2][1][RTW89_MKK][50] = 127,
- [2][1][RTW89_IC][50] = 127,
+ [2][1][RTW89_IC][50] = 40,
[2][1][RTW89_KCC][50] = 127,
[2][1][RTW89_ACMA][50] = 127,
[2][1][RTW89_CN][50] = 127,
@@ -51220,7 +49756,7 @@ const s8 rtw89_8852c_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_FCC][52] = 40,
[2][1][RTW89_ETSI][52] = 127,
[2][1][RTW89_MKK][52] = 127,
- [2][1][RTW89_IC][52] = 127,
+ [2][1][RTW89_IC][52] = 40,
[2][1][RTW89_KCC][52] = 127,
[2][1][RTW89_ACMA][52] = 127,
[2][1][RTW89_CN][52] = 127,
@@ -51238,1164 +49774,778 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[RTW89_6G_CH_NUM] = {
[0][0][RTW89_WW][0][0] = -16,
[0][0][RTW89_WW][1][0] = -16,
- [0][0][RTW89_WW][2][0] = 44,
[0][0][RTW89_WW][0][2] = -18,
[0][0][RTW89_WW][1][2] = -18,
- [0][0][RTW89_WW][2][2] = 44,
[0][0][RTW89_WW][0][4] = -18,
[0][0][RTW89_WW][1][4] = -18,
- [0][0][RTW89_WW][2][4] = 44,
[0][0][RTW89_WW][0][6] = -18,
[0][0][RTW89_WW][1][6] = -18,
- [0][0][RTW89_WW][2][6] = 44,
[0][0][RTW89_WW][0][8] = -18,
[0][0][RTW89_WW][1][8] = -18,
- [0][0][RTW89_WW][2][8] = 44,
[0][0][RTW89_WW][0][10] = -18,
[0][0][RTW89_WW][1][10] = -18,
- [0][0][RTW89_WW][2][10] = 44,
[0][0][RTW89_WW][0][12] = -18,
[0][0][RTW89_WW][1][12] = -18,
- [0][0][RTW89_WW][2][12] = 44,
[0][0][RTW89_WW][0][14] = -18,
[0][0][RTW89_WW][1][14] = -18,
- [0][0][RTW89_WW][2][14] = 44,
[0][0][RTW89_WW][0][15] = -18,
[0][0][RTW89_WW][1][15] = -18,
- [0][0][RTW89_WW][2][15] = 44,
[0][0][RTW89_WW][0][17] = -18,
[0][0][RTW89_WW][1][17] = -18,
- [0][0][RTW89_WW][2][17] = 44,
[0][0][RTW89_WW][0][19] = -18,
[0][0][RTW89_WW][1][19] = -18,
- [0][0][RTW89_WW][2][19] = 44,
[0][0][RTW89_WW][0][21] = -18,
[0][0][RTW89_WW][1][21] = -18,
- [0][0][RTW89_WW][2][21] = 44,
[0][0][RTW89_WW][0][23] = -18,
[0][0][RTW89_WW][1][23] = -18,
- [0][0][RTW89_WW][2][23] = 54,
[0][0][RTW89_WW][0][25] = -18,
[0][0][RTW89_WW][1][25] = -18,
- [0][0][RTW89_WW][2][25] = 54,
[0][0][RTW89_WW][0][27] = -18,
[0][0][RTW89_WW][1][27] = -18,
- [0][0][RTW89_WW][2][27] = 54,
[0][0][RTW89_WW][0][29] = -18,
[0][0][RTW89_WW][1][29] = -18,
- [0][0][RTW89_WW][2][29] = 54,
[0][0][RTW89_WW][0][30] = -18,
[0][0][RTW89_WW][1][30] = -18,
- [0][0][RTW89_WW][2][30] = 54,
[0][0][RTW89_WW][0][32] = -18,
[0][0][RTW89_WW][1][32] = -18,
- [0][0][RTW89_WW][2][32] = 54,
[0][0][RTW89_WW][0][34] = -18,
[0][0][RTW89_WW][1][34] = -18,
- [0][0][RTW89_WW][2][34] = 54,
[0][0][RTW89_WW][0][36] = -18,
[0][0][RTW89_WW][1][36] = -18,
- [0][0][RTW89_WW][2][36] = 54,
[0][0][RTW89_WW][0][38] = -18,
[0][0][RTW89_WW][1][38] = -18,
- [0][0][RTW89_WW][2][38] = 54,
[0][0][RTW89_WW][0][40] = -18,
[0][0][RTW89_WW][1][40] = -18,
- [0][0][RTW89_WW][2][40] = 54,
[0][0][RTW89_WW][0][42] = -18,
[0][0][RTW89_WW][1][42] = -18,
- [0][0][RTW89_WW][2][42] = 54,
[0][0][RTW89_WW][0][44] = -16,
[0][0][RTW89_WW][1][44] = -16,
- [0][0][RTW89_WW][2][44] = 56,
[0][0][RTW89_WW][0][45] = -16,
[0][0][RTW89_WW][1][45] = -16,
- [0][0][RTW89_WW][2][45] = 56,
[0][0][RTW89_WW][0][47] = -18,
[0][0][RTW89_WW][1][47] = -18,
- [0][0][RTW89_WW][2][47] = 56,
[0][0][RTW89_WW][0][49] = -18,
[0][0][RTW89_WW][1][49] = -18,
- [0][0][RTW89_WW][2][49] = 56,
[0][0][RTW89_WW][0][51] = -18,
[0][0][RTW89_WW][1][51] = -18,
- [0][0][RTW89_WW][2][51] = 56,
[0][0][RTW89_WW][0][53] = -16,
[0][0][RTW89_WW][1][53] = -16,
- [0][0][RTW89_WW][2][53] = 56,
[0][0][RTW89_WW][0][55] = -18,
[0][0][RTW89_WW][1][55] = -18,
- [0][0][RTW89_WW][2][55] = 56,
[0][0][RTW89_WW][0][57] = -18,
[0][0][RTW89_WW][1][57] = -18,
- [0][0][RTW89_WW][2][57] = 56,
[0][0][RTW89_WW][0][59] = -18,
[0][0][RTW89_WW][1][59] = -18,
- [0][0][RTW89_WW][2][59] = 56,
[0][0][RTW89_WW][0][60] = -18,
[0][0][RTW89_WW][1][60] = -18,
- [0][0][RTW89_WW][2][60] = 56,
[0][0][RTW89_WW][0][62] = -18,
[0][0][RTW89_WW][1][62] = -18,
- [0][0][RTW89_WW][2][62] = 56,
[0][0][RTW89_WW][0][64] = -18,
[0][0][RTW89_WW][1][64] = -18,
- [0][0][RTW89_WW][2][64] = 56,
[0][0][RTW89_WW][0][66] = -18,
[0][0][RTW89_WW][1][66] = -18,
- [0][0][RTW89_WW][2][66] = 56,
[0][0][RTW89_WW][0][68] = -18,
[0][0][RTW89_WW][1][68] = -18,
- [0][0][RTW89_WW][2][68] = 56,
[0][0][RTW89_WW][0][70] = -16,
[0][0][RTW89_WW][1][70] = -16,
- [0][0][RTW89_WW][2][70] = 56,
[0][0][RTW89_WW][0][72] = -18,
[0][0][RTW89_WW][1][72] = -18,
- [0][0][RTW89_WW][2][72] = 56,
[0][0][RTW89_WW][0][74] = -18,
[0][0][RTW89_WW][1][74] = -18,
- [0][0][RTW89_WW][2][74] = 56,
[0][0][RTW89_WW][0][75] = -18,
[0][0][RTW89_WW][1][75] = -18,
- [0][0][RTW89_WW][2][75] = 56,
[0][0][RTW89_WW][0][77] = -18,
[0][0][RTW89_WW][1][77] = -18,
- [0][0][RTW89_WW][2][77] = 56,
[0][0][RTW89_WW][0][79] = -18,
[0][0][RTW89_WW][1][79] = -18,
- [0][0][RTW89_WW][2][79] = 56,
[0][0][RTW89_WW][0][81] = -18,
[0][0][RTW89_WW][1][81] = -18,
- [0][0][RTW89_WW][2][81] = 56,
[0][0][RTW89_WW][0][83] = -18,
[0][0][RTW89_WW][1][83] = -18,
- [0][0][RTW89_WW][2][83] = 56,
[0][0][RTW89_WW][0][85] = -18,
[0][0][RTW89_WW][1][85] = -18,
- [0][0][RTW89_WW][2][85] = 56,
[0][0][RTW89_WW][0][87] = -16,
[0][0][RTW89_WW][1][87] = -16,
- [0][0][RTW89_WW][2][87] = 0,
[0][0][RTW89_WW][0][89] = -16,
[0][0][RTW89_WW][1][89] = -16,
- [0][0][RTW89_WW][2][89] = 0,
[0][0][RTW89_WW][0][90] = -16,
[0][0][RTW89_WW][1][90] = -16,
- [0][0][RTW89_WW][2][90] = 0,
[0][0][RTW89_WW][0][92] = -16,
[0][0][RTW89_WW][1][92] = -16,
- [0][0][RTW89_WW][2][92] = 0,
[0][0][RTW89_WW][0][94] = -16,
[0][0][RTW89_WW][1][94] = -16,
- [0][0][RTW89_WW][2][94] = 0,
[0][0][RTW89_WW][0][96] = -16,
[0][0][RTW89_WW][1][96] = -16,
- [0][0][RTW89_WW][2][96] = 0,
[0][0][RTW89_WW][0][98] = -16,
[0][0][RTW89_WW][1][98] = -16,
- [0][0][RTW89_WW][2][98] = 0,
[0][0][RTW89_WW][0][100] = -16,
[0][0][RTW89_WW][1][100] = -16,
- [0][0][RTW89_WW][2][100] = 0,
[0][0][RTW89_WW][0][102] = -16,
[0][0][RTW89_WW][1][102] = -16,
- [0][0][RTW89_WW][2][102] = 0,
[0][0][RTW89_WW][0][104] = -16,
[0][0][RTW89_WW][1][104] = -16,
- [0][0][RTW89_WW][2][104] = 0,
[0][0][RTW89_WW][0][105] = -16,
[0][0][RTW89_WW][1][105] = -16,
- [0][0][RTW89_WW][2][105] = 0,
[0][0][RTW89_WW][0][107] = -12,
[0][0][RTW89_WW][1][107] = -12,
- [0][0][RTW89_WW][2][107] = 0,
[0][0][RTW89_WW][0][109] = -12,
[0][0][RTW89_WW][1][109] = -12,
- [0][0][RTW89_WW][2][109] = 0,
[0][0][RTW89_WW][0][111] = 0,
[0][0][RTW89_WW][1][111] = 0,
- [0][0][RTW89_WW][2][111] = 0,
[0][0][RTW89_WW][0][113] = 0,
[0][0][RTW89_WW][1][113] = 0,
- [0][0][RTW89_WW][2][113] = 0,
[0][0][RTW89_WW][0][115] = 0,
[0][0][RTW89_WW][1][115] = 0,
- [0][0][RTW89_WW][2][115] = 0,
[0][0][RTW89_WW][0][117] = 0,
[0][0][RTW89_WW][1][117] = 0,
- [0][0][RTW89_WW][2][117] = 0,
[0][0][RTW89_WW][0][119] = 0,
[0][0][RTW89_WW][1][119] = 0,
- [0][0][RTW89_WW][2][119] = 0,
[0][1][RTW89_WW][0][0] = -40,
[0][1][RTW89_WW][1][0] = -40,
- [0][1][RTW89_WW][2][0] = 32,
[0][1][RTW89_WW][0][2] = -40,
[0][1][RTW89_WW][1][2] = -40,
- [0][1][RTW89_WW][2][2] = 32,
[0][1][RTW89_WW][0][4] = -40,
[0][1][RTW89_WW][1][4] = -40,
- [0][1][RTW89_WW][2][4] = 32,
[0][1][RTW89_WW][0][6] = -40,
[0][1][RTW89_WW][1][6] = -40,
- [0][1][RTW89_WW][2][6] = 32,
[0][1][RTW89_WW][0][8] = -40,
[0][1][RTW89_WW][1][8] = -40,
- [0][1][RTW89_WW][2][8] = 32,
[0][1][RTW89_WW][0][10] = -40,
[0][1][RTW89_WW][1][10] = -40,
- [0][1][RTW89_WW][2][10] = 32,
[0][1][RTW89_WW][0][12] = -40,
[0][1][RTW89_WW][1][12] = -40,
- [0][1][RTW89_WW][2][12] = 32,
[0][1][RTW89_WW][0][14] = -40,
[0][1][RTW89_WW][1][14] = -40,
- [0][1][RTW89_WW][2][14] = 32,
[0][1][RTW89_WW][0][15] = -40,
[0][1][RTW89_WW][1][15] = -40,
- [0][1][RTW89_WW][2][15] = 32,
[0][1][RTW89_WW][0][17] = -40,
[0][1][RTW89_WW][1][17] = -40,
- [0][1][RTW89_WW][2][17] = 32,
[0][1][RTW89_WW][0][19] = -40,
[0][1][RTW89_WW][1][19] = -40,
- [0][1][RTW89_WW][2][19] = 32,
[0][1][RTW89_WW][0][21] = -40,
[0][1][RTW89_WW][1][21] = -40,
- [0][1][RTW89_WW][2][21] = 32,
[0][1][RTW89_WW][0][23] = -40,
[0][1][RTW89_WW][1][23] = -40,
- [0][1][RTW89_WW][2][23] = 32,
[0][1][RTW89_WW][0][25] = -40,
[0][1][RTW89_WW][1][25] = -40,
- [0][1][RTW89_WW][2][25] = 32,
[0][1][RTW89_WW][0][27] = -40,
[0][1][RTW89_WW][1][27] = -40,
- [0][1][RTW89_WW][2][27] = 32,
[0][1][RTW89_WW][0][29] = -40,
[0][1][RTW89_WW][1][29] = -40,
- [0][1][RTW89_WW][2][29] = 32,
[0][1][RTW89_WW][0][30] = -40,
[0][1][RTW89_WW][1][30] = -40,
- [0][1][RTW89_WW][2][30] = 32,
[0][1][RTW89_WW][0][32] = -40,
[0][1][RTW89_WW][1][32] = -40,
- [0][1][RTW89_WW][2][32] = 32,
[0][1][RTW89_WW][0][34] = -40,
[0][1][RTW89_WW][1][34] = -40,
- [0][1][RTW89_WW][2][34] = 32,
[0][1][RTW89_WW][0][36] = -40,
[0][1][RTW89_WW][1][36] = -40,
- [0][1][RTW89_WW][2][36] = 32,
[0][1][RTW89_WW][0][38] = -40,
[0][1][RTW89_WW][1][38] = -40,
- [0][1][RTW89_WW][2][38] = 32,
[0][1][RTW89_WW][0][40] = -40,
[0][1][RTW89_WW][1][40] = -40,
- [0][1][RTW89_WW][2][40] = 32,
[0][1][RTW89_WW][0][42] = -40,
[0][1][RTW89_WW][1][42] = -40,
- [0][1][RTW89_WW][2][42] = 32,
[0][1][RTW89_WW][0][44] = -40,
[0][1][RTW89_WW][1][44] = -40,
- [0][1][RTW89_WW][2][44] = 32,
[0][1][RTW89_WW][0][45] = -40,
[0][1][RTW89_WW][1][45] = -40,
- [0][1][RTW89_WW][2][45] = 32,
[0][1][RTW89_WW][0][47] = -40,
[0][1][RTW89_WW][1][47] = -40,
- [0][1][RTW89_WW][2][47] = 32,
[0][1][RTW89_WW][0][49] = -40,
[0][1][RTW89_WW][1][49] = -40,
- [0][1][RTW89_WW][2][49] = 32,
[0][1][RTW89_WW][0][51] = -40,
[0][1][RTW89_WW][1][51] = -40,
- [0][1][RTW89_WW][2][51] = 32,
[0][1][RTW89_WW][0][53] = -40,
[0][1][RTW89_WW][1][53] = -40,
- [0][1][RTW89_WW][2][53] = 32,
[0][1][RTW89_WW][0][55] = -40,
[0][1][RTW89_WW][1][55] = -40,
- [0][1][RTW89_WW][2][55] = 30,
[0][1][RTW89_WW][0][57] = -40,
[0][1][RTW89_WW][1][57] = -40,
- [0][1][RTW89_WW][2][57] = 30,
[0][1][RTW89_WW][0][59] = -40,
[0][1][RTW89_WW][1][59] = -40,
- [0][1][RTW89_WW][2][59] = 30,
[0][1][RTW89_WW][0][60] = -40,
[0][1][RTW89_WW][1][60] = -40,
- [0][1][RTW89_WW][2][60] = 30,
[0][1][RTW89_WW][0][62] = -40,
[0][1][RTW89_WW][1][62] = -40,
- [0][1][RTW89_WW][2][62] = 30,
[0][1][RTW89_WW][0][64] = -40,
[0][1][RTW89_WW][1][64] = -40,
- [0][1][RTW89_WW][2][64] = 30,
[0][1][RTW89_WW][0][66] = -40,
[0][1][RTW89_WW][1][66] = -40,
- [0][1][RTW89_WW][2][66] = 30,
[0][1][RTW89_WW][0][68] = -40,
[0][1][RTW89_WW][1][68] = -40,
- [0][1][RTW89_WW][2][68] = 30,
[0][1][RTW89_WW][0][70] = -38,
[0][1][RTW89_WW][1][70] = -38,
- [0][1][RTW89_WW][2][70] = 30,
[0][1][RTW89_WW][0][72] = -38,
[0][1][RTW89_WW][1][72] = -38,
- [0][1][RTW89_WW][2][72] = 30,
[0][1][RTW89_WW][0][74] = -38,
[0][1][RTW89_WW][1][74] = -38,
- [0][1][RTW89_WW][2][74] = 30,
[0][1][RTW89_WW][0][75] = -38,
[0][1][RTW89_WW][1][75] = -38,
- [0][1][RTW89_WW][2][75] = 30,
[0][1][RTW89_WW][0][77] = -38,
[0][1][RTW89_WW][1][77] = -38,
- [0][1][RTW89_WW][2][77] = 30,
[0][1][RTW89_WW][0][79] = -38,
[0][1][RTW89_WW][1][79] = -38,
- [0][1][RTW89_WW][2][79] = 30,
[0][1][RTW89_WW][0][81] = -38,
[0][1][RTW89_WW][1][81] = -38,
- [0][1][RTW89_WW][2][81] = 30,
[0][1][RTW89_WW][0][83] = -38,
[0][1][RTW89_WW][1][83] = -38,
- [0][1][RTW89_WW][2][83] = 30,
[0][1][RTW89_WW][0][85] = -38,
[0][1][RTW89_WW][1][85] = -38,
- [0][1][RTW89_WW][2][85] = 30,
[0][1][RTW89_WW][0][87] = -40,
[0][1][RTW89_WW][1][87] = -40,
- [0][1][RTW89_WW][2][87] = 0,
[0][1][RTW89_WW][0][89] = -38,
[0][1][RTW89_WW][1][89] = -38,
- [0][1][RTW89_WW][2][89] = 0,
[0][1][RTW89_WW][0][90] = -38,
[0][1][RTW89_WW][1][90] = -38,
- [0][1][RTW89_WW][2][90] = 0,
[0][1][RTW89_WW][0][92] = -38,
[0][1][RTW89_WW][1][92] = -38,
- [0][1][RTW89_WW][2][92] = 0,
[0][1][RTW89_WW][0][94] = -38,
[0][1][RTW89_WW][1][94] = -38,
- [0][1][RTW89_WW][2][94] = 0,
[0][1][RTW89_WW][0][96] = -38,
[0][1][RTW89_WW][1][96] = -38,
- [0][1][RTW89_WW][2][96] = 0,
[0][1][RTW89_WW][0][98] = -38,
[0][1][RTW89_WW][1][98] = -38,
- [0][1][RTW89_WW][2][98] = 0,
[0][1][RTW89_WW][0][100] = -38,
[0][1][RTW89_WW][1][100] = -38,
- [0][1][RTW89_WW][2][100] = 0,
[0][1][RTW89_WW][0][102] = -38,
[0][1][RTW89_WW][1][102] = -38,
- [0][1][RTW89_WW][2][102] = 0,
[0][1][RTW89_WW][0][104] = -38,
[0][1][RTW89_WW][1][104] = -38,
- [0][1][RTW89_WW][2][104] = 0,
[0][1][RTW89_WW][0][105] = -38,
[0][1][RTW89_WW][1][105] = -38,
- [0][1][RTW89_WW][2][105] = 0,
[0][1][RTW89_WW][0][107] = -34,
[0][1][RTW89_WW][1][107] = -34,
- [0][1][RTW89_WW][2][107] = 0,
[0][1][RTW89_WW][0][109] = -34,
[0][1][RTW89_WW][1][109] = -34,
- [0][1][RTW89_WW][2][109] = 0,
[0][1][RTW89_WW][0][111] = 0,
[0][1][RTW89_WW][1][111] = 0,
- [0][1][RTW89_WW][2][111] = 0,
[0][1][RTW89_WW][0][113] = 0,
[0][1][RTW89_WW][1][113] = 0,
- [0][1][RTW89_WW][2][113] = 0,
[0][1][RTW89_WW][0][115] = 0,
[0][1][RTW89_WW][1][115] = 0,
- [0][1][RTW89_WW][2][115] = 0,
[0][1][RTW89_WW][0][117] = 0,
[0][1][RTW89_WW][1][117] = 0,
- [0][1][RTW89_WW][2][117] = 0,
[0][1][RTW89_WW][0][119] = 0,
[0][1][RTW89_WW][1][119] = 0,
- [0][1][RTW89_WW][2][119] = 0,
[1][0][RTW89_WW][0][0] = -4,
[1][0][RTW89_WW][1][0] = -4,
- [1][0][RTW89_WW][2][0] = 52,
[1][0][RTW89_WW][0][2] = -4,
[1][0][RTW89_WW][1][2] = -4,
- [1][0][RTW89_WW][2][2] = 52,
[1][0][RTW89_WW][0][4] = -4,
[1][0][RTW89_WW][1][4] = -4,
- [1][0][RTW89_WW][2][4] = 52,
[1][0][RTW89_WW][0][6] = -4,
[1][0][RTW89_WW][1][6] = -4,
- [1][0][RTW89_WW][2][6] = 52,
[1][0][RTW89_WW][0][8] = -4,
[1][0][RTW89_WW][1][8] = -4,
- [1][0][RTW89_WW][2][8] = 52,
[1][0][RTW89_WW][0][10] = -4,
[1][0][RTW89_WW][1][10] = -4,
- [1][0][RTW89_WW][2][10] = 52,
[1][0][RTW89_WW][0][12] = -4,
[1][0][RTW89_WW][1][12] = -4,
- [1][0][RTW89_WW][2][12] = 52,
[1][0][RTW89_WW][0][14] = -4,
[1][0][RTW89_WW][1][14] = -4,
- [1][0][RTW89_WW][2][14] = 52,
[1][0][RTW89_WW][0][15] = -4,
[1][0][RTW89_WW][1][15] = -4,
- [1][0][RTW89_WW][2][15] = 52,
[1][0][RTW89_WW][0][17] = -4,
[1][0][RTW89_WW][1][17] = -4,
- [1][0][RTW89_WW][2][17] = 52,
[1][0][RTW89_WW][0][19] = -4,
[1][0][RTW89_WW][1][19] = -4,
- [1][0][RTW89_WW][2][19] = 52,
[1][0][RTW89_WW][0][21] = -4,
[1][0][RTW89_WW][1][21] = -4,
- [1][0][RTW89_WW][2][21] = 52,
[1][0][RTW89_WW][0][23] = -4,
[1][0][RTW89_WW][1][23] = -4,
- [1][0][RTW89_WW][2][23] = 66,
[1][0][RTW89_WW][0][25] = -4,
[1][0][RTW89_WW][1][25] = -4,
- [1][0][RTW89_WW][2][25] = 66,
[1][0][RTW89_WW][0][27] = -4,
[1][0][RTW89_WW][1][27] = -4,
- [1][0][RTW89_WW][2][27] = 66,
[1][0][RTW89_WW][0][29] = -4,
[1][0][RTW89_WW][1][29] = -4,
- [1][0][RTW89_WW][2][29] = 66,
[1][0][RTW89_WW][0][30] = -4,
[1][0][RTW89_WW][1][30] = -4,
- [1][0][RTW89_WW][2][30] = 66,
[1][0][RTW89_WW][0][32] = -4,
[1][0][RTW89_WW][1][32] = -4,
- [1][0][RTW89_WW][2][32] = 66,
[1][0][RTW89_WW][0][34] = -4,
[1][0][RTW89_WW][1][34] = -4,
- [1][0][RTW89_WW][2][34] = 66,
[1][0][RTW89_WW][0][36] = -4,
[1][0][RTW89_WW][1][36] = -4,
- [1][0][RTW89_WW][2][36] = 66,
[1][0][RTW89_WW][0][38] = -4,
[1][0][RTW89_WW][1][38] = -4,
- [1][0][RTW89_WW][2][38] = 66,
[1][0][RTW89_WW][0][40] = -4,
[1][0][RTW89_WW][1][40] = -4,
- [1][0][RTW89_WW][2][40] = 66,
[1][0][RTW89_WW][0][42] = -4,
[1][0][RTW89_WW][1][42] = -4,
- [1][0][RTW89_WW][2][42] = 66,
[1][0][RTW89_WW][0][44] = -4,
[1][0][RTW89_WW][1][44] = -4,
- [1][0][RTW89_WW][2][44] = 66,
[1][0][RTW89_WW][0][45] = -4,
[1][0][RTW89_WW][1][45] = -4,
- [1][0][RTW89_WW][2][45] = 68,
[1][0][RTW89_WW][0][47] = -4,
[1][0][RTW89_WW][1][47] = -4,
- [1][0][RTW89_WW][2][47] = 68,
[1][0][RTW89_WW][0][49] = -4,
[1][0][RTW89_WW][1][49] = -4,
- [1][0][RTW89_WW][2][49] = 68,
[1][0][RTW89_WW][0][51] = -4,
[1][0][RTW89_WW][1][51] = -4,
- [1][0][RTW89_WW][2][51] = 68,
[1][0][RTW89_WW][0][53] = -4,
[1][0][RTW89_WW][1][53] = -4,
- [1][0][RTW89_WW][2][53] = 68,
[1][0][RTW89_WW][0][55] = -4,
[1][0][RTW89_WW][1][55] = -4,
- [1][0][RTW89_WW][2][55] = 68,
[1][0][RTW89_WW][0][57] = -4,
[1][0][RTW89_WW][1][57] = -4,
- [1][0][RTW89_WW][2][57] = 68,
[1][0][RTW89_WW][0][59] = -4,
[1][0][RTW89_WW][1][59] = -4,
- [1][0][RTW89_WW][2][59] = 68,
[1][0][RTW89_WW][0][60] = -4,
[1][0][RTW89_WW][1][60] = -4,
- [1][0][RTW89_WW][2][60] = 68,
[1][0][RTW89_WW][0][62] = -4,
[1][0][RTW89_WW][1][62] = -4,
- [1][0][RTW89_WW][2][62] = 68,
[1][0][RTW89_WW][0][64] = -4,
[1][0][RTW89_WW][1][64] = -4,
- [1][0][RTW89_WW][2][64] = 68,
[1][0][RTW89_WW][0][66] = -4,
[1][0][RTW89_WW][1][66] = -4,
- [1][0][RTW89_WW][2][66] = 68,
[1][0][RTW89_WW][0][68] = -4,
[1][0][RTW89_WW][1][68] = -4,
- [1][0][RTW89_WW][2][68] = 68,
[1][0][RTW89_WW][0][70] = -4,
[1][0][RTW89_WW][1][70] = -4,
- [1][0][RTW89_WW][2][70] = 68,
[1][0][RTW89_WW][0][72] = -4,
[1][0][RTW89_WW][1][72] = -4,
- [1][0][RTW89_WW][2][72] = 68,
[1][0][RTW89_WW][0][74] = -4,
[1][0][RTW89_WW][1][74] = -4,
- [1][0][RTW89_WW][2][74] = 68,
[1][0][RTW89_WW][0][75] = -4,
[1][0][RTW89_WW][1][75] = -4,
- [1][0][RTW89_WW][2][75] = 68,
[1][0][RTW89_WW][0][77] = -4,
[1][0][RTW89_WW][1][77] = -4,
- [1][0][RTW89_WW][2][77] = 68,
[1][0][RTW89_WW][0][79] = -4,
[1][0][RTW89_WW][1][79] = -4,
- [1][0][RTW89_WW][2][79] = 68,
[1][0][RTW89_WW][0][81] = -4,
[1][0][RTW89_WW][1][81] = -4,
- [1][0][RTW89_WW][2][81] = 68,
[1][0][RTW89_WW][0][83] = -4,
[1][0][RTW89_WW][1][83] = -4,
- [1][0][RTW89_WW][2][83] = 68,
[1][0][RTW89_WW][0][85] = -4,
[1][0][RTW89_WW][1][85] = -4,
- [1][0][RTW89_WW][2][85] = 68,
[1][0][RTW89_WW][0][87] = -4,
[1][0][RTW89_WW][1][87] = -4,
- [1][0][RTW89_WW][2][87] = 0,
[1][0][RTW89_WW][0][89] = -4,
[1][0][RTW89_WW][1][89] = -4,
- [1][0][RTW89_WW][2][89] = 0,
[1][0][RTW89_WW][0][90] = -4,
[1][0][RTW89_WW][1][90] = -4,
- [1][0][RTW89_WW][2][90] = 0,
[1][0][RTW89_WW][0][92] = -4,
[1][0][RTW89_WW][1][92] = -4,
- [1][0][RTW89_WW][2][92] = 0,
[1][0][RTW89_WW][0][94] = -4,
[1][0][RTW89_WW][1][94] = -4,
- [1][0][RTW89_WW][2][94] = 0,
[1][0][RTW89_WW][0][96] = -4,
[1][0][RTW89_WW][1][96] = -4,
- [1][0][RTW89_WW][2][96] = 0,
[1][0][RTW89_WW][0][98] = -4,
[1][0][RTW89_WW][1][98] = -4,
- [1][0][RTW89_WW][2][98] = 0,
[1][0][RTW89_WW][0][100] = -4,
[1][0][RTW89_WW][1][100] = -4,
- [1][0][RTW89_WW][2][100] = 0,
[1][0][RTW89_WW][0][102] = -4,
[1][0][RTW89_WW][1][102] = -4,
- [1][0][RTW89_WW][2][102] = 0,
[1][0][RTW89_WW][0][104] = -4,
[1][0][RTW89_WW][1][104] = -4,
- [1][0][RTW89_WW][2][104] = 0,
[1][0][RTW89_WW][0][105] = -4,
[1][0][RTW89_WW][1][105] = -4,
- [1][0][RTW89_WW][2][105] = 0,
[1][0][RTW89_WW][0][107] = -2,
[1][0][RTW89_WW][1][107] = -2,
- [1][0][RTW89_WW][2][107] = 0,
[1][0][RTW89_WW][0][109] = 2,
[1][0][RTW89_WW][1][109] = 2,
- [1][0][RTW89_WW][2][109] = 0,
[1][0][RTW89_WW][0][111] = 0,
[1][0][RTW89_WW][1][111] = 0,
- [1][0][RTW89_WW][2][111] = 0,
[1][0][RTW89_WW][0][113] = 0,
[1][0][RTW89_WW][1][113] = 0,
- [1][0][RTW89_WW][2][113] = 0,
[1][0][RTW89_WW][0][115] = 0,
[1][0][RTW89_WW][1][115] = 0,
- [1][0][RTW89_WW][2][115] = 0,
[1][0][RTW89_WW][0][117] = 0,
[1][0][RTW89_WW][1][117] = 0,
- [1][0][RTW89_WW][2][117] = 0,
[1][0][RTW89_WW][0][119] = 0,
[1][0][RTW89_WW][1][119] = 0,
- [1][0][RTW89_WW][2][119] = 0,
[1][1][RTW89_WW][0][0] = -26,
[1][1][RTW89_WW][1][0] = -26,
- [1][1][RTW89_WW][2][0] = 44,
[1][1][RTW89_WW][0][2] = -28,
[1][1][RTW89_WW][1][2] = -28,
- [1][1][RTW89_WW][2][2] = 44,
[1][1][RTW89_WW][0][4] = -28,
[1][1][RTW89_WW][1][4] = -28,
- [1][1][RTW89_WW][2][4] = 44,
[1][1][RTW89_WW][0][6] = -28,
[1][1][RTW89_WW][1][6] = -28,
- [1][1][RTW89_WW][2][6] = 44,
[1][1][RTW89_WW][0][8] = -28,
[1][1][RTW89_WW][1][8] = -28,
- [1][1][RTW89_WW][2][8] = 44,
[1][1][RTW89_WW][0][10] = -28,
[1][1][RTW89_WW][1][10] = -28,
- [1][1][RTW89_WW][2][10] = 44,
[1][1][RTW89_WW][0][12] = -28,
[1][1][RTW89_WW][1][12] = -28,
- [1][1][RTW89_WW][2][12] = 44,
[1][1][RTW89_WW][0][14] = -28,
[1][1][RTW89_WW][1][14] = -28,
- [1][1][RTW89_WW][2][14] = 44,
[1][1][RTW89_WW][0][15] = -28,
[1][1][RTW89_WW][1][15] = -28,
- [1][1][RTW89_WW][2][15] = 44,
[1][1][RTW89_WW][0][17] = -28,
[1][1][RTW89_WW][1][17] = -28,
- [1][1][RTW89_WW][2][17] = 44,
[1][1][RTW89_WW][0][19] = -28,
[1][1][RTW89_WW][1][19] = -28,
- [1][1][RTW89_WW][2][19] = 44,
[1][1][RTW89_WW][0][21] = -28,
[1][1][RTW89_WW][1][21] = -28,
- [1][1][RTW89_WW][2][21] = 44,
[1][1][RTW89_WW][0][23] = -28,
[1][1][RTW89_WW][1][23] = -28,
- [1][1][RTW89_WW][2][23] = 44,
[1][1][RTW89_WW][0][25] = -28,
[1][1][RTW89_WW][1][25] = -28,
- [1][1][RTW89_WW][2][25] = 44,
[1][1][RTW89_WW][0][27] = -28,
[1][1][RTW89_WW][1][27] = -28,
- [1][1][RTW89_WW][2][27] = 44,
[1][1][RTW89_WW][0][29] = -28,
[1][1][RTW89_WW][1][29] = -28,
- [1][1][RTW89_WW][2][29] = 44,
[1][1][RTW89_WW][0][30] = -28,
[1][1][RTW89_WW][1][30] = -28,
- [1][1][RTW89_WW][2][30] = 44,
[1][1][RTW89_WW][0][32] = -28,
[1][1][RTW89_WW][1][32] = -28,
- [1][1][RTW89_WW][2][32] = 44,
[1][1][RTW89_WW][0][34] = -28,
[1][1][RTW89_WW][1][34] = -28,
- [1][1][RTW89_WW][2][34] = 44,
[1][1][RTW89_WW][0][36] = -28,
[1][1][RTW89_WW][1][36] = -28,
- [1][1][RTW89_WW][2][36] = 44,
[1][1][RTW89_WW][0][38] = -28,
[1][1][RTW89_WW][1][38] = -28,
- [1][1][RTW89_WW][2][38] = 44,
[1][1][RTW89_WW][0][40] = -28,
[1][1][RTW89_WW][1][40] = -28,
- [1][1][RTW89_WW][2][40] = 44,
[1][1][RTW89_WW][0][42] = -28,
[1][1][RTW89_WW][1][42] = -28,
- [1][1][RTW89_WW][2][42] = 44,
[1][1][RTW89_WW][0][44] = -28,
[1][1][RTW89_WW][1][44] = -28,
- [1][1][RTW89_WW][2][44] = 44,
[1][1][RTW89_WW][0][45] = -26,
[1][1][RTW89_WW][1][45] = -26,
- [1][1][RTW89_WW][2][45] = 44,
[1][1][RTW89_WW][0][47] = -28,
[1][1][RTW89_WW][1][47] = -28,
- [1][1][RTW89_WW][2][47] = 44,
[1][1][RTW89_WW][0][49] = -28,
[1][1][RTW89_WW][1][49] = -28,
- [1][1][RTW89_WW][2][49] = 44,
[1][1][RTW89_WW][0][51] = -28,
[1][1][RTW89_WW][1][51] = -28,
- [1][1][RTW89_WW][2][51] = 44,
[1][1][RTW89_WW][0][53] = -26,
[1][1][RTW89_WW][1][53] = -26,
- [1][1][RTW89_WW][2][53] = 44,
[1][1][RTW89_WW][0][55] = -28,
[1][1][RTW89_WW][1][55] = -28,
- [1][1][RTW89_WW][2][55] = 44,
[1][1][RTW89_WW][0][57] = -28,
[1][1][RTW89_WW][1][57] = -28,
- [1][1][RTW89_WW][2][57] = 44,
[1][1][RTW89_WW][0][59] = -28,
[1][1][RTW89_WW][1][59] = -28,
- [1][1][RTW89_WW][2][59] = 44,
[1][1][RTW89_WW][0][60] = -28,
[1][1][RTW89_WW][1][60] = -28,
- [1][1][RTW89_WW][2][60] = 44,
[1][1][RTW89_WW][0][62] = -28,
[1][1][RTW89_WW][1][62] = -28,
- [1][1][RTW89_WW][2][62] = 44,
[1][1][RTW89_WW][0][64] = -28,
[1][1][RTW89_WW][1][64] = -28,
- [1][1][RTW89_WW][2][64] = 44,
[1][1][RTW89_WW][0][66] = -28,
[1][1][RTW89_WW][1][66] = -28,
- [1][1][RTW89_WW][2][66] = 44,
[1][1][RTW89_WW][0][68] = -28,
[1][1][RTW89_WW][1][68] = -28,
- [1][1][RTW89_WW][2][68] = 44,
[1][1][RTW89_WW][0][70] = -26,
[1][1][RTW89_WW][1][70] = -26,
- [1][1][RTW89_WW][2][70] = 44,
[1][1][RTW89_WW][0][72] = -28,
[1][1][RTW89_WW][1][72] = -28,
- [1][1][RTW89_WW][2][72] = 44,
[1][1][RTW89_WW][0][74] = -28,
[1][1][RTW89_WW][1][74] = -28,
- [1][1][RTW89_WW][2][74] = 44,
[1][1][RTW89_WW][0][75] = -28,
[1][1][RTW89_WW][1][75] = -28,
- [1][1][RTW89_WW][2][75] = 44,
[1][1][RTW89_WW][0][77] = -28,
[1][1][RTW89_WW][1][77] = -28,
- [1][1][RTW89_WW][2][77] = 44,
[1][1][RTW89_WW][0][79] = -28,
[1][1][RTW89_WW][1][79] = -28,
- [1][1][RTW89_WW][2][79] = 44,
[1][1][RTW89_WW][0][81] = -28,
[1][1][RTW89_WW][1][81] = -28,
- [1][1][RTW89_WW][2][81] = 44,
[1][1][RTW89_WW][0][83] = -28,
[1][1][RTW89_WW][1][83] = -28,
- [1][1][RTW89_WW][2][83] = 44,
[1][1][RTW89_WW][0][85] = -28,
[1][1][RTW89_WW][1][85] = -28,
- [1][1][RTW89_WW][2][85] = 44,
[1][1][RTW89_WW][0][87] = -28,
[1][1][RTW89_WW][1][87] = -28,
- [1][1][RTW89_WW][2][87] = 0,
[1][1][RTW89_WW][0][89] = -26,
[1][1][RTW89_WW][1][89] = -26,
- [1][1][RTW89_WW][2][89] = 0,
[1][1][RTW89_WW][0][90] = -26,
[1][1][RTW89_WW][1][90] = -26,
- [1][1][RTW89_WW][2][90] = 0,
[1][1][RTW89_WW][0][92] = -26,
[1][1][RTW89_WW][1][92] = -26,
- [1][1][RTW89_WW][2][92] = 0,
[1][1][RTW89_WW][0][94] = -26,
[1][1][RTW89_WW][1][94] = -26,
- [1][1][RTW89_WW][2][94] = 0,
[1][1][RTW89_WW][0][96] = -26,
[1][1][RTW89_WW][1][96] = -26,
- [1][1][RTW89_WW][2][96] = 0,
[1][1][RTW89_WW][0][98] = -26,
[1][1][RTW89_WW][1][98] = -26,
- [1][1][RTW89_WW][2][98] = 0,
[1][1][RTW89_WW][0][100] = -26,
[1][1][RTW89_WW][1][100] = -26,
- [1][1][RTW89_WW][2][100] = 0,
[1][1][RTW89_WW][0][102] = -26,
[1][1][RTW89_WW][1][102] = -26,
- [1][1][RTW89_WW][2][102] = 0,
[1][1][RTW89_WW][0][104] = -26,
[1][1][RTW89_WW][1][104] = -26,
- [1][1][RTW89_WW][2][104] = 0,
[1][1][RTW89_WW][0][105] = -26,
[1][1][RTW89_WW][1][105] = -26,
- [1][1][RTW89_WW][2][105] = 0,
[1][1][RTW89_WW][0][107] = -22,
[1][1][RTW89_WW][1][107] = -22,
- [1][1][RTW89_WW][2][107] = 0,
[1][1][RTW89_WW][0][109] = -22,
[1][1][RTW89_WW][1][109] = -22,
- [1][1][RTW89_WW][2][109] = 0,
[1][1][RTW89_WW][0][111] = 0,
[1][1][RTW89_WW][1][111] = 0,
- [1][1][RTW89_WW][2][111] = 0,
[1][1][RTW89_WW][0][113] = 0,
[1][1][RTW89_WW][1][113] = 0,
- [1][1][RTW89_WW][2][113] = 0,
[1][1][RTW89_WW][0][115] = 0,
[1][1][RTW89_WW][1][115] = 0,
- [1][1][RTW89_WW][2][115] = 0,
[1][1][RTW89_WW][0][117] = 0,
[1][1][RTW89_WW][1][117] = 0,
- [1][1][RTW89_WW][2][117] = 0,
[1][1][RTW89_WW][0][119] = 0,
[1][1][RTW89_WW][1][119] = 0,
- [1][1][RTW89_WW][2][119] = 0,
[2][0][RTW89_WW][0][0] = -2,
[2][0][RTW89_WW][1][0] = -2,
- [2][0][RTW89_WW][2][0] = 60,
[2][0][RTW89_WW][0][2] = -2,
[2][0][RTW89_WW][1][2] = -2,
- [2][0][RTW89_WW][2][2] = 60,
[2][0][RTW89_WW][0][4] = -2,
[2][0][RTW89_WW][1][4] = -2,
- [2][0][RTW89_WW][2][4] = 60,
[2][0][RTW89_WW][0][6] = -2,
[2][0][RTW89_WW][1][6] = -2,
- [2][0][RTW89_WW][2][6] = 60,
[2][0][RTW89_WW][0][8] = -2,
[2][0][RTW89_WW][1][8] = -2,
- [2][0][RTW89_WW][2][8] = 60,
[2][0][RTW89_WW][0][10] = -2,
[2][0][RTW89_WW][1][10] = -2,
- [2][0][RTW89_WW][2][10] = 60,
[2][0][RTW89_WW][0][12] = -2,
[2][0][RTW89_WW][1][12] = -2,
- [2][0][RTW89_WW][2][12] = 60,
[2][0][RTW89_WW][0][14] = -2,
[2][0][RTW89_WW][1][14] = -2,
- [2][0][RTW89_WW][2][14] = 60,
[2][0][RTW89_WW][0][15] = -2,
[2][0][RTW89_WW][1][15] = -2,
- [2][0][RTW89_WW][2][15] = 60,
[2][0][RTW89_WW][0][17] = -2,
[2][0][RTW89_WW][1][17] = -2,
- [2][0][RTW89_WW][2][17] = 60,
[2][0][RTW89_WW][0][19] = -2,
[2][0][RTW89_WW][1][19] = -2,
- [2][0][RTW89_WW][2][19] = 60,
[2][0][RTW89_WW][0][21] = -2,
[2][0][RTW89_WW][1][21] = -2,
- [2][0][RTW89_WW][2][21] = 60,
[2][0][RTW89_WW][0][23] = -2,
[2][0][RTW89_WW][1][23] = -2,
- [2][0][RTW89_WW][2][23] = 70,
[2][0][RTW89_WW][0][25] = -2,
[2][0][RTW89_WW][1][25] = -2,
- [2][0][RTW89_WW][2][25] = 70,
[2][0][RTW89_WW][0][27] = -2,
[2][0][RTW89_WW][1][27] = -2,
- [2][0][RTW89_WW][2][27] = 70,
[2][0][RTW89_WW][0][29] = -2,
[2][0][RTW89_WW][1][29] = -2,
- [2][0][RTW89_WW][2][29] = 70,
[2][0][RTW89_WW][0][30] = -2,
[2][0][RTW89_WW][1][30] = -2,
- [2][0][RTW89_WW][2][30] = 70,
[2][0][RTW89_WW][0][32] = -2,
[2][0][RTW89_WW][1][32] = -2,
- [2][0][RTW89_WW][2][32] = 70,
[2][0][RTW89_WW][0][34] = -2,
[2][0][RTW89_WW][1][34] = -2,
- [2][0][RTW89_WW][2][34] = 70,
[2][0][RTW89_WW][0][36] = -2,
[2][0][RTW89_WW][1][36] = -2,
- [2][0][RTW89_WW][2][36] = 70,
[2][0][RTW89_WW][0][38] = -2,
[2][0][RTW89_WW][1][38] = -2,
- [2][0][RTW89_WW][2][38] = 70,
[2][0][RTW89_WW][0][40] = -2,
[2][0][RTW89_WW][1][40] = -2,
- [2][0][RTW89_WW][2][40] = 70,
[2][0][RTW89_WW][0][42] = -2,
[2][0][RTW89_WW][1][42] = -2,
- [2][0][RTW89_WW][2][42] = 70,
[2][0][RTW89_WW][0][44] = -2,
[2][0][RTW89_WW][1][44] = -2,
- [2][0][RTW89_WW][2][44] = 70,
[2][0][RTW89_WW][0][45] = -2,
[2][0][RTW89_WW][1][45] = -2,
- [2][0][RTW89_WW][2][45] = 70,
[2][0][RTW89_WW][0][47] = -2,
[2][0][RTW89_WW][1][47] = -2,
- [2][0][RTW89_WW][2][47] = 70,
[2][0][RTW89_WW][0][49] = -2,
[2][0][RTW89_WW][1][49] = -2,
- [2][0][RTW89_WW][2][49] = 70,
[2][0][RTW89_WW][0][51] = -2,
[2][0][RTW89_WW][1][51] = -2,
- [2][0][RTW89_WW][2][51] = 70,
[2][0][RTW89_WW][0][53] = -2,
[2][0][RTW89_WW][1][53] = -2,
- [2][0][RTW89_WW][2][53] = 70,
[2][0][RTW89_WW][0][55] = -2,
[2][0][RTW89_WW][1][55] = -2,
- [2][0][RTW89_WW][2][55] = 68,
[2][0][RTW89_WW][0][57] = -2,
[2][0][RTW89_WW][1][57] = -2,
- [2][0][RTW89_WW][2][57] = 68,
[2][0][RTW89_WW][0][59] = -2,
[2][0][RTW89_WW][1][59] = -2,
- [2][0][RTW89_WW][2][59] = 68,
[2][0][RTW89_WW][0][60] = -2,
[2][0][RTW89_WW][1][60] = -2,
- [2][0][RTW89_WW][2][60] = 68,
[2][0][RTW89_WW][0][62] = -2,
[2][0][RTW89_WW][1][62] = -2,
- [2][0][RTW89_WW][2][62] = 68,
[2][0][RTW89_WW][0][64] = -2,
[2][0][RTW89_WW][1][64] = -2,
- [2][0][RTW89_WW][2][64] = 68,
[2][0][RTW89_WW][0][66] = -2,
[2][0][RTW89_WW][1][66] = -2,
- [2][0][RTW89_WW][2][66] = 68,
[2][0][RTW89_WW][0][68] = -2,
[2][0][RTW89_WW][1][68] = -2,
- [2][0][RTW89_WW][2][68] = 68,
[2][0][RTW89_WW][0][70] = -2,
[2][0][RTW89_WW][1][70] = -2,
- [2][0][RTW89_WW][2][70] = 68,
[2][0][RTW89_WW][0][72] = -2,
[2][0][RTW89_WW][1][72] = -2,
- [2][0][RTW89_WW][2][72] = 68,
[2][0][RTW89_WW][0][74] = -2,
[2][0][RTW89_WW][1][74] = -2,
- [2][0][RTW89_WW][2][74] = 68,
[2][0][RTW89_WW][0][75] = -2,
[2][0][RTW89_WW][1][75] = -2,
- [2][0][RTW89_WW][2][75] = 68,
[2][0][RTW89_WW][0][77] = -2,
[2][0][RTW89_WW][1][77] = -2,
- [2][0][RTW89_WW][2][77] = 68,
[2][0][RTW89_WW][0][79] = -2,
[2][0][RTW89_WW][1][79] = -2,
- [2][0][RTW89_WW][2][79] = 68,
[2][0][RTW89_WW][0][81] = -2,
[2][0][RTW89_WW][1][81] = -2,
- [2][0][RTW89_WW][2][81] = 68,
[2][0][RTW89_WW][0][83] = -2,
[2][0][RTW89_WW][1][83] = -2,
- [2][0][RTW89_WW][2][83] = 68,
[2][0][RTW89_WW][0][85] = -2,
[2][0][RTW89_WW][1][85] = -2,
- [2][0][RTW89_WW][2][85] = 68,
[2][0][RTW89_WW][0][87] = -2,
[2][0][RTW89_WW][1][87] = -2,
- [2][0][RTW89_WW][2][87] = 0,
[2][0][RTW89_WW][0][89] = -2,
[2][0][RTW89_WW][1][89] = -2,
- [2][0][RTW89_WW][2][89] = 0,
[2][0][RTW89_WW][0][90] = -2,
[2][0][RTW89_WW][1][90] = -2,
- [2][0][RTW89_WW][2][90] = 0,
[2][0][RTW89_WW][0][92] = -2,
[2][0][RTW89_WW][1][92] = -2,
- [2][0][RTW89_WW][2][92] = 0,
[2][0][RTW89_WW][0][94] = -2,
[2][0][RTW89_WW][1][94] = -2,
- [2][0][RTW89_WW][2][94] = 0,
[2][0][RTW89_WW][0][96] = -2,
[2][0][RTW89_WW][1][96] = -2,
- [2][0][RTW89_WW][2][96] = 0,
[2][0][RTW89_WW][0][98] = -2,
[2][0][RTW89_WW][1][98] = -2,
- [2][0][RTW89_WW][2][98] = 0,
[2][0][RTW89_WW][0][100] = -2,
[2][0][RTW89_WW][1][100] = -2,
- [2][0][RTW89_WW][2][100] = 0,
[2][0][RTW89_WW][0][102] = -2,
[2][0][RTW89_WW][1][102] = -2,
- [2][0][RTW89_WW][2][102] = 0,
[2][0][RTW89_WW][0][104] = -2,
[2][0][RTW89_WW][1][104] = -2,
- [2][0][RTW89_WW][2][104] = 0,
[2][0][RTW89_WW][0][105] = -2,
[2][0][RTW89_WW][1][105] = -2,
- [2][0][RTW89_WW][2][105] = 0,
[2][0][RTW89_WW][0][107] = -2,
[2][0][RTW89_WW][1][107] = -2,
- [2][0][RTW89_WW][2][107] = 0,
[2][0][RTW89_WW][0][109] = 12,
[2][0][RTW89_WW][1][109] = 12,
- [2][0][RTW89_WW][2][109] = 0,
[2][0][RTW89_WW][0][111] = 0,
[2][0][RTW89_WW][1][111] = 0,
- [2][0][RTW89_WW][2][111] = 0,
[2][0][RTW89_WW][0][113] = 0,
[2][0][RTW89_WW][1][113] = 0,
- [2][0][RTW89_WW][2][113] = 0,
[2][0][RTW89_WW][0][115] = 0,
[2][0][RTW89_WW][1][115] = 0,
- [2][0][RTW89_WW][2][115] = 0,
[2][0][RTW89_WW][0][117] = 0,
[2][0][RTW89_WW][1][117] = 0,
- [2][0][RTW89_WW][2][117] = 0,
[2][0][RTW89_WW][0][119] = 0,
[2][0][RTW89_WW][1][119] = 0,
- [2][0][RTW89_WW][2][119] = 0,
[2][1][RTW89_WW][0][0] = -16,
[2][1][RTW89_WW][1][0] = -16,
- [2][1][RTW89_WW][2][0] = 54,
[2][1][RTW89_WW][0][2] = -16,
[2][1][RTW89_WW][1][2] = -16,
- [2][1][RTW89_WW][2][2] = 54,
[2][1][RTW89_WW][0][4] = -16,
[2][1][RTW89_WW][1][4] = -16,
- [2][1][RTW89_WW][2][4] = 54,
[2][1][RTW89_WW][0][6] = -16,
[2][1][RTW89_WW][1][6] = -16,
- [2][1][RTW89_WW][2][6] = 54,
[2][1][RTW89_WW][0][8] = -16,
[2][1][RTW89_WW][1][8] = -16,
- [2][1][RTW89_WW][2][8] = 54,
[2][1][RTW89_WW][0][10] = -16,
[2][1][RTW89_WW][1][10] = -16,
- [2][1][RTW89_WW][2][10] = 54,
[2][1][RTW89_WW][0][12] = -16,
[2][1][RTW89_WW][1][12] = -16,
- [2][1][RTW89_WW][2][12] = 54,
[2][1][RTW89_WW][0][14] = -16,
[2][1][RTW89_WW][1][14] = -16,
- [2][1][RTW89_WW][2][14] = 54,
[2][1][RTW89_WW][0][15] = -16,
[2][1][RTW89_WW][1][15] = -16,
- [2][1][RTW89_WW][2][15] = 54,
[2][1][RTW89_WW][0][17] = -16,
[2][1][RTW89_WW][1][17] = -16,
- [2][1][RTW89_WW][2][17] = 54,
[2][1][RTW89_WW][0][19] = -16,
[2][1][RTW89_WW][1][19] = -16,
- [2][1][RTW89_WW][2][19] = 54,
[2][1][RTW89_WW][0][21] = -16,
[2][1][RTW89_WW][1][21] = -16,
- [2][1][RTW89_WW][2][21] = 54,
[2][1][RTW89_WW][0][23] = -16,
[2][1][RTW89_WW][1][23] = -16,
- [2][1][RTW89_WW][2][23] = 54,
[2][1][RTW89_WW][0][25] = -16,
[2][1][RTW89_WW][1][25] = -16,
- [2][1][RTW89_WW][2][25] = 54,
[2][1][RTW89_WW][0][27] = -16,
[2][1][RTW89_WW][1][27] = -16,
- [2][1][RTW89_WW][2][27] = 54,
[2][1][RTW89_WW][0][29] = -16,
[2][1][RTW89_WW][1][29] = -16,
- [2][1][RTW89_WW][2][29] = 54,
[2][1][RTW89_WW][0][30] = -16,
[2][1][RTW89_WW][1][30] = -16,
- [2][1][RTW89_WW][2][30] = 54,
[2][1][RTW89_WW][0][32] = -16,
[2][1][RTW89_WW][1][32] = -16,
- [2][1][RTW89_WW][2][32] = 54,
[2][1][RTW89_WW][0][34] = -16,
[2][1][RTW89_WW][1][34] = -16,
- [2][1][RTW89_WW][2][34] = 54,
[2][1][RTW89_WW][0][36] = -16,
[2][1][RTW89_WW][1][36] = -16,
- [2][1][RTW89_WW][2][36] = 54,
[2][1][RTW89_WW][0][38] = -16,
[2][1][RTW89_WW][1][38] = -16,
- [2][1][RTW89_WW][2][38] = 54,
[2][1][RTW89_WW][0][40] = -16,
[2][1][RTW89_WW][1][40] = -16,
- [2][1][RTW89_WW][2][40] = 54,
[2][1][RTW89_WW][0][42] = -16,
[2][1][RTW89_WW][1][42] = -16,
- [2][1][RTW89_WW][2][42] = 54,
[2][1][RTW89_WW][0][44] = -16,
[2][1][RTW89_WW][1][44] = -16,
- [2][1][RTW89_WW][2][44] = 54,
[2][1][RTW89_WW][0][45] = -16,
[2][1][RTW89_WW][1][45] = -16,
- [2][1][RTW89_WW][2][45] = 56,
[2][1][RTW89_WW][0][47] = -16,
[2][1][RTW89_WW][1][47] = -16,
- [2][1][RTW89_WW][2][47] = 56,
[2][1][RTW89_WW][0][49] = -16,
[2][1][RTW89_WW][1][49] = -16,
- [2][1][RTW89_WW][2][49] = 56,
[2][1][RTW89_WW][0][51] = -16,
[2][1][RTW89_WW][1][51] = -16,
- [2][1][RTW89_WW][2][51] = 56,
[2][1][RTW89_WW][0][53] = -16,
[2][1][RTW89_WW][1][53] = -16,
- [2][1][RTW89_WW][2][53] = 56,
[2][1][RTW89_WW][0][55] = -16,
[2][1][RTW89_WW][1][55] = -16,
- [2][1][RTW89_WW][2][55] = 54,
[2][1][RTW89_WW][0][57] = -16,
[2][1][RTW89_WW][1][57] = -16,
- [2][1][RTW89_WW][2][57] = 54,
[2][1][RTW89_WW][0][59] = -16,
[2][1][RTW89_WW][1][59] = -16,
- [2][1][RTW89_WW][2][59] = 54,
[2][1][RTW89_WW][0][60] = -16,
[2][1][RTW89_WW][1][60] = -16,
- [2][1][RTW89_WW][2][60] = 54,
[2][1][RTW89_WW][0][62] = -16,
[2][1][RTW89_WW][1][62] = -16,
- [2][1][RTW89_WW][2][62] = 54,
[2][1][RTW89_WW][0][64] = -16,
[2][1][RTW89_WW][1][64] = -16,
- [2][1][RTW89_WW][2][64] = 54,
[2][1][RTW89_WW][0][66] = -16,
[2][1][RTW89_WW][1][66] = -16,
- [2][1][RTW89_WW][2][66] = 54,
[2][1][RTW89_WW][0][68] = -16,
[2][1][RTW89_WW][1][68] = -16,
- [2][1][RTW89_WW][2][68] = 54,
[2][1][RTW89_WW][0][70] = -16,
[2][1][RTW89_WW][1][70] = -16,
- [2][1][RTW89_WW][2][70] = 56,
[2][1][RTW89_WW][0][72] = -16,
[2][1][RTW89_WW][1][72] = -16,
- [2][1][RTW89_WW][2][72] = 56,
[2][1][RTW89_WW][0][74] = -16,
[2][1][RTW89_WW][1][74] = -16,
- [2][1][RTW89_WW][2][74] = 56,
[2][1][RTW89_WW][0][75] = -16,
[2][1][RTW89_WW][1][75] = -16,
- [2][1][RTW89_WW][2][75] = 56,
[2][1][RTW89_WW][0][77] = -16,
[2][1][RTW89_WW][1][77] = -16,
- [2][1][RTW89_WW][2][77] = 56,
[2][1][RTW89_WW][0][79] = -16,
[2][1][RTW89_WW][1][79] = -16,
- [2][1][RTW89_WW][2][79] = 56,
[2][1][RTW89_WW][0][81] = -16,
[2][1][RTW89_WW][1][81] = -16,
- [2][1][RTW89_WW][2][81] = 56,
[2][1][RTW89_WW][0][83] = -16,
[2][1][RTW89_WW][1][83] = -16,
- [2][1][RTW89_WW][2][83] = 56,
[2][1][RTW89_WW][0][85] = -18,
[2][1][RTW89_WW][1][85] = -18,
- [2][1][RTW89_WW][2][85] = 56,
[2][1][RTW89_WW][0][87] = -16,
[2][1][RTW89_WW][1][87] = -16,
- [2][1][RTW89_WW][2][87] = 0,
[2][1][RTW89_WW][0][89] = -16,
[2][1][RTW89_WW][1][89] = -16,
- [2][1][RTW89_WW][2][89] = 0,
[2][1][RTW89_WW][0][90] = -16,
[2][1][RTW89_WW][1][90] = -16,
- [2][1][RTW89_WW][2][90] = 0,
[2][1][RTW89_WW][0][92] = -16,
[2][1][RTW89_WW][1][92] = -16,
- [2][1][RTW89_WW][2][92] = 0,
[2][1][RTW89_WW][0][94] = -16,
[2][1][RTW89_WW][1][94] = -16,
- [2][1][RTW89_WW][2][94] = 0,
[2][1][RTW89_WW][0][96] = -16,
[2][1][RTW89_WW][1][96] = -16,
- [2][1][RTW89_WW][2][96] = 0,
[2][1][RTW89_WW][0][98] = -16,
[2][1][RTW89_WW][1][98] = -16,
- [2][1][RTW89_WW][2][98] = 0,
[2][1][RTW89_WW][0][100] = -16,
[2][1][RTW89_WW][1][100] = -16,
- [2][1][RTW89_WW][2][100] = 0,
[2][1][RTW89_WW][0][102] = -16,
[2][1][RTW89_WW][1][102] = -16,
- [2][1][RTW89_WW][2][102] = 0,
[2][1][RTW89_WW][0][104] = -16,
[2][1][RTW89_WW][1][104] = -16,
- [2][1][RTW89_WW][2][104] = 0,
[2][1][RTW89_WW][0][105] = -16,
[2][1][RTW89_WW][1][105] = -16,
- [2][1][RTW89_WW][2][105] = 0,
[2][1][RTW89_WW][0][107] = -14,
[2][1][RTW89_WW][1][107] = -14,
- [2][1][RTW89_WW][2][107] = 0,
[2][1][RTW89_WW][0][109] = -10,
[2][1][RTW89_WW][1][109] = -10,
- [2][1][RTW89_WW][2][109] = 0,
[2][1][RTW89_WW][0][111] = 0,
[2][1][RTW89_WW][1][111] = 0,
- [2][1][RTW89_WW][2][111] = 0,
[2][1][RTW89_WW][0][113] = 0,
[2][1][RTW89_WW][1][113] = 0,
- [2][1][RTW89_WW][2][113] = 0,
[2][1][RTW89_WW][0][115] = 0,
[2][1][RTW89_WW][1][115] = 0,
- [2][1][RTW89_WW][2][115] = 0,
[2][1][RTW89_WW][0][117] = 0,
[2][1][RTW89_WW][1][117] = 0,
- [2][1][RTW89_WW][2][117] = 0,
[2][1][RTW89_WW][0][119] = 0,
[2][1][RTW89_WW][1][119] = 0,
- [2][1][RTW89_WW][2][119] = 0,
[0][0][RTW89_FCC][1][0] = -16,
- [0][0][RTW89_FCC][2][0] = 44,
[0][0][RTW89_ETSI][1][0] = 32,
[0][0][RTW89_ETSI][0][0] = -8,
[0][0][RTW89_MKK][1][0] = 30,
[0][0][RTW89_MKK][0][0] = -8,
[0][0][RTW89_IC][1][0] = -16,
- [0][0][RTW89_IC][2][0] = 44,
[0][0][RTW89_KCC][1][0] = -2,
[0][0][RTW89_KCC][0][0] = -2,
[0][0][RTW89_ACMA][1][0] = 32,
@@ -52408,13 +50558,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][0] = 30,
[0][0][RTW89_THAILAND][0][0] = -16,
[0][0][RTW89_FCC][1][2] = -18,
- [0][0][RTW89_FCC][2][2] = 44,
[0][0][RTW89_ETSI][1][2] = 32,
[0][0][RTW89_ETSI][0][2] = -8,
[0][0][RTW89_MKK][1][2] = 30,
[0][0][RTW89_MKK][0][2] = -8,
[0][0][RTW89_IC][1][2] = -18,
- [0][0][RTW89_IC][2][2] = 44,
[0][0][RTW89_KCC][1][2] = -2,
[0][0][RTW89_KCC][0][2] = -2,
[0][0][RTW89_ACMA][1][2] = 32,
@@ -52427,13 +50575,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][2] = 30,
[0][0][RTW89_THAILAND][0][2] = -18,
[0][0][RTW89_FCC][1][4] = -18,
- [0][0][RTW89_FCC][2][4] = 44,
[0][0][RTW89_ETSI][1][4] = 32,
[0][0][RTW89_ETSI][0][4] = -8,
[0][0][RTW89_MKK][1][4] = 30,
[0][0][RTW89_MKK][0][4] = -8,
[0][0][RTW89_IC][1][4] = -18,
- [0][0][RTW89_IC][2][4] = 44,
[0][0][RTW89_KCC][1][4] = -2,
[0][0][RTW89_KCC][0][4] = -2,
[0][0][RTW89_ACMA][1][4] = 32,
@@ -52446,13 +50592,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][4] = 30,
[0][0][RTW89_THAILAND][0][4] = -18,
[0][0][RTW89_FCC][1][6] = -18,
- [0][0][RTW89_FCC][2][6] = 44,
[0][0][RTW89_ETSI][1][6] = 32,
[0][0][RTW89_ETSI][0][6] = -8,
[0][0][RTW89_MKK][1][6] = 30,
[0][0][RTW89_MKK][0][6] = -8,
[0][0][RTW89_IC][1][6] = -18,
- [0][0][RTW89_IC][2][6] = 44,
[0][0][RTW89_KCC][1][6] = -2,
[0][0][RTW89_KCC][0][6] = -2,
[0][0][RTW89_ACMA][1][6] = 32,
@@ -52465,13 +50609,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][6] = 30,
[0][0][RTW89_THAILAND][0][6] = -18,
[0][0][RTW89_FCC][1][8] = -18,
- [0][0][RTW89_FCC][2][8] = 44,
[0][0][RTW89_ETSI][1][8] = 32,
[0][0][RTW89_ETSI][0][8] = -8,
[0][0][RTW89_MKK][1][8] = 30,
[0][0][RTW89_MKK][0][8] = -8,
[0][0][RTW89_IC][1][8] = -18,
- [0][0][RTW89_IC][2][8] = 44,
[0][0][RTW89_KCC][1][8] = -2,
[0][0][RTW89_KCC][0][8] = -2,
[0][0][RTW89_ACMA][1][8] = 32,
@@ -52484,13 +50626,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][8] = 30,
[0][0][RTW89_THAILAND][0][8] = -18,
[0][0][RTW89_FCC][1][10] = -18,
- [0][0][RTW89_FCC][2][10] = 44,
[0][0][RTW89_ETSI][1][10] = 32,
[0][0][RTW89_ETSI][0][10] = -8,
[0][0][RTW89_MKK][1][10] = 30,
[0][0][RTW89_MKK][0][10] = -8,
[0][0][RTW89_IC][1][10] = -18,
- [0][0][RTW89_IC][2][10] = 44,
[0][0][RTW89_KCC][1][10] = -2,
[0][0][RTW89_KCC][0][10] = -2,
[0][0][RTW89_ACMA][1][10] = 32,
@@ -52503,13 +50643,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][10] = 30,
[0][0][RTW89_THAILAND][0][10] = -18,
[0][0][RTW89_FCC][1][12] = -18,
- [0][0][RTW89_FCC][2][12] = 44,
[0][0][RTW89_ETSI][1][12] = 32,
[0][0][RTW89_ETSI][0][12] = -8,
[0][0][RTW89_MKK][1][12] = 30,
[0][0][RTW89_MKK][0][12] = -8,
[0][0][RTW89_IC][1][12] = -18,
- [0][0][RTW89_IC][2][12] = 44,
[0][0][RTW89_KCC][1][12] = -2,
[0][0][RTW89_KCC][0][12] = -2,
[0][0][RTW89_ACMA][1][12] = 32,
@@ -52522,13 +50660,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][12] = 30,
[0][0][RTW89_THAILAND][0][12] = -18,
[0][0][RTW89_FCC][1][14] = -18,
- [0][0][RTW89_FCC][2][14] = 44,
[0][0][RTW89_ETSI][1][14] = 32,
[0][0][RTW89_ETSI][0][14] = -8,
[0][0][RTW89_MKK][1][14] = 30,
[0][0][RTW89_MKK][0][14] = -8,
[0][0][RTW89_IC][1][14] = -18,
- [0][0][RTW89_IC][2][14] = 44,
[0][0][RTW89_KCC][1][14] = -2,
[0][0][RTW89_KCC][0][14] = -2,
[0][0][RTW89_ACMA][1][14] = 32,
@@ -52541,13 +50677,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][14] = 30,
[0][0][RTW89_THAILAND][0][14] = -18,
[0][0][RTW89_FCC][1][15] = -18,
- [0][0][RTW89_FCC][2][15] = 44,
[0][0][RTW89_ETSI][1][15] = 32,
[0][0][RTW89_ETSI][0][15] = -8,
[0][0][RTW89_MKK][1][15] = 30,
[0][0][RTW89_MKK][0][15] = -8,
[0][0][RTW89_IC][1][15] = -18,
- [0][0][RTW89_IC][2][15] = 44,
[0][0][RTW89_KCC][1][15] = -2,
[0][0][RTW89_KCC][0][15] = -2,
[0][0][RTW89_ACMA][1][15] = 32,
@@ -52560,13 +50694,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][15] = 30,
[0][0][RTW89_THAILAND][0][15] = -18,
[0][0][RTW89_FCC][1][17] = -18,
- [0][0][RTW89_FCC][2][17] = 44,
[0][0][RTW89_ETSI][1][17] = 32,
[0][0][RTW89_ETSI][0][17] = -8,
[0][0][RTW89_MKK][1][17] = 30,
[0][0][RTW89_MKK][0][17] = -8,
[0][0][RTW89_IC][1][17] = -18,
- [0][0][RTW89_IC][2][17] = 44,
[0][0][RTW89_KCC][1][17] = -2,
[0][0][RTW89_KCC][0][17] = -2,
[0][0][RTW89_ACMA][1][17] = 32,
@@ -52579,13 +50711,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][17] = 30,
[0][0][RTW89_THAILAND][0][17] = -18,
[0][0][RTW89_FCC][1][19] = -18,
- [0][0][RTW89_FCC][2][19] = 44,
[0][0][RTW89_ETSI][1][19] = 32,
[0][0][RTW89_ETSI][0][19] = -8,
[0][0][RTW89_MKK][1][19] = 30,
[0][0][RTW89_MKK][0][19] = -8,
[0][0][RTW89_IC][1][19] = -18,
- [0][0][RTW89_IC][2][19] = 44,
[0][0][RTW89_KCC][1][19] = -2,
[0][0][RTW89_KCC][0][19] = -2,
[0][0][RTW89_ACMA][1][19] = 32,
@@ -52598,13 +50728,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][19] = 30,
[0][0][RTW89_THAILAND][0][19] = -18,
[0][0][RTW89_FCC][1][21] = -18,
- [0][0][RTW89_FCC][2][21] = 44,
[0][0][RTW89_ETSI][1][21] = 32,
[0][0][RTW89_ETSI][0][21] = -8,
[0][0][RTW89_MKK][1][21] = 30,
[0][0][RTW89_MKK][0][21] = -8,
[0][0][RTW89_IC][1][21] = -18,
- [0][0][RTW89_IC][2][21] = 44,
[0][0][RTW89_KCC][1][21] = -2,
[0][0][RTW89_KCC][0][21] = -2,
[0][0][RTW89_ACMA][1][21] = 32,
@@ -52617,13 +50745,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][21] = 30,
[0][0][RTW89_THAILAND][0][21] = -18,
[0][0][RTW89_FCC][1][23] = -18,
- [0][0][RTW89_FCC][2][23] = 54,
[0][0][RTW89_ETSI][1][23] = 32,
[0][0][RTW89_ETSI][0][23] = -8,
[0][0][RTW89_MKK][1][23] = 30,
[0][0][RTW89_MKK][0][23] = -8,
[0][0][RTW89_IC][1][23] = -18,
- [0][0][RTW89_IC][2][23] = 54,
[0][0][RTW89_KCC][1][23] = -2,
[0][0][RTW89_KCC][0][23] = -2,
[0][0][RTW89_ACMA][1][23] = 32,
@@ -52636,13 +50762,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][23] = 30,
[0][0][RTW89_THAILAND][0][23] = -18,
[0][0][RTW89_FCC][1][25] = -18,
- [0][0][RTW89_FCC][2][25] = 54,
[0][0][RTW89_ETSI][1][25] = 32,
[0][0][RTW89_ETSI][0][25] = -8,
[0][0][RTW89_MKK][1][25] = 30,
[0][0][RTW89_MKK][0][25] = -8,
[0][0][RTW89_IC][1][25] = -18,
- [0][0][RTW89_IC][2][25] = 54,
[0][0][RTW89_KCC][1][25] = -2,
[0][0][RTW89_KCC][0][25] = -2,
[0][0][RTW89_ACMA][1][25] = 32,
@@ -52655,13 +50779,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][25] = 30,
[0][0][RTW89_THAILAND][0][25] = -18,
[0][0][RTW89_FCC][1][27] = -18,
- [0][0][RTW89_FCC][2][27] = 54,
[0][0][RTW89_ETSI][1][27] = 32,
[0][0][RTW89_ETSI][0][27] = -8,
[0][0][RTW89_MKK][1][27] = 30,
[0][0][RTW89_MKK][0][27] = -8,
[0][0][RTW89_IC][1][27] = -18,
- [0][0][RTW89_IC][2][27] = 54,
[0][0][RTW89_KCC][1][27] = -2,
[0][0][RTW89_KCC][0][27] = -2,
[0][0][RTW89_ACMA][1][27] = 32,
@@ -52674,13 +50796,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][27] = 30,
[0][0][RTW89_THAILAND][0][27] = -18,
[0][0][RTW89_FCC][1][29] = -18,
- [0][0][RTW89_FCC][2][29] = 54,
[0][0][RTW89_ETSI][1][29] = 32,
[0][0][RTW89_ETSI][0][29] = -8,
[0][0][RTW89_MKK][1][29] = 30,
[0][0][RTW89_MKK][0][29] = -8,
[0][0][RTW89_IC][1][29] = -18,
- [0][0][RTW89_IC][2][29] = 54,
[0][0][RTW89_KCC][1][29] = -2,
[0][0][RTW89_KCC][0][29] = -2,
[0][0][RTW89_ACMA][1][29] = 32,
@@ -52693,13 +50813,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][29] = 30,
[0][0][RTW89_THAILAND][0][29] = -18,
[0][0][RTW89_FCC][1][30] = -18,
- [0][0][RTW89_FCC][2][30] = 54,
[0][0][RTW89_ETSI][1][30] = 32,
[0][0][RTW89_ETSI][0][30] = -8,
[0][0][RTW89_MKK][1][30] = 30,
[0][0][RTW89_MKK][0][30] = -8,
[0][0][RTW89_IC][1][30] = -18,
- [0][0][RTW89_IC][2][30] = 54,
[0][0][RTW89_KCC][1][30] = -2,
[0][0][RTW89_KCC][0][30] = -2,
[0][0][RTW89_ACMA][1][30] = 32,
@@ -52712,13 +50830,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][30] = 30,
[0][0][RTW89_THAILAND][0][30] = -18,
[0][0][RTW89_FCC][1][32] = -18,
- [0][0][RTW89_FCC][2][32] = 54,
[0][0][RTW89_ETSI][1][32] = 32,
[0][0][RTW89_ETSI][0][32] = -8,
[0][0][RTW89_MKK][1][32] = 30,
[0][0][RTW89_MKK][0][32] = -8,
[0][0][RTW89_IC][1][32] = -18,
- [0][0][RTW89_IC][2][32] = 54,
[0][0][RTW89_KCC][1][32] = -2,
[0][0][RTW89_KCC][0][32] = -2,
[0][0][RTW89_ACMA][1][32] = 32,
@@ -52731,13 +50847,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][32] = 30,
[0][0][RTW89_THAILAND][0][32] = -18,
[0][0][RTW89_FCC][1][34] = -18,
- [0][0][RTW89_FCC][2][34] = 54,
[0][0][RTW89_ETSI][1][34] = 32,
[0][0][RTW89_ETSI][0][34] = -8,
[0][0][RTW89_MKK][1][34] = 30,
[0][0][RTW89_MKK][0][34] = -8,
[0][0][RTW89_IC][1][34] = -18,
- [0][0][RTW89_IC][2][34] = 54,
[0][0][RTW89_KCC][1][34] = -2,
[0][0][RTW89_KCC][0][34] = -2,
[0][0][RTW89_ACMA][1][34] = 32,
@@ -52750,13 +50864,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][34] = 30,
[0][0][RTW89_THAILAND][0][34] = -18,
[0][0][RTW89_FCC][1][36] = -18,
- [0][0][RTW89_FCC][2][36] = 54,
[0][0][RTW89_ETSI][1][36] = 32,
[0][0][RTW89_ETSI][0][36] = -8,
[0][0][RTW89_MKK][1][36] = 30,
[0][0][RTW89_MKK][0][36] = -8,
[0][0][RTW89_IC][1][36] = -18,
- [0][0][RTW89_IC][2][36] = 54,
[0][0][RTW89_KCC][1][36] = -2,
[0][0][RTW89_KCC][0][36] = -2,
[0][0][RTW89_ACMA][1][36] = 32,
@@ -52769,13 +50881,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][36] = 30,
[0][0][RTW89_THAILAND][0][36] = -18,
[0][0][RTW89_FCC][1][38] = -18,
- [0][0][RTW89_FCC][2][38] = 54,
[0][0][RTW89_ETSI][1][38] = 32,
[0][0][RTW89_ETSI][0][38] = -8,
[0][0][RTW89_MKK][1][38] = 30,
[0][0][RTW89_MKK][0][38] = -8,
[0][0][RTW89_IC][1][38] = -18,
- [0][0][RTW89_IC][2][38] = 54,
[0][0][RTW89_KCC][1][38] = -2,
[0][0][RTW89_KCC][0][38] = -2,
[0][0][RTW89_ACMA][1][38] = 32,
@@ -52788,13 +50898,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][38] = 30,
[0][0][RTW89_THAILAND][0][38] = -18,
[0][0][RTW89_FCC][1][40] = -18,
- [0][0][RTW89_FCC][2][40] = 54,
[0][0][RTW89_ETSI][1][40] = 32,
[0][0][RTW89_ETSI][0][40] = -8,
[0][0][RTW89_MKK][1][40] = 30,
[0][0][RTW89_MKK][0][40] = -8,
[0][0][RTW89_IC][1][40] = -18,
- [0][0][RTW89_IC][2][40] = 54,
[0][0][RTW89_KCC][1][40] = -2,
[0][0][RTW89_KCC][0][40] = -2,
[0][0][RTW89_ACMA][1][40] = 32,
@@ -52807,13 +50915,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][40] = 30,
[0][0][RTW89_THAILAND][0][40] = -18,
[0][0][RTW89_FCC][1][42] = -18,
- [0][0][RTW89_FCC][2][42] = 54,
[0][0][RTW89_ETSI][1][42] = 32,
[0][0][RTW89_ETSI][0][42] = -8,
[0][0][RTW89_MKK][1][42] = 30,
[0][0][RTW89_MKK][0][42] = -8,
[0][0][RTW89_IC][1][42] = -18,
- [0][0][RTW89_IC][2][42] = 54,
[0][0][RTW89_KCC][1][42] = -2,
[0][0][RTW89_KCC][0][42] = -2,
[0][0][RTW89_ACMA][1][42] = 32,
@@ -52826,13 +50932,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][42] = 30,
[0][0][RTW89_THAILAND][0][42] = -18,
[0][0][RTW89_FCC][1][44] = -16,
- [0][0][RTW89_FCC][2][44] = 56,
[0][0][RTW89_ETSI][1][44] = 32,
[0][0][RTW89_ETSI][0][44] = -6,
[0][0][RTW89_MKK][1][44] = 8,
[0][0][RTW89_MKK][0][44] = -10,
[0][0][RTW89_IC][1][44] = -16,
- [0][0][RTW89_IC][2][44] = 56,
[0][0][RTW89_KCC][1][44] = -2,
[0][0][RTW89_KCC][0][44] = -2,
[0][0][RTW89_ACMA][1][44] = 32,
@@ -52845,13 +50949,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][44] = 30,
[0][0][RTW89_THAILAND][0][44] = -16,
[0][0][RTW89_FCC][1][45] = -16,
- [0][0][RTW89_FCC][2][45] = 127,
[0][0][RTW89_ETSI][1][45] = 127,
[0][0][RTW89_ETSI][0][45] = 127,
[0][0][RTW89_MKK][1][45] = 127,
[0][0][RTW89_MKK][0][45] = 127,
[0][0][RTW89_IC][1][45] = -16,
- [0][0][RTW89_IC][2][45] = 56,
[0][0][RTW89_KCC][1][45] = -2,
[0][0][RTW89_KCC][0][45] = 127,
[0][0][RTW89_ACMA][1][45] = 127,
@@ -52864,13 +50966,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][45] = 127,
[0][0][RTW89_THAILAND][0][45] = 127,
[0][0][RTW89_FCC][1][47] = -18,
- [0][0][RTW89_FCC][2][47] = 127,
[0][0][RTW89_ETSI][1][47] = 127,
[0][0][RTW89_ETSI][0][47] = 127,
[0][0][RTW89_MKK][1][47] = 127,
[0][0][RTW89_MKK][0][47] = 127,
[0][0][RTW89_IC][1][47] = -18,
- [0][0][RTW89_IC][2][47] = 56,
[0][0][RTW89_KCC][1][47] = -2,
[0][0][RTW89_KCC][0][47] = 127,
[0][0][RTW89_ACMA][1][47] = 127,
@@ -52883,13 +50983,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][47] = 127,
[0][0][RTW89_THAILAND][0][47] = 127,
[0][0][RTW89_FCC][1][49] = -18,
- [0][0][RTW89_FCC][2][49] = 127,
[0][0][RTW89_ETSI][1][49] = 127,
[0][0][RTW89_ETSI][0][49] = 127,
[0][0][RTW89_MKK][1][49] = 127,
[0][0][RTW89_MKK][0][49] = 127,
[0][0][RTW89_IC][1][49] = -18,
- [0][0][RTW89_IC][2][49] = 56,
[0][0][RTW89_KCC][1][49] = -2,
[0][0][RTW89_KCC][0][49] = 127,
[0][0][RTW89_ACMA][1][49] = 127,
@@ -52902,13 +51000,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][49] = 127,
[0][0][RTW89_THAILAND][0][49] = 127,
[0][0][RTW89_FCC][1][51] = -18,
- [0][0][RTW89_FCC][2][51] = 127,
[0][0][RTW89_ETSI][1][51] = 127,
[0][0][RTW89_ETSI][0][51] = 127,
[0][0][RTW89_MKK][1][51] = 127,
[0][0][RTW89_MKK][0][51] = 127,
[0][0][RTW89_IC][1][51] = -18,
- [0][0][RTW89_IC][2][51] = 56,
[0][0][RTW89_KCC][1][51] = -2,
[0][0][RTW89_KCC][0][51] = 127,
[0][0][RTW89_ACMA][1][51] = 127,
@@ -52921,13 +51017,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][51] = 127,
[0][0][RTW89_THAILAND][0][51] = 127,
[0][0][RTW89_FCC][1][53] = -16,
- [0][0][RTW89_FCC][2][53] = 127,
[0][0][RTW89_ETSI][1][53] = 127,
[0][0][RTW89_ETSI][0][53] = 127,
[0][0][RTW89_MKK][1][53] = 127,
[0][0][RTW89_MKK][0][53] = 127,
[0][0][RTW89_IC][1][53] = -16,
- [0][0][RTW89_IC][2][53] = 56,
[0][0][RTW89_KCC][1][53] = -2,
[0][0][RTW89_KCC][0][53] = 127,
[0][0][RTW89_ACMA][1][53] = 127,
@@ -52940,13 +51034,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][53] = 127,
[0][0][RTW89_THAILAND][0][53] = 127,
[0][0][RTW89_FCC][1][55] = -18,
- [0][0][RTW89_FCC][2][55] = 56,
[0][0][RTW89_ETSI][1][55] = 127,
[0][0][RTW89_ETSI][0][55] = 127,
[0][0][RTW89_MKK][1][55] = 127,
[0][0][RTW89_MKK][0][55] = 127,
[0][0][RTW89_IC][1][55] = -18,
- [0][0][RTW89_IC][2][55] = 56,
[0][0][RTW89_KCC][1][55] = -2,
[0][0][RTW89_KCC][0][55] = 127,
[0][0][RTW89_ACMA][1][55] = 127,
@@ -52959,13 +51051,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][55] = 127,
[0][0][RTW89_THAILAND][0][55] = 127,
[0][0][RTW89_FCC][1][57] = -18,
- [0][0][RTW89_FCC][2][57] = 56,
[0][0][RTW89_ETSI][1][57] = 127,
[0][0][RTW89_ETSI][0][57] = 127,
[0][0][RTW89_MKK][1][57] = 127,
[0][0][RTW89_MKK][0][57] = 127,
[0][0][RTW89_IC][1][57] = -18,
- [0][0][RTW89_IC][2][57] = 56,
[0][0][RTW89_KCC][1][57] = -2,
[0][0][RTW89_KCC][0][57] = 127,
[0][0][RTW89_ACMA][1][57] = 127,
@@ -52978,13 +51068,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][57] = 127,
[0][0][RTW89_THAILAND][0][57] = 127,
[0][0][RTW89_FCC][1][59] = -18,
- [0][0][RTW89_FCC][2][59] = 56,
[0][0][RTW89_ETSI][1][59] = 127,
[0][0][RTW89_ETSI][0][59] = 127,
[0][0][RTW89_MKK][1][59] = 127,
[0][0][RTW89_MKK][0][59] = 127,
[0][0][RTW89_IC][1][59] = -18,
- [0][0][RTW89_IC][2][59] = 56,
[0][0][RTW89_KCC][1][59] = -2,
[0][0][RTW89_KCC][0][59] = 127,
[0][0][RTW89_ACMA][1][59] = 127,
@@ -52997,13 +51085,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][59] = 127,
[0][0][RTW89_THAILAND][0][59] = 127,
[0][0][RTW89_FCC][1][60] = -18,
- [0][0][RTW89_FCC][2][60] = 56,
[0][0][RTW89_ETSI][1][60] = 127,
[0][0][RTW89_ETSI][0][60] = 127,
[0][0][RTW89_MKK][1][60] = 127,
[0][0][RTW89_MKK][0][60] = 127,
[0][0][RTW89_IC][1][60] = -18,
- [0][0][RTW89_IC][2][60] = 56,
[0][0][RTW89_KCC][1][60] = -2,
[0][0][RTW89_KCC][0][60] = 127,
[0][0][RTW89_ACMA][1][60] = 127,
@@ -53016,13 +51102,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][60] = 127,
[0][0][RTW89_THAILAND][0][60] = 127,
[0][0][RTW89_FCC][1][62] = -18,
- [0][0][RTW89_FCC][2][62] = 56,
[0][0][RTW89_ETSI][1][62] = 127,
[0][0][RTW89_ETSI][0][62] = 127,
[0][0][RTW89_MKK][1][62] = 127,
[0][0][RTW89_MKK][0][62] = 127,
[0][0][RTW89_IC][1][62] = -18,
- [0][0][RTW89_IC][2][62] = 56,
[0][0][RTW89_KCC][1][62] = -2,
[0][0][RTW89_KCC][0][62] = 127,
[0][0][RTW89_ACMA][1][62] = 127,
@@ -53035,13 +51119,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][62] = 127,
[0][0][RTW89_THAILAND][0][62] = 127,
[0][0][RTW89_FCC][1][64] = -18,
- [0][0][RTW89_FCC][2][64] = 56,
[0][0][RTW89_ETSI][1][64] = 127,
[0][0][RTW89_ETSI][0][64] = 127,
[0][0][RTW89_MKK][1][64] = 127,
[0][0][RTW89_MKK][0][64] = 127,
[0][0][RTW89_IC][1][64] = -18,
- [0][0][RTW89_IC][2][64] = 56,
[0][0][RTW89_KCC][1][64] = -2,
[0][0][RTW89_KCC][0][64] = 127,
[0][0][RTW89_ACMA][1][64] = 127,
@@ -53054,13 +51136,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][64] = 127,
[0][0][RTW89_THAILAND][0][64] = 127,
[0][0][RTW89_FCC][1][66] = -18,
- [0][0][RTW89_FCC][2][66] = 56,
[0][0][RTW89_ETSI][1][66] = 127,
[0][0][RTW89_ETSI][0][66] = 127,
[0][0][RTW89_MKK][1][66] = 127,
[0][0][RTW89_MKK][0][66] = 127,
[0][0][RTW89_IC][1][66] = -18,
- [0][0][RTW89_IC][2][66] = 56,
[0][0][RTW89_KCC][1][66] = -2,
[0][0][RTW89_KCC][0][66] = 127,
[0][0][RTW89_ACMA][1][66] = 127,
@@ -53073,13 +51153,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][66] = 127,
[0][0][RTW89_THAILAND][0][66] = 127,
[0][0][RTW89_FCC][1][68] = -18,
- [0][0][RTW89_FCC][2][68] = 56,
[0][0][RTW89_ETSI][1][68] = 127,
[0][0][RTW89_ETSI][0][68] = 127,
[0][0][RTW89_MKK][1][68] = 127,
[0][0][RTW89_MKK][0][68] = 127,
[0][0][RTW89_IC][1][68] = -18,
- [0][0][RTW89_IC][2][68] = 56,
[0][0][RTW89_KCC][1][68] = -2,
[0][0][RTW89_KCC][0][68] = 127,
[0][0][RTW89_ACMA][1][68] = 127,
@@ -53092,13 +51170,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][68] = 127,
[0][0][RTW89_THAILAND][0][68] = 127,
[0][0][RTW89_FCC][1][70] = -16,
- [0][0][RTW89_FCC][2][70] = 56,
[0][0][RTW89_ETSI][1][70] = 127,
[0][0][RTW89_ETSI][0][70] = 127,
[0][0][RTW89_MKK][1][70] = 127,
[0][0][RTW89_MKK][0][70] = 127,
[0][0][RTW89_IC][1][70] = -16,
- [0][0][RTW89_IC][2][70] = 56,
[0][0][RTW89_KCC][1][70] = -2,
[0][0][RTW89_KCC][0][70] = 127,
[0][0][RTW89_ACMA][1][70] = 127,
@@ -53111,13 +51187,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][70] = 127,
[0][0][RTW89_THAILAND][0][70] = 127,
[0][0][RTW89_FCC][1][72] = -18,
- [0][0][RTW89_FCC][2][72] = 56,
[0][0][RTW89_ETSI][1][72] = 127,
[0][0][RTW89_ETSI][0][72] = 127,
[0][0][RTW89_MKK][1][72] = 127,
[0][0][RTW89_MKK][0][72] = 127,
[0][0][RTW89_IC][1][72] = -18,
- [0][0][RTW89_IC][2][72] = 56,
[0][0][RTW89_KCC][1][72] = -2,
[0][0][RTW89_KCC][0][72] = 127,
[0][0][RTW89_ACMA][1][72] = 127,
@@ -53130,13 +51204,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][72] = 127,
[0][0][RTW89_THAILAND][0][72] = 127,
[0][0][RTW89_FCC][1][74] = -18,
- [0][0][RTW89_FCC][2][74] = 56,
[0][0][RTW89_ETSI][1][74] = 127,
[0][0][RTW89_ETSI][0][74] = 127,
[0][0][RTW89_MKK][1][74] = 127,
[0][0][RTW89_MKK][0][74] = 127,
[0][0][RTW89_IC][1][74] = -18,
- [0][0][RTW89_IC][2][74] = 56,
[0][0][RTW89_KCC][1][74] = -2,
[0][0][RTW89_KCC][0][74] = 127,
[0][0][RTW89_ACMA][1][74] = 127,
@@ -53149,13 +51221,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][74] = 127,
[0][0][RTW89_THAILAND][0][74] = 127,
[0][0][RTW89_FCC][1][75] = -18,
- [0][0][RTW89_FCC][2][75] = 56,
[0][0][RTW89_ETSI][1][75] = 127,
[0][0][RTW89_ETSI][0][75] = 127,
[0][0][RTW89_MKK][1][75] = 127,
[0][0][RTW89_MKK][0][75] = 127,
[0][0][RTW89_IC][1][75] = -18,
- [0][0][RTW89_IC][2][75] = 56,
[0][0][RTW89_KCC][1][75] = -2,
[0][0][RTW89_KCC][0][75] = 127,
[0][0][RTW89_ACMA][1][75] = 127,
@@ -53168,13 +51238,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][75] = 127,
[0][0][RTW89_THAILAND][0][75] = 127,
[0][0][RTW89_FCC][1][77] = -18,
- [0][0][RTW89_FCC][2][77] = 56,
[0][0][RTW89_ETSI][1][77] = 127,
[0][0][RTW89_ETSI][0][77] = 127,
[0][0][RTW89_MKK][1][77] = 127,
[0][0][RTW89_MKK][0][77] = 127,
[0][0][RTW89_IC][1][77] = -18,
- [0][0][RTW89_IC][2][77] = 56,
[0][0][RTW89_KCC][1][77] = -2,
[0][0][RTW89_KCC][0][77] = 127,
[0][0][RTW89_ACMA][1][77] = 127,
@@ -53187,13 +51255,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][77] = 127,
[0][0][RTW89_THAILAND][0][77] = 127,
[0][0][RTW89_FCC][1][79] = -18,
- [0][0][RTW89_FCC][2][79] = 56,
[0][0][RTW89_ETSI][1][79] = 127,
[0][0][RTW89_ETSI][0][79] = 127,
[0][0][RTW89_MKK][1][79] = 127,
[0][0][RTW89_MKK][0][79] = 127,
[0][0][RTW89_IC][1][79] = -18,
- [0][0][RTW89_IC][2][79] = 56,
[0][0][RTW89_KCC][1][79] = -2,
[0][0][RTW89_KCC][0][79] = 127,
[0][0][RTW89_ACMA][1][79] = 127,
@@ -53206,13 +51272,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][79] = 127,
[0][0][RTW89_THAILAND][0][79] = 127,
[0][0][RTW89_FCC][1][81] = -18,
- [0][0][RTW89_FCC][2][81] = 56,
[0][0][RTW89_ETSI][1][81] = 127,
[0][0][RTW89_ETSI][0][81] = 127,
[0][0][RTW89_MKK][1][81] = 127,
[0][0][RTW89_MKK][0][81] = 127,
[0][0][RTW89_IC][1][81] = -18,
- [0][0][RTW89_IC][2][81] = 56,
[0][0][RTW89_KCC][1][81] = -2,
[0][0][RTW89_KCC][0][81] = 127,
[0][0][RTW89_ACMA][1][81] = 127,
@@ -53225,13 +51289,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][81] = 127,
[0][0][RTW89_THAILAND][0][81] = 127,
[0][0][RTW89_FCC][1][83] = -18,
- [0][0][RTW89_FCC][2][83] = 56,
[0][0][RTW89_ETSI][1][83] = 127,
[0][0][RTW89_ETSI][0][83] = 127,
[0][0][RTW89_MKK][1][83] = 127,
[0][0][RTW89_MKK][0][83] = 127,
[0][0][RTW89_IC][1][83] = -18,
- [0][0][RTW89_IC][2][83] = 56,
[0][0][RTW89_KCC][1][83] = -2,
[0][0][RTW89_KCC][0][83] = 127,
[0][0][RTW89_ACMA][1][83] = 127,
@@ -53244,13 +51306,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][83] = 127,
[0][0][RTW89_THAILAND][0][83] = 127,
[0][0][RTW89_FCC][1][85] = -18,
- [0][0][RTW89_FCC][2][85] = 56,
[0][0][RTW89_ETSI][1][85] = 127,
[0][0][RTW89_ETSI][0][85] = 127,
[0][0][RTW89_MKK][1][85] = 127,
[0][0][RTW89_MKK][0][85] = 127,
[0][0][RTW89_IC][1][85] = -18,
- [0][0][RTW89_IC][2][85] = 56,
[0][0][RTW89_KCC][1][85] = -2,
[0][0][RTW89_KCC][0][85] = 127,
[0][0][RTW89_ACMA][1][85] = 127,
@@ -53263,13 +51323,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][85] = 127,
[0][0][RTW89_THAILAND][0][85] = 127,
[0][0][RTW89_FCC][1][87] = -16,
- [0][0][RTW89_FCC][2][87] = 127,
[0][0][RTW89_ETSI][1][87] = 127,
[0][0][RTW89_ETSI][0][87] = 127,
[0][0][RTW89_MKK][1][87] = 127,
[0][0][RTW89_MKK][0][87] = 127,
[0][0][RTW89_IC][1][87] = -16,
- [0][0][RTW89_IC][2][87] = 127,
[0][0][RTW89_KCC][1][87] = -2,
[0][0][RTW89_KCC][0][87] = 127,
[0][0][RTW89_ACMA][1][87] = 127,
@@ -53282,13 +51340,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][87] = 127,
[0][0][RTW89_THAILAND][0][87] = 127,
[0][0][RTW89_FCC][1][89] = -16,
- [0][0][RTW89_FCC][2][89] = 127,
[0][0][RTW89_ETSI][1][89] = 127,
[0][0][RTW89_ETSI][0][89] = 127,
[0][0][RTW89_MKK][1][89] = 127,
[0][0][RTW89_MKK][0][89] = 127,
[0][0][RTW89_IC][1][89] = -16,
- [0][0][RTW89_IC][2][89] = 127,
[0][0][RTW89_KCC][1][89] = -2,
[0][0][RTW89_KCC][0][89] = 127,
[0][0][RTW89_ACMA][1][89] = 127,
@@ -53301,13 +51357,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][89] = 127,
[0][0][RTW89_THAILAND][0][89] = 127,
[0][0][RTW89_FCC][1][90] = -16,
- [0][0][RTW89_FCC][2][90] = 127,
[0][0][RTW89_ETSI][1][90] = 127,
[0][0][RTW89_ETSI][0][90] = 127,
[0][0][RTW89_MKK][1][90] = 127,
[0][0][RTW89_MKK][0][90] = 127,
[0][0][RTW89_IC][1][90] = -16,
- [0][0][RTW89_IC][2][90] = 127,
[0][0][RTW89_KCC][1][90] = -2,
[0][0][RTW89_KCC][0][90] = 127,
[0][0][RTW89_ACMA][1][90] = 127,
@@ -53320,13 +51374,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][90] = 127,
[0][0][RTW89_THAILAND][0][90] = 127,
[0][0][RTW89_FCC][1][92] = -16,
- [0][0][RTW89_FCC][2][92] = 127,
[0][0][RTW89_ETSI][1][92] = 127,
[0][0][RTW89_ETSI][0][92] = 127,
[0][0][RTW89_MKK][1][92] = 127,
[0][0][RTW89_MKK][0][92] = 127,
[0][0][RTW89_IC][1][92] = -16,
- [0][0][RTW89_IC][2][92] = 127,
[0][0][RTW89_KCC][1][92] = -2,
[0][0][RTW89_KCC][0][92] = 127,
[0][0][RTW89_ACMA][1][92] = 127,
@@ -53339,13 +51391,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][92] = 127,
[0][0][RTW89_THAILAND][0][92] = 127,
[0][0][RTW89_FCC][1][94] = -16,
- [0][0][RTW89_FCC][2][94] = 127,
[0][0][RTW89_ETSI][1][94] = 127,
[0][0][RTW89_ETSI][0][94] = 127,
[0][0][RTW89_MKK][1][94] = 127,
[0][0][RTW89_MKK][0][94] = 127,
[0][0][RTW89_IC][1][94] = -16,
- [0][0][RTW89_IC][2][94] = 127,
[0][0][RTW89_KCC][1][94] = -2,
[0][0][RTW89_KCC][0][94] = 127,
[0][0][RTW89_ACMA][1][94] = 127,
@@ -53358,13 +51408,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][94] = 127,
[0][0][RTW89_THAILAND][0][94] = 127,
[0][0][RTW89_FCC][1][96] = -16,
- [0][0][RTW89_FCC][2][96] = 127,
[0][0][RTW89_ETSI][1][96] = 127,
[0][0][RTW89_ETSI][0][96] = 127,
[0][0][RTW89_MKK][1][96] = 127,
[0][0][RTW89_MKK][0][96] = 127,
[0][0][RTW89_IC][1][96] = -16,
- [0][0][RTW89_IC][2][96] = 127,
[0][0][RTW89_KCC][1][96] = -2,
[0][0][RTW89_KCC][0][96] = 127,
[0][0][RTW89_ACMA][1][96] = 127,
@@ -53377,13 +51425,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][96] = 127,
[0][0][RTW89_THAILAND][0][96] = 127,
[0][0][RTW89_FCC][1][98] = -16,
- [0][0][RTW89_FCC][2][98] = 127,
[0][0][RTW89_ETSI][1][98] = 127,
[0][0][RTW89_ETSI][0][98] = 127,
[0][0][RTW89_MKK][1][98] = 127,
[0][0][RTW89_MKK][0][98] = 127,
[0][0][RTW89_IC][1][98] = -16,
- [0][0][RTW89_IC][2][98] = 127,
[0][0][RTW89_KCC][1][98] = -2,
[0][0][RTW89_KCC][0][98] = 127,
[0][0][RTW89_ACMA][1][98] = 127,
@@ -53396,13 +51442,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][98] = 127,
[0][0][RTW89_THAILAND][0][98] = 127,
[0][0][RTW89_FCC][1][100] = -16,
- [0][0][RTW89_FCC][2][100] = 127,
[0][0][RTW89_ETSI][1][100] = 127,
[0][0][RTW89_ETSI][0][100] = 127,
[0][0][RTW89_MKK][1][100] = 127,
[0][0][RTW89_MKK][0][100] = 127,
[0][0][RTW89_IC][1][100] = -16,
- [0][0][RTW89_IC][2][100] = 127,
[0][0][RTW89_KCC][1][100] = -2,
[0][0][RTW89_KCC][0][100] = 127,
[0][0][RTW89_ACMA][1][100] = 127,
@@ -53415,13 +51459,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][100] = 127,
[0][0][RTW89_THAILAND][0][100] = 127,
[0][0][RTW89_FCC][1][102] = -16,
- [0][0][RTW89_FCC][2][102] = 127,
[0][0][RTW89_ETSI][1][102] = 127,
[0][0][RTW89_ETSI][0][102] = 127,
[0][0][RTW89_MKK][1][102] = 127,
[0][0][RTW89_MKK][0][102] = 127,
[0][0][RTW89_IC][1][102] = -16,
- [0][0][RTW89_IC][2][102] = 127,
[0][0][RTW89_KCC][1][102] = -2,
[0][0][RTW89_KCC][0][102] = 127,
[0][0][RTW89_ACMA][1][102] = 127,
@@ -53434,13 +51476,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][102] = 127,
[0][0][RTW89_THAILAND][0][102] = 127,
[0][0][RTW89_FCC][1][104] = -16,
- [0][0][RTW89_FCC][2][104] = 127,
[0][0][RTW89_ETSI][1][104] = 127,
[0][0][RTW89_ETSI][0][104] = 127,
[0][0][RTW89_MKK][1][104] = 127,
[0][0][RTW89_MKK][0][104] = 127,
[0][0][RTW89_IC][1][104] = -16,
- [0][0][RTW89_IC][2][104] = 127,
[0][0][RTW89_KCC][1][104] = -2,
[0][0][RTW89_KCC][0][104] = 127,
[0][0][RTW89_ACMA][1][104] = 127,
@@ -53453,13 +51493,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][104] = 127,
[0][0][RTW89_THAILAND][0][104] = 127,
[0][0][RTW89_FCC][1][105] = -16,
- [0][0][RTW89_FCC][2][105] = 127,
[0][0][RTW89_ETSI][1][105] = 127,
[0][0][RTW89_ETSI][0][105] = 127,
[0][0][RTW89_MKK][1][105] = 127,
[0][0][RTW89_MKK][0][105] = 127,
[0][0][RTW89_IC][1][105] = -16,
- [0][0][RTW89_IC][2][105] = 127,
[0][0][RTW89_KCC][1][105] = -2,
[0][0][RTW89_KCC][0][105] = 127,
[0][0][RTW89_ACMA][1][105] = 127,
@@ -53472,13 +51510,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][105] = 127,
[0][0][RTW89_THAILAND][0][105] = 127,
[0][0][RTW89_FCC][1][107] = -12,
- [0][0][RTW89_FCC][2][107] = 127,
[0][0][RTW89_ETSI][1][107] = 127,
[0][0][RTW89_ETSI][0][107] = 127,
[0][0][RTW89_MKK][1][107] = 127,
[0][0][RTW89_MKK][0][107] = 127,
[0][0][RTW89_IC][1][107] = -12,
- [0][0][RTW89_IC][2][107] = 127,
[0][0][RTW89_KCC][1][107] = -2,
[0][0][RTW89_KCC][0][107] = 127,
[0][0][RTW89_ACMA][1][107] = 127,
@@ -53491,13 +51527,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][107] = 127,
[0][0][RTW89_THAILAND][0][107] = 127,
[0][0][RTW89_FCC][1][109] = -12,
- [0][0][RTW89_FCC][2][109] = 127,
[0][0][RTW89_ETSI][1][109] = 127,
[0][0][RTW89_ETSI][0][109] = 127,
[0][0][RTW89_MKK][1][109] = 127,
[0][0][RTW89_MKK][0][109] = 127,
[0][0][RTW89_IC][1][109] = -12,
- [0][0][RTW89_IC][2][109] = 127,
[0][0][RTW89_KCC][1][109] = 127,
[0][0][RTW89_KCC][0][109] = 127,
[0][0][RTW89_ACMA][1][109] = 127,
@@ -53510,13 +51544,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][109] = 127,
[0][0][RTW89_THAILAND][0][109] = 127,
[0][0][RTW89_FCC][1][111] = 127,
- [0][0][RTW89_FCC][2][111] = 127,
[0][0][RTW89_ETSI][1][111] = 127,
[0][0][RTW89_ETSI][0][111] = 127,
[0][0][RTW89_MKK][1][111] = 127,
[0][0][RTW89_MKK][0][111] = 127,
[0][0][RTW89_IC][1][111] = 127,
- [0][0][RTW89_IC][2][111] = 127,
[0][0][RTW89_KCC][1][111] = 127,
[0][0][RTW89_KCC][0][111] = 127,
[0][0][RTW89_ACMA][1][111] = 127,
@@ -53529,13 +51561,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][111] = 127,
[0][0][RTW89_THAILAND][0][111] = 127,
[0][0][RTW89_FCC][1][113] = 127,
- [0][0][RTW89_FCC][2][113] = 127,
[0][0][RTW89_ETSI][1][113] = 127,
[0][0][RTW89_ETSI][0][113] = 127,
[0][0][RTW89_MKK][1][113] = 127,
[0][0][RTW89_MKK][0][113] = 127,
[0][0][RTW89_IC][1][113] = 127,
- [0][0][RTW89_IC][2][113] = 127,
[0][0][RTW89_KCC][1][113] = 127,
[0][0][RTW89_KCC][0][113] = 127,
[0][0][RTW89_ACMA][1][113] = 127,
@@ -53548,13 +51578,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][113] = 127,
[0][0][RTW89_THAILAND][0][113] = 127,
[0][0][RTW89_FCC][1][115] = 127,
- [0][0][RTW89_FCC][2][115] = 127,
[0][0][RTW89_ETSI][1][115] = 127,
[0][0][RTW89_ETSI][0][115] = 127,
[0][0][RTW89_MKK][1][115] = 127,
[0][0][RTW89_MKK][0][115] = 127,
[0][0][RTW89_IC][1][115] = 127,
- [0][0][RTW89_IC][2][115] = 127,
[0][0][RTW89_KCC][1][115] = 127,
[0][0][RTW89_KCC][0][115] = 127,
[0][0][RTW89_ACMA][1][115] = 127,
@@ -53567,13 +51595,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][115] = 127,
[0][0][RTW89_THAILAND][0][115] = 127,
[0][0][RTW89_FCC][1][117] = 127,
- [0][0][RTW89_FCC][2][117] = 127,
[0][0][RTW89_ETSI][1][117] = 127,
[0][0][RTW89_ETSI][0][117] = 127,
[0][0][RTW89_MKK][1][117] = 127,
[0][0][RTW89_MKK][0][117] = 127,
[0][0][RTW89_IC][1][117] = 127,
- [0][0][RTW89_IC][2][117] = 127,
[0][0][RTW89_KCC][1][117] = 127,
[0][0][RTW89_KCC][0][117] = 127,
[0][0][RTW89_ACMA][1][117] = 127,
@@ -53586,13 +51612,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][117] = 127,
[0][0][RTW89_THAILAND][0][117] = 127,
[0][0][RTW89_FCC][1][119] = 127,
- [0][0][RTW89_FCC][2][119] = 127,
[0][0][RTW89_ETSI][1][119] = 127,
[0][0][RTW89_ETSI][0][119] = 127,
[0][0][RTW89_MKK][1][119] = 127,
[0][0][RTW89_MKK][0][119] = 127,
[0][0][RTW89_IC][1][119] = 127,
- [0][0][RTW89_IC][2][119] = 127,
[0][0][RTW89_KCC][1][119] = 127,
[0][0][RTW89_KCC][0][119] = 127,
[0][0][RTW89_ACMA][1][119] = 127,
@@ -53605,13 +51629,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][0][RTW89_THAILAND][1][119] = 127,
[0][0][RTW89_THAILAND][0][119] = 127,
[0][1][RTW89_FCC][1][0] = -40,
- [0][1][RTW89_FCC][2][0] = 32,
[0][1][RTW89_ETSI][1][0] = 20,
[0][1][RTW89_ETSI][0][0] = -18,
[0][1][RTW89_MKK][1][0] = 18,
[0][1][RTW89_MKK][0][0] = -20,
[0][1][RTW89_IC][1][0] = -40,
- [0][1][RTW89_IC][2][0] = 32,
[0][1][RTW89_KCC][1][0] = -14,
[0][1][RTW89_KCC][0][0] = -14,
[0][1][RTW89_ACMA][1][0] = 20,
@@ -53624,13 +51646,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][0] = 6,
[0][1][RTW89_THAILAND][0][0] = -40,
[0][1][RTW89_FCC][1][2] = -40,
- [0][1][RTW89_FCC][2][2] = 32,
[0][1][RTW89_ETSI][1][2] = 20,
[0][1][RTW89_ETSI][0][2] = -18,
[0][1][RTW89_MKK][1][2] = 18,
[0][1][RTW89_MKK][0][2] = -22,
[0][1][RTW89_IC][1][2] = -40,
- [0][1][RTW89_IC][2][2] = 32,
[0][1][RTW89_KCC][1][2] = -14,
[0][1][RTW89_KCC][0][2] = -14,
[0][1][RTW89_ACMA][1][2] = 20,
@@ -53643,13 +51663,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][2] = 6,
[0][1][RTW89_THAILAND][0][2] = -40,
[0][1][RTW89_FCC][1][4] = -40,
- [0][1][RTW89_FCC][2][4] = 32,
[0][1][RTW89_ETSI][1][4] = 20,
[0][1][RTW89_ETSI][0][4] = -18,
[0][1][RTW89_MKK][1][4] = 18,
[0][1][RTW89_MKK][0][4] = -22,
[0][1][RTW89_IC][1][4] = -40,
- [0][1][RTW89_IC][2][4] = 32,
[0][1][RTW89_KCC][1][4] = -14,
[0][1][RTW89_KCC][0][4] = -14,
[0][1][RTW89_ACMA][1][4] = 20,
@@ -53662,13 +51680,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][4] = 6,
[0][1][RTW89_THAILAND][0][4] = -40,
[0][1][RTW89_FCC][1][6] = -40,
- [0][1][RTW89_FCC][2][6] = 32,
[0][1][RTW89_ETSI][1][6] = 20,
[0][1][RTW89_ETSI][0][6] = -18,
[0][1][RTW89_MKK][1][6] = 18,
[0][1][RTW89_MKK][0][6] = -22,
[0][1][RTW89_IC][1][6] = -40,
- [0][1][RTW89_IC][2][6] = 32,
[0][1][RTW89_KCC][1][6] = -14,
[0][1][RTW89_KCC][0][6] = -14,
[0][1][RTW89_ACMA][1][6] = 20,
@@ -53681,13 +51697,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][6] = 6,
[0][1][RTW89_THAILAND][0][6] = -40,
[0][1][RTW89_FCC][1][8] = -40,
- [0][1][RTW89_FCC][2][8] = 32,
[0][1][RTW89_ETSI][1][8] = 20,
[0][1][RTW89_ETSI][0][8] = -18,
[0][1][RTW89_MKK][1][8] = 18,
[0][1][RTW89_MKK][0][8] = -22,
[0][1][RTW89_IC][1][8] = -40,
- [0][1][RTW89_IC][2][8] = 32,
[0][1][RTW89_KCC][1][8] = -14,
[0][1][RTW89_KCC][0][8] = -14,
[0][1][RTW89_ACMA][1][8] = 20,
@@ -53700,13 +51714,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][8] = 6,
[0][1][RTW89_THAILAND][0][8] = -40,
[0][1][RTW89_FCC][1][10] = -40,
- [0][1][RTW89_FCC][2][10] = 32,
[0][1][RTW89_ETSI][1][10] = 20,
[0][1][RTW89_ETSI][0][10] = -18,
[0][1][RTW89_MKK][1][10] = 18,
[0][1][RTW89_MKK][0][10] = -22,
[0][1][RTW89_IC][1][10] = -40,
- [0][1][RTW89_IC][2][10] = 32,
[0][1][RTW89_KCC][1][10] = -14,
[0][1][RTW89_KCC][0][10] = -14,
[0][1][RTW89_ACMA][1][10] = 20,
@@ -53719,13 +51731,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][10] = 6,
[0][1][RTW89_THAILAND][0][10] = -40,
[0][1][RTW89_FCC][1][12] = -40,
- [0][1][RTW89_FCC][2][12] = 32,
[0][1][RTW89_ETSI][1][12] = 20,
[0][1][RTW89_ETSI][0][12] = -18,
[0][1][RTW89_MKK][1][12] = 18,
[0][1][RTW89_MKK][0][12] = -22,
[0][1][RTW89_IC][1][12] = -40,
- [0][1][RTW89_IC][2][12] = 32,
[0][1][RTW89_KCC][1][12] = -14,
[0][1][RTW89_KCC][0][12] = -14,
[0][1][RTW89_ACMA][1][12] = 20,
@@ -53738,13 +51748,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][12] = 6,
[0][1][RTW89_THAILAND][0][12] = -40,
[0][1][RTW89_FCC][1][14] = -40,
- [0][1][RTW89_FCC][2][14] = 32,
[0][1][RTW89_ETSI][1][14] = 20,
[0][1][RTW89_ETSI][0][14] = -18,
[0][1][RTW89_MKK][1][14] = 18,
[0][1][RTW89_MKK][0][14] = -22,
[0][1][RTW89_IC][1][14] = -40,
- [0][1][RTW89_IC][2][14] = 32,
[0][1][RTW89_KCC][1][14] = -14,
[0][1][RTW89_KCC][0][14] = -14,
[0][1][RTW89_ACMA][1][14] = 20,
@@ -53757,13 +51765,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][14] = 6,
[0][1][RTW89_THAILAND][0][14] = -40,
[0][1][RTW89_FCC][1][15] = -40,
- [0][1][RTW89_FCC][2][15] = 32,
[0][1][RTW89_ETSI][1][15] = 20,
[0][1][RTW89_ETSI][0][15] = -18,
[0][1][RTW89_MKK][1][15] = 18,
[0][1][RTW89_MKK][0][15] = -22,
[0][1][RTW89_IC][1][15] = -40,
- [0][1][RTW89_IC][2][15] = 32,
[0][1][RTW89_KCC][1][15] = -14,
[0][1][RTW89_KCC][0][15] = -14,
[0][1][RTW89_ACMA][1][15] = 20,
@@ -53776,13 +51782,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][15] = 6,
[0][1][RTW89_THAILAND][0][15] = -40,
[0][1][RTW89_FCC][1][17] = -40,
- [0][1][RTW89_FCC][2][17] = 32,
[0][1][RTW89_ETSI][1][17] = 20,
[0][1][RTW89_ETSI][0][17] = -18,
[0][1][RTW89_MKK][1][17] = 18,
[0][1][RTW89_MKK][0][17] = -22,
[0][1][RTW89_IC][1][17] = -40,
- [0][1][RTW89_IC][2][17] = 32,
[0][1][RTW89_KCC][1][17] = -14,
[0][1][RTW89_KCC][0][17] = -14,
[0][1][RTW89_ACMA][1][17] = 20,
@@ -53795,13 +51799,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][17] = 6,
[0][1][RTW89_THAILAND][0][17] = -40,
[0][1][RTW89_FCC][1][19] = -40,
- [0][1][RTW89_FCC][2][19] = 32,
[0][1][RTW89_ETSI][1][19] = 20,
[0][1][RTW89_ETSI][0][19] = -18,
[0][1][RTW89_MKK][1][19] = 18,
[0][1][RTW89_MKK][0][19] = -22,
[0][1][RTW89_IC][1][19] = -40,
- [0][1][RTW89_IC][2][19] = 32,
[0][1][RTW89_KCC][1][19] = -14,
[0][1][RTW89_KCC][0][19] = -14,
[0][1][RTW89_ACMA][1][19] = 20,
@@ -53814,13 +51816,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][19] = 6,
[0][1][RTW89_THAILAND][0][19] = -40,
[0][1][RTW89_FCC][1][21] = -40,
- [0][1][RTW89_FCC][2][21] = 32,
[0][1][RTW89_ETSI][1][21] = 20,
[0][1][RTW89_ETSI][0][21] = -18,
[0][1][RTW89_MKK][1][21] = 18,
[0][1][RTW89_MKK][0][21] = -22,
[0][1][RTW89_IC][1][21] = -40,
- [0][1][RTW89_IC][2][21] = 32,
[0][1][RTW89_KCC][1][21] = -14,
[0][1][RTW89_KCC][0][21] = -14,
[0][1][RTW89_ACMA][1][21] = 20,
@@ -53833,13 +51833,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][21] = 6,
[0][1][RTW89_THAILAND][0][21] = -40,
[0][1][RTW89_FCC][1][23] = -40,
- [0][1][RTW89_FCC][2][23] = 32,
[0][1][RTW89_ETSI][1][23] = 20,
[0][1][RTW89_ETSI][0][23] = -18,
[0][1][RTW89_MKK][1][23] = 18,
[0][1][RTW89_MKK][0][23] = -22,
[0][1][RTW89_IC][1][23] = -40,
- [0][1][RTW89_IC][2][23] = 32,
[0][1][RTW89_KCC][1][23] = -14,
[0][1][RTW89_KCC][0][23] = -14,
[0][1][RTW89_ACMA][1][23] = 20,
@@ -53852,13 +51850,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][23] = 6,
[0][1][RTW89_THAILAND][0][23] = -40,
[0][1][RTW89_FCC][1][25] = -40,
- [0][1][RTW89_FCC][2][25] = 32,
[0][1][RTW89_ETSI][1][25] = 20,
[0][1][RTW89_ETSI][0][25] = -18,
[0][1][RTW89_MKK][1][25] = -4,
[0][1][RTW89_MKK][0][25] = -22,
[0][1][RTW89_IC][1][25] = -40,
- [0][1][RTW89_IC][2][25] = 32,
[0][1][RTW89_KCC][1][25] = -14,
[0][1][RTW89_KCC][0][25] = -14,
[0][1][RTW89_ACMA][1][25] = 20,
@@ -53871,13 +51867,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][25] = 6,
[0][1][RTW89_THAILAND][0][25] = -40,
[0][1][RTW89_FCC][1][27] = -40,
- [0][1][RTW89_FCC][2][27] = 32,
[0][1][RTW89_ETSI][1][27] = 20,
[0][1][RTW89_ETSI][0][27] = -18,
[0][1][RTW89_MKK][1][27] = -4,
[0][1][RTW89_MKK][0][27] = -22,
[0][1][RTW89_IC][1][27] = -40,
- [0][1][RTW89_IC][2][27] = 32,
[0][1][RTW89_KCC][1][27] = -14,
[0][1][RTW89_KCC][0][27] = -14,
[0][1][RTW89_ACMA][1][27] = 20,
@@ -53890,13 +51884,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][27] = 6,
[0][1][RTW89_THAILAND][0][27] = -40,
[0][1][RTW89_FCC][1][29] = -40,
- [0][1][RTW89_FCC][2][29] = 32,
[0][1][RTW89_ETSI][1][29] = 20,
[0][1][RTW89_ETSI][0][29] = -18,
[0][1][RTW89_MKK][1][29] = -4,
[0][1][RTW89_MKK][0][29] = -22,
[0][1][RTW89_IC][1][29] = -40,
- [0][1][RTW89_IC][2][29] = 32,
[0][1][RTW89_KCC][1][29] = -14,
[0][1][RTW89_KCC][0][29] = -14,
[0][1][RTW89_ACMA][1][29] = 20,
@@ -53909,13 +51901,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][29] = 6,
[0][1][RTW89_THAILAND][0][29] = -40,
[0][1][RTW89_FCC][1][30] = -40,
- [0][1][RTW89_FCC][2][30] = 32,
[0][1][RTW89_ETSI][1][30] = 20,
[0][1][RTW89_ETSI][0][30] = -18,
[0][1][RTW89_MKK][1][30] = -4,
[0][1][RTW89_MKK][0][30] = -22,
[0][1][RTW89_IC][1][30] = -40,
- [0][1][RTW89_IC][2][30] = 32,
[0][1][RTW89_KCC][1][30] = -14,
[0][1][RTW89_KCC][0][30] = -14,
[0][1][RTW89_ACMA][1][30] = 20,
@@ -53928,13 +51918,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][30] = 6,
[0][1][RTW89_THAILAND][0][30] = -40,
[0][1][RTW89_FCC][1][32] = -40,
- [0][1][RTW89_FCC][2][32] = 32,
[0][1][RTW89_ETSI][1][32] = 20,
[0][1][RTW89_ETSI][0][32] = -18,
[0][1][RTW89_MKK][1][32] = -4,
[0][1][RTW89_MKK][0][32] = -22,
[0][1][RTW89_IC][1][32] = -40,
- [0][1][RTW89_IC][2][32] = 32,
[0][1][RTW89_KCC][1][32] = -14,
[0][1][RTW89_KCC][0][32] = -14,
[0][1][RTW89_ACMA][1][32] = 20,
@@ -53947,13 +51935,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][32] = 6,
[0][1][RTW89_THAILAND][0][32] = -40,
[0][1][RTW89_FCC][1][34] = -40,
- [0][1][RTW89_FCC][2][34] = 32,
[0][1][RTW89_ETSI][1][34] = 20,
[0][1][RTW89_ETSI][0][34] = -18,
[0][1][RTW89_MKK][1][34] = -4,
[0][1][RTW89_MKK][0][34] = -22,
[0][1][RTW89_IC][1][34] = -40,
- [0][1][RTW89_IC][2][34] = 32,
[0][1][RTW89_KCC][1][34] = -14,
[0][1][RTW89_KCC][0][34] = -14,
[0][1][RTW89_ACMA][1][34] = 20,
@@ -53966,13 +51952,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][34] = 6,
[0][1][RTW89_THAILAND][0][34] = -40,
[0][1][RTW89_FCC][1][36] = -40,
- [0][1][RTW89_FCC][2][36] = 32,
[0][1][RTW89_ETSI][1][36] = 20,
[0][1][RTW89_ETSI][0][36] = -18,
[0][1][RTW89_MKK][1][36] = -4,
[0][1][RTW89_MKK][0][36] = -22,
[0][1][RTW89_IC][1][36] = -40,
- [0][1][RTW89_IC][2][36] = 32,
[0][1][RTW89_KCC][1][36] = -14,
[0][1][RTW89_KCC][0][36] = -14,
[0][1][RTW89_ACMA][1][36] = 20,
@@ -53985,13 +51969,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][36] = 6,
[0][1][RTW89_THAILAND][0][36] = -40,
[0][1][RTW89_FCC][1][38] = -40,
- [0][1][RTW89_FCC][2][38] = 32,
[0][1][RTW89_ETSI][1][38] = 20,
[0][1][RTW89_ETSI][0][38] = -18,
[0][1][RTW89_MKK][1][38] = -4,
[0][1][RTW89_MKK][0][38] = -22,
[0][1][RTW89_IC][1][38] = -40,
- [0][1][RTW89_IC][2][38] = 32,
[0][1][RTW89_KCC][1][38] = -14,
[0][1][RTW89_KCC][0][38] = -14,
[0][1][RTW89_ACMA][1][38] = 20,
@@ -54004,13 +51986,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][38] = 6,
[0][1][RTW89_THAILAND][0][38] = -40,
[0][1][RTW89_FCC][1][40] = -40,
- [0][1][RTW89_FCC][2][40] = 32,
[0][1][RTW89_ETSI][1][40] = 20,
[0][1][RTW89_ETSI][0][40] = -18,
[0][1][RTW89_MKK][1][40] = -4,
[0][1][RTW89_MKK][0][40] = -22,
[0][1][RTW89_IC][1][40] = -40,
- [0][1][RTW89_IC][2][40] = 32,
[0][1][RTW89_KCC][1][40] = -14,
[0][1][RTW89_KCC][0][40] = -14,
[0][1][RTW89_ACMA][1][40] = 20,
@@ -54023,13 +52003,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][40] = 6,
[0][1][RTW89_THAILAND][0][40] = -40,
[0][1][RTW89_FCC][1][42] = -40,
- [0][1][RTW89_FCC][2][42] = 32,
[0][1][RTW89_ETSI][1][42] = 20,
[0][1][RTW89_ETSI][0][42] = -18,
[0][1][RTW89_MKK][1][42] = -4,
[0][1][RTW89_MKK][0][42] = -22,
[0][1][RTW89_IC][1][42] = -40,
- [0][1][RTW89_IC][2][42] = 32,
[0][1][RTW89_KCC][1][42] = -14,
[0][1][RTW89_KCC][0][42] = -14,
[0][1][RTW89_ACMA][1][42] = 20,
@@ -54042,13 +52020,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][42] = 6,
[0][1][RTW89_THAILAND][0][42] = -40,
[0][1][RTW89_FCC][1][44] = -40,
- [0][1][RTW89_FCC][2][44] = 32,
[0][1][RTW89_ETSI][1][44] = 20,
[0][1][RTW89_ETSI][0][44] = -18,
[0][1][RTW89_MKK][1][44] = -4,
[0][1][RTW89_MKK][0][44] = -22,
[0][1][RTW89_IC][1][44] = -40,
- [0][1][RTW89_IC][2][44] = 32,
[0][1][RTW89_KCC][1][44] = -14,
[0][1][RTW89_KCC][0][44] = -14,
[0][1][RTW89_ACMA][1][44] = 20,
@@ -54061,13 +52037,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][44] = 6,
[0][1][RTW89_THAILAND][0][44] = -40,
[0][1][RTW89_FCC][1][45] = -40,
- [0][1][RTW89_FCC][2][45] = 127,
[0][1][RTW89_ETSI][1][45] = 127,
[0][1][RTW89_ETSI][0][45] = 127,
[0][1][RTW89_MKK][1][45] = 127,
[0][1][RTW89_MKK][0][45] = 127,
[0][1][RTW89_IC][1][45] = -40,
- [0][1][RTW89_IC][2][45] = 32,
[0][1][RTW89_KCC][1][45] = -14,
[0][1][RTW89_KCC][0][45] = 127,
[0][1][RTW89_ACMA][1][45] = 127,
@@ -54080,13 +52054,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][45] = 127,
[0][1][RTW89_THAILAND][0][45] = 127,
[0][1][RTW89_FCC][1][47] = -40,
- [0][1][RTW89_FCC][2][47] = 127,
[0][1][RTW89_ETSI][1][47] = 127,
[0][1][RTW89_ETSI][0][47] = 127,
[0][1][RTW89_MKK][1][47] = 127,
[0][1][RTW89_MKK][0][47] = 127,
[0][1][RTW89_IC][1][47] = -40,
- [0][1][RTW89_IC][2][47] = 32,
[0][1][RTW89_KCC][1][47] = -14,
[0][1][RTW89_KCC][0][47] = 127,
[0][1][RTW89_ACMA][1][47] = 127,
@@ -54099,13 +52071,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][47] = 127,
[0][1][RTW89_THAILAND][0][47] = 127,
[0][1][RTW89_FCC][1][49] = -40,
- [0][1][RTW89_FCC][2][49] = 127,
[0][1][RTW89_ETSI][1][49] = 127,
[0][1][RTW89_ETSI][0][49] = 127,
[0][1][RTW89_MKK][1][49] = 127,
[0][1][RTW89_MKK][0][49] = 127,
[0][1][RTW89_IC][1][49] = -40,
- [0][1][RTW89_IC][2][49] = 32,
[0][1][RTW89_KCC][1][49] = -14,
[0][1][RTW89_KCC][0][49] = 127,
[0][1][RTW89_ACMA][1][49] = 127,
@@ -54118,13 +52088,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][49] = 127,
[0][1][RTW89_THAILAND][0][49] = 127,
[0][1][RTW89_FCC][1][51] = -40,
- [0][1][RTW89_FCC][2][51] = 127,
[0][1][RTW89_ETSI][1][51] = 127,
[0][1][RTW89_ETSI][0][51] = 127,
[0][1][RTW89_MKK][1][51] = 127,
[0][1][RTW89_MKK][0][51] = 127,
[0][1][RTW89_IC][1][51] = -40,
- [0][1][RTW89_IC][2][51] = 32,
[0][1][RTW89_KCC][1][51] = -14,
[0][1][RTW89_KCC][0][51] = 127,
[0][1][RTW89_ACMA][1][51] = 127,
@@ -54137,13 +52105,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][51] = 127,
[0][1][RTW89_THAILAND][0][51] = 127,
[0][1][RTW89_FCC][1][53] = -40,
- [0][1][RTW89_FCC][2][53] = 127,
[0][1][RTW89_ETSI][1][53] = 127,
[0][1][RTW89_ETSI][0][53] = 127,
[0][1][RTW89_MKK][1][53] = 127,
[0][1][RTW89_MKK][0][53] = 127,
[0][1][RTW89_IC][1][53] = -40,
- [0][1][RTW89_IC][2][53] = 32,
[0][1][RTW89_KCC][1][53] = -14,
[0][1][RTW89_KCC][0][53] = 127,
[0][1][RTW89_ACMA][1][53] = 127,
@@ -54156,13 +52122,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][53] = 127,
[0][1][RTW89_THAILAND][0][53] = 127,
[0][1][RTW89_FCC][1][55] = -40,
- [0][1][RTW89_FCC][2][55] = 30,
[0][1][RTW89_ETSI][1][55] = 127,
[0][1][RTW89_ETSI][0][55] = 127,
[0][1][RTW89_MKK][1][55] = 127,
[0][1][RTW89_MKK][0][55] = 127,
[0][1][RTW89_IC][1][55] = -40,
- [0][1][RTW89_IC][2][55] = 30,
[0][1][RTW89_KCC][1][55] = -14,
[0][1][RTW89_KCC][0][55] = 127,
[0][1][RTW89_ACMA][1][55] = 127,
@@ -54175,13 +52139,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][55] = 127,
[0][1][RTW89_THAILAND][0][55] = 127,
[0][1][RTW89_FCC][1][57] = -40,
- [0][1][RTW89_FCC][2][57] = 30,
[0][1][RTW89_ETSI][1][57] = 127,
[0][1][RTW89_ETSI][0][57] = 127,
[0][1][RTW89_MKK][1][57] = 127,
[0][1][RTW89_MKK][0][57] = 127,
[0][1][RTW89_IC][1][57] = -40,
- [0][1][RTW89_IC][2][57] = 30,
[0][1][RTW89_KCC][1][57] = -14,
[0][1][RTW89_KCC][0][57] = 127,
[0][1][RTW89_ACMA][1][57] = 127,
@@ -54194,13 +52156,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][57] = 127,
[0][1][RTW89_THAILAND][0][57] = 127,
[0][1][RTW89_FCC][1][59] = -40,
- [0][1][RTW89_FCC][2][59] = 30,
[0][1][RTW89_ETSI][1][59] = 127,
[0][1][RTW89_ETSI][0][59] = 127,
[0][1][RTW89_MKK][1][59] = 127,
[0][1][RTW89_MKK][0][59] = 127,
[0][1][RTW89_IC][1][59] = -40,
- [0][1][RTW89_IC][2][59] = 30,
[0][1][RTW89_KCC][1][59] = -14,
[0][1][RTW89_KCC][0][59] = 127,
[0][1][RTW89_ACMA][1][59] = 127,
@@ -54213,13 +52173,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][59] = 127,
[0][1][RTW89_THAILAND][0][59] = 127,
[0][1][RTW89_FCC][1][60] = -40,
- [0][1][RTW89_FCC][2][60] = 30,
[0][1][RTW89_ETSI][1][60] = 127,
[0][1][RTW89_ETSI][0][60] = 127,
[0][1][RTW89_MKK][1][60] = 127,
[0][1][RTW89_MKK][0][60] = 127,
[0][1][RTW89_IC][1][60] = -40,
- [0][1][RTW89_IC][2][60] = 30,
[0][1][RTW89_KCC][1][60] = -14,
[0][1][RTW89_KCC][0][60] = 127,
[0][1][RTW89_ACMA][1][60] = 127,
@@ -54232,13 +52190,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][60] = 127,
[0][1][RTW89_THAILAND][0][60] = 127,
[0][1][RTW89_FCC][1][62] = -40,
- [0][1][RTW89_FCC][2][62] = 30,
[0][1][RTW89_ETSI][1][62] = 127,
[0][1][RTW89_ETSI][0][62] = 127,
[0][1][RTW89_MKK][1][62] = 127,
[0][1][RTW89_MKK][0][62] = 127,
[0][1][RTW89_IC][1][62] = -40,
- [0][1][RTW89_IC][2][62] = 30,
[0][1][RTW89_KCC][1][62] = -14,
[0][1][RTW89_KCC][0][62] = 127,
[0][1][RTW89_ACMA][1][62] = 127,
@@ -54251,13 +52207,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][62] = 127,
[0][1][RTW89_THAILAND][0][62] = 127,
[0][1][RTW89_FCC][1][64] = -40,
- [0][1][RTW89_FCC][2][64] = 30,
[0][1][RTW89_ETSI][1][64] = 127,
[0][1][RTW89_ETSI][0][64] = 127,
[0][1][RTW89_MKK][1][64] = 127,
[0][1][RTW89_MKK][0][64] = 127,
[0][1][RTW89_IC][1][64] = -40,
- [0][1][RTW89_IC][2][64] = 30,
[0][1][RTW89_KCC][1][64] = -14,
[0][1][RTW89_KCC][0][64] = 127,
[0][1][RTW89_ACMA][1][64] = 127,
@@ -54270,13 +52224,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][64] = 127,
[0][1][RTW89_THAILAND][0][64] = 127,
[0][1][RTW89_FCC][1][66] = -40,
- [0][1][RTW89_FCC][2][66] = 30,
[0][1][RTW89_ETSI][1][66] = 127,
[0][1][RTW89_ETSI][0][66] = 127,
[0][1][RTW89_MKK][1][66] = 127,
[0][1][RTW89_MKK][0][66] = 127,
[0][1][RTW89_IC][1][66] = -40,
- [0][1][RTW89_IC][2][66] = 30,
[0][1][RTW89_KCC][1][66] = -14,
[0][1][RTW89_KCC][0][66] = 127,
[0][1][RTW89_ACMA][1][66] = 127,
@@ -54289,13 +52241,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][66] = 127,
[0][1][RTW89_THAILAND][0][66] = 127,
[0][1][RTW89_FCC][1][68] = -40,
- [0][1][RTW89_FCC][2][68] = 30,
[0][1][RTW89_ETSI][1][68] = 127,
[0][1][RTW89_ETSI][0][68] = 127,
[0][1][RTW89_MKK][1][68] = 127,
[0][1][RTW89_MKK][0][68] = 127,
[0][1][RTW89_IC][1][68] = -40,
- [0][1][RTW89_IC][2][68] = 30,
[0][1][RTW89_KCC][1][68] = -14,
[0][1][RTW89_KCC][0][68] = 127,
[0][1][RTW89_ACMA][1][68] = 127,
@@ -54308,13 +52258,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][68] = 127,
[0][1][RTW89_THAILAND][0][68] = 127,
[0][1][RTW89_FCC][1][70] = -38,
- [0][1][RTW89_FCC][2][70] = 30,
[0][1][RTW89_ETSI][1][70] = 127,
[0][1][RTW89_ETSI][0][70] = 127,
[0][1][RTW89_MKK][1][70] = 127,
[0][1][RTW89_MKK][0][70] = 127,
[0][1][RTW89_IC][1][70] = -38,
- [0][1][RTW89_IC][2][70] = 30,
[0][1][RTW89_KCC][1][70] = -14,
[0][1][RTW89_KCC][0][70] = 127,
[0][1][RTW89_ACMA][1][70] = 127,
@@ -54327,13 +52275,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][70] = 127,
[0][1][RTW89_THAILAND][0][70] = 127,
[0][1][RTW89_FCC][1][72] = -38,
- [0][1][RTW89_FCC][2][72] = 30,
[0][1][RTW89_ETSI][1][72] = 127,
[0][1][RTW89_ETSI][0][72] = 127,
[0][1][RTW89_MKK][1][72] = 127,
[0][1][RTW89_MKK][0][72] = 127,
[0][1][RTW89_IC][1][72] = -38,
- [0][1][RTW89_IC][2][72] = 30,
[0][1][RTW89_KCC][1][72] = -14,
[0][1][RTW89_KCC][0][72] = 127,
[0][1][RTW89_ACMA][1][72] = 127,
@@ -54346,13 +52292,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][72] = 127,
[0][1][RTW89_THAILAND][0][72] = 127,
[0][1][RTW89_FCC][1][74] = -38,
- [0][1][RTW89_FCC][2][74] = 30,
[0][1][RTW89_ETSI][1][74] = 127,
[0][1][RTW89_ETSI][0][74] = 127,
[0][1][RTW89_MKK][1][74] = 127,
[0][1][RTW89_MKK][0][74] = 127,
[0][1][RTW89_IC][1][74] = -38,
- [0][1][RTW89_IC][2][74] = 30,
[0][1][RTW89_KCC][1][74] = -14,
[0][1][RTW89_KCC][0][74] = 127,
[0][1][RTW89_ACMA][1][74] = 127,
@@ -54365,13 +52309,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][74] = 127,
[0][1][RTW89_THAILAND][0][74] = 127,
[0][1][RTW89_FCC][1][75] = -38,
- [0][1][RTW89_FCC][2][75] = 30,
[0][1][RTW89_ETSI][1][75] = 127,
[0][1][RTW89_ETSI][0][75] = 127,
[0][1][RTW89_MKK][1][75] = 127,
[0][1][RTW89_MKK][0][75] = 127,
[0][1][RTW89_IC][1][75] = -38,
- [0][1][RTW89_IC][2][75] = 30,
[0][1][RTW89_KCC][1][75] = -14,
[0][1][RTW89_KCC][0][75] = 127,
[0][1][RTW89_ACMA][1][75] = 127,
@@ -54384,13 +52326,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][75] = 127,
[0][1][RTW89_THAILAND][0][75] = 127,
[0][1][RTW89_FCC][1][77] = -38,
- [0][1][RTW89_FCC][2][77] = 30,
[0][1][RTW89_ETSI][1][77] = 127,
[0][1][RTW89_ETSI][0][77] = 127,
[0][1][RTW89_MKK][1][77] = 127,
[0][1][RTW89_MKK][0][77] = 127,
[0][1][RTW89_IC][1][77] = -38,
- [0][1][RTW89_IC][2][77] = 30,
[0][1][RTW89_KCC][1][77] = -14,
[0][1][RTW89_KCC][0][77] = 127,
[0][1][RTW89_ACMA][1][77] = 127,
@@ -54403,13 +52343,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][77] = 127,
[0][1][RTW89_THAILAND][0][77] = 127,
[0][1][RTW89_FCC][1][79] = -38,
- [0][1][RTW89_FCC][2][79] = 30,
[0][1][RTW89_ETSI][1][79] = 127,
[0][1][RTW89_ETSI][0][79] = 127,
[0][1][RTW89_MKK][1][79] = 127,
[0][1][RTW89_MKK][0][79] = 127,
[0][1][RTW89_IC][1][79] = -38,
- [0][1][RTW89_IC][2][79] = 30,
[0][1][RTW89_KCC][1][79] = -14,
[0][1][RTW89_KCC][0][79] = 127,
[0][1][RTW89_ACMA][1][79] = 127,
@@ -54422,13 +52360,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][79] = 127,
[0][1][RTW89_THAILAND][0][79] = 127,
[0][1][RTW89_FCC][1][81] = -38,
- [0][1][RTW89_FCC][2][81] = 30,
[0][1][RTW89_ETSI][1][81] = 127,
[0][1][RTW89_ETSI][0][81] = 127,
[0][1][RTW89_MKK][1][81] = 127,
[0][1][RTW89_MKK][0][81] = 127,
[0][1][RTW89_IC][1][81] = -38,
- [0][1][RTW89_IC][2][81] = 30,
[0][1][RTW89_KCC][1][81] = -14,
[0][1][RTW89_KCC][0][81] = 127,
[0][1][RTW89_ACMA][1][81] = 127,
@@ -54441,13 +52377,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][81] = 127,
[0][1][RTW89_THAILAND][0][81] = 127,
[0][1][RTW89_FCC][1][83] = -38,
- [0][1][RTW89_FCC][2][83] = 30,
[0][1][RTW89_ETSI][1][83] = 127,
[0][1][RTW89_ETSI][0][83] = 127,
[0][1][RTW89_MKK][1][83] = 127,
[0][1][RTW89_MKK][0][83] = 127,
[0][1][RTW89_IC][1][83] = -38,
- [0][1][RTW89_IC][2][83] = 30,
[0][1][RTW89_KCC][1][83] = -14,
[0][1][RTW89_KCC][0][83] = 127,
[0][1][RTW89_ACMA][1][83] = 127,
@@ -54460,13 +52394,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][83] = 127,
[0][1][RTW89_THAILAND][0][83] = 127,
[0][1][RTW89_FCC][1][85] = -38,
- [0][1][RTW89_FCC][2][85] = 30,
[0][1][RTW89_ETSI][1][85] = 127,
[0][1][RTW89_ETSI][0][85] = 127,
[0][1][RTW89_MKK][1][85] = 127,
[0][1][RTW89_MKK][0][85] = 127,
[0][1][RTW89_IC][1][85] = -38,
- [0][1][RTW89_IC][2][85] = 30,
[0][1][RTW89_KCC][1][85] = -14,
[0][1][RTW89_KCC][0][85] = 127,
[0][1][RTW89_ACMA][1][85] = 127,
@@ -54479,13 +52411,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][85] = 127,
[0][1][RTW89_THAILAND][0][85] = 127,
[0][1][RTW89_FCC][1][87] = -40,
- [0][1][RTW89_FCC][2][87] = 127,
[0][1][RTW89_ETSI][1][87] = 127,
[0][1][RTW89_ETSI][0][87] = 127,
[0][1][RTW89_MKK][1][87] = 127,
[0][1][RTW89_MKK][0][87] = 127,
[0][1][RTW89_IC][1][87] = -40,
- [0][1][RTW89_IC][2][87] = 127,
[0][1][RTW89_KCC][1][87] = -14,
[0][1][RTW89_KCC][0][87] = 127,
[0][1][RTW89_ACMA][1][87] = 127,
@@ -54498,13 +52428,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][87] = 127,
[0][1][RTW89_THAILAND][0][87] = 127,
[0][1][RTW89_FCC][1][89] = -38,
- [0][1][RTW89_FCC][2][89] = 127,
[0][1][RTW89_ETSI][1][89] = 127,
[0][1][RTW89_ETSI][0][89] = 127,
[0][1][RTW89_MKK][1][89] = 127,
[0][1][RTW89_MKK][0][89] = 127,
[0][1][RTW89_IC][1][89] = -38,
- [0][1][RTW89_IC][2][89] = 127,
[0][1][RTW89_KCC][1][89] = -14,
[0][1][RTW89_KCC][0][89] = 127,
[0][1][RTW89_ACMA][1][89] = 127,
@@ -54517,13 +52445,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][89] = 127,
[0][1][RTW89_THAILAND][0][89] = 127,
[0][1][RTW89_FCC][1][90] = -38,
- [0][1][RTW89_FCC][2][90] = 127,
[0][1][RTW89_ETSI][1][90] = 127,
[0][1][RTW89_ETSI][0][90] = 127,
[0][1][RTW89_MKK][1][90] = 127,
[0][1][RTW89_MKK][0][90] = 127,
[0][1][RTW89_IC][1][90] = -38,
- [0][1][RTW89_IC][2][90] = 127,
[0][1][RTW89_KCC][1][90] = -14,
[0][1][RTW89_KCC][0][90] = 127,
[0][1][RTW89_ACMA][1][90] = 127,
@@ -54536,13 +52462,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][90] = 127,
[0][1][RTW89_THAILAND][0][90] = 127,
[0][1][RTW89_FCC][1][92] = -38,
- [0][1][RTW89_FCC][2][92] = 127,
[0][1][RTW89_ETSI][1][92] = 127,
[0][1][RTW89_ETSI][0][92] = 127,
[0][1][RTW89_MKK][1][92] = 127,
[0][1][RTW89_MKK][0][92] = 127,
[0][1][RTW89_IC][1][92] = -38,
- [0][1][RTW89_IC][2][92] = 127,
[0][1][RTW89_KCC][1][92] = -14,
[0][1][RTW89_KCC][0][92] = 127,
[0][1][RTW89_ACMA][1][92] = 127,
@@ -54555,13 +52479,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][92] = 127,
[0][1][RTW89_THAILAND][0][92] = 127,
[0][1][RTW89_FCC][1][94] = -38,
- [0][1][RTW89_FCC][2][94] = 127,
[0][1][RTW89_ETSI][1][94] = 127,
[0][1][RTW89_ETSI][0][94] = 127,
[0][1][RTW89_MKK][1][94] = 127,
[0][1][RTW89_MKK][0][94] = 127,
[0][1][RTW89_IC][1][94] = -38,
- [0][1][RTW89_IC][2][94] = 127,
[0][1][RTW89_KCC][1][94] = -14,
[0][1][RTW89_KCC][0][94] = 127,
[0][1][RTW89_ACMA][1][94] = 127,
@@ -54574,13 +52496,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][94] = 127,
[0][1][RTW89_THAILAND][0][94] = 127,
[0][1][RTW89_FCC][1][96] = -38,
- [0][1][RTW89_FCC][2][96] = 127,
[0][1][RTW89_ETSI][1][96] = 127,
[0][1][RTW89_ETSI][0][96] = 127,
[0][1][RTW89_MKK][1][96] = 127,
[0][1][RTW89_MKK][0][96] = 127,
[0][1][RTW89_IC][1][96] = -38,
- [0][1][RTW89_IC][2][96] = 127,
[0][1][RTW89_KCC][1][96] = -14,
[0][1][RTW89_KCC][0][96] = 127,
[0][1][RTW89_ACMA][1][96] = 127,
@@ -54593,13 +52513,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][96] = 127,
[0][1][RTW89_THAILAND][0][96] = 127,
[0][1][RTW89_FCC][1][98] = -38,
- [0][1][RTW89_FCC][2][98] = 127,
[0][1][RTW89_ETSI][1][98] = 127,
[0][1][RTW89_ETSI][0][98] = 127,
[0][1][RTW89_MKK][1][98] = 127,
[0][1][RTW89_MKK][0][98] = 127,
[0][1][RTW89_IC][1][98] = -38,
- [0][1][RTW89_IC][2][98] = 127,
[0][1][RTW89_KCC][1][98] = -14,
[0][1][RTW89_KCC][0][98] = 127,
[0][1][RTW89_ACMA][1][98] = 127,
@@ -54612,13 +52530,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][98] = 127,
[0][1][RTW89_THAILAND][0][98] = 127,
[0][1][RTW89_FCC][1][100] = -38,
- [0][1][RTW89_FCC][2][100] = 127,
[0][1][RTW89_ETSI][1][100] = 127,
[0][1][RTW89_ETSI][0][100] = 127,
[0][1][RTW89_MKK][1][100] = 127,
[0][1][RTW89_MKK][0][100] = 127,
[0][1][RTW89_IC][1][100] = -38,
- [0][1][RTW89_IC][2][100] = 127,
[0][1][RTW89_KCC][1][100] = -14,
[0][1][RTW89_KCC][0][100] = 127,
[0][1][RTW89_ACMA][1][100] = 127,
@@ -54631,13 +52547,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][100] = 127,
[0][1][RTW89_THAILAND][0][100] = 127,
[0][1][RTW89_FCC][1][102] = -38,
- [0][1][RTW89_FCC][2][102] = 127,
[0][1][RTW89_ETSI][1][102] = 127,
[0][1][RTW89_ETSI][0][102] = 127,
[0][1][RTW89_MKK][1][102] = 127,
[0][1][RTW89_MKK][0][102] = 127,
[0][1][RTW89_IC][1][102] = -38,
- [0][1][RTW89_IC][2][102] = 127,
[0][1][RTW89_KCC][1][102] = -14,
[0][1][RTW89_KCC][0][102] = 127,
[0][1][RTW89_ACMA][1][102] = 127,
@@ -54650,13 +52564,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][102] = 127,
[0][1][RTW89_THAILAND][0][102] = 127,
[0][1][RTW89_FCC][1][104] = -38,
- [0][1][RTW89_FCC][2][104] = 127,
[0][1][RTW89_ETSI][1][104] = 127,
[0][1][RTW89_ETSI][0][104] = 127,
[0][1][RTW89_MKK][1][104] = 127,
[0][1][RTW89_MKK][0][104] = 127,
[0][1][RTW89_IC][1][104] = -38,
- [0][1][RTW89_IC][2][104] = 127,
[0][1][RTW89_KCC][1][104] = -14,
[0][1][RTW89_KCC][0][104] = 127,
[0][1][RTW89_ACMA][1][104] = 127,
@@ -54669,13 +52581,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][104] = 127,
[0][1][RTW89_THAILAND][0][104] = 127,
[0][1][RTW89_FCC][1][105] = -38,
- [0][1][RTW89_FCC][2][105] = 127,
[0][1][RTW89_ETSI][1][105] = 127,
[0][1][RTW89_ETSI][0][105] = 127,
[0][1][RTW89_MKK][1][105] = 127,
[0][1][RTW89_MKK][0][105] = 127,
[0][1][RTW89_IC][1][105] = -38,
- [0][1][RTW89_IC][2][105] = 127,
[0][1][RTW89_KCC][1][105] = -14,
[0][1][RTW89_KCC][0][105] = 127,
[0][1][RTW89_ACMA][1][105] = 127,
@@ -54688,13 +52598,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][105] = 127,
[0][1][RTW89_THAILAND][0][105] = 127,
[0][1][RTW89_FCC][1][107] = -34,
- [0][1][RTW89_FCC][2][107] = 127,
[0][1][RTW89_ETSI][1][107] = 127,
[0][1][RTW89_ETSI][0][107] = 127,
[0][1][RTW89_MKK][1][107] = 127,
[0][1][RTW89_MKK][0][107] = 127,
[0][1][RTW89_IC][1][107] = -34,
- [0][1][RTW89_IC][2][107] = 127,
[0][1][RTW89_KCC][1][107] = -14,
[0][1][RTW89_KCC][0][107] = 127,
[0][1][RTW89_ACMA][1][107] = 127,
@@ -54707,13 +52615,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][107] = 127,
[0][1][RTW89_THAILAND][0][107] = 127,
[0][1][RTW89_FCC][1][109] = -34,
- [0][1][RTW89_FCC][2][109] = 127,
[0][1][RTW89_ETSI][1][109] = 127,
[0][1][RTW89_ETSI][0][109] = 127,
[0][1][RTW89_MKK][1][109] = 127,
[0][1][RTW89_MKK][0][109] = 127,
[0][1][RTW89_IC][1][109] = -34,
- [0][1][RTW89_IC][2][109] = 127,
[0][1][RTW89_KCC][1][109] = 127,
[0][1][RTW89_KCC][0][109] = 127,
[0][1][RTW89_ACMA][1][109] = 127,
@@ -54726,13 +52632,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][109] = 127,
[0][1][RTW89_THAILAND][0][109] = 127,
[0][1][RTW89_FCC][1][111] = 127,
- [0][1][RTW89_FCC][2][111] = 127,
[0][1][RTW89_ETSI][1][111] = 127,
[0][1][RTW89_ETSI][0][111] = 127,
[0][1][RTW89_MKK][1][111] = 127,
[0][1][RTW89_MKK][0][111] = 127,
[0][1][RTW89_IC][1][111] = 127,
- [0][1][RTW89_IC][2][111] = 127,
[0][1][RTW89_KCC][1][111] = 127,
[0][1][RTW89_KCC][0][111] = 127,
[0][1][RTW89_ACMA][1][111] = 127,
@@ -54745,13 +52649,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][111] = 127,
[0][1][RTW89_THAILAND][0][111] = 127,
[0][1][RTW89_FCC][1][113] = 127,
- [0][1][RTW89_FCC][2][113] = 127,
[0][1][RTW89_ETSI][1][113] = 127,
[0][1][RTW89_ETSI][0][113] = 127,
[0][1][RTW89_MKK][1][113] = 127,
[0][1][RTW89_MKK][0][113] = 127,
[0][1][RTW89_IC][1][113] = 127,
- [0][1][RTW89_IC][2][113] = 127,
[0][1][RTW89_KCC][1][113] = 127,
[0][1][RTW89_KCC][0][113] = 127,
[0][1][RTW89_ACMA][1][113] = 127,
@@ -54764,13 +52666,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][113] = 127,
[0][1][RTW89_THAILAND][0][113] = 127,
[0][1][RTW89_FCC][1][115] = 127,
- [0][1][RTW89_FCC][2][115] = 127,
[0][1][RTW89_ETSI][1][115] = 127,
[0][1][RTW89_ETSI][0][115] = 127,
[0][1][RTW89_MKK][1][115] = 127,
[0][1][RTW89_MKK][0][115] = 127,
[0][1][RTW89_IC][1][115] = 127,
- [0][1][RTW89_IC][2][115] = 127,
[0][1][RTW89_KCC][1][115] = 127,
[0][1][RTW89_KCC][0][115] = 127,
[0][1][RTW89_ACMA][1][115] = 127,
@@ -54783,13 +52683,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][115] = 127,
[0][1][RTW89_THAILAND][0][115] = 127,
[0][1][RTW89_FCC][1][117] = 127,
- [0][1][RTW89_FCC][2][117] = 127,
[0][1][RTW89_ETSI][1][117] = 127,
[0][1][RTW89_ETSI][0][117] = 127,
[0][1][RTW89_MKK][1][117] = 127,
[0][1][RTW89_MKK][0][117] = 127,
[0][1][RTW89_IC][1][117] = 127,
- [0][1][RTW89_IC][2][117] = 127,
[0][1][RTW89_KCC][1][117] = 127,
[0][1][RTW89_KCC][0][117] = 127,
[0][1][RTW89_ACMA][1][117] = 127,
@@ -54802,13 +52700,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][117] = 127,
[0][1][RTW89_THAILAND][0][117] = 127,
[0][1][RTW89_FCC][1][119] = 127,
- [0][1][RTW89_FCC][2][119] = 127,
[0][1][RTW89_ETSI][1][119] = 127,
[0][1][RTW89_ETSI][0][119] = 127,
[0][1][RTW89_MKK][1][119] = 127,
[0][1][RTW89_MKK][0][119] = 127,
[0][1][RTW89_IC][1][119] = 127,
- [0][1][RTW89_IC][2][119] = 127,
[0][1][RTW89_KCC][1][119] = 127,
[0][1][RTW89_KCC][0][119] = 127,
[0][1][RTW89_ACMA][1][119] = 127,
@@ -54821,13 +52717,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[0][1][RTW89_THAILAND][1][119] = 127,
[0][1][RTW89_THAILAND][0][119] = 127,
[1][0][RTW89_FCC][1][0] = -4,
- [1][0][RTW89_FCC][2][0] = 52,
[1][0][RTW89_ETSI][1][0] = 46,
[1][0][RTW89_ETSI][0][0] = 6,
[1][0][RTW89_MKK][1][0] = 42,
[1][0][RTW89_MKK][0][0] = 2,
[1][0][RTW89_IC][1][0] = -4,
- [1][0][RTW89_IC][2][0] = 52,
[1][0][RTW89_KCC][1][0] = -2,
[1][0][RTW89_KCC][0][0] = -2,
[1][0][RTW89_ACMA][1][0] = 46,
@@ -54840,13 +52734,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][0] = 42,
[1][0][RTW89_THAILAND][0][0] = -4,
[1][0][RTW89_FCC][1][2] = -4,
- [1][0][RTW89_FCC][2][2] = 52,
[1][0][RTW89_ETSI][1][2] = 46,
[1][0][RTW89_ETSI][0][2] = 6,
[1][0][RTW89_MKK][1][2] = 42,
[1][0][RTW89_MKK][0][2] = 2,
[1][0][RTW89_IC][1][2] = -4,
- [1][0][RTW89_IC][2][2] = 52,
[1][0][RTW89_KCC][1][2] = -2,
[1][0][RTW89_KCC][0][2] = -2,
[1][0][RTW89_ACMA][1][2] = 46,
@@ -54859,13 +52751,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][2] = 42,
[1][0][RTW89_THAILAND][0][2] = -4,
[1][0][RTW89_FCC][1][4] = -4,
- [1][0][RTW89_FCC][2][4] = 52,
[1][0][RTW89_ETSI][1][4] = 46,
[1][0][RTW89_ETSI][0][4] = 6,
[1][0][RTW89_MKK][1][4] = 42,
[1][0][RTW89_MKK][0][4] = 2,
[1][0][RTW89_IC][1][4] = -4,
- [1][0][RTW89_IC][2][4] = 52,
[1][0][RTW89_KCC][1][4] = -2,
[1][0][RTW89_KCC][0][4] = -2,
[1][0][RTW89_ACMA][1][4] = 46,
@@ -54878,13 +52768,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][4] = 42,
[1][0][RTW89_THAILAND][0][4] = -4,
[1][0][RTW89_FCC][1][6] = -4,
- [1][0][RTW89_FCC][2][6] = 52,
[1][0][RTW89_ETSI][1][6] = 46,
[1][0][RTW89_ETSI][0][6] = 6,
[1][0][RTW89_MKK][1][6] = 42,
[1][0][RTW89_MKK][0][6] = 2,
[1][0][RTW89_IC][1][6] = -4,
- [1][0][RTW89_IC][2][6] = 52,
[1][0][RTW89_KCC][1][6] = -2,
[1][0][RTW89_KCC][0][6] = -2,
[1][0][RTW89_ACMA][1][6] = 46,
@@ -54897,13 +52785,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][6] = 42,
[1][0][RTW89_THAILAND][0][6] = -4,
[1][0][RTW89_FCC][1][8] = -4,
- [1][0][RTW89_FCC][2][8] = 52,
[1][0][RTW89_ETSI][1][8] = 46,
[1][0][RTW89_ETSI][0][8] = 6,
[1][0][RTW89_MKK][1][8] = 42,
[1][0][RTW89_MKK][0][8] = 2,
[1][0][RTW89_IC][1][8] = -4,
- [1][0][RTW89_IC][2][8] = 52,
[1][0][RTW89_KCC][1][8] = -2,
[1][0][RTW89_KCC][0][8] = -2,
[1][0][RTW89_ACMA][1][8] = 46,
@@ -54916,13 +52802,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][8] = 42,
[1][0][RTW89_THAILAND][0][8] = -4,
[1][0][RTW89_FCC][1][10] = -4,
- [1][0][RTW89_FCC][2][10] = 52,
[1][0][RTW89_ETSI][1][10] = 46,
[1][0][RTW89_ETSI][0][10] = 6,
[1][0][RTW89_MKK][1][10] = 42,
[1][0][RTW89_MKK][0][10] = 2,
[1][0][RTW89_IC][1][10] = -4,
- [1][0][RTW89_IC][2][10] = 52,
[1][0][RTW89_KCC][1][10] = -2,
[1][0][RTW89_KCC][0][10] = -2,
[1][0][RTW89_ACMA][1][10] = 46,
@@ -54935,13 +52819,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][10] = 42,
[1][0][RTW89_THAILAND][0][10] = -4,
[1][0][RTW89_FCC][1][12] = -4,
- [1][0][RTW89_FCC][2][12] = 52,
[1][0][RTW89_ETSI][1][12] = 46,
[1][0][RTW89_ETSI][0][12] = 6,
[1][0][RTW89_MKK][1][12] = 42,
[1][0][RTW89_MKK][0][12] = 2,
[1][0][RTW89_IC][1][12] = -4,
- [1][0][RTW89_IC][2][12] = 52,
[1][0][RTW89_KCC][1][12] = -2,
[1][0][RTW89_KCC][0][12] = -2,
[1][0][RTW89_ACMA][1][12] = 46,
@@ -54954,13 +52836,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][12] = 42,
[1][0][RTW89_THAILAND][0][12] = -4,
[1][0][RTW89_FCC][1][14] = -4,
- [1][0][RTW89_FCC][2][14] = 52,
[1][0][RTW89_ETSI][1][14] = 46,
[1][0][RTW89_ETSI][0][14] = 6,
[1][0][RTW89_MKK][1][14] = 42,
[1][0][RTW89_MKK][0][14] = 2,
[1][0][RTW89_IC][1][14] = -4,
- [1][0][RTW89_IC][2][14] = 52,
[1][0][RTW89_KCC][1][14] = -2,
[1][0][RTW89_KCC][0][14] = -2,
[1][0][RTW89_ACMA][1][14] = 46,
@@ -54973,13 +52853,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][14] = 42,
[1][0][RTW89_THAILAND][0][14] = -4,
[1][0][RTW89_FCC][1][15] = -4,
- [1][0][RTW89_FCC][2][15] = 52,
[1][0][RTW89_ETSI][1][15] = 46,
[1][0][RTW89_ETSI][0][15] = 6,
[1][0][RTW89_MKK][1][15] = 42,
[1][0][RTW89_MKK][0][15] = 2,
[1][0][RTW89_IC][1][15] = -4,
- [1][0][RTW89_IC][2][15] = 52,
[1][0][RTW89_KCC][1][15] = -2,
[1][0][RTW89_KCC][0][15] = -2,
[1][0][RTW89_ACMA][1][15] = 46,
@@ -54992,13 +52870,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][15] = 42,
[1][0][RTW89_THAILAND][0][15] = -4,
[1][0][RTW89_FCC][1][17] = -4,
- [1][0][RTW89_FCC][2][17] = 52,
[1][0][RTW89_ETSI][1][17] = 46,
[1][0][RTW89_ETSI][0][17] = 6,
[1][0][RTW89_MKK][1][17] = 42,
[1][0][RTW89_MKK][0][17] = 2,
[1][0][RTW89_IC][1][17] = -4,
- [1][0][RTW89_IC][2][17] = 52,
[1][0][RTW89_KCC][1][17] = -2,
[1][0][RTW89_KCC][0][17] = -2,
[1][0][RTW89_ACMA][1][17] = 46,
@@ -55011,13 +52887,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][17] = 42,
[1][0][RTW89_THAILAND][0][17] = -4,
[1][0][RTW89_FCC][1][19] = -4,
- [1][0][RTW89_FCC][2][19] = 52,
[1][0][RTW89_ETSI][1][19] = 46,
[1][0][RTW89_ETSI][0][19] = 6,
[1][0][RTW89_MKK][1][19] = 42,
[1][0][RTW89_MKK][0][19] = 2,
[1][0][RTW89_IC][1][19] = -4,
- [1][0][RTW89_IC][2][19] = 52,
[1][0][RTW89_KCC][1][19] = -2,
[1][0][RTW89_KCC][0][19] = -2,
[1][0][RTW89_ACMA][1][19] = 46,
@@ -55030,13 +52904,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][19] = 42,
[1][0][RTW89_THAILAND][0][19] = -4,
[1][0][RTW89_FCC][1][21] = -4,
- [1][0][RTW89_FCC][2][21] = 52,
[1][0][RTW89_ETSI][1][21] = 46,
[1][0][RTW89_ETSI][0][21] = 6,
[1][0][RTW89_MKK][1][21] = 42,
[1][0][RTW89_MKK][0][21] = 2,
[1][0][RTW89_IC][1][21] = -4,
- [1][0][RTW89_IC][2][21] = 52,
[1][0][RTW89_KCC][1][21] = -2,
[1][0][RTW89_KCC][0][21] = -2,
[1][0][RTW89_ACMA][1][21] = 46,
@@ -55049,13 +52921,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][21] = 42,
[1][0][RTW89_THAILAND][0][21] = -4,
[1][0][RTW89_FCC][1][23] = -4,
- [1][0][RTW89_FCC][2][23] = 66,
[1][0][RTW89_ETSI][1][23] = 46,
[1][0][RTW89_ETSI][0][23] = 6,
[1][0][RTW89_MKK][1][23] = 42,
[1][0][RTW89_MKK][0][23] = 2,
[1][0][RTW89_IC][1][23] = -4,
- [1][0][RTW89_IC][2][23] = 66,
[1][0][RTW89_KCC][1][23] = -2,
[1][0][RTW89_KCC][0][23] = -2,
[1][0][RTW89_ACMA][1][23] = 46,
@@ -55068,13 +52938,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][23] = 42,
[1][0][RTW89_THAILAND][0][23] = -4,
[1][0][RTW89_FCC][1][25] = -4,
- [1][0][RTW89_FCC][2][25] = 66,
[1][0][RTW89_ETSI][1][25] = 46,
[1][0][RTW89_ETSI][0][25] = 6,
[1][0][RTW89_MKK][1][25] = 42,
[1][0][RTW89_MKK][0][25] = 2,
[1][0][RTW89_IC][1][25] = -4,
- [1][0][RTW89_IC][2][25] = 66,
[1][0][RTW89_KCC][1][25] = -2,
[1][0][RTW89_KCC][0][25] = -2,
[1][0][RTW89_ACMA][1][25] = 46,
@@ -55087,13 +52955,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][25] = 42,
[1][0][RTW89_THAILAND][0][25] = -4,
[1][0][RTW89_FCC][1][27] = -4,
- [1][0][RTW89_FCC][2][27] = 66,
[1][0][RTW89_ETSI][1][27] = 46,
[1][0][RTW89_ETSI][0][27] = 6,
[1][0][RTW89_MKK][1][27] = 42,
[1][0][RTW89_MKK][0][27] = 2,
[1][0][RTW89_IC][1][27] = -4,
- [1][0][RTW89_IC][2][27] = 66,
[1][0][RTW89_KCC][1][27] = -2,
[1][0][RTW89_KCC][0][27] = -2,
[1][0][RTW89_ACMA][1][27] = 46,
@@ -55106,13 +52972,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][27] = 42,
[1][0][RTW89_THAILAND][0][27] = -4,
[1][0][RTW89_FCC][1][29] = -4,
- [1][0][RTW89_FCC][2][29] = 66,
[1][0][RTW89_ETSI][1][29] = 46,
[1][0][RTW89_ETSI][0][29] = 6,
[1][0][RTW89_MKK][1][29] = 42,
[1][0][RTW89_MKK][0][29] = 2,
[1][0][RTW89_IC][1][29] = -4,
- [1][0][RTW89_IC][2][29] = 66,
[1][0][RTW89_KCC][1][29] = -2,
[1][0][RTW89_KCC][0][29] = -2,
[1][0][RTW89_ACMA][1][29] = 46,
@@ -55125,13 +52989,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][29] = 42,
[1][0][RTW89_THAILAND][0][29] = -4,
[1][0][RTW89_FCC][1][30] = -4,
- [1][0][RTW89_FCC][2][30] = 66,
[1][0][RTW89_ETSI][1][30] = 46,
[1][0][RTW89_ETSI][0][30] = 6,
[1][0][RTW89_MKK][1][30] = 42,
[1][0][RTW89_MKK][0][30] = 2,
[1][0][RTW89_IC][1][30] = -4,
- [1][0][RTW89_IC][2][30] = 66,
[1][0][RTW89_KCC][1][30] = -2,
[1][0][RTW89_KCC][0][30] = -2,
[1][0][RTW89_ACMA][1][30] = 46,
@@ -55144,13 +53006,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][30] = 42,
[1][0][RTW89_THAILAND][0][30] = -4,
[1][0][RTW89_FCC][1][32] = -4,
- [1][0][RTW89_FCC][2][32] = 66,
[1][0][RTW89_ETSI][1][32] = 46,
[1][0][RTW89_ETSI][0][32] = 6,
[1][0][RTW89_MKK][1][32] = 42,
[1][0][RTW89_MKK][0][32] = 2,
[1][0][RTW89_IC][1][32] = -4,
- [1][0][RTW89_IC][2][32] = 66,
[1][0][RTW89_KCC][1][32] = -2,
[1][0][RTW89_KCC][0][32] = -2,
[1][0][RTW89_ACMA][1][32] = 46,
@@ -55163,13 +53023,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][32] = 42,
[1][0][RTW89_THAILAND][0][32] = -4,
[1][0][RTW89_FCC][1][34] = -4,
- [1][0][RTW89_FCC][2][34] = 66,
[1][0][RTW89_ETSI][1][34] = 46,
[1][0][RTW89_ETSI][0][34] = 6,
[1][0][RTW89_MKK][1][34] = 42,
[1][0][RTW89_MKK][0][34] = 2,
[1][0][RTW89_IC][1][34] = -4,
- [1][0][RTW89_IC][2][34] = 66,
[1][0][RTW89_KCC][1][34] = -2,
[1][0][RTW89_KCC][0][34] = -2,
[1][0][RTW89_ACMA][1][34] = 46,
@@ -55182,13 +53040,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][34] = 42,
[1][0][RTW89_THAILAND][0][34] = -4,
[1][0][RTW89_FCC][1][36] = -4,
- [1][0][RTW89_FCC][2][36] = 66,
[1][0][RTW89_ETSI][1][36] = 46,
[1][0][RTW89_ETSI][0][36] = 6,
[1][0][RTW89_MKK][1][36] = 42,
[1][0][RTW89_MKK][0][36] = 2,
[1][0][RTW89_IC][1][36] = -4,
- [1][0][RTW89_IC][2][36] = 66,
[1][0][RTW89_KCC][1][36] = -2,
[1][0][RTW89_KCC][0][36] = -2,
[1][0][RTW89_ACMA][1][36] = 46,
@@ -55201,13 +53057,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][36] = 42,
[1][0][RTW89_THAILAND][0][36] = -4,
[1][0][RTW89_FCC][1][38] = -4,
- [1][0][RTW89_FCC][2][38] = 66,
[1][0][RTW89_ETSI][1][38] = 46,
[1][0][RTW89_ETSI][0][38] = 6,
[1][0][RTW89_MKK][1][38] = 42,
[1][0][RTW89_MKK][0][38] = 2,
[1][0][RTW89_IC][1][38] = -4,
- [1][0][RTW89_IC][2][38] = 66,
[1][0][RTW89_KCC][1][38] = -2,
[1][0][RTW89_KCC][0][38] = -2,
[1][0][RTW89_ACMA][1][38] = 46,
@@ -55220,13 +53074,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][38] = 42,
[1][0][RTW89_THAILAND][0][38] = -4,
[1][0][RTW89_FCC][1][40] = -4,
- [1][0][RTW89_FCC][2][40] = 66,
[1][0][RTW89_ETSI][1][40] = 46,
[1][0][RTW89_ETSI][0][40] = 6,
[1][0][RTW89_MKK][1][40] = 42,
[1][0][RTW89_MKK][0][40] = 2,
[1][0][RTW89_IC][1][40] = -4,
- [1][0][RTW89_IC][2][40] = 66,
[1][0][RTW89_KCC][1][40] = -2,
[1][0][RTW89_KCC][0][40] = -2,
[1][0][RTW89_ACMA][1][40] = 46,
@@ -55239,13 +53091,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][40] = 42,
[1][0][RTW89_THAILAND][0][40] = -4,
[1][0][RTW89_FCC][1][42] = -4,
- [1][0][RTW89_FCC][2][42] = 66,
[1][0][RTW89_ETSI][1][42] = 46,
[1][0][RTW89_ETSI][0][42] = 6,
[1][0][RTW89_MKK][1][42] = 42,
[1][0][RTW89_MKK][0][42] = 2,
[1][0][RTW89_IC][1][42] = -4,
- [1][0][RTW89_IC][2][42] = 66,
[1][0][RTW89_KCC][1][42] = -2,
[1][0][RTW89_KCC][0][42] = -2,
[1][0][RTW89_ACMA][1][42] = 46,
@@ -55258,13 +53108,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][42] = 42,
[1][0][RTW89_THAILAND][0][42] = -4,
[1][0][RTW89_FCC][1][44] = -4,
- [1][0][RTW89_FCC][2][44] = 66,
[1][0][RTW89_ETSI][1][44] = 46,
[1][0][RTW89_ETSI][0][44] = 8,
[1][0][RTW89_MKK][1][44] = 22,
[1][0][RTW89_MKK][0][44] = 4,
[1][0][RTW89_IC][1][44] = -4,
- [1][0][RTW89_IC][2][44] = 66,
[1][0][RTW89_KCC][1][44] = -2,
[1][0][RTW89_KCC][0][44] = -2,
[1][0][RTW89_ACMA][1][44] = 46,
@@ -55277,13 +53125,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][44] = 42,
[1][0][RTW89_THAILAND][0][44] = -4,
[1][0][RTW89_FCC][1][45] = -4,
- [1][0][RTW89_FCC][2][45] = 127,
[1][0][RTW89_ETSI][1][45] = 127,
[1][0][RTW89_ETSI][0][45] = 127,
[1][0][RTW89_MKK][1][45] = 127,
[1][0][RTW89_MKK][0][45] = 127,
[1][0][RTW89_IC][1][45] = -4,
- [1][0][RTW89_IC][2][45] = 68,
[1][0][RTW89_KCC][1][45] = -2,
[1][0][RTW89_KCC][0][45] = 127,
[1][0][RTW89_ACMA][1][45] = 127,
@@ -55296,13 +53142,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][45] = 127,
[1][0][RTW89_THAILAND][0][45] = 127,
[1][0][RTW89_FCC][1][47] = -4,
- [1][0][RTW89_FCC][2][47] = 127,
[1][0][RTW89_ETSI][1][47] = 127,
[1][0][RTW89_ETSI][0][47] = 127,
[1][0][RTW89_MKK][1][47] = 127,
[1][0][RTW89_MKK][0][47] = 127,
[1][0][RTW89_IC][1][47] = -4,
- [1][0][RTW89_IC][2][47] = 68,
[1][0][RTW89_KCC][1][47] = -2,
[1][0][RTW89_KCC][0][47] = 127,
[1][0][RTW89_ACMA][1][47] = 127,
@@ -55315,13 +53159,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][47] = 127,
[1][0][RTW89_THAILAND][0][47] = 127,
[1][0][RTW89_FCC][1][49] = -4,
- [1][0][RTW89_FCC][2][49] = 127,
[1][0][RTW89_ETSI][1][49] = 127,
[1][0][RTW89_ETSI][0][49] = 127,
[1][0][RTW89_MKK][1][49] = 127,
[1][0][RTW89_MKK][0][49] = 127,
[1][0][RTW89_IC][1][49] = -4,
- [1][0][RTW89_IC][2][49] = 68,
[1][0][RTW89_KCC][1][49] = -2,
[1][0][RTW89_KCC][0][49] = 127,
[1][0][RTW89_ACMA][1][49] = 127,
@@ -55334,13 +53176,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][49] = 127,
[1][0][RTW89_THAILAND][0][49] = 127,
[1][0][RTW89_FCC][1][51] = -4,
- [1][0][RTW89_FCC][2][51] = 127,
[1][0][RTW89_ETSI][1][51] = 127,
[1][0][RTW89_ETSI][0][51] = 127,
[1][0][RTW89_MKK][1][51] = 127,
[1][0][RTW89_MKK][0][51] = 127,
[1][0][RTW89_IC][1][51] = -4,
- [1][0][RTW89_IC][2][51] = 68,
[1][0][RTW89_KCC][1][51] = -2,
[1][0][RTW89_KCC][0][51] = 127,
[1][0][RTW89_ACMA][1][51] = 127,
@@ -55353,13 +53193,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][51] = 127,
[1][0][RTW89_THAILAND][0][51] = 127,
[1][0][RTW89_FCC][1][53] = -4,
- [1][0][RTW89_FCC][2][53] = 127,
[1][0][RTW89_ETSI][1][53] = 127,
[1][0][RTW89_ETSI][0][53] = 127,
[1][0][RTW89_MKK][1][53] = 127,
[1][0][RTW89_MKK][0][53] = 127,
[1][0][RTW89_IC][1][53] = -4,
- [1][0][RTW89_IC][2][53] = 68,
[1][0][RTW89_KCC][1][53] = -2,
[1][0][RTW89_KCC][0][53] = 127,
[1][0][RTW89_ACMA][1][53] = 127,
@@ -55372,13 +53210,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][53] = 127,
[1][0][RTW89_THAILAND][0][53] = 127,
[1][0][RTW89_FCC][1][55] = -4,
- [1][0][RTW89_FCC][2][55] = 68,
[1][0][RTW89_ETSI][1][55] = 127,
[1][0][RTW89_ETSI][0][55] = 127,
[1][0][RTW89_MKK][1][55] = 127,
[1][0][RTW89_MKK][0][55] = 127,
[1][0][RTW89_IC][1][55] = -4,
- [1][0][RTW89_IC][2][55] = 68,
[1][0][RTW89_KCC][1][55] = -2,
[1][0][RTW89_KCC][0][55] = 127,
[1][0][RTW89_ACMA][1][55] = 127,
@@ -55391,13 +53227,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][55] = 127,
[1][0][RTW89_THAILAND][0][55] = 127,
[1][0][RTW89_FCC][1][57] = -4,
- [1][0][RTW89_FCC][2][57] = 68,
[1][0][RTW89_ETSI][1][57] = 127,
[1][0][RTW89_ETSI][0][57] = 127,
[1][0][RTW89_MKK][1][57] = 127,
[1][0][RTW89_MKK][0][57] = 127,
[1][0][RTW89_IC][1][57] = -4,
- [1][0][RTW89_IC][2][57] = 68,
[1][0][RTW89_KCC][1][57] = -2,
[1][0][RTW89_KCC][0][57] = 127,
[1][0][RTW89_ACMA][1][57] = 127,
@@ -55410,13 +53244,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][57] = 127,
[1][0][RTW89_THAILAND][0][57] = 127,
[1][0][RTW89_FCC][1][59] = -4,
- [1][0][RTW89_FCC][2][59] = 68,
[1][0][RTW89_ETSI][1][59] = 127,
[1][0][RTW89_ETSI][0][59] = 127,
[1][0][RTW89_MKK][1][59] = 127,
[1][0][RTW89_MKK][0][59] = 127,
[1][0][RTW89_IC][1][59] = -4,
- [1][0][RTW89_IC][2][59] = 68,
[1][0][RTW89_KCC][1][59] = -2,
[1][0][RTW89_KCC][0][59] = 127,
[1][0][RTW89_ACMA][1][59] = 127,
@@ -55429,13 +53261,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][59] = 127,
[1][0][RTW89_THAILAND][0][59] = 127,
[1][0][RTW89_FCC][1][60] = -4,
- [1][0][RTW89_FCC][2][60] = 68,
[1][0][RTW89_ETSI][1][60] = 127,
[1][0][RTW89_ETSI][0][60] = 127,
[1][0][RTW89_MKK][1][60] = 127,
[1][0][RTW89_MKK][0][60] = 127,
[1][0][RTW89_IC][1][60] = -4,
- [1][0][RTW89_IC][2][60] = 68,
[1][0][RTW89_KCC][1][60] = -2,
[1][0][RTW89_KCC][0][60] = 127,
[1][0][RTW89_ACMA][1][60] = 127,
@@ -55448,13 +53278,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][60] = 127,
[1][0][RTW89_THAILAND][0][60] = 127,
[1][0][RTW89_FCC][1][62] = -4,
- [1][0][RTW89_FCC][2][62] = 68,
[1][0][RTW89_ETSI][1][62] = 127,
[1][0][RTW89_ETSI][0][62] = 127,
[1][0][RTW89_MKK][1][62] = 127,
[1][0][RTW89_MKK][0][62] = 127,
[1][0][RTW89_IC][1][62] = -4,
- [1][0][RTW89_IC][2][62] = 68,
[1][0][RTW89_KCC][1][62] = -2,
[1][0][RTW89_KCC][0][62] = 127,
[1][0][RTW89_ACMA][1][62] = 127,
@@ -55467,13 +53295,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][62] = 127,
[1][0][RTW89_THAILAND][0][62] = 127,
[1][0][RTW89_FCC][1][64] = -4,
- [1][0][RTW89_FCC][2][64] = 68,
[1][0][RTW89_ETSI][1][64] = 127,
[1][0][RTW89_ETSI][0][64] = 127,
[1][0][RTW89_MKK][1][64] = 127,
[1][0][RTW89_MKK][0][64] = 127,
[1][0][RTW89_IC][1][64] = -4,
- [1][0][RTW89_IC][2][64] = 68,
[1][0][RTW89_KCC][1][64] = -2,
[1][0][RTW89_KCC][0][64] = 127,
[1][0][RTW89_ACMA][1][64] = 127,
@@ -55486,13 +53312,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][64] = 127,
[1][0][RTW89_THAILAND][0][64] = 127,
[1][0][RTW89_FCC][1][66] = -4,
- [1][0][RTW89_FCC][2][66] = 68,
[1][0][RTW89_ETSI][1][66] = 127,
[1][0][RTW89_ETSI][0][66] = 127,
[1][0][RTW89_MKK][1][66] = 127,
[1][0][RTW89_MKK][0][66] = 127,
[1][0][RTW89_IC][1][66] = -4,
- [1][0][RTW89_IC][2][66] = 68,
[1][0][RTW89_KCC][1][66] = -2,
[1][0][RTW89_KCC][0][66] = 127,
[1][0][RTW89_ACMA][1][66] = 127,
@@ -55505,13 +53329,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][66] = 127,
[1][0][RTW89_THAILAND][0][66] = 127,
[1][0][RTW89_FCC][1][68] = -4,
- [1][0][RTW89_FCC][2][68] = 68,
[1][0][RTW89_ETSI][1][68] = 127,
[1][0][RTW89_ETSI][0][68] = 127,
[1][0][RTW89_MKK][1][68] = 127,
[1][0][RTW89_MKK][0][68] = 127,
[1][0][RTW89_IC][1][68] = -4,
- [1][0][RTW89_IC][2][68] = 68,
[1][0][RTW89_KCC][1][68] = -2,
[1][0][RTW89_KCC][0][68] = 127,
[1][0][RTW89_ACMA][1][68] = 127,
@@ -55524,13 +53346,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][68] = 127,
[1][0][RTW89_THAILAND][0][68] = 127,
[1][0][RTW89_FCC][1][70] = -4,
- [1][0][RTW89_FCC][2][70] = 68,
[1][0][RTW89_ETSI][1][70] = 127,
[1][0][RTW89_ETSI][0][70] = 127,
[1][0][RTW89_MKK][1][70] = 127,
[1][0][RTW89_MKK][0][70] = 127,
[1][0][RTW89_IC][1][70] = -4,
- [1][0][RTW89_IC][2][70] = 68,
[1][0][RTW89_KCC][1][70] = -2,
[1][0][RTW89_KCC][0][70] = 127,
[1][0][RTW89_ACMA][1][70] = 127,
@@ -55543,13 +53363,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][70] = 127,
[1][0][RTW89_THAILAND][0][70] = 127,
[1][0][RTW89_FCC][1][72] = -4,
- [1][0][RTW89_FCC][2][72] = 68,
[1][0][RTW89_ETSI][1][72] = 127,
[1][0][RTW89_ETSI][0][72] = 127,
[1][0][RTW89_MKK][1][72] = 127,
[1][0][RTW89_MKK][0][72] = 127,
[1][0][RTW89_IC][1][72] = -4,
- [1][0][RTW89_IC][2][72] = 68,
[1][0][RTW89_KCC][1][72] = -2,
[1][0][RTW89_KCC][0][72] = 127,
[1][0][RTW89_ACMA][1][72] = 127,
@@ -55562,13 +53380,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][72] = 127,
[1][0][RTW89_THAILAND][0][72] = 127,
[1][0][RTW89_FCC][1][74] = -4,
- [1][0][RTW89_FCC][2][74] = 68,
[1][0][RTW89_ETSI][1][74] = 127,
[1][0][RTW89_ETSI][0][74] = 127,
[1][0][RTW89_MKK][1][74] = 127,
[1][0][RTW89_MKK][0][74] = 127,
[1][0][RTW89_IC][1][74] = -4,
- [1][0][RTW89_IC][2][74] = 68,
[1][0][RTW89_KCC][1][74] = -2,
[1][0][RTW89_KCC][0][74] = 127,
[1][0][RTW89_ACMA][1][74] = 127,
@@ -55581,13 +53397,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][74] = 127,
[1][0][RTW89_THAILAND][0][74] = 127,
[1][0][RTW89_FCC][1][75] = -4,
- [1][0][RTW89_FCC][2][75] = 68,
[1][0][RTW89_ETSI][1][75] = 127,
[1][0][RTW89_ETSI][0][75] = 127,
[1][0][RTW89_MKK][1][75] = 127,
[1][0][RTW89_MKK][0][75] = 127,
[1][0][RTW89_IC][1][75] = -4,
- [1][0][RTW89_IC][2][75] = 68,
[1][0][RTW89_KCC][1][75] = -2,
[1][0][RTW89_KCC][0][75] = 127,
[1][0][RTW89_ACMA][1][75] = 127,
@@ -55600,13 +53414,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][75] = 127,
[1][0][RTW89_THAILAND][0][75] = 127,
[1][0][RTW89_FCC][1][77] = -4,
- [1][0][RTW89_FCC][2][77] = 68,
[1][0][RTW89_ETSI][1][77] = 127,
[1][0][RTW89_ETSI][0][77] = 127,
[1][0][RTW89_MKK][1][77] = 127,
[1][0][RTW89_MKK][0][77] = 127,
[1][0][RTW89_IC][1][77] = -4,
- [1][0][RTW89_IC][2][77] = 68,
[1][0][RTW89_KCC][1][77] = -2,
[1][0][RTW89_KCC][0][77] = 127,
[1][0][RTW89_ACMA][1][77] = 127,
@@ -55619,13 +53431,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][77] = 127,
[1][0][RTW89_THAILAND][0][77] = 127,
[1][0][RTW89_FCC][1][79] = -4,
- [1][0][RTW89_FCC][2][79] = 68,
[1][0][RTW89_ETSI][1][79] = 127,
[1][0][RTW89_ETSI][0][79] = 127,
[1][0][RTW89_MKK][1][79] = 127,
[1][0][RTW89_MKK][0][79] = 127,
[1][0][RTW89_IC][1][79] = -4,
- [1][0][RTW89_IC][2][79] = 68,
[1][0][RTW89_KCC][1][79] = -2,
[1][0][RTW89_KCC][0][79] = 127,
[1][0][RTW89_ACMA][1][79] = 127,
@@ -55638,13 +53448,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][79] = 127,
[1][0][RTW89_THAILAND][0][79] = 127,
[1][0][RTW89_FCC][1][81] = -4,
- [1][0][RTW89_FCC][2][81] = 68,
[1][0][RTW89_ETSI][1][81] = 127,
[1][0][RTW89_ETSI][0][81] = 127,
[1][0][RTW89_MKK][1][81] = 127,
[1][0][RTW89_MKK][0][81] = 127,
[1][0][RTW89_IC][1][81] = -4,
- [1][0][RTW89_IC][2][81] = 68,
[1][0][RTW89_KCC][1][81] = -2,
[1][0][RTW89_KCC][0][81] = 127,
[1][0][RTW89_ACMA][1][81] = 127,
@@ -55657,13 +53465,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][81] = 127,
[1][0][RTW89_THAILAND][0][81] = 127,
[1][0][RTW89_FCC][1][83] = -4,
- [1][0][RTW89_FCC][2][83] = 68,
[1][0][RTW89_ETSI][1][83] = 127,
[1][0][RTW89_ETSI][0][83] = 127,
[1][0][RTW89_MKK][1][83] = 127,
[1][0][RTW89_MKK][0][83] = 127,
[1][0][RTW89_IC][1][83] = -4,
- [1][0][RTW89_IC][2][83] = 68,
[1][0][RTW89_KCC][1][83] = -2,
[1][0][RTW89_KCC][0][83] = 127,
[1][0][RTW89_ACMA][1][83] = 127,
@@ -55676,13 +53482,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][83] = 127,
[1][0][RTW89_THAILAND][0][83] = 127,
[1][0][RTW89_FCC][1][85] = -4,
- [1][0][RTW89_FCC][2][85] = 68,
[1][0][RTW89_ETSI][1][85] = 127,
[1][0][RTW89_ETSI][0][85] = 127,
[1][0][RTW89_MKK][1][85] = 127,
[1][0][RTW89_MKK][0][85] = 127,
[1][0][RTW89_IC][1][85] = -4,
- [1][0][RTW89_IC][2][85] = 68,
[1][0][RTW89_KCC][1][85] = -2,
[1][0][RTW89_KCC][0][85] = 127,
[1][0][RTW89_ACMA][1][85] = 127,
@@ -55695,13 +53499,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][85] = 127,
[1][0][RTW89_THAILAND][0][85] = 127,
[1][0][RTW89_FCC][1][87] = -4,
- [1][0][RTW89_FCC][2][87] = 127,
[1][0][RTW89_ETSI][1][87] = 127,
[1][0][RTW89_ETSI][0][87] = 127,
[1][0][RTW89_MKK][1][87] = 127,
[1][0][RTW89_MKK][0][87] = 127,
[1][0][RTW89_IC][1][87] = -4,
- [1][0][RTW89_IC][2][87] = 127,
[1][0][RTW89_KCC][1][87] = -2,
[1][0][RTW89_KCC][0][87] = 127,
[1][0][RTW89_ACMA][1][87] = 127,
@@ -55714,13 +53516,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][87] = 127,
[1][0][RTW89_THAILAND][0][87] = 127,
[1][0][RTW89_FCC][1][89] = -4,
- [1][0][RTW89_FCC][2][89] = 127,
[1][0][RTW89_ETSI][1][89] = 127,
[1][0][RTW89_ETSI][0][89] = 127,
[1][0][RTW89_MKK][1][89] = 127,
[1][0][RTW89_MKK][0][89] = 127,
[1][0][RTW89_IC][1][89] = -4,
- [1][0][RTW89_IC][2][89] = 127,
[1][0][RTW89_KCC][1][89] = -2,
[1][0][RTW89_KCC][0][89] = 127,
[1][0][RTW89_ACMA][1][89] = 127,
@@ -55733,13 +53533,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][89] = 127,
[1][0][RTW89_THAILAND][0][89] = 127,
[1][0][RTW89_FCC][1][90] = -4,
- [1][0][RTW89_FCC][2][90] = 127,
[1][0][RTW89_ETSI][1][90] = 127,
[1][0][RTW89_ETSI][0][90] = 127,
[1][0][RTW89_MKK][1][90] = 127,
[1][0][RTW89_MKK][0][90] = 127,
[1][0][RTW89_IC][1][90] = -4,
- [1][0][RTW89_IC][2][90] = 127,
[1][0][RTW89_KCC][1][90] = -2,
[1][0][RTW89_KCC][0][90] = 127,
[1][0][RTW89_ACMA][1][90] = 127,
@@ -55752,13 +53550,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][90] = 127,
[1][0][RTW89_THAILAND][0][90] = 127,
[1][0][RTW89_FCC][1][92] = -4,
- [1][0][RTW89_FCC][2][92] = 127,
[1][0][RTW89_ETSI][1][92] = 127,
[1][0][RTW89_ETSI][0][92] = 127,
[1][0][RTW89_MKK][1][92] = 127,
[1][0][RTW89_MKK][0][92] = 127,
[1][0][RTW89_IC][1][92] = -4,
- [1][0][RTW89_IC][2][92] = 127,
[1][0][RTW89_KCC][1][92] = -2,
[1][0][RTW89_KCC][0][92] = 127,
[1][0][RTW89_ACMA][1][92] = 127,
@@ -55771,13 +53567,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][92] = 127,
[1][0][RTW89_THAILAND][0][92] = 127,
[1][0][RTW89_FCC][1][94] = -4,
- [1][0][RTW89_FCC][2][94] = 127,
[1][0][RTW89_ETSI][1][94] = 127,
[1][0][RTW89_ETSI][0][94] = 127,
[1][0][RTW89_MKK][1][94] = 127,
[1][0][RTW89_MKK][0][94] = 127,
[1][0][RTW89_IC][1][94] = -4,
- [1][0][RTW89_IC][2][94] = 127,
[1][0][RTW89_KCC][1][94] = -2,
[1][0][RTW89_KCC][0][94] = 127,
[1][0][RTW89_ACMA][1][94] = 127,
@@ -55790,13 +53584,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][94] = 127,
[1][0][RTW89_THAILAND][0][94] = 127,
[1][0][RTW89_FCC][1][96] = -4,
- [1][0][RTW89_FCC][2][96] = 127,
[1][0][RTW89_ETSI][1][96] = 127,
[1][0][RTW89_ETSI][0][96] = 127,
[1][0][RTW89_MKK][1][96] = 127,
[1][0][RTW89_MKK][0][96] = 127,
[1][0][RTW89_IC][1][96] = -4,
- [1][0][RTW89_IC][2][96] = 127,
[1][0][RTW89_KCC][1][96] = -2,
[1][0][RTW89_KCC][0][96] = 127,
[1][0][RTW89_ACMA][1][96] = 127,
@@ -55809,13 +53601,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][96] = 127,
[1][0][RTW89_THAILAND][0][96] = 127,
[1][0][RTW89_FCC][1][98] = -4,
- [1][0][RTW89_FCC][2][98] = 127,
[1][0][RTW89_ETSI][1][98] = 127,
[1][0][RTW89_ETSI][0][98] = 127,
[1][0][RTW89_MKK][1][98] = 127,
[1][0][RTW89_MKK][0][98] = 127,
[1][0][RTW89_IC][1][98] = -4,
- [1][0][RTW89_IC][2][98] = 127,
[1][0][RTW89_KCC][1][98] = -2,
[1][0][RTW89_KCC][0][98] = 127,
[1][0][RTW89_ACMA][1][98] = 127,
@@ -55828,13 +53618,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][98] = 127,
[1][0][RTW89_THAILAND][0][98] = 127,
[1][0][RTW89_FCC][1][100] = -4,
- [1][0][RTW89_FCC][2][100] = 127,
[1][0][RTW89_ETSI][1][100] = 127,
[1][0][RTW89_ETSI][0][100] = 127,
[1][0][RTW89_MKK][1][100] = 127,
[1][0][RTW89_MKK][0][100] = 127,
[1][0][RTW89_IC][1][100] = -4,
- [1][0][RTW89_IC][2][100] = 127,
[1][0][RTW89_KCC][1][100] = -2,
[1][0][RTW89_KCC][0][100] = 127,
[1][0][RTW89_ACMA][1][100] = 127,
@@ -55847,13 +53635,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][100] = 127,
[1][0][RTW89_THAILAND][0][100] = 127,
[1][0][RTW89_FCC][1][102] = -4,
- [1][0][RTW89_FCC][2][102] = 127,
[1][0][RTW89_ETSI][1][102] = 127,
[1][0][RTW89_ETSI][0][102] = 127,
[1][0][RTW89_MKK][1][102] = 127,
[1][0][RTW89_MKK][0][102] = 127,
[1][0][RTW89_IC][1][102] = -4,
- [1][0][RTW89_IC][2][102] = 127,
[1][0][RTW89_KCC][1][102] = -2,
[1][0][RTW89_KCC][0][102] = 127,
[1][0][RTW89_ACMA][1][102] = 127,
@@ -55866,13 +53652,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][102] = 127,
[1][0][RTW89_THAILAND][0][102] = 127,
[1][0][RTW89_FCC][1][104] = -4,
- [1][0][RTW89_FCC][2][104] = 127,
[1][0][RTW89_ETSI][1][104] = 127,
[1][0][RTW89_ETSI][0][104] = 127,
[1][0][RTW89_MKK][1][104] = 127,
[1][0][RTW89_MKK][0][104] = 127,
[1][0][RTW89_IC][1][104] = -4,
- [1][0][RTW89_IC][2][104] = 127,
[1][0][RTW89_KCC][1][104] = -2,
[1][0][RTW89_KCC][0][104] = 127,
[1][0][RTW89_ACMA][1][104] = 127,
@@ -55885,13 +53669,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][104] = 127,
[1][0][RTW89_THAILAND][0][104] = 127,
[1][0][RTW89_FCC][1][105] = -4,
- [1][0][RTW89_FCC][2][105] = 127,
[1][0][RTW89_ETSI][1][105] = 127,
[1][0][RTW89_ETSI][0][105] = 127,
[1][0][RTW89_MKK][1][105] = 127,
[1][0][RTW89_MKK][0][105] = 127,
[1][0][RTW89_IC][1][105] = -4,
- [1][0][RTW89_IC][2][105] = 127,
[1][0][RTW89_KCC][1][105] = -2,
[1][0][RTW89_KCC][0][105] = 127,
[1][0][RTW89_ACMA][1][105] = 127,
@@ -55904,13 +53686,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][105] = 127,
[1][0][RTW89_THAILAND][0][105] = 127,
[1][0][RTW89_FCC][1][107] = 1,
- [1][0][RTW89_FCC][2][107] = 127,
[1][0][RTW89_ETSI][1][107] = 127,
[1][0][RTW89_ETSI][0][107] = 127,
[1][0][RTW89_MKK][1][107] = 127,
[1][0][RTW89_MKK][0][107] = 127,
[1][0][RTW89_IC][1][107] = 1,
- [1][0][RTW89_IC][2][107] = 127,
[1][0][RTW89_KCC][1][107] = -2,
[1][0][RTW89_KCC][0][107] = 127,
[1][0][RTW89_ACMA][1][107] = 127,
@@ -55923,13 +53703,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][107] = 127,
[1][0][RTW89_THAILAND][0][107] = 127,
[1][0][RTW89_FCC][1][109] = 2,
- [1][0][RTW89_FCC][2][109] = 127,
[1][0][RTW89_ETSI][1][109] = 127,
[1][0][RTW89_ETSI][0][109] = 127,
[1][0][RTW89_MKK][1][109] = 127,
[1][0][RTW89_MKK][0][109] = 127,
[1][0][RTW89_IC][1][109] = 2,
- [1][0][RTW89_IC][2][109] = 127,
[1][0][RTW89_KCC][1][109] = 127,
[1][0][RTW89_KCC][0][109] = 127,
[1][0][RTW89_ACMA][1][109] = 127,
@@ -55942,13 +53720,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][109] = 127,
[1][0][RTW89_THAILAND][0][109] = 127,
[1][0][RTW89_FCC][1][111] = 127,
- [1][0][RTW89_FCC][2][111] = 127,
[1][0][RTW89_ETSI][1][111] = 127,
[1][0][RTW89_ETSI][0][111] = 127,
[1][0][RTW89_MKK][1][111] = 127,
[1][0][RTW89_MKK][0][111] = 127,
[1][0][RTW89_IC][1][111] = 127,
- [1][0][RTW89_IC][2][111] = 127,
[1][0][RTW89_KCC][1][111] = 127,
[1][0][RTW89_KCC][0][111] = 127,
[1][0][RTW89_ACMA][1][111] = 127,
@@ -55961,13 +53737,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][111] = 127,
[1][0][RTW89_THAILAND][0][111] = 127,
[1][0][RTW89_FCC][1][113] = 127,
- [1][0][RTW89_FCC][2][113] = 127,
[1][0][RTW89_ETSI][1][113] = 127,
[1][0][RTW89_ETSI][0][113] = 127,
[1][0][RTW89_MKK][1][113] = 127,
[1][0][RTW89_MKK][0][113] = 127,
[1][0][RTW89_IC][1][113] = 127,
- [1][0][RTW89_IC][2][113] = 127,
[1][0][RTW89_KCC][1][113] = 127,
[1][0][RTW89_KCC][0][113] = 127,
[1][0][RTW89_ACMA][1][113] = 127,
@@ -55980,13 +53754,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][113] = 127,
[1][0][RTW89_THAILAND][0][113] = 127,
[1][0][RTW89_FCC][1][115] = 127,
- [1][0][RTW89_FCC][2][115] = 127,
[1][0][RTW89_ETSI][1][115] = 127,
[1][0][RTW89_ETSI][0][115] = 127,
[1][0][RTW89_MKK][1][115] = 127,
[1][0][RTW89_MKK][0][115] = 127,
[1][0][RTW89_IC][1][115] = 127,
- [1][0][RTW89_IC][2][115] = 127,
[1][0][RTW89_KCC][1][115] = 127,
[1][0][RTW89_KCC][0][115] = 127,
[1][0][RTW89_ACMA][1][115] = 127,
@@ -55999,13 +53771,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][115] = 127,
[1][0][RTW89_THAILAND][0][115] = 127,
[1][0][RTW89_FCC][1][117] = 127,
- [1][0][RTW89_FCC][2][117] = 127,
[1][0][RTW89_ETSI][1][117] = 127,
[1][0][RTW89_ETSI][0][117] = 127,
[1][0][RTW89_MKK][1][117] = 127,
[1][0][RTW89_MKK][0][117] = 127,
[1][0][RTW89_IC][1][117] = 127,
- [1][0][RTW89_IC][2][117] = 127,
[1][0][RTW89_KCC][1][117] = 127,
[1][0][RTW89_KCC][0][117] = 127,
[1][0][RTW89_ACMA][1][117] = 127,
@@ -56018,13 +53788,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][117] = 127,
[1][0][RTW89_THAILAND][0][117] = 127,
[1][0][RTW89_FCC][1][119] = 127,
- [1][0][RTW89_FCC][2][119] = 127,
[1][0][RTW89_ETSI][1][119] = 127,
[1][0][RTW89_ETSI][0][119] = 127,
[1][0][RTW89_MKK][1][119] = 127,
[1][0][RTW89_MKK][0][119] = 127,
[1][0][RTW89_IC][1][119] = 127,
- [1][0][RTW89_IC][2][119] = 127,
[1][0][RTW89_KCC][1][119] = 127,
[1][0][RTW89_KCC][0][119] = 127,
[1][0][RTW89_ACMA][1][119] = 127,
@@ -56037,13 +53805,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][0][RTW89_THAILAND][1][119] = 127,
[1][0][RTW89_THAILAND][0][119] = 127,
[1][1][RTW89_FCC][1][0] = -26,
- [1][1][RTW89_FCC][2][0] = 44,
[1][1][RTW89_ETSI][1][0] = 32,
[1][1][RTW89_ETSI][0][0] = -6,
[1][1][RTW89_MKK][1][0] = 30,
[1][1][RTW89_MKK][0][0] = -10,
[1][1][RTW89_IC][1][0] = -26,
- [1][1][RTW89_IC][2][0] = 44,
[1][1][RTW89_KCC][1][0] = -14,
[1][1][RTW89_KCC][0][0] = -14,
[1][1][RTW89_ACMA][1][0] = 32,
@@ -56056,13 +53822,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][0] = 18,
[1][1][RTW89_THAILAND][0][0] = -26,
[1][1][RTW89_FCC][1][2] = -28,
- [1][1][RTW89_FCC][2][2] = 44,
[1][1][RTW89_ETSI][1][2] = 32,
[1][1][RTW89_ETSI][0][2] = -6,
[1][1][RTW89_MKK][1][2] = 30,
[1][1][RTW89_MKK][0][2] = -10,
[1][1][RTW89_IC][1][2] = -28,
- [1][1][RTW89_IC][2][2] = 44,
[1][1][RTW89_KCC][1][2] = -14,
[1][1][RTW89_KCC][0][2] = -14,
[1][1][RTW89_ACMA][1][2] = 32,
@@ -56075,13 +53839,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][2] = 18,
[1][1][RTW89_THAILAND][0][2] = -28,
[1][1][RTW89_FCC][1][4] = -28,
- [1][1][RTW89_FCC][2][4] = 44,
[1][1][RTW89_ETSI][1][4] = 32,
[1][1][RTW89_ETSI][0][4] = -6,
[1][1][RTW89_MKK][1][4] = 30,
[1][1][RTW89_MKK][0][4] = -10,
[1][1][RTW89_IC][1][4] = -28,
- [1][1][RTW89_IC][2][4] = 44,
[1][1][RTW89_KCC][1][4] = -14,
[1][1][RTW89_KCC][0][4] = -14,
[1][1][RTW89_ACMA][1][4] = 32,
@@ -56094,13 +53856,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][4] = 18,
[1][1][RTW89_THAILAND][0][4] = -28,
[1][1][RTW89_FCC][1][6] = -28,
- [1][1][RTW89_FCC][2][6] = 44,
[1][1][RTW89_ETSI][1][6] = 32,
[1][1][RTW89_ETSI][0][6] = -6,
[1][1][RTW89_MKK][1][6] = 30,
[1][1][RTW89_MKK][0][6] = -10,
[1][1][RTW89_IC][1][6] = -28,
- [1][1][RTW89_IC][2][6] = 44,
[1][1][RTW89_KCC][1][6] = -14,
[1][1][RTW89_KCC][0][6] = -14,
[1][1][RTW89_ACMA][1][6] = 32,
@@ -56113,13 +53873,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][6] = 18,
[1][1][RTW89_THAILAND][0][6] = -28,
[1][1][RTW89_FCC][1][8] = -28,
- [1][1][RTW89_FCC][2][8] = 44,
[1][1][RTW89_ETSI][1][8] = 32,
[1][1][RTW89_ETSI][0][8] = -6,
[1][1][RTW89_MKK][1][8] = 30,
[1][1][RTW89_MKK][0][8] = -10,
[1][1][RTW89_IC][1][8] = -28,
- [1][1][RTW89_IC][2][8] = 44,
[1][1][RTW89_KCC][1][8] = -14,
[1][1][RTW89_KCC][0][8] = -14,
[1][1][RTW89_ACMA][1][8] = 32,
@@ -56132,13 +53890,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][8] = 18,
[1][1][RTW89_THAILAND][0][8] = -28,
[1][1][RTW89_FCC][1][10] = -28,
- [1][1][RTW89_FCC][2][10] = 44,
[1][1][RTW89_ETSI][1][10] = 32,
[1][1][RTW89_ETSI][0][10] = -6,
[1][1][RTW89_MKK][1][10] = 30,
[1][1][RTW89_MKK][0][10] = -10,
[1][1][RTW89_IC][1][10] = -28,
- [1][1][RTW89_IC][2][10] = 44,
[1][1][RTW89_KCC][1][10] = -14,
[1][1][RTW89_KCC][0][10] = -14,
[1][1][RTW89_ACMA][1][10] = 32,
@@ -56151,13 +53907,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][10] = 18,
[1][1][RTW89_THAILAND][0][10] = -28,
[1][1][RTW89_FCC][1][12] = -28,
- [1][1][RTW89_FCC][2][12] = 44,
[1][1][RTW89_ETSI][1][12] = 32,
[1][1][RTW89_ETSI][0][12] = -6,
[1][1][RTW89_MKK][1][12] = 30,
[1][1][RTW89_MKK][0][12] = -10,
[1][1][RTW89_IC][1][12] = -28,
- [1][1][RTW89_IC][2][12] = 44,
[1][1][RTW89_KCC][1][12] = -14,
[1][1][RTW89_KCC][0][12] = -14,
[1][1][RTW89_ACMA][1][12] = 32,
@@ -56170,13 +53924,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][12] = 18,
[1][1][RTW89_THAILAND][0][12] = -28,
[1][1][RTW89_FCC][1][14] = -28,
- [1][1][RTW89_FCC][2][14] = 44,
[1][1][RTW89_ETSI][1][14] = 32,
[1][1][RTW89_ETSI][0][14] = -6,
[1][1][RTW89_MKK][1][14] = 30,
[1][1][RTW89_MKK][0][14] = -10,
[1][1][RTW89_IC][1][14] = -28,
- [1][1][RTW89_IC][2][14] = 44,
[1][1][RTW89_KCC][1][14] = -14,
[1][1][RTW89_KCC][0][14] = -14,
[1][1][RTW89_ACMA][1][14] = 32,
@@ -56189,13 +53941,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][14] = 18,
[1][1][RTW89_THAILAND][0][14] = -28,
[1][1][RTW89_FCC][1][15] = -28,
- [1][1][RTW89_FCC][2][15] = 44,
[1][1][RTW89_ETSI][1][15] = 32,
[1][1][RTW89_ETSI][0][15] = -6,
[1][1][RTW89_MKK][1][15] = 30,
[1][1][RTW89_MKK][0][15] = -10,
[1][1][RTW89_IC][1][15] = -28,
- [1][1][RTW89_IC][2][15] = 44,
[1][1][RTW89_KCC][1][15] = -14,
[1][1][RTW89_KCC][0][15] = -14,
[1][1][RTW89_ACMA][1][15] = 32,
@@ -56208,13 +53958,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][15] = 18,
[1][1][RTW89_THAILAND][0][15] = -28,
[1][1][RTW89_FCC][1][17] = -28,
- [1][1][RTW89_FCC][2][17] = 44,
[1][1][RTW89_ETSI][1][17] = 32,
[1][1][RTW89_ETSI][0][17] = -6,
[1][1][RTW89_MKK][1][17] = 30,
[1][1][RTW89_MKK][0][17] = -10,
[1][1][RTW89_IC][1][17] = -28,
- [1][1][RTW89_IC][2][17] = 44,
[1][1][RTW89_KCC][1][17] = -14,
[1][1][RTW89_KCC][0][17] = -14,
[1][1][RTW89_ACMA][1][17] = 32,
@@ -56227,13 +53975,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][17] = 18,
[1][1][RTW89_THAILAND][0][17] = -28,
[1][1][RTW89_FCC][1][19] = -28,
- [1][1][RTW89_FCC][2][19] = 44,
[1][1][RTW89_ETSI][1][19] = 32,
[1][1][RTW89_ETSI][0][19] = -6,
[1][1][RTW89_MKK][1][19] = 30,
[1][1][RTW89_MKK][0][19] = -10,
[1][1][RTW89_IC][1][19] = -28,
- [1][1][RTW89_IC][2][19] = 44,
[1][1][RTW89_KCC][1][19] = -14,
[1][1][RTW89_KCC][0][19] = -14,
[1][1][RTW89_ACMA][1][19] = 32,
@@ -56246,13 +53992,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][19] = 18,
[1][1][RTW89_THAILAND][0][19] = -28,
[1][1][RTW89_FCC][1][21] = -28,
- [1][1][RTW89_FCC][2][21] = 44,
[1][1][RTW89_ETSI][1][21] = 32,
[1][1][RTW89_ETSI][0][21] = -6,
[1][1][RTW89_MKK][1][21] = 30,
[1][1][RTW89_MKK][0][21] = -10,
[1][1][RTW89_IC][1][21] = -28,
- [1][1][RTW89_IC][2][21] = 44,
[1][1][RTW89_KCC][1][21] = -14,
[1][1][RTW89_KCC][0][21] = -14,
[1][1][RTW89_ACMA][1][21] = 32,
@@ -56265,13 +54009,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][21] = 18,
[1][1][RTW89_THAILAND][0][21] = -28,
[1][1][RTW89_FCC][1][23] = -28,
- [1][1][RTW89_FCC][2][23] = 44,
[1][1][RTW89_ETSI][1][23] = 32,
[1][1][RTW89_ETSI][0][23] = -6,
[1][1][RTW89_MKK][1][23] = 32,
[1][1][RTW89_MKK][0][23] = -10,
[1][1][RTW89_IC][1][23] = -28,
- [1][1][RTW89_IC][2][23] = 44,
[1][1][RTW89_KCC][1][23] = -14,
[1][1][RTW89_KCC][0][23] = -14,
[1][1][RTW89_ACMA][1][23] = 32,
@@ -56284,13 +54026,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][23] = 18,
[1][1][RTW89_THAILAND][0][23] = -28,
[1][1][RTW89_FCC][1][25] = -28,
- [1][1][RTW89_FCC][2][25] = 44,
[1][1][RTW89_ETSI][1][25] = 32,
[1][1][RTW89_ETSI][0][25] = -6,
[1][1][RTW89_MKK][1][25] = 32,
[1][1][RTW89_MKK][0][25] = -10,
[1][1][RTW89_IC][1][25] = -28,
- [1][1][RTW89_IC][2][25] = 44,
[1][1][RTW89_KCC][1][25] = -14,
[1][1][RTW89_KCC][0][25] = -14,
[1][1][RTW89_ACMA][1][25] = 32,
@@ -56303,13 +54043,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][25] = 18,
[1][1][RTW89_THAILAND][0][25] = -28,
[1][1][RTW89_FCC][1][27] = -28,
- [1][1][RTW89_FCC][2][27] = 44,
[1][1][RTW89_ETSI][1][27] = 32,
[1][1][RTW89_ETSI][0][27] = -6,
[1][1][RTW89_MKK][1][27] = 32,
[1][1][RTW89_MKK][0][27] = -10,
[1][1][RTW89_IC][1][27] = -28,
- [1][1][RTW89_IC][2][27] = 44,
[1][1][RTW89_KCC][1][27] = -14,
[1][1][RTW89_KCC][0][27] = -14,
[1][1][RTW89_ACMA][1][27] = 32,
@@ -56322,13 +54060,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][27] = 18,
[1][1][RTW89_THAILAND][0][27] = -28,
[1][1][RTW89_FCC][1][29] = -28,
- [1][1][RTW89_FCC][2][29] = 44,
[1][1][RTW89_ETSI][1][29] = 32,
[1][1][RTW89_ETSI][0][29] = -6,
[1][1][RTW89_MKK][1][29] = 32,
[1][1][RTW89_MKK][0][29] = -10,
[1][1][RTW89_IC][1][29] = -28,
- [1][1][RTW89_IC][2][29] = 44,
[1][1][RTW89_KCC][1][29] = -14,
[1][1][RTW89_KCC][0][29] = -14,
[1][1][RTW89_ACMA][1][29] = 32,
@@ -56341,13 +54077,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][29] = 18,
[1][1][RTW89_THAILAND][0][29] = -28,
[1][1][RTW89_FCC][1][30] = -28,
- [1][1][RTW89_FCC][2][30] = 44,
[1][1][RTW89_ETSI][1][30] = 32,
[1][1][RTW89_ETSI][0][30] = -6,
[1][1][RTW89_MKK][1][30] = 32,
[1][1][RTW89_MKK][0][30] = -10,
[1][1][RTW89_IC][1][30] = -28,
- [1][1][RTW89_IC][2][30] = 44,
[1][1][RTW89_KCC][1][30] = -14,
[1][1][RTW89_KCC][0][30] = -14,
[1][1][RTW89_ACMA][1][30] = 32,
@@ -56360,13 +54094,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][30] = 18,
[1][1][RTW89_THAILAND][0][30] = -28,
[1][1][RTW89_FCC][1][32] = -28,
- [1][1][RTW89_FCC][2][32] = 44,
[1][1][RTW89_ETSI][1][32] = 32,
[1][1][RTW89_ETSI][0][32] = -6,
[1][1][RTW89_MKK][1][32] = 32,
[1][1][RTW89_MKK][0][32] = -10,
[1][1][RTW89_IC][1][32] = -28,
- [1][1][RTW89_IC][2][32] = 44,
[1][1][RTW89_KCC][1][32] = -14,
[1][1][RTW89_KCC][0][32] = -14,
[1][1][RTW89_ACMA][1][32] = 32,
@@ -56379,13 +54111,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][32] = 18,
[1][1][RTW89_THAILAND][0][32] = -28,
[1][1][RTW89_FCC][1][34] = -28,
- [1][1][RTW89_FCC][2][34] = 44,
[1][1][RTW89_ETSI][1][34] = 32,
[1][1][RTW89_ETSI][0][34] = -6,
[1][1][RTW89_MKK][1][34] = 32,
[1][1][RTW89_MKK][0][34] = -10,
[1][1][RTW89_IC][1][34] = -28,
- [1][1][RTW89_IC][2][34] = 44,
[1][1][RTW89_KCC][1][34] = -14,
[1][1][RTW89_KCC][0][34] = -14,
[1][1][RTW89_ACMA][1][34] = 32,
@@ -56398,13 +54128,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][34] = 18,
[1][1][RTW89_THAILAND][0][34] = -28,
[1][1][RTW89_FCC][1][36] = -28,
- [1][1][RTW89_FCC][2][36] = 44,
[1][1][RTW89_ETSI][1][36] = 32,
[1][1][RTW89_ETSI][0][36] = -6,
[1][1][RTW89_MKK][1][36] = 32,
[1][1][RTW89_MKK][0][36] = -10,
[1][1][RTW89_IC][1][36] = -28,
- [1][1][RTW89_IC][2][36] = 44,
[1][1][RTW89_KCC][1][36] = -14,
[1][1][RTW89_KCC][0][36] = -14,
[1][1][RTW89_ACMA][1][36] = 32,
@@ -56417,13 +54145,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][36] = 18,
[1][1][RTW89_THAILAND][0][36] = -28,
[1][1][RTW89_FCC][1][38] = -28,
- [1][1][RTW89_FCC][2][38] = 44,
[1][1][RTW89_ETSI][1][38] = 32,
[1][1][RTW89_ETSI][0][38] = -6,
[1][1][RTW89_MKK][1][38] = 32,
[1][1][RTW89_MKK][0][38] = -10,
[1][1][RTW89_IC][1][38] = -28,
- [1][1][RTW89_IC][2][38] = 44,
[1][1][RTW89_KCC][1][38] = -14,
[1][1][RTW89_KCC][0][38] = -14,
[1][1][RTW89_ACMA][1][38] = 32,
@@ -56436,13 +54162,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][38] = 18,
[1][1][RTW89_THAILAND][0][38] = -28,
[1][1][RTW89_FCC][1][40] = -28,
- [1][1][RTW89_FCC][2][40] = 44,
[1][1][RTW89_ETSI][1][40] = 32,
[1][1][RTW89_ETSI][0][40] = -6,
[1][1][RTW89_MKK][1][40] = 32,
[1][1][RTW89_MKK][0][40] = -10,
[1][1][RTW89_IC][1][40] = -28,
- [1][1][RTW89_IC][2][40] = 44,
[1][1][RTW89_KCC][1][40] = -14,
[1][1][RTW89_KCC][0][40] = -14,
[1][1][RTW89_ACMA][1][40] = 32,
@@ -56455,13 +54179,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][40] = 18,
[1][1][RTW89_THAILAND][0][40] = -28,
[1][1][RTW89_FCC][1][42] = -28,
- [1][1][RTW89_FCC][2][42] = 44,
[1][1][RTW89_ETSI][1][42] = 32,
[1][1][RTW89_ETSI][0][42] = -6,
[1][1][RTW89_MKK][1][42] = 32,
[1][1][RTW89_MKK][0][42] = -10,
[1][1][RTW89_IC][1][42] = -28,
- [1][1][RTW89_IC][2][42] = 44,
[1][1][RTW89_KCC][1][42] = -14,
[1][1][RTW89_KCC][0][42] = -14,
[1][1][RTW89_ACMA][1][42] = 32,
@@ -56474,13 +54196,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][42] = 18,
[1][1][RTW89_THAILAND][0][42] = -28,
[1][1][RTW89_FCC][1][44] = -28,
- [1][1][RTW89_FCC][2][44] = 44,
[1][1][RTW89_ETSI][1][44] = 34,
[1][1][RTW89_ETSI][0][44] = -4,
[1][1][RTW89_MKK][1][44] = 4,
[1][1][RTW89_MKK][0][44] = -8,
[1][1][RTW89_IC][1][44] = -28,
- [1][1][RTW89_IC][2][44] = 44,
[1][1][RTW89_KCC][1][44] = -14,
[1][1][RTW89_KCC][0][44] = -14,
[1][1][RTW89_ACMA][1][44] = 34,
@@ -56493,13 +54213,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][44] = 18,
[1][1][RTW89_THAILAND][0][44] = -28,
[1][1][RTW89_FCC][1][45] = -26,
- [1][1][RTW89_FCC][2][45] = 127,
[1][1][RTW89_ETSI][1][45] = 127,
[1][1][RTW89_ETSI][0][45] = 127,
[1][1][RTW89_MKK][1][45] = 127,
[1][1][RTW89_MKK][0][45] = 127,
[1][1][RTW89_IC][1][45] = -26,
- [1][1][RTW89_IC][2][45] = 44,
[1][1][RTW89_KCC][1][45] = -14,
[1][1][RTW89_KCC][0][45] = 127,
[1][1][RTW89_ACMA][1][45] = 127,
@@ -56512,13 +54230,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][45] = 127,
[1][1][RTW89_THAILAND][0][45] = 127,
[1][1][RTW89_FCC][1][47] = -28,
- [1][1][RTW89_FCC][2][47] = 127,
[1][1][RTW89_ETSI][1][47] = 127,
[1][1][RTW89_ETSI][0][47] = 127,
[1][1][RTW89_MKK][1][47] = 127,
[1][1][RTW89_MKK][0][47] = 127,
[1][1][RTW89_IC][1][47] = -28,
- [1][1][RTW89_IC][2][47] = 44,
[1][1][RTW89_KCC][1][47] = -14,
[1][1][RTW89_KCC][0][47] = 127,
[1][1][RTW89_ACMA][1][47] = 127,
@@ -56531,13 +54247,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][47] = 127,
[1][1][RTW89_THAILAND][0][47] = 127,
[1][1][RTW89_FCC][1][49] = -28,
- [1][1][RTW89_FCC][2][49] = 127,
[1][1][RTW89_ETSI][1][49] = 127,
[1][1][RTW89_ETSI][0][49] = 127,
[1][1][RTW89_MKK][1][49] = 127,
[1][1][RTW89_MKK][0][49] = 127,
[1][1][RTW89_IC][1][49] = -28,
- [1][1][RTW89_IC][2][49] = 44,
[1][1][RTW89_KCC][1][49] = -14,
[1][1][RTW89_KCC][0][49] = 127,
[1][1][RTW89_ACMA][1][49] = 127,
@@ -56550,13 +54264,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][49] = 127,
[1][1][RTW89_THAILAND][0][49] = 127,
[1][1][RTW89_FCC][1][51] = -28,
- [1][1][RTW89_FCC][2][51] = 127,
[1][1][RTW89_ETSI][1][51] = 127,
[1][1][RTW89_ETSI][0][51] = 127,
[1][1][RTW89_MKK][1][51] = 127,
[1][1][RTW89_MKK][0][51] = 127,
[1][1][RTW89_IC][1][51] = -28,
- [1][1][RTW89_IC][2][51] = 44,
[1][1][RTW89_KCC][1][51] = -14,
[1][1][RTW89_KCC][0][51] = 127,
[1][1][RTW89_ACMA][1][51] = 127,
@@ -56569,13 +54281,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][51] = 127,
[1][1][RTW89_THAILAND][0][51] = 127,
[1][1][RTW89_FCC][1][53] = -26,
- [1][1][RTW89_FCC][2][53] = 127,
[1][1][RTW89_ETSI][1][53] = 127,
[1][1][RTW89_ETSI][0][53] = 127,
[1][1][RTW89_MKK][1][53] = 127,
[1][1][RTW89_MKK][0][53] = 127,
[1][1][RTW89_IC][1][53] = -26,
- [1][1][RTW89_IC][2][53] = 44,
[1][1][RTW89_KCC][1][53] = -14,
[1][1][RTW89_KCC][0][53] = 127,
[1][1][RTW89_ACMA][1][53] = 127,
@@ -56588,13 +54298,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][53] = 127,
[1][1][RTW89_THAILAND][0][53] = 127,
[1][1][RTW89_FCC][1][55] = -28,
- [1][1][RTW89_FCC][2][55] = 44,
[1][1][RTW89_ETSI][1][55] = 127,
[1][1][RTW89_ETSI][0][55] = 127,
[1][1][RTW89_MKK][1][55] = 127,
[1][1][RTW89_MKK][0][55] = 127,
[1][1][RTW89_IC][1][55] = -28,
- [1][1][RTW89_IC][2][55] = 44,
[1][1][RTW89_KCC][1][55] = -14,
[1][1][RTW89_KCC][0][55] = 127,
[1][1][RTW89_ACMA][1][55] = 127,
@@ -56607,13 +54315,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][55] = 127,
[1][1][RTW89_THAILAND][0][55] = 127,
[1][1][RTW89_FCC][1][57] = -28,
- [1][1][RTW89_FCC][2][57] = 44,
[1][1][RTW89_ETSI][1][57] = 127,
[1][1][RTW89_ETSI][0][57] = 127,
[1][1][RTW89_MKK][1][57] = 127,
[1][1][RTW89_MKK][0][57] = 127,
[1][1][RTW89_IC][1][57] = -28,
- [1][1][RTW89_IC][2][57] = 44,
[1][1][RTW89_KCC][1][57] = -14,
[1][1][RTW89_KCC][0][57] = 127,
[1][1][RTW89_ACMA][1][57] = 127,
@@ -56626,13 +54332,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][57] = 127,
[1][1][RTW89_THAILAND][0][57] = 127,
[1][1][RTW89_FCC][1][59] = -28,
- [1][1][RTW89_FCC][2][59] = 44,
[1][1][RTW89_ETSI][1][59] = 127,
[1][1][RTW89_ETSI][0][59] = 127,
[1][1][RTW89_MKK][1][59] = 127,
[1][1][RTW89_MKK][0][59] = 127,
[1][1][RTW89_IC][1][59] = -28,
- [1][1][RTW89_IC][2][59] = 44,
[1][1][RTW89_KCC][1][59] = -14,
[1][1][RTW89_KCC][0][59] = 127,
[1][1][RTW89_ACMA][1][59] = 127,
@@ -56645,13 +54349,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][59] = 127,
[1][1][RTW89_THAILAND][0][59] = 127,
[1][1][RTW89_FCC][1][60] = -28,
- [1][1][RTW89_FCC][2][60] = 44,
[1][1][RTW89_ETSI][1][60] = 127,
[1][1][RTW89_ETSI][0][60] = 127,
[1][1][RTW89_MKK][1][60] = 127,
[1][1][RTW89_MKK][0][60] = 127,
[1][1][RTW89_IC][1][60] = -28,
- [1][1][RTW89_IC][2][60] = 44,
[1][1][RTW89_KCC][1][60] = -14,
[1][1][RTW89_KCC][0][60] = 127,
[1][1][RTW89_ACMA][1][60] = 127,
@@ -56664,13 +54366,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][60] = 127,
[1][1][RTW89_THAILAND][0][60] = 127,
[1][1][RTW89_FCC][1][62] = -28,
- [1][1][RTW89_FCC][2][62] = 44,
[1][1][RTW89_ETSI][1][62] = 127,
[1][1][RTW89_ETSI][0][62] = 127,
[1][1][RTW89_MKK][1][62] = 127,
[1][1][RTW89_MKK][0][62] = 127,
[1][1][RTW89_IC][1][62] = -28,
- [1][1][RTW89_IC][2][62] = 44,
[1][1][RTW89_KCC][1][62] = -14,
[1][1][RTW89_KCC][0][62] = 127,
[1][1][RTW89_ACMA][1][62] = 127,
@@ -56683,13 +54383,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][62] = 127,
[1][1][RTW89_THAILAND][0][62] = 127,
[1][1][RTW89_FCC][1][64] = -28,
- [1][1][RTW89_FCC][2][64] = 44,
[1][1][RTW89_ETSI][1][64] = 127,
[1][1][RTW89_ETSI][0][64] = 127,
[1][1][RTW89_MKK][1][64] = 127,
[1][1][RTW89_MKK][0][64] = 127,
[1][1][RTW89_IC][1][64] = -28,
- [1][1][RTW89_IC][2][64] = 44,
[1][1][RTW89_KCC][1][64] = -14,
[1][1][RTW89_KCC][0][64] = 127,
[1][1][RTW89_ACMA][1][64] = 127,
@@ -56702,13 +54400,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][64] = 127,
[1][1][RTW89_THAILAND][0][64] = 127,
[1][1][RTW89_FCC][1][66] = -28,
- [1][1][RTW89_FCC][2][66] = 44,
[1][1][RTW89_ETSI][1][66] = 127,
[1][1][RTW89_ETSI][0][66] = 127,
[1][1][RTW89_MKK][1][66] = 127,
[1][1][RTW89_MKK][0][66] = 127,
[1][1][RTW89_IC][1][66] = -28,
- [1][1][RTW89_IC][2][66] = 44,
[1][1][RTW89_KCC][1][66] = -14,
[1][1][RTW89_KCC][0][66] = 127,
[1][1][RTW89_ACMA][1][66] = 127,
@@ -56721,13 +54417,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][66] = 127,
[1][1][RTW89_THAILAND][0][66] = 127,
[1][1][RTW89_FCC][1][68] = -28,
- [1][1][RTW89_FCC][2][68] = 44,
[1][1][RTW89_ETSI][1][68] = 127,
[1][1][RTW89_ETSI][0][68] = 127,
[1][1][RTW89_MKK][1][68] = 127,
[1][1][RTW89_MKK][0][68] = 127,
[1][1][RTW89_IC][1][68] = -28,
- [1][1][RTW89_IC][2][68] = 44,
[1][1][RTW89_KCC][1][68] = -14,
[1][1][RTW89_KCC][0][68] = 127,
[1][1][RTW89_ACMA][1][68] = 127,
@@ -56740,13 +54434,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][68] = 127,
[1][1][RTW89_THAILAND][0][68] = 127,
[1][1][RTW89_FCC][1][70] = -26,
- [1][1][RTW89_FCC][2][70] = 44,
[1][1][RTW89_ETSI][1][70] = 127,
[1][1][RTW89_ETSI][0][70] = 127,
[1][1][RTW89_MKK][1][70] = 127,
[1][1][RTW89_MKK][0][70] = 127,
[1][1][RTW89_IC][1][70] = -26,
- [1][1][RTW89_IC][2][70] = 44,
[1][1][RTW89_KCC][1][70] = -14,
[1][1][RTW89_KCC][0][70] = 127,
[1][1][RTW89_ACMA][1][70] = 127,
@@ -56759,13 +54451,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][70] = 127,
[1][1][RTW89_THAILAND][0][70] = 127,
[1][1][RTW89_FCC][1][72] = -28,
- [1][1][RTW89_FCC][2][72] = 44,
[1][1][RTW89_ETSI][1][72] = 127,
[1][1][RTW89_ETSI][0][72] = 127,
[1][1][RTW89_MKK][1][72] = 127,
[1][1][RTW89_MKK][0][72] = 127,
[1][1][RTW89_IC][1][72] = -28,
- [1][1][RTW89_IC][2][72] = 44,
[1][1][RTW89_KCC][1][72] = -14,
[1][1][RTW89_KCC][0][72] = 127,
[1][1][RTW89_ACMA][1][72] = 127,
@@ -56778,13 +54468,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][72] = 127,
[1][1][RTW89_THAILAND][0][72] = 127,
[1][1][RTW89_FCC][1][74] = -28,
- [1][1][RTW89_FCC][2][74] = 44,
[1][1][RTW89_ETSI][1][74] = 127,
[1][1][RTW89_ETSI][0][74] = 127,
[1][1][RTW89_MKK][1][74] = 127,
[1][1][RTW89_MKK][0][74] = 127,
[1][1][RTW89_IC][1][74] = -28,
- [1][1][RTW89_IC][2][74] = 44,
[1][1][RTW89_KCC][1][74] = -14,
[1][1][RTW89_KCC][0][74] = 127,
[1][1][RTW89_ACMA][1][74] = 127,
@@ -56797,13 +54485,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][74] = 127,
[1][1][RTW89_THAILAND][0][74] = 127,
[1][1][RTW89_FCC][1][75] = -28,
- [1][1][RTW89_FCC][2][75] = 44,
[1][1][RTW89_ETSI][1][75] = 127,
[1][1][RTW89_ETSI][0][75] = 127,
[1][1][RTW89_MKK][1][75] = 127,
[1][1][RTW89_MKK][0][75] = 127,
[1][1][RTW89_IC][1][75] = -28,
- [1][1][RTW89_IC][2][75] = 44,
[1][1][RTW89_KCC][1][75] = -14,
[1][1][RTW89_KCC][0][75] = 127,
[1][1][RTW89_ACMA][1][75] = 127,
@@ -56816,13 +54502,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][75] = 127,
[1][1][RTW89_THAILAND][0][75] = 127,
[1][1][RTW89_FCC][1][77] = -28,
- [1][1][RTW89_FCC][2][77] = 44,
[1][1][RTW89_ETSI][1][77] = 127,
[1][1][RTW89_ETSI][0][77] = 127,
[1][1][RTW89_MKK][1][77] = 127,
[1][1][RTW89_MKK][0][77] = 127,
[1][1][RTW89_IC][1][77] = -28,
- [1][1][RTW89_IC][2][77] = 44,
[1][1][RTW89_KCC][1][77] = -14,
[1][1][RTW89_KCC][0][77] = 127,
[1][1][RTW89_ACMA][1][77] = 127,
@@ -56835,13 +54519,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][77] = 127,
[1][1][RTW89_THAILAND][0][77] = 127,
[1][1][RTW89_FCC][1][79] = -28,
- [1][1][RTW89_FCC][2][79] = 44,
[1][1][RTW89_ETSI][1][79] = 127,
[1][1][RTW89_ETSI][0][79] = 127,
[1][1][RTW89_MKK][1][79] = 127,
[1][1][RTW89_MKK][0][79] = 127,
[1][1][RTW89_IC][1][79] = -28,
- [1][1][RTW89_IC][2][79] = 44,
[1][1][RTW89_KCC][1][79] = -14,
[1][1][RTW89_KCC][0][79] = 127,
[1][1][RTW89_ACMA][1][79] = 127,
@@ -56854,13 +54536,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][79] = 127,
[1][1][RTW89_THAILAND][0][79] = 127,
[1][1][RTW89_FCC][1][81] = -28,
- [1][1][RTW89_FCC][2][81] = 44,
[1][1][RTW89_ETSI][1][81] = 127,
[1][1][RTW89_ETSI][0][81] = 127,
[1][1][RTW89_MKK][1][81] = 127,
[1][1][RTW89_MKK][0][81] = 127,
[1][1][RTW89_IC][1][81] = -28,
- [1][1][RTW89_IC][2][81] = 44,
[1][1][RTW89_KCC][1][81] = -14,
[1][1][RTW89_KCC][0][81] = 127,
[1][1][RTW89_ACMA][1][81] = 127,
@@ -56873,13 +54553,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][81] = 127,
[1][1][RTW89_THAILAND][0][81] = 127,
[1][1][RTW89_FCC][1][83] = -28,
- [1][1][RTW89_FCC][2][83] = 44,
[1][1][RTW89_ETSI][1][83] = 127,
[1][1][RTW89_ETSI][0][83] = 127,
[1][1][RTW89_MKK][1][83] = 127,
[1][1][RTW89_MKK][0][83] = 127,
[1][1][RTW89_IC][1][83] = -28,
- [1][1][RTW89_IC][2][83] = 44,
[1][1][RTW89_KCC][1][83] = -14,
[1][1][RTW89_KCC][0][83] = 127,
[1][1][RTW89_ACMA][1][83] = 127,
@@ -56892,13 +54570,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][83] = 127,
[1][1][RTW89_THAILAND][0][83] = 127,
[1][1][RTW89_FCC][1][85] = -28,
- [1][1][RTW89_FCC][2][85] = 44,
[1][1][RTW89_ETSI][1][85] = 127,
[1][1][RTW89_ETSI][0][85] = 127,
[1][1][RTW89_MKK][1][85] = 127,
[1][1][RTW89_MKK][0][85] = 127,
[1][1][RTW89_IC][1][85] = -28,
- [1][1][RTW89_IC][2][85] = 44,
[1][1][RTW89_KCC][1][85] = -14,
[1][1][RTW89_KCC][0][85] = 127,
[1][1][RTW89_ACMA][1][85] = 127,
@@ -56911,13 +54587,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][85] = 127,
[1][1][RTW89_THAILAND][0][85] = 127,
[1][1][RTW89_FCC][1][87] = -28,
- [1][1][RTW89_FCC][2][87] = 127,
[1][1][RTW89_ETSI][1][87] = 127,
[1][1][RTW89_ETSI][0][87] = 127,
[1][1][RTW89_MKK][1][87] = 127,
[1][1][RTW89_MKK][0][87] = 127,
[1][1][RTW89_IC][1][87] = -28,
- [1][1][RTW89_IC][2][87] = 127,
[1][1][RTW89_KCC][1][87] = -14,
[1][1][RTW89_KCC][0][87] = 127,
[1][1][RTW89_ACMA][1][87] = 127,
@@ -56930,13 +54604,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][87] = 127,
[1][1][RTW89_THAILAND][0][87] = 127,
[1][1][RTW89_FCC][1][89] = -26,
- [1][1][RTW89_FCC][2][89] = 127,
[1][1][RTW89_ETSI][1][89] = 127,
[1][1][RTW89_ETSI][0][89] = 127,
[1][1][RTW89_MKK][1][89] = 127,
[1][1][RTW89_MKK][0][89] = 127,
[1][1][RTW89_IC][1][89] = -26,
- [1][1][RTW89_IC][2][89] = 127,
[1][1][RTW89_KCC][1][89] = -14,
[1][1][RTW89_KCC][0][89] = 127,
[1][1][RTW89_ACMA][1][89] = 127,
@@ -56949,13 +54621,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][89] = 127,
[1][1][RTW89_THAILAND][0][89] = 127,
[1][1][RTW89_FCC][1][90] = -26,
- [1][1][RTW89_FCC][2][90] = 127,
[1][1][RTW89_ETSI][1][90] = 127,
[1][1][RTW89_ETSI][0][90] = 127,
[1][1][RTW89_MKK][1][90] = 127,
[1][1][RTW89_MKK][0][90] = 127,
[1][1][RTW89_IC][1][90] = -26,
- [1][1][RTW89_IC][2][90] = 127,
[1][1][RTW89_KCC][1][90] = -14,
[1][1][RTW89_KCC][0][90] = 127,
[1][1][RTW89_ACMA][1][90] = 127,
@@ -56968,13 +54638,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][90] = 127,
[1][1][RTW89_THAILAND][0][90] = 127,
[1][1][RTW89_FCC][1][92] = -26,
- [1][1][RTW89_FCC][2][92] = 127,
[1][1][RTW89_ETSI][1][92] = 127,
[1][1][RTW89_ETSI][0][92] = 127,
[1][1][RTW89_MKK][1][92] = 127,
[1][1][RTW89_MKK][0][92] = 127,
[1][1][RTW89_IC][1][92] = -26,
- [1][1][RTW89_IC][2][92] = 127,
[1][1][RTW89_KCC][1][92] = -14,
[1][1][RTW89_KCC][0][92] = 127,
[1][1][RTW89_ACMA][1][92] = 127,
@@ -56987,13 +54655,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][92] = 127,
[1][1][RTW89_THAILAND][0][92] = 127,
[1][1][RTW89_FCC][1][94] = -26,
- [1][1][RTW89_FCC][2][94] = 127,
[1][1][RTW89_ETSI][1][94] = 127,
[1][1][RTW89_ETSI][0][94] = 127,
[1][1][RTW89_MKK][1][94] = 127,
[1][1][RTW89_MKK][0][94] = 127,
[1][1][RTW89_IC][1][94] = -26,
- [1][1][RTW89_IC][2][94] = 127,
[1][1][RTW89_KCC][1][94] = -14,
[1][1][RTW89_KCC][0][94] = 127,
[1][1][RTW89_ACMA][1][94] = 127,
@@ -57006,13 +54672,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][94] = 127,
[1][1][RTW89_THAILAND][0][94] = 127,
[1][1][RTW89_FCC][1][96] = -26,
- [1][1][RTW89_FCC][2][96] = 127,
[1][1][RTW89_ETSI][1][96] = 127,
[1][1][RTW89_ETSI][0][96] = 127,
[1][1][RTW89_MKK][1][96] = 127,
[1][1][RTW89_MKK][0][96] = 127,
[1][1][RTW89_IC][1][96] = -26,
- [1][1][RTW89_IC][2][96] = 127,
[1][1][RTW89_KCC][1][96] = -14,
[1][1][RTW89_KCC][0][96] = 127,
[1][1][RTW89_ACMA][1][96] = 127,
@@ -57025,13 +54689,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][96] = 127,
[1][1][RTW89_THAILAND][0][96] = 127,
[1][1][RTW89_FCC][1][98] = -26,
- [1][1][RTW89_FCC][2][98] = 127,
[1][1][RTW89_ETSI][1][98] = 127,
[1][1][RTW89_ETSI][0][98] = 127,
[1][1][RTW89_MKK][1][98] = 127,
[1][1][RTW89_MKK][0][98] = 127,
[1][1][RTW89_IC][1][98] = -26,
- [1][1][RTW89_IC][2][98] = 127,
[1][1][RTW89_KCC][1][98] = -14,
[1][1][RTW89_KCC][0][98] = 127,
[1][1][RTW89_ACMA][1][98] = 127,
@@ -57044,13 +54706,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][98] = 127,
[1][1][RTW89_THAILAND][0][98] = 127,
[1][1][RTW89_FCC][1][100] = -26,
- [1][1][RTW89_FCC][2][100] = 127,
[1][1][RTW89_ETSI][1][100] = 127,
[1][1][RTW89_ETSI][0][100] = 127,
[1][1][RTW89_MKK][1][100] = 127,
[1][1][RTW89_MKK][0][100] = 127,
[1][1][RTW89_IC][1][100] = -26,
- [1][1][RTW89_IC][2][100] = 127,
[1][1][RTW89_KCC][1][100] = -14,
[1][1][RTW89_KCC][0][100] = 127,
[1][1][RTW89_ACMA][1][100] = 127,
@@ -57063,13 +54723,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][100] = 127,
[1][1][RTW89_THAILAND][0][100] = 127,
[1][1][RTW89_FCC][1][102] = -26,
- [1][1][RTW89_FCC][2][102] = 127,
[1][1][RTW89_ETSI][1][102] = 127,
[1][1][RTW89_ETSI][0][102] = 127,
[1][1][RTW89_MKK][1][102] = 127,
[1][1][RTW89_MKK][0][102] = 127,
[1][1][RTW89_IC][1][102] = -26,
- [1][1][RTW89_IC][2][102] = 127,
[1][1][RTW89_KCC][1][102] = -14,
[1][1][RTW89_KCC][0][102] = 127,
[1][1][RTW89_ACMA][1][102] = 127,
@@ -57082,13 +54740,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][102] = 127,
[1][1][RTW89_THAILAND][0][102] = 127,
[1][1][RTW89_FCC][1][104] = -26,
- [1][1][RTW89_FCC][2][104] = 127,
[1][1][RTW89_ETSI][1][104] = 127,
[1][1][RTW89_ETSI][0][104] = 127,
[1][1][RTW89_MKK][1][104] = 127,
[1][1][RTW89_MKK][0][104] = 127,
[1][1][RTW89_IC][1][104] = -26,
- [1][1][RTW89_IC][2][104] = 127,
[1][1][RTW89_KCC][1][104] = -14,
[1][1][RTW89_KCC][0][104] = 127,
[1][1][RTW89_ACMA][1][104] = 127,
@@ -57101,13 +54757,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][104] = 127,
[1][1][RTW89_THAILAND][0][104] = 127,
[1][1][RTW89_FCC][1][105] = -26,
- [1][1][RTW89_FCC][2][105] = 127,
[1][1][RTW89_ETSI][1][105] = 127,
[1][1][RTW89_ETSI][0][105] = 127,
[1][1][RTW89_MKK][1][105] = 127,
[1][1][RTW89_MKK][0][105] = 127,
[1][1][RTW89_IC][1][105] = -26,
- [1][1][RTW89_IC][2][105] = 127,
[1][1][RTW89_KCC][1][105] = -14,
[1][1][RTW89_KCC][0][105] = 127,
[1][1][RTW89_ACMA][1][105] = 127,
@@ -57120,13 +54774,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][105] = 127,
[1][1][RTW89_THAILAND][0][105] = 127,
[1][1][RTW89_FCC][1][107] = -22,
- [1][1][RTW89_FCC][2][107] = 127,
[1][1][RTW89_ETSI][1][107] = 127,
[1][1][RTW89_ETSI][0][107] = 127,
[1][1][RTW89_MKK][1][107] = 127,
[1][1][RTW89_MKK][0][107] = 127,
[1][1][RTW89_IC][1][107] = -22,
- [1][1][RTW89_IC][2][107] = 127,
[1][1][RTW89_KCC][1][107] = -14,
[1][1][RTW89_KCC][0][107] = 127,
[1][1][RTW89_ACMA][1][107] = 127,
@@ -57139,13 +54791,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][107] = 127,
[1][1][RTW89_THAILAND][0][107] = 127,
[1][1][RTW89_FCC][1][109] = -22,
- [1][1][RTW89_FCC][2][109] = 127,
[1][1][RTW89_ETSI][1][109] = 127,
[1][1][RTW89_ETSI][0][109] = 127,
[1][1][RTW89_MKK][1][109] = 127,
[1][1][RTW89_MKK][0][109] = 127,
[1][1][RTW89_IC][1][109] = -22,
- [1][1][RTW89_IC][2][109] = 127,
[1][1][RTW89_KCC][1][109] = 127,
[1][1][RTW89_KCC][0][109] = 127,
[1][1][RTW89_ACMA][1][109] = 127,
@@ -57158,13 +54808,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][109] = 127,
[1][1][RTW89_THAILAND][0][109] = 127,
[1][1][RTW89_FCC][1][111] = 127,
- [1][1][RTW89_FCC][2][111] = 127,
[1][1][RTW89_ETSI][1][111] = 127,
[1][1][RTW89_ETSI][0][111] = 127,
[1][1][RTW89_MKK][1][111] = 127,
[1][1][RTW89_MKK][0][111] = 127,
[1][1][RTW89_IC][1][111] = 127,
- [1][1][RTW89_IC][2][111] = 127,
[1][1][RTW89_KCC][1][111] = 127,
[1][1][RTW89_KCC][0][111] = 127,
[1][1][RTW89_ACMA][1][111] = 127,
@@ -57177,13 +54825,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][111] = 127,
[1][1][RTW89_THAILAND][0][111] = 127,
[1][1][RTW89_FCC][1][113] = 127,
- [1][1][RTW89_FCC][2][113] = 127,
[1][1][RTW89_ETSI][1][113] = 127,
[1][1][RTW89_ETSI][0][113] = 127,
[1][1][RTW89_MKK][1][113] = 127,
[1][1][RTW89_MKK][0][113] = 127,
[1][1][RTW89_IC][1][113] = 127,
- [1][1][RTW89_IC][2][113] = 127,
[1][1][RTW89_KCC][1][113] = 127,
[1][1][RTW89_KCC][0][113] = 127,
[1][1][RTW89_ACMA][1][113] = 127,
@@ -57196,13 +54842,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][113] = 127,
[1][1][RTW89_THAILAND][0][113] = 127,
[1][1][RTW89_FCC][1][115] = 127,
- [1][1][RTW89_FCC][2][115] = 127,
[1][1][RTW89_ETSI][1][115] = 127,
[1][1][RTW89_ETSI][0][115] = 127,
[1][1][RTW89_MKK][1][115] = 127,
[1][1][RTW89_MKK][0][115] = 127,
[1][1][RTW89_IC][1][115] = 127,
- [1][1][RTW89_IC][2][115] = 127,
[1][1][RTW89_KCC][1][115] = 127,
[1][1][RTW89_KCC][0][115] = 127,
[1][1][RTW89_ACMA][1][115] = 127,
@@ -57215,13 +54859,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][115] = 127,
[1][1][RTW89_THAILAND][0][115] = 127,
[1][1][RTW89_FCC][1][117] = 127,
- [1][1][RTW89_FCC][2][117] = 127,
[1][1][RTW89_ETSI][1][117] = 127,
[1][1][RTW89_ETSI][0][117] = 127,
[1][1][RTW89_MKK][1][117] = 127,
[1][1][RTW89_MKK][0][117] = 127,
[1][1][RTW89_IC][1][117] = 127,
- [1][1][RTW89_IC][2][117] = 127,
[1][1][RTW89_KCC][1][117] = 127,
[1][1][RTW89_KCC][0][117] = 127,
[1][1][RTW89_ACMA][1][117] = 127,
@@ -57234,13 +54876,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][117] = 127,
[1][1][RTW89_THAILAND][0][117] = 127,
[1][1][RTW89_FCC][1][119] = 127,
- [1][1][RTW89_FCC][2][119] = 127,
[1][1][RTW89_ETSI][1][119] = 127,
[1][1][RTW89_ETSI][0][119] = 127,
[1][1][RTW89_MKK][1][119] = 127,
[1][1][RTW89_MKK][0][119] = 127,
[1][1][RTW89_IC][1][119] = 127,
- [1][1][RTW89_IC][2][119] = 127,
[1][1][RTW89_KCC][1][119] = 127,
[1][1][RTW89_KCC][0][119] = 127,
[1][1][RTW89_ACMA][1][119] = 127,
@@ -57253,13 +54893,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[1][1][RTW89_THAILAND][1][119] = 127,
[1][1][RTW89_THAILAND][0][119] = 127,
[2][0][RTW89_FCC][1][0] = 8,
- [2][0][RTW89_FCC][2][0] = 60,
[2][0][RTW89_ETSI][1][0] = 56,
[2][0][RTW89_ETSI][0][0] = 18,
[2][0][RTW89_MKK][1][0] = 54,
[2][0][RTW89_MKK][0][0] = 14,
[2][0][RTW89_IC][1][0] = 8,
- [2][0][RTW89_IC][2][0] = 60,
[2][0][RTW89_KCC][1][0] = -2,
[2][0][RTW89_KCC][0][0] = -2,
[2][0][RTW89_ACMA][1][0] = 56,
@@ -57272,13 +54910,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][0] = 52,
[2][0][RTW89_THAILAND][0][0] = 8,
[2][0][RTW89_FCC][1][2] = 8,
- [2][0][RTW89_FCC][2][2] = 60,
[2][0][RTW89_ETSI][1][2] = 56,
[2][0][RTW89_ETSI][0][2] = 18,
[2][0][RTW89_MKK][1][2] = 54,
[2][0][RTW89_MKK][0][2] = 14,
[2][0][RTW89_IC][1][2] = 8,
- [2][0][RTW89_IC][2][2] = 60,
[2][0][RTW89_KCC][1][2] = -2,
[2][0][RTW89_KCC][0][2] = -2,
[2][0][RTW89_ACMA][1][2] = 56,
@@ -57291,13 +54927,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][2] = 52,
[2][0][RTW89_THAILAND][0][2] = 8,
[2][0][RTW89_FCC][1][4] = 8,
- [2][0][RTW89_FCC][2][4] = 60,
[2][0][RTW89_ETSI][1][4] = 56,
[2][0][RTW89_ETSI][0][4] = 18,
[2][0][RTW89_MKK][1][4] = 54,
[2][0][RTW89_MKK][0][4] = 14,
[2][0][RTW89_IC][1][4] = 8,
- [2][0][RTW89_IC][2][4] = 60,
[2][0][RTW89_KCC][1][4] = -2,
[2][0][RTW89_KCC][0][4] = -2,
[2][0][RTW89_ACMA][1][4] = 56,
@@ -57310,13 +54944,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][4] = 52,
[2][0][RTW89_THAILAND][0][4] = 8,
[2][0][RTW89_FCC][1][6] = 8,
- [2][0][RTW89_FCC][2][6] = 60,
[2][0][RTW89_ETSI][1][6] = 56,
[2][0][RTW89_ETSI][0][6] = 18,
[2][0][RTW89_MKK][1][6] = 54,
[2][0][RTW89_MKK][0][6] = 14,
[2][0][RTW89_IC][1][6] = 8,
- [2][0][RTW89_IC][2][6] = 60,
[2][0][RTW89_KCC][1][6] = -2,
[2][0][RTW89_KCC][0][6] = -2,
[2][0][RTW89_ACMA][1][6] = 56,
@@ -57329,13 +54961,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][6] = 52,
[2][0][RTW89_THAILAND][0][6] = 8,
[2][0][RTW89_FCC][1][8] = 8,
- [2][0][RTW89_FCC][2][8] = 60,
[2][0][RTW89_ETSI][1][8] = 56,
[2][0][RTW89_ETSI][0][8] = 18,
[2][0][RTW89_MKK][1][8] = 54,
[2][0][RTW89_MKK][0][8] = 14,
[2][0][RTW89_IC][1][8] = 8,
- [2][0][RTW89_IC][2][8] = 60,
[2][0][RTW89_KCC][1][8] = -2,
[2][0][RTW89_KCC][0][8] = -2,
[2][0][RTW89_ACMA][1][8] = 56,
@@ -57348,13 +54978,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][8] = 52,
[2][0][RTW89_THAILAND][0][8] = 8,
[2][0][RTW89_FCC][1][10] = 8,
- [2][0][RTW89_FCC][2][10] = 60,
[2][0][RTW89_ETSI][1][10] = 56,
[2][0][RTW89_ETSI][0][10] = 18,
[2][0][RTW89_MKK][1][10] = 54,
[2][0][RTW89_MKK][0][10] = 14,
[2][0][RTW89_IC][1][10] = 8,
- [2][0][RTW89_IC][2][10] = 60,
[2][0][RTW89_KCC][1][10] = -2,
[2][0][RTW89_KCC][0][10] = -2,
[2][0][RTW89_ACMA][1][10] = 56,
@@ -57367,13 +54995,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][10] = 52,
[2][0][RTW89_THAILAND][0][10] = 8,
[2][0][RTW89_FCC][1][12] = 8,
- [2][0][RTW89_FCC][2][12] = 60,
[2][0][RTW89_ETSI][1][12] = 56,
[2][0][RTW89_ETSI][0][12] = 18,
[2][0][RTW89_MKK][1][12] = 54,
[2][0][RTW89_MKK][0][12] = 14,
[2][0][RTW89_IC][1][12] = 8,
- [2][0][RTW89_IC][2][12] = 60,
[2][0][RTW89_KCC][1][12] = -2,
[2][0][RTW89_KCC][0][12] = -2,
[2][0][RTW89_ACMA][1][12] = 56,
@@ -57386,13 +55012,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][12] = 52,
[2][0][RTW89_THAILAND][0][12] = 8,
[2][0][RTW89_FCC][1][14] = 8,
- [2][0][RTW89_FCC][2][14] = 60,
[2][0][RTW89_ETSI][1][14] = 56,
[2][0][RTW89_ETSI][0][14] = 18,
[2][0][RTW89_MKK][1][14] = 54,
[2][0][RTW89_MKK][0][14] = 14,
[2][0][RTW89_IC][1][14] = 8,
- [2][0][RTW89_IC][2][14] = 60,
[2][0][RTW89_KCC][1][14] = -2,
[2][0][RTW89_KCC][0][14] = -2,
[2][0][RTW89_ACMA][1][14] = 56,
@@ -57405,13 +55029,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][14] = 52,
[2][0][RTW89_THAILAND][0][14] = 8,
[2][0][RTW89_FCC][1][15] = 8,
- [2][0][RTW89_FCC][2][15] = 60,
[2][0][RTW89_ETSI][1][15] = 56,
[2][0][RTW89_ETSI][0][15] = 18,
[2][0][RTW89_MKK][1][15] = 54,
[2][0][RTW89_MKK][0][15] = 14,
[2][0][RTW89_IC][1][15] = 8,
- [2][0][RTW89_IC][2][15] = 60,
[2][0][RTW89_KCC][1][15] = -2,
[2][0][RTW89_KCC][0][15] = -2,
[2][0][RTW89_ACMA][1][15] = 56,
@@ -57424,13 +55046,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][15] = 52,
[2][0][RTW89_THAILAND][0][15] = 8,
[2][0][RTW89_FCC][1][17] = 8,
- [2][0][RTW89_FCC][2][17] = 60,
[2][0][RTW89_ETSI][1][17] = 56,
[2][0][RTW89_ETSI][0][17] = 18,
[2][0][RTW89_MKK][1][17] = 54,
[2][0][RTW89_MKK][0][17] = 14,
[2][0][RTW89_IC][1][17] = 8,
- [2][0][RTW89_IC][2][17] = 60,
[2][0][RTW89_KCC][1][17] = -2,
[2][0][RTW89_KCC][0][17] = -2,
[2][0][RTW89_ACMA][1][17] = 56,
@@ -57443,13 +55063,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][17] = 52,
[2][0][RTW89_THAILAND][0][17] = 8,
[2][0][RTW89_FCC][1][19] = 8,
- [2][0][RTW89_FCC][2][19] = 60,
[2][0][RTW89_ETSI][1][19] = 56,
[2][0][RTW89_ETSI][0][19] = 18,
[2][0][RTW89_MKK][1][19] = 54,
[2][0][RTW89_MKK][0][19] = 14,
[2][0][RTW89_IC][1][19] = 8,
- [2][0][RTW89_IC][2][19] = 60,
[2][0][RTW89_KCC][1][19] = -2,
[2][0][RTW89_KCC][0][19] = -2,
[2][0][RTW89_ACMA][1][19] = 56,
@@ -57462,13 +55080,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][19] = 52,
[2][0][RTW89_THAILAND][0][19] = 8,
[2][0][RTW89_FCC][1][21] = 8,
- [2][0][RTW89_FCC][2][21] = 60,
[2][0][RTW89_ETSI][1][21] = 56,
[2][0][RTW89_ETSI][0][21] = 18,
[2][0][RTW89_MKK][1][21] = 54,
[2][0][RTW89_MKK][0][21] = 14,
[2][0][RTW89_IC][1][21] = 8,
- [2][0][RTW89_IC][2][21] = 60,
[2][0][RTW89_KCC][1][21] = -2,
[2][0][RTW89_KCC][0][21] = -2,
[2][0][RTW89_ACMA][1][21] = 56,
@@ -57481,13 +55097,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][21] = 52,
[2][0][RTW89_THAILAND][0][21] = 8,
[2][0][RTW89_FCC][1][23] = 8,
- [2][0][RTW89_FCC][2][23] = 70,
[2][0][RTW89_ETSI][1][23] = 56,
[2][0][RTW89_ETSI][0][23] = 18,
[2][0][RTW89_MKK][1][23] = 56,
[2][0][RTW89_MKK][0][23] = 14,
[2][0][RTW89_IC][1][23] = 8,
- [2][0][RTW89_IC][2][23] = 70,
[2][0][RTW89_KCC][1][23] = -2,
[2][0][RTW89_KCC][0][23] = -2,
[2][0][RTW89_ACMA][1][23] = 56,
@@ -57500,13 +55114,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][23] = 52,
[2][0][RTW89_THAILAND][0][23] = 8,
[2][0][RTW89_FCC][1][25] = 8,
- [2][0][RTW89_FCC][2][25] = 70,
[2][0][RTW89_ETSI][1][25] = 56,
[2][0][RTW89_ETSI][0][25] = 18,
[2][0][RTW89_MKK][1][25] = 56,
[2][0][RTW89_MKK][0][25] = 14,
[2][0][RTW89_IC][1][25] = 8,
- [2][0][RTW89_IC][2][25] = 70,
[2][0][RTW89_KCC][1][25] = -2,
[2][0][RTW89_KCC][0][25] = -2,
[2][0][RTW89_ACMA][1][25] = 56,
@@ -57519,13 +55131,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][25] = 52,
[2][0][RTW89_THAILAND][0][25] = 8,
[2][0][RTW89_FCC][1][27] = 8,
- [2][0][RTW89_FCC][2][27] = 70,
[2][0][RTW89_ETSI][1][27] = 56,
[2][0][RTW89_ETSI][0][27] = 18,
[2][0][RTW89_MKK][1][27] = 56,
[2][0][RTW89_MKK][0][27] = 14,
[2][0][RTW89_IC][1][27] = 8,
- [2][0][RTW89_IC][2][27] = 70,
[2][0][RTW89_KCC][1][27] = -2,
[2][0][RTW89_KCC][0][27] = -2,
[2][0][RTW89_ACMA][1][27] = 56,
@@ -57538,13 +55148,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][27] = 52,
[2][0][RTW89_THAILAND][0][27] = 8,
[2][0][RTW89_FCC][1][29] = 8,
- [2][0][RTW89_FCC][2][29] = 70,
[2][0][RTW89_ETSI][1][29] = 56,
[2][0][RTW89_ETSI][0][29] = 18,
[2][0][RTW89_MKK][1][29] = 56,
[2][0][RTW89_MKK][0][29] = 14,
[2][0][RTW89_IC][1][29] = 8,
- [2][0][RTW89_IC][2][29] = 70,
[2][0][RTW89_KCC][1][29] = -2,
[2][0][RTW89_KCC][0][29] = -2,
[2][0][RTW89_ACMA][1][29] = 56,
@@ -57557,13 +55165,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][29] = 52,
[2][0][RTW89_THAILAND][0][29] = 8,
[2][0][RTW89_FCC][1][30] = 8,
- [2][0][RTW89_FCC][2][30] = 70,
[2][0][RTW89_ETSI][1][30] = 56,
[2][0][RTW89_ETSI][0][30] = 18,
[2][0][RTW89_MKK][1][30] = 56,
[2][0][RTW89_MKK][0][30] = 14,
[2][0][RTW89_IC][1][30] = 8,
- [2][0][RTW89_IC][2][30] = 70,
[2][0][RTW89_KCC][1][30] = -2,
[2][0][RTW89_KCC][0][30] = -2,
[2][0][RTW89_ACMA][1][30] = 56,
@@ -57576,13 +55182,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][30] = 52,
[2][0][RTW89_THAILAND][0][30] = 8,
[2][0][RTW89_FCC][1][32] = 8,
- [2][0][RTW89_FCC][2][32] = 70,
[2][0][RTW89_ETSI][1][32] = 56,
[2][0][RTW89_ETSI][0][32] = 18,
[2][0][RTW89_MKK][1][32] = 56,
[2][0][RTW89_MKK][0][32] = 14,
[2][0][RTW89_IC][1][32] = 8,
- [2][0][RTW89_IC][2][32] = 70,
[2][0][RTW89_KCC][1][32] = -2,
[2][0][RTW89_KCC][0][32] = -2,
[2][0][RTW89_ACMA][1][32] = 56,
@@ -57595,13 +55199,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][32] = 52,
[2][0][RTW89_THAILAND][0][32] = 8,
[2][0][RTW89_FCC][1][34] = 8,
- [2][0][RTW89_FCC][2][34] = 70,
[2][0][RTW89_ETSI][1][34] = 56,
[2][0][RTW89_ETSI][0][34] = 18,
[2][0][RTW89_MKK][1][34] = 56,
[2][0][RTW89_MKK][0][34] = 14,
[2][0][RTW89_IC][1][34] = 8,
- [2][0][RTW89_IC][2][34] = 70,
[2][0][RTW89_KCC][1][34] = -2,
[2][0][RTW89_KCC][0][34] = -2,
[2][0][RTW89_ACMA][1][34] = 56,
@@ -57614,13 +55216,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][34] = 52,
[2][0][RTW89_THAILAND][0][34] = 8,
[2][0][RTW89_FCC][1][36] = 8,
- [2][0][RTW89_FCC][2][36] = 70,
[2][0][RTW89_ETSI][1][36] = 56,
[2][0][RTW89_ETSI][0][36] = 18,
[2][0][RTW89_MKK][1][36] = 56,
[2][0][RTW89_MKK][0][36] = 14,
[2][0][RTW89_IC][1][36] = 8,
- [2][0][RTW89_IC][2][36] = 70,
[2][0][RTW89_KCC][1][36] = -2,
[2][0][RTW89_KCC][0][36] = -2,
[2][0][RTW89_ACMA][1][36] = 56,
@@ -57633,13 +55233,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][36] = 52,
[2][0][RTW89_THAILAND][0][36] = 8,
[2][0][RTW89_FCC][1][38] = 8,
- [2][0][RTW89_FCC][2][38] = 70,
[2][0][RTW89_ETSI][1][38] = 56,
[2][0][RTW89_ETSI][0][38] = 18,
[2][0][RTW89_MKK][1][38] = 56,
[2][0][RTW89_MKK][0][38] = 14,
[2][0][RTW89_IC][1][38] = 8,
- [2][0][RTW89_IC][2][38] = 70,
[2][0][RTW89_KCC][1][38] = -2,
[2][0][RTW89_KCC][0][38] = -2,
[2][0][RTW89_ACMA][1][38] = 56,
@@ -57652,13 +55250,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][38] = 52,
[2][0][RTW89_THAILAND][0][38] = 8,
[2][0][RTW89_FCC][1][40] = 8,
- [2][0][RTW89_FCC][2][40] = 70,
[2][0][RTW89_ETSI][1][40] = 56,
[2][0][RTW89_ETSI][0][40] = 18,
[2][0][RTW89_MKK][1][40] = 56,
[2][0][RTW89_MKK][0][40] = 14,
[2][0][RTW89_IC][1][40] = 8,
- [2][0][RTW89_IC][2][40] = 70,
[2][0][RTW89_KCC][1][40] = -2,
[2][0][RTW89_KCC][0][40] = -2,
[2][0][RTW89_ACMA][1][40] = 56,
@@ -57671,13 +55267,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][40] = 52,
[2][0][RTW89_THAILAND][0][40] = 8,
[2][0][RTW89_FCC][1][42] = 8,
- [2][0][RTW89_FCC][2][42] = 70,
[2][0][RTW89_ETSI][1][42] = 56,
[2][0][RTW89_ETSI][0][42] = 18,
[2][0][RTW89_MKK][1][42] = 56,
[2][0][RTW89_MKK][0][42] = 14,
[2][0][RTW89_IC][1][42] = 8,
- [2][0][RTW89_IC][2][42] = 70,
[2][0][RTW89_KCC][1][42] = -2,
[2][0][RTW89_KCC][0][42] = -2,
[2][0][RTW89_ACMA][1][42] = 56,
@@ -57690,13 +55284,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][42] = 52,
[2][0][RTW89_THAILAND][0][42] = 8,
[2][0][RTW89_FCC][1][44] = 8,
- [2][0][RTW89_FCC][2][44] = 70,
[2][0][RTW89_ETSI][1][44] = 56,
[2][0][RTW89_ETSI][0][44] = 18,
[2][0][RTW89_MKK][1][44] = 32,
[2][0][RTW89_MKK][0][44] = 14,
[2][0][RTW89_IC][1][44] = 8,
- [2][0][RTW89_IC][2][44] = 70,
[2][0][RTW89_KCC][1][44] = -2,
[2][0][RTW89_KCC][0][44] = -2,
[2][0][RTW89_ACMA][1][44] = 56,
@@ -57709,13 +55301,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][44] = 52,
[2][0][RTW89_THAILAND][0][44] = 8,
[2][0][RTW89_FCC][1][45] = 8,
- [2][0][RTW89_FCC][2][45] = 127,
[2][0][RTW89_ETSI][1][45] = 127,
[2][0][RTW89_ETSI][0][45] = 127,
[2][0][RTW89_MKK][1][45] = 127,
[2][0][RTW89_MKK][0][45] = 127,
[2][0][RTW89_IC][1][45] = 8,
- [2][0][RTW89_IC][2][45] = 70,
[2][0][RTW89_KCC][1][45] = -2,
[2][0][RTW89_KCC][0][45] = 127,
[2][0][RTW89_ACMA][1][45] = 127,
@@ -57728,13 +55318,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][45] = 127,
[2][0][RTW89_THAILAND][0][45] = 127,
[2][0][RTW89_FCC][1][47] = 8,
- [2][0][RTW89_FCC][2][47] = 127,
[2][0][RTW89_ETSI][1][47] = 127,
[2][0][RTW89_ETSI][0][47] = 127,
[2][0][RTW89_MKK][1][47] = 127,
[2][0][RTW89_MKK][0][47] = 127,
[2][0][RTW89_IC][1][47] = 8,
- [2][0][RTW89_IC][2][47] = 70,
[2][0][RTW89_KCC][1][47] = -2,
[2][0][RTW89_KCC][0][47] = 127,
[2][0][RTW89_ACMA][1][47] = 127,
@@ -57747,13 +55335,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][47] = 127,
[2][0][RTW89_THAILAND][0][47] = 127,
[2][0][RTW89_FCC][1][49] = 8,
- [2][0][RTW89_FCC][2][49] = 127,
[2][0][RTW89_ETSI][1][49] = 127,
[2][0][RTW89_ETSI][0][49] = 127,
[2][0][RTW89_MKK][1][49] = 127,
[2][0][RTW89_MKK][0][49] = 127,
[2][0][RTW89_IC][1][49] = 8,
- [2][0][RTW89_IC][2][49] = 70,
[2][0][RTW89_KCC][1][49] = -2,
[2][0][RTW89_KCC][0][49] = 127,
[2][0][RTW89_ACMA][1][49] = 127,
@@ -57766,13 +55352,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][49] = 127,
[2][0][RTW89_THAILAND][0][49] = 127,
[2][0][RTW89_FCC][1][51] = 8,
- [2][0][RTW89_FCC][2][51] = 127,
[2][0][RTW89_ETSI][1][51] = 127,
[2][0][RTW89_ETSI][0][51] = 127,
[2][0][RTW89_MKK][1][51] = 127,
[2][0][RTW89_MKK][0][51] = 127,
[2][0][RTW89_IC][1][51] = 8,
- [2][0][RTW89_IC][2][51] = 70,
[2][0][RTW89_KCC][1][51] = -2,
[2][0][RTW89_KCC][0][51] = 127,
[2][0][RTW89_ACMA][1][51] = 127,
@@ -57785,13 +55369,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][51] = 127,
[2][0][RTW89_THAILAND][0][51] = 127,
[2][0][RTW89_FCC][1][53] = 8,
- [2][0][RTW89_FCC][2][53] = 127,
[2][0][RTW89_ETSI][1][53] = 127,
[2][0][RTW89_ETSI][0][53] = 127,
[2][0][RTW89_MKK][1][53] = 127,
[2][0][RTW89_MKK][0][53] = 127,
[2][0][RTW89_IC][1][53] = 8,
- [2][0][RTW89_IC][2][53] = 70,
[2][0][RTW89_KCC][1][53] = -2,
[2][0][RTW89_KCC][0][53] = 127,
[2][0][RTW89_ACMA][1][53] = 127,
@@ -57804,13 +55386,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][53] = 127,
[2][0][RTW89_THAILAND][0][53] = 127,
[2][0][RTW89_FCC][1][55] = 8,
- [2][0][RTW89_FCC][2][55] = 68,
[2][0][RTW89_ETSI][1][55] = 127,
[2][0][RTW89_ETSI][0][55] = 127,
[2][0][RTW89_MKK][1][55] = 127,
[2][0][RTW89_MKK][0][55] = 127,
[2][0][RTW89_IC][1][55] = 8,
- [2][0][RTW89_IC][2][55] = 68,
[2][0][RTW89_KCC][1][55] = -2,
[2][0][RTW89_KCC][0][55] = 127,
[2][0][RTW89_ACMA][1][55] = 127,
@@ -57823,13 +55403,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][55] = 127,
[2][0][RTW89_THAILAND][0][55] = 127,
[2][0][RTW89_FCC][1][57] = 8,
- [2][0][RTW89_FCC][2][57] = 68,
[2][0][RTW89_ETSI][1][57] = 127,
[2][0][RTW89_ETSI][0][57] = 127,
[2][0][RTW89_MKK][1][57] = 127,
[2][0][RTW89_MKK][0][57] = 127,
[2][0][RTW89_IC][1][57] = 8,
- [2][0][RTW89_IC][2][57] = 68,
[2][0][RTW89_KCC][1][57] = -2,
[2][0][RTW89_KCC][0][57] = 127,
[2][0][RTW89_ACMA][1][57] = 127,
@@ -57842,13 +55420,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][57] = 127,
[2][0][RTW89_THAILAND][0][57] = 127,
[2][0][RTW89_FCC][1][59] = 8,
- [2][0][RTW89_FCC][2][59] = 68,
[2][0][RTW89_ETSI][1][59] = 127,
[2][0][RTW89_ETSI][0][59] = 127,
[2][0][RTW89_MKK][1][59] = 127,
[2][0][RTW89_MKK][0][59] = 127,
[2][0][RTW89_IC][1][59] = 8,
- [2][0][RTW89_IC][2][59] = 68,
[2][0][RTW89_KCC][1][59] = -2,
[2][0][RTW89_KCC][0][59] = 127,
[2][0][RTW89_ACMA][1][59] = 127,
@@ -57861,13 +55437,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][59] = 127,
[2][0][RTW89_THAILAND][0][59] = 127,
[2][0][RTW89_FCC][1][60] = 8,
- [2][0][RTW89_FCC][2][60] = 68,
[2][0][RTW89_ETSI][1][60] = 127,
[2][0][RTW89_ETSI][0][60] = 127,
[2][0][RTW89_MKK][1][60] = 127,
[2][0][RTW89_MKK][0][60] = 127,
[2][0][RTW89_IC][1][60] = 8,
- [2][0][RTW89_IC][2][60] = 68,
[2][0][RTW89_KCC][1][60] = -2,
[2][0][RTW89_KCC][0][60] = 127,
[2][0][RTW89_ACMA][1][60] = 127,
@@ -57880,13 +55454,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][60] = 127,
[2][0][RTW89_THAILAND][0][60] = 127,
[2][0][RTW89_FCC][1][62] = 8,
- [2][0][RTW89_FCC][2][62] = 68,
[2][0][RTW89_ETSI][1][62] = 127,
[2][0][RTW89_ETSI][0][62] = 127,
[2][0][RTW89_MKK][1][62] = 127,
[2][0][RTW89_MKK][0][62] = 127,
[2][0][RTW89_IC][1][62] = 8,
- [2][0][RTW89_IC][2][62] = 68,
[2][0][RTW89_KCC][1][62] = -2,
[2][0][RTW89_KCC][0][62] = 127,
[2][0][RTW89_ACMA][1][62] = 127,
@@ -57899,13 +55471,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][62] = 127,
[2][0][RTW89_THAILAND][0][62] = 127,
[2][0][RTW89_FCC][1][64] = 8,
- [2][0][RTW89_FCC][2][64] = 68,
[2][0][RTW89_ETSI][1][64] = 127,
[2][0][RTW89_ETSI][0][64] = 127,
[2][0][RTW89_MKK][1][64] = 127,
[2][0][RTW89_MKK][0][64] = 127,
[2][0][RTW89_IC][1][64] = 8,
- [2][0][RTW89_IC][2][64] = 68,
[2][0][RTW89_KCC][1][64] = -2,
[2][0][RTW89_KCC][0][64] = 127,
[2][0][RTW89_ACMA][1][64] = 127,
@@ -57918,13 +55488,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][64] = 127,
[2][0][RTW89_THAILAND][0][64] = 127,
[2][0][RTW89_FCC][1][66] = 8,
- [2][0][RTW89_FCC][2][66] = 68,
[2][0][RTW89_ETSI][1][66] = 127,
[2][0][RTW89_ETSI][0][66] = 127,
[2][0][RTW89_MKK][1][66] = 127,
[2][0][RTW89_MKK][0][66] = 127,
[2][0][RTW89_IC][1][66] = 8,
- [2][0][RTW89_IC][2][66] = 68,
[2][0][RTW89_KCC][1][66] = -2,
[2][0][RTW89_KCC][0][66] = 127,
[2][0][RTW89_ACMA][1][66] = 127,
@@ -57937,13 +55505,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][66] = 127,
[2][0][RTW89_THAILAND][0][66] = 127,
[2][0][RTW89_FCC][1][68] = 8,
- [2][0][RTW89_FCC][2][68] = 68,
[2][0][RTW89_ETSI][1][68] = 127,
[2][0][RTW89_ETSI][0][68] = 127,
[2][0][RTW89_MKK][1][68] = 127,
[2][0][RTW89_MKK][0][68] = 127,
[2][0][RTW89_IC][1][68] = 8,
- [2][0][RTW89_IC][2][68] = 68,
[2][0][RTW89_KCC][1][68] = -2,
[2][0][RTW89_KCC][0][68] = 127,
[2][0][RTW89_ACMA][1][68] = 127,
@@ -57956,13 +55522,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][68] = 127,
[2][0][RTW89_THAILAND][0][68] = 127,
[2][0][RTW89_FCC][1][70] = 8,
- [2][0][RTW89_FCC][2][70] = 68,
[2][0][RTW89_ETSI][1][70] = 127,
[2][0][RTW89_ETSI][0][70] = 127,
[2][0][RTW89_MKK][1][70] = 127,
[2][0][RTW89_MKK][0][70] = 127,
[2][0][RTW89_IC][1][70] = 8,
- [2][0][RTW89_IC][2][70] = 68,
[2][0][RTW89_KCC][1][70] = -2,
[2][0][RTW89_KCC][0][70] = 127,
[2][0][RTW89_ACMA][1][70] = 127,
@@ -57975,13 +55539,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][70] = 127,
[2][0][RTW89_THAILAND][0][70] = 127,
[2][0][RTW89_FCC][1][72] = 8,
- [2][0][RTW89_FCC][2][72] = 68,
[2][0][RTW89_ETSI][1][72] = 127,
[2][0][RTW89_ETSI][0][72] = 127,
[2][0][RTW89_MKK][1][72] = 127,
[2][0][RTW89_MKK][0][72] = 127,
[2][0][RTW89_IC][1][72] = 8,
- [2][0][RTW89_IC][2][72] = 68,
[2][0][RTW89_KCC][1][72] = -2,
[2][0][RTW89_KCC][0][72] = 127,
[2][0][RTW89_ACMA][1][72] = 127,
@@ -57994,13 +55556,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][72] = 127,
[2][0][RTW89_THAILAND][0][72] = 127,
[2][0][RTW89_FCC][1][74] = 8,
- [2][0][RTW89_FCC][2][74] = 68,
[2][0][RTW89_ETSI][1][74] = 127,
[2][0][RTW89_ETSI][0][74] = 127,
[2][0][RTW89_MKK][1][74] = 127,
[2][0][RTW89_MKK][0][74] = 127,
[2][0][RTW89_IC][1][74] = 8,
- [2][0][RTW89_IC][2][74] = 68,
[2][0][RTW89_KCC][1][74] = -2,
[2][0][RTW89_KCC][0][74] = 127,
[2][0][RTW89_ACMA][1][74] = 127,
@@ -58013,13 +55573,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][74] = 127,
[2][0][RTW89_THAILAND][0][74] = 127,
[2][0][RTW89_FCC][1][75] = 8,
- [2][0][RTW89_FCC][2][75] = 68,
[2][0][RTW89_ETSI][1][75] = 127,
[2][0][RTW89_ETSI][0][75] = 127,
[2][0][RTW89_MKK][1][75] = 127,
[2][0][RTW89_MKK][0][75] = 127,
[2][0][RTW89_IC][1][75] = 8,
- [2][0][RTW89_IC][2][75] = 68,
[2][0][RTW89_KCC][1][75] = -2,
[2][0][RTW89_KCC][0][75] = 127,
[2][0][RTW89_ACMA][1][75] = 127,
@@ -58032,13 +55590,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][75] = 127,
[2][0][RTW89_THAILAND][0][75] = 127,
[2][0][RTW89_FCC][1][77] = 8,
- [2][0][RTW89_FCC][2][77] = 68,
[2][0][RTW89_ETSI][1][77] = 127,
[2][0][RTW89_ETSI][0][77] = 127,
[2][0][RTW89_MKK][1][77] = 127,
[2][0][RTW89_MKK][0][77] = 127,
[2][0][RTW89_IC][1][77] = 8,
- [2][0][RTW89_IC][2][77] = 68,
[2][0][RTW89_KCC][1][77] = -2,
[2][0][RTW89_KCC][0][77] = 127,
[2][0][RTW89_ACMA][1][77] = 127,
@@ -58051,13 +55607,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][77] = 127,
[2][0][RTW89_THAILAND][0][77] = 127,
[2][0][RTW89_FCC][1][79] = 8,
- [2][0][RTW89_FCC][2][79] = 68,
[2][0][RTW89_ETSI][1][79] = 127,
[2][0][RTW89_ETSI][0][79] = 127,
[2][0][RTW89_MKK][1][79] = 127,
[2][0][RTW89_MKK][0][79] = 127,
[2][0][RTW89_IC][1][79] = 8,
- [2][0][RTW89_IC][2][79] = 68,
[2][0][RTW89_KCC][1][79] = -2,
[2][0][RTW89_KCC][0][79] = 127,
[2][0][RTW89_ACMA][1][79] = 127,
@@ -58070,13 +55624,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][79] = 127,
[2][0][RTW89_THAILAND][0][79] = 127,
[2][0][RTW89_FCC][1][81] = 8,
- [2][0][RTW89_FCC][2][81] = 68,
[2][0][RTW89_ETSI][1][81] = 127,
[2][0][RTW89_ETSI][0][81] = 127,
[2][0][RTW89_MKK][1][81] = 127,
[2][0][RTW89_MKK][0][81] = 127,
[2][0][RTW89_IC][1][81] = 8,
- [2][0][RTW89_IC][2][81] = 68,
[2][0][RTW89_KCC][1][81] = -2,
[2][0][RTW89_KCC][0][81] = 127,
[2][0][RTW89_ACMA][1][81] = 127,
@@ -58089,13 +55641,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][81] = 127,
[2][0][RTW89_THAILAND][0][81] = 127,
[2][0][RTW89_FCC][1][83] = 8,
- [2][0][RTW89_FCC][2][83] = 68,
[2][0][RTW89_ETSI][1][83] = 127,
[2][0][RTW89_ETSI][0][83] = 127,
[2][0][RTW89_MKK][1][83] = 127,
[2][0][RTW89_MKK][0][83] = 127,
[2][0][RTW89_IC][1][83] = 8,
- [2][0][RTW89_IC][2][83] = 68,
[2][0][RTW89_KCC][1][83] = -2,
[2][0][RTW89_KCC][0][83] = 127,
[2][0][RTW89_ACMA][1][83] = 127,
@@ -58108,13 +55658,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][83] = 127,
[2][0][RTW89_THAILAND][0][83] = 127,
[2][0][RTW89_FCC][1][85] = 8,
- [2][0][RTW89_FCC][2][85] = 68,
[2][0][RTW89_ETSI][1][85] = 127,
[2][0][RTW89_ETSI][0][85] = 127,
[2][0][RTW89_MKK][1][85] = 127,
[2][0][RTW89_MKK][0][85] = 127,
[2][0][RTW89_IC][1][85] = 8,
- [2][0][RTW89_IC][2][85] = 68,
[2][0][RTW89_KCC][1][85] = -2,
[2][0][RTW89_KCC][0][85] = 127,
[2][0][RTW89_ACMA][1][85] = 127,
@@ -58127,13 +55675,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][85] = 127,
[2][0][RTW89_THAILAND][0][85] = 127,
[2][0][RTW89_FCC][1][87] = 8,
- [2][0][RTW89_FCC][2][87] = 127,
[2][0][RTW89_ETSI][1][87] = 127,
[2][0][RTW89_ETSI][0][87] = 127,
[2][0][RTW89_MKK][1][87] = 127,
[2][0][RTW89_MKK][0][87] = 127,
[2][0][RTW89_IC][1][87] = 8,
- [2][0][RTW89_IC][2][87] = 127,
[2][0][RTW89_KCC][1][87] = -2,
[2][0][RTW89_KCC][0][87] = 127,
[2][0][RTW89_ACMA][1][87] = 127,
@@ -58146,13 +55692,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][87] = 127,
[2][0][RTW89_THAILAND][0][87] = 127,
[2][0][RTW89_FCC][1][89] = 8,
- [2][0][RTW89_FCC][2][89] = 127,
[2][0][RTW89_ETSI][1][89] = 127,
[2][0][RTW89_ETSI][0][89] = 127,
[2][0][RTW89_MKK][1][89] = 127,
[2][0][RTW89_MKK][0][89] = 127,
[2][0][RTW89_IC][1][89] = 8,
- [2][0][RTW89_IC][2][89] = 127,
[2][0][RTW89_KCC][1][89] = -2,
[2][0][RTW89_KCC][0][89] = 127,
[2][0][RTW89_ACMA][1][89] = 127,
@@ -58165,13 +55709,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][89] = 127,
[2][0][RTW89_THAILAND][0][89] = 127,
[2][0][RTW89_FCC][1][90] = 8,
- [2][0][RTW89_FCC][2][90] = 127,
[2][0][RTW89_ETSI][1][90] = 127,
[2][0][RTW89_ETSI][0][90] = 127,
[2][0][RTW89_MKK][1][90] = 127,
[2][0][RTW89_MKK][0][90] = 127,
[2][0][RTW89_IC][1][90] = 8,
- [2][0][RTW89_IC][2][90] = 127,
[2][0][RTW89_KCC][1][90] = -2,
[2][0][RTW89_KCC][0][90] = 127,
[2][0][RTW89_ACMA][1][90] = 127,
@@ -58184,13 +55726,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][90] = 127,
[2][0][RTW89_THAILAND][0][90] = 127,
[2][0][RTW89_FCC][1][92] = 8,
- [2][0][RTW89_FCC][2][92] = 127,
[2][0][RTW89_ETSI][1][92] = 127,
[2][0][RTW89_ETSI][0][92] = 127,
[2][0][RTW89_MKK][1][92] = 127,
[2][0][RTW89_MKK][0][92] = 127,
[2][0][RTW89_IC][1][92] = 8,
- [2][0][RTW89_IC][2][92] = 127,
[2][0][RTW89_KCC][1][92] = -2,
[2][0][RTW89_KCC][0][92] = 127,
[2][0][RTW89_ACMA][1][92] = 127,
@@ -58203,13 +55743,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][92] = 127,
[2][0][RTW89_THAILAND][0][92] = 127,
[2][0][RTW89_FCC][1][94] = 8,
- [2][0][RTW89_FCC][2][94] = 127,
[2][0][RTW89_ETSI][1][94] = 127,
[2][0][RTW89_ETSI][0][94] = 127,
[2][0][RTW89_MKK][1][94] = 127,
[2][0][RTW89_MKK][0][94] = 127,
[2][0][RTW89_IC][1][94] = 8,
- [2][0][RTW89_IC][2][94] = 127,
[2][0][RTW89_KCC][1][94] = -2,
[2][0][RTW89_KCC][0][94] = 127,
[2][0][RTW89_ACMA][1][94] = 127,
@@ -58222,13 +55760,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][94] = 127,
[2][0][RTW89_THAILAND][0][94] = 127,
[2][0][RTW89_FCC][1][96] = 8,
- [2][0][RTW89_FCC][2][96] = 127,
[2][0][RTW89_ETSI][1][96] = 127,
[2][0][RTW89_ETSI][0][96] = 127,
[2][0][RTW89_MKK][1][96] = 127,
[2][0][RTW89_MKK][0][96] = 127,
[2][0][RTW89_IC][1][96] = 8,
- [2][0][RTW89_IC][2][96] = 127,
[2][0][RTW89_KCC][1][96] = -2,
[2][0][RTW89_KCC][0][96] = 127,
[2][0][RTW89_ACMA][1][96] = 127,
@@ -58241,13 +55777,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][96] = 127,
[2][0][RTW89_THAILAND][0][96] = 127,
[2][0][RTW89_FCC][1][98] = 8,
- [2][0][RTW89_FCC][2][98] = 127,
[2][0][RTW89_ETSI][1][98] = 127,
[2][0][RTW89_ETSI][0][98] = 127,
[2][0][RTW89_MKK][1][98] = 127,
[2][0][RTW89_MKK][0][98] = 127,
[2][0][RTW89_IC][1][98] = 8,
- [2][0][RTW89_IC][2][98] = 127,
[2][0][RTW89_KCC][1][98] = -2,
[2][0][RTW89_KCC][0][98] = 127,
[2][0][RTW89_ACMA][1][98] = 127,
@@ -58260,13 +55794,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][98] = 127,
[2][0][RTW89_THAILAND][0][98] = 127,
[2][0][RTW89_FCC][1][100] = 8,
- [2][0][RTW89_FCC][2][100] = 127,
[2][0][RTW89_ETSI][1][100] = 127,
[2][0][RTW89_ETSI][0][100] = 127,
[2][0][RTW89_MKK][1][100] = 127,
[2][0][RTW89_MKK][0][100] = 127,
[2][0][RTW89_IC][1][100] = 8,
- [2][0][RTW89_IC][2][100] = 127,
[2][0][RTW89_KCC][1][100] = -2,
[2][0][RTW89_KCC][0][100] = 127,
[2][0][RTW89_ACMA][1][100] = 127,
@@ -58279,13 +55811,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][100] = 127,
[2][0][RTW89_THAILAND][0][100] = 127,
[2][0][RTW89_FCC][1][102] = 8,
- [2][0][RTW89_FCC][2][102] = 127,
[2][0][RTW89_ETSI][1][102] = 127,
[2][0][RTW89_ETSI][0][102] = 127,
[2][0][RTW89_MKK][1][102] = 127,
[2][0][RTW89_MKK][0][102] = 127,
[2][0][RTW89_IC][1][102] = 8,
- [2][0][RTW89_IC][2][102] = 127,
[2][0][RTW89_KCC][1][102] = -2,
[2][0][RTW89_KCC][0][102] = 127,
[2][0][RTW89_ACMA][1][102] = 127,
@@ -58298,13 +55828,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][102] = 127,
[2][0][RTW89_THAILAND][0][102] = 127,
[2][0][RTW89_FCC][1][104] = 8,
- [2][0][RTW89_FCC][2][104] = 127,
[2][0][RTW89_ETSI][1][104] = 127,
[2][0][RTW89_ETSI][0][104] = 127,
[2][0][RTW89_MKK][1][104] = 127,
[2][0][RTW89_MKK][0][104] = 127,
[2][0][RTW89_IC][1][104] = 8,
- [2][0][RTW89_IC][2][104] = 127,
[2][0][RTW89_KCC][1][104] = -2,
[2][0][RTW89_KCC][0][104] = 127,
[2][0][RTW89_ACMA][1][104] = 127,
@@ -58317,13 +55845,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][104] = 127,
[2][0][RTW89_THAILAND][0][104] = 127,
[2][0][RTW89_FCC][1][105] = 8,
- [2][0][RTW89_FCC][2][105] = 127,
[2][0][RTW89_ETSI][1][105] = 127,
[2][0][RTW89_ETSI][0][105] = 127,
[2][0][RTW89_MKK][1][105] = 127,
[2][0][RTW89_MKK][0][105] = 127,
[2][0][RTW89_IC][1][105] = 8,
- [2][0][RTW89_IC][2][105] = 127,
[2][0][RTW89_KCC][1][105] = -2,
[2][0][RTW89_KCC][0][105] = 127,
[2][0][RTW89_ACMA][1][105] = 127,
@@ -58336,13 +55862,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][105] = 127,
[2][0][RTW89_THAILAND][0][105] = 127,
[2][0][RTW89_FCC][1][107] = 10,
- [2][0][RTW89_FCC][2][107] = 127,
[2][0][RTW89_ETSI][1][107] = 127,
[2][0][RTW89_ETSI][0][107] = 127,
[2][0][RTW89_MKK][1][107] = 127,
[2][0][RTW89_MKK][0][107] = 127,
[2][0][RTW89_IC][1][107] = 10,
- [2][0][RTW89_IC][2][107] = 127,
[2][0][RTW89_KCC][1][107] = -2,
[2][0][RTW89_KCC][0][107] = 127,
[2][0][RTW89_ACMA][1][107] = 127,
@@ -58355,13 +55879,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][107] = 127,
[2][0][RTW89_THAILAND][0][107] = 127,
[2][0][RTW89_FCC][1][109] = 12,
- [2][0][RTW89_FCC][2][109] = 127,
[2][0][RTW89_ETSI][1][109] = 127,
[2][0][RTW89_ETSI][0][109] = 127,
[2][0][RTW89_MKK][1][109] = 127,
[2][0][RTW89_MKK][0][109] = 127,
[2][0][RTW89_IC][1][109] = 12,
- [2][0][RTW89_IC][2][109] = 127,
[2][0][RTW89_KCC][1][109] = 127,
[2][0][RTW89_KCC][0][109] = 127,
[2][0][RTW89_ACMA][1][109] = 127,
@@ -58374,13 +55896,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][109] = 127,
[2][0][RTW89_THAILAND][0][109] = 127,
[2][0][RTW89_FCC][1][111] = 127,
- [2][0][RTW89_FCC][2][111] = 127,
[2][0][RTW89_ETSI][1][111] = 127,
[2][0][RTW89_ETSI][0][111] = 127,
[2][0][RTW89_MKK][1][111] = 127,
[2][0][RTW89_MKK][0][111] = 127,
[2][0][RTW89_IC][1][111] = 127,
- [2][0][RTW89_IC][2][111] = 127,
[2][0][RTW89_KCC][1][111] = 127,
[2][0][RTW89_KCC][0][111] = 127,
[2][0][RTW89_ACMA][1][111] = 127,
@@ -58393,13 +55913,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][111] = 127,
[2][0][RTW89_THAILAND][0][111] = 127,
[2][0][RTW89_FCC][1][113] = 127,
- [2][0][RTW89_FCC][2][113] = 127,
[2][0][RTW89_ETSI][1][113] = 127,
[2][0][RTW89_ETSI][0][113] = 127,
[2][0][RTW89_MKK][1][113] = 127,
[2][0][RTW89_MKK][0][113] = 127,
[2][0][RTW89_IC][1][113] = 127,
- [2][0][RTW89_IC][2][113] = 127,
[2][0][RTW89_KCC][1][113] = 127,
[2][0][RTW89_KCC][0][113] = 127,
[2][0][RTW89_ACMA][1][113] = 127,
@@ -58412,13 +55930,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][113] = 127,
[2][0][RTW89_THAILAND][0][113] = 127,
[2][0][RTW89_FCC][1][115] = 127,
- [2][0][RTW89_FCC][2][115] = 127,
[2][0][RTW89_ETSI][1][115] = 127,
[2][0][RTW89_ETSI][0][115] = 127,
[2][0][RTW89_MKK][1][115] = 127,
[2][0][RTW89_MKK][0][115] = 127,
[2][0][RTW89_IC][1][115] = 127,
- [2][0][RTW89_IC][2][115] = 127,
[2][0][RTW89_KCC][1][115] = 127,
[2][0][RTW89_KCC][0][115] = 127,
[2][0][RTW89_ACMA][1][115] = 127,
@@ -58431,13 +55947,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][115] = 127,
[2][0][RTW89_THAILAND][0][115] = 127,
[2][0][RTW89_FCC][1][117] = 127,
- [2][0][RTW89_FCC][2][117] = 127,
[2][0][RTW89_ETSI][1][117] = 127,
[2][0][RTW89_ETSI][0][117] = 127,
[2][0][RTW89_MKK][1][117] = 127,
[2][0][RTW89_MKK][0][117] = 127,
[2][0][RTW89_IC][1][117] = 127,
- [2][0][RTW89_IC][2][117] = 127,
[2][0][RTW89_KCC][1][117] = 127,
[2][0][RTW89_KCC][0][117] = 127,
[2][0][RTW89_ACMA][1][117] = 127,
@@ -58450,13 +55964,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][117] = 127,
[2][0][RTW89_THAILAND][0][117] = 127,
[2][0][RTW89_FCC][1][119] = 127,
- [2][0][RTW89_FCC][2][119] = 127,
[2][0][RTW89_ETSI][1][119] = 127,
[2][0][RTW89_ETSI][0][119] = 127,
[2][0][RTW89_MKK][1][119] = 127,
[2][0][RTW89_MKK][0][119] = 127,
[2][0][RTW89_IC][1][119] = 127,
- [2][0][RTW89_IC][2][119] = 127,
[2][0][RTW89_KCC][1][119] = 127,
[2][0][RTW89_KCC][0][119] = 127,
[2][0][RTW89_ACMA][1][119] = 127,
@@ -58469,13 +55981,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][0][RTW89_THAILAND][1][119] = 127,
[2][0][RTW89_THAILAND][0][119] = 127,
[2][1][RTW89_FCC][1][0] = -16,
- [2][1][RTW89_FCC][2][0] = 54,
[2][1][RTW89_ETSI][1][0] = 44,
[2][1][RTW89_ETSI][0][0] = 6,
[2][1][RTW89_MKK][1][0] = 42,
[2][1][RTW89_MKK][0][0] = 2,
[2][1][RTW89_IC][1][0] = -16,
- [2][1][RTW89_IC][2][0] = 54,
[2][1][RTW89_KCC][1][0] = -14,
[2][1][RTW89_KCC][0][0] = -14,
[2][1][RTW89_ACMA][1][0] = 44,
@@ -58488,13 +55998,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][0] = 28,
[2][1][RTW89_THAILAND][0][0] = -16,
[2][1][RTW89_FCC][1][2] = -16,
- [2][1][RTW89_FCC][2][2] = 54,
[2][1][RTW89_ETSI][1][2] = 44,
[2][1][RTW89_ETSI][0][2] = 6,
[2][1][RTW89_MKK][1][2] = 40,
[2][1][RTW89_MKK][0][2] = 2,
[2][1][RTW89_IC][1][2] = -16,
- [2][1][RTW89_IC][2][2] = 54,
[2][1][RTW89_KCC][1][2] = -14,
[2][1][RTW89_KCC][0][2] = -14,
[2][1][RTW89_ACMA][1][2] = 44,
@@ -58507,13 +56015,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][2] = 28,
[2][1][RTW89_THAILAND][0][2] = -16,
[2][1][RTW89_FCC][1][4] = -16,
- [2][1][RTW89_FCC][2][4] = 54,
[2][1][RTW89_ETSI][1][4] = 44,
[2][1][RTW89_ETSI][0][4] = 6,
[2][1][RTW89_MKK][1][4] = 40,
[2][1][RTW89_MKK][0][4] = 2,
[2][1][RTW89_IC][1][4] = -16,
- [2][1][RTW89_IC][2][4] = 54,
[2][1][RTW89_KCC][1][4] = -14,
[2][1][RTW89_KCC][0][4] = -14,
[2][1][RTW89_ACMA][1][4] = 44,
@@ -58526,13 +56032,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][4] = 28,
[2][1][RTW89_THAILAND][0][4] = -16,
[2][1][RTW89_FCC][1][6] = -16,
- [2][1][RTW89_FCC][2][6] = 54,
[2][1][RTW89_ETSI][1][6] = 44,
[2][1][RTW89_ETSI][0][6] = 6,
[2][1][RTW89_MKK][1][6] = 40,
[2][1][RTW89_MKK][0][6] = 2,
[2][1][RTW89_IC][1][6] = -16,
- [2][1][RTW89_IC][2][6] = 54,
[2][1][RTW89_KCC][1][6] = -14,
[2][1][RTW89_KCC][0][6] = -14,
[2][1][RTW89_ACMA][1][6] = 44,
@@ -58545,13 +56049,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][6] = 28,
[2][1][RTW89_THAILAND][0][6] = -16,
[2][1][RTW89_FCC][1][8] = -16,
- [2][1][RTW89_FCC][2][8] = 54,
[2][1][RTW89_ETSI][1][8] = 44,
[2][1][RTW89_ETSI][0][8] = 6,
[2][1][RTW89_MKK][1][8] = 40,
[2][1][RTW89_MKK][0][8] = 2,
[2][1][RTW89_IC][1][8] = -16,
- [2][1][RTW89_IC][2][8] = 54,
[2][1][RTW89_KCC][1][8] = -14,
[2][1][RTW89_KCC][0][8] = -14,
[2][1][RTW89_ACMA][1][8] = 44,
@@ -58564,13 +56066,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][8] = 28,
[2][1][RTW89_THAILAND][0][8] = -16,
[2][1][RTW89_FCC][1][10] = -16,
- [2][1][RTW89_FCC][2][10] = 54,
[2][1][RTW89_ETSI][1][10] = 44,
[2][1][RTW89_ETSI][0][10] = 6,
[2][1][RTW89_MKK][1][10] = 40,
[2][1][RTW89_MKK][0][10] = 2,
[2][1][RTW89_IC][1][10] = -16,
- [2][1][RTW89_IC][2][10] = 54,
[2][1][RTW89_KCC][1][10] = -14,
[2][1][RTW89_KCC][0][10] = -14,
[2][1][RTW89_ACMA][1][10] = 44,
@@ -58583,13 +56083,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][10] = 28,
[2][1][RTW89_THAILAND][0][10] = -16,
[2][1][RTW89_FCC][1][12] = -16,
- [2][1][RTW89_FCC][2][12] = 54,
[2][1][RTW89_ETSI][1][12] = 44,
[2][1][RTW89_ETSI][0][12] = 6,
[2][1][RTW89_MKK][1][12] = 40,
[2][1][RTW89_MKK][0][12] = 2,
[2][1][RTW89_IC][1][12] = -16,
- [2][1][RTW89_IC][2][12] = 54,
[2][1][RTW89_KCC][1][12] = -14,
[2][1][RTW89_KCC][0][12] = -14,
[2][1][RTW89_ACMA][1][12] = 44,
@@ -58602,13 +56100,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][12] = 28,
[2][1][RTW89_THAILAND][0][12] = -16,
[2][1][RTW89_FCC][1][14] = -16,
- [2][1][RTW89_FCC][2][14] = 54,
[2][1][RTW89_ETSI][1][14] = 44,
[2][1][RTW89_ETSI][0][14] = 6,
[2][1][RTW89_MKK][1][14] = 40,
[2][1][RTW89_MKK][0][14] = 2,
[2][1][RTW89_IC][1][14] = -16,
- [2][1][RTW89_IC][2][14] = 54,
[2][1][RTW89_KCC][1][14] = -14,
[2][1][RTW89_KCC][0][14] = -14,
[2][1][RTW89_ACMA][1][14] = 44,
@@ -58621,13 +56117,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][14] = 28,
[2][1][RTW89_THAILAND][0][14] = -16,
[2][1][RTW89_FCC][1][15] = -16,
- [2][1][RTW89_FCC][2][15] = 54,
[2][1][RTW89_ETSI][1][15] = 44,
[2][1][RTW89_ETSI][0][15] = 6,
[2][1][RTW89_MKK][1][15] = 40,
[2][1][RTW89_MKK][0][15] = 2,
[2][1][RTW89_IC][1][15] = -16,
- [2][1][RTW89_IC][2][15] = 54,
[2][1][RTW89_KCC][1][15] = -14,
[2][1][RTW89_KCC][0][15] = -14,
[2][1][RTW89_ACMA][1][15] = 44,
@@ -58640,13 +56134,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][15] = 28,
[2][1][RTW89_THAILAND][0][15] = -16,
[2][1][RTW89_FCC][1][17] = -16,
- [2][1][RTW89_FCC][2][17] = 54,
[2][1][RTW89_ETSI][1][17] = 44,
[2][1][RTW89_ETSI][0][17] = 6,
[2][1][RTW89_MKK][1][17] = 40,
[2][1][RTW89_MKK][0][17] = 2,
[2][1][RTW89_IC][1][17] = -16,
- [2][1][RTW89_IC][2][17] = 54,
[2][1][RTW89_KCC][1][17] = -14,
[2][1][RTW89_KCC][0][17] = -14,
[2][1][RTW89_ACMA][1][17] = 44,
@@ -58659,13 +56151,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][17] = 28,
[2][1][RTW89_THAILAND][0][17] = -16,
[2][1][RTW89_FCC][1][19] = -16,
- [2][1][RTW89_FCC][2][19] = 54,
[2][1][RTW89_ETSI][1][19] = 44,
[2][1][RTW89_ETSI][0][19] = 6,
[2][1][RTW89_MKK][1][19] = 40,
[2][1][RTW89_MKK][0][19] = 2,
[2][1][RTW89_IC][1][19] = -16,
- [2][1][RTW89_IC][2][19] = 54,
[2][1][RTW89_KCC][1][19] = -14,
[2][1][RTW89_KCC][0][19] = -14,
[2][1][RTW89_ACMA][1][19] = 44,
@@ -58678,13 +56168,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][19] = 28,
[2][1][RTW89_THAILAND][0][19] = -16,
[2][1][RTW89_FCC][1][21] = -16,
- [2][1][RTW89_FCC][2][21] = 54,
[2][1][RTW89_ETSI][1][21] = 44,
[2][1][RTW89_ETSI][0][21] = 6,
[2][1][RTW89_MKK][1][21] = 40,
[2][1][RTW89_MKK][0][21] = 2,
[2][1][RTW89_IC][1][21] = -16,
- [2][1][RTW89_IC][2][21] = 54,
[2][1][RTW89_KCC][1][21] = -14,
[2][1][RTW89_KCC][0][21] = -14,
[2][1][RTW89_ACMA][1][21] = 44,
@@ -58697,13 +56185,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][21] = 28,
[2][1][RTW89_THAILAND][0][21] = -16,
[2][1][RTW89_FCC][1][23] = -16,
- [2][1][RTW89_FCC][2][23] = 54,
[2][1][RTW89_ETSI][1][23] = 44,
[2][1][RTW89_ETSI][0][23] = 6,
[2][1][RTW89_MKK][1][23] = 40,
[2][1][RTW89_MKK][0][23] = 2,
[2][1][RTW89_IC][1][23] = -16,
- [2][1][RTW89_IC][2][23] = 54,
[2][1][RTW89_KCC][1][23] = -14,
[2][1][RTW89_KCC][0][23] = -14,
[2][1][RTW89_ACMA][1][23] = 44,
@@ -58716,13 +56202,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][23] = 30,
[2][1][RTW89_THAILAND][0][23] = -16,
[2][1][RTW89_FCC][1][25] = -16,
- [2][1][RTW89_FCC][2][25] = 54,
[2][1][RTW89_ETSI][1][25] = 44,
[2][1][RTW89_ETSI][0][25] = 6,
[2][1][RTW89_MKK][1][25] = 40,
[2][1][RTW89_MKK][0][25] = 2,
[2][1][RTW89_IC][1][25] = -16,
- [2][1][RTW89_IC][2][25] = 54,
[2][1][RTW89_KCC][1][25] = -14,
[2][1][RTW89_KCC][0][25] = -14,
[2][1][RTW89_ACMA][1][25] = 44,
@@ -58735,13 +56219,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][25] = 28,
[2][1][RTW89_THAILAND][0][25] = -16,
[2][1][RTW89_FCC][1][27] = -16,
- [2][1][RTW89_FCC][2][27] = 54,
[2][1][RTW89_ETSI][1][27] = 44,
[2][1][RTW89_ETSI][0][27] = 6,
[2][1][RTW89_MKK][1][27] = 40,
[2][1][RTW89_MKK][0][27] = 2,
[2][1][RTW89_IC][1][27] = -16,
- [2][1][RTW89_IC][2][27] = 54,
[2][1][RTW89_KCC][1][27] = -14,
[2][1][RTW89_KCC][0][27] = -14,
[2][1][RTW89_ACMA][1][27] = 44,
@@ -58754,13 +56236,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][27] = 28,
[2][1][RTW89_THAILAND][0][27] = -16,
[2][1][RTW89_FCC][1][29] = -16,
- [2][1][RTW89_FCC][2][29] = 54,
[2][1][RTW89_ETSI][1][29] = 44,
[2][1][RTW89_ETSI][0][29] = 6,
[2][1][RTW89_MKK][1][29] = 40,
[2][1][RTW89_MKK][0][29] = 2,
[2][1][RTW89_IC][1][29] = -16,
- [2][1][RTW89_IC][2][29] = 54,
[2][1][RTW89_KCC][1][29] = -14,
[2][1][RTW89_KCC][0][29] = -14,
[2][1][RTW89_ACMA][1][29] = 44,
@@ -58773,13 +56253,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][29] = 28,
[2][1][RTW89_THAILAND][0][29] = -16,
[2][1][RTW89_FCC][1][30] = -16,
- [2][1][RTW89_FCC][2][30] = 54,
[2][1][RTW89_ETSI][1][30] = 44,
[2][1][RTW89_ETSI][0][30] = 6,
[2][1][RTW89_MKK][1][30] = 40,
[2][1][RTW89_MKK][0][30] = 2,
[2][1][RTW89_IC][1][30] = -16,
- [2][1][RTW89_IC][2][30] = 54,
[2][1][RTW89_KCC][1][30] = -14,
[2][1][RTW89_KCC][0][30] = -14,
[2][1][RTW89_ACMA][1][30] = 44,
@@ -58792,13 +56270,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][30] = 28,
[2][1][RTW89_THAILAND][0][30] = -16,
[2][1][RTW89_FCC][1][32] = -16,
- [2][1][RTW89_FCC][2][32] = 54,
[2][1][RTW89_ETSI][1][32] = 44,
[2][1][RTW89_ETSI][0][32] = 6,
[2][1][RTW89_MKK][1][32] = 40,
[2][1][RTW89_MKK][0][32] = 2,
[2][1][RTW89_IC][1][32] = -16,
- [2][1][RTW89_IC][2][32] = 54,
[2][1][RTW89_KCC][1][32] = -14,
[2][1][RTW89_KCC][0][32] = -14,
[2][1][RTW89_ACMA][1][32] = 44,
@@ -58811,13 +56287,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][32] = 28,
[2][1][RTW89_THAILAND][0][32] = -16,
[2][1][RTW89_FCC][1][34] = -16,
- [2][1][RTW89_FCC][2][34] = 54,
[2][1][RTW89_ETSI][1][34] = 44,
[2][1][RTW89_ETSI][0][34] = 6,
[2][1][RTW89_MKK][1][34] = 40,
[2][1][RTW89_MKK][0][34] = 2,
[2][1][RTW89_IC][1][34] = -16,
- [2][1][RTW89_IC][2][34] = 54,
[2][1][RTW89_KCC][1][34] = -14,
[2][1][RTW89_KCC][0][34] = -14,
[2][1][RTW89_ACMA][1][34] = 44,
@@ -58830,13 +56304,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][34] = 28,
[2][1][RTW89_THAILAND][0][34] = -16,
[2][1][RTW89_FCC][1][36] = -16,
- [2][1][RTW89_FCC][2][36] = 54,
[2][1][RTW89_ETSI][1][36] = 44,
[2][1][RTW89_ETSI][0][36] = 6,
[2][1][RTW89_MKK][1][36] = 40,
[2][1][RTW89_MKK][0][36] = 2,
[2][1][RTW89_IC][1][36] = -16,
- [2][1][RTW89_IC][2][36] = 54,
[2][1][RTW89_KCC][1][36] = -14,
[2][1][RTW89_KCC][0][36] = -14,
[2][1][RTW89_ACMA][1][36] = 44,
@@ -58849,13 +56321,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][36] = 28,
[2][1][RTW89_THAILAND][0][36] = -16,
[2][1][RTW89_FCC][1][38] = -16,
- [2][1][RTW89_FCC][2][38] = 54,
[2][1][RTW89_ETSI][1][38] = 44,
[2][1][RTW89_ETSI][0][38] = 6,
[2][1][RTW89_MKK][1][38] = 40,
[2][1][RTW89_MKK][0][38] = 2,
[2][1][RTW89_IC][1][38] = -16,
- [2][1][RTW89_IC][2][38] = 54,
[2][1][RTW89_KCC][1][38] = -14,
[2][1][RTW89_KCC][0][38] = -14,
[2][1][RTW89_ACMA][1][38] = 44,
@@ -58868,13 +56338,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][38] = 28,
[2][1][RTW89_THAILAND][0][38] = -16,
[2][1][RTW89_FCC][1][40] = -16,
- [2][1][RTW89_FCC][2][40] = 54,
[2][1][RTW89_ETSI][1][40] = 44,
[2][1][RTW89_ETSI][0][40] = 6,
[2][1][RTW89_MKK][1][40] = 40,
[2][1][RTW89_MKK][0][40] = 2,
[2][1][RTW89_IC][1][40] = -16,
- [2][1][RTW89_IC][2][40] = 54,
[2][1][RTW89_KCC][1][40] = -14,
[2][1][RTW89_KCC][0][40] = -14,
[2][1][RTW89_ACMA][1][40] = 44,
@@ -58887,13 +56355,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][40] = 28,
[2][1][RTW89_THAILAND][0][40] = -16,
[2][1][RTW89_FCC][1][42] = -16,
- [2][1][RTW89_FCC][2][42] = 54,
[2][1][RTW89_ETSI][1][42] = 44,
[2][1][RTW89_ETSI][0][42] = 6,
[2][1][RTW89_MKK][1][42] = 40,
[2][1][RTW89_MKK][0][42] = 2,
[2][1][RTW89_IC][1][42] = -16,
- [2][1][RTW89_IC][2][42] = 54,
[2][1][RTW89_KCC][1][42] = -14,
[2][1][RTW89_KCC][0][42] = -14,
[2][1][RTW89_ACMA][1][42] = 44,
@@ -58906,13 +56372,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][42] = 28,
[2][1][RTW89_THAILAND][0][42] = -16,
[2][1][RTW89_FCC][1][44] = -16,
- [2][1][RTW89_FCC][2][44] = 54,
[2][1][RTW89_ETSI][1][44] = 44,
[2][1][RTW89_ETSI][0][44] = 6,
[2][1][RTW89_MKK][1][44] = 16,
[2][1][RTW89_MKK][0][44] = 2,
[2][1][RTW89_IC][1][44] = -16,
- [2][1][RTW89_IC][2][44] = 54,
[2][1][RTW89_KCC][1][44] = -14,
[2][1][RTW89_KCC][0][44] = -14,
[2][1][RTW89_ACMA][1][44] = 44,
@@ -58925,13 +56389,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][44] = 28,
[2][1][RTW89_THAILAND][0][44] = -16,
[2][1][RTW89_FCC][1][45] = -16,
- [2][1][RTW89_FCC][2][45] = 127,
[2][1][RTW89_ETSI][1][45] = 127,
[2][1][RTW89_ETSI][0][45] = 127,
[2][1][RTW89_MKK][1][45] = 127,
[2][1][RTW89_MKK][0][45] = 127,
[2][1][RTW89_IC][1][45] = -16,
- [2][1][RTW89_IC][2][45] = 56,
[2][1][RTW89_KCC][1][45] = -14,
[2][1][RTW89_KCC][0][45] = 127,
[2][1][RTW89_ACMA][1][45] = 127,
@@ -58944,13 +56406,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][45] = 127,
[2][1][RTW89_THAILAND][0][45] = 127,
[2][1][RTW89_FCC][1][47] = -16,
- [2][1][RTW89_FCC][2][47] = 127,
[2][1][RTW89_ETSI][1][47] = 127,
[2][1][RTW89_ETSI][0][47] = 127,
[2][1][RTW89_MKK][1][47] = 127,
[2][1][RTW89_MKK][0][47] = 127,
[2][1][RTW89_IC][1][47] = -16,
- [2][1][RTW89_IC][2][47] = 56,
[2][1][RTW89_KCC][1][47] = -14,
[2][1][RTW89_KCC][0][47] = 127,
[2][1][RTW89_ACMA][1][47] = 127,
@@ -58963,13 +56423,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][47] = 127,
[2][1][RTW89_THAILAND][0][47] = 127,
[2][1][RTW89_FCC][1][49] = -16,
- [2][1][RTW89_FCC][2][49] = 127,
[2][1][RTW89_ETSI][1][49] = 127,
[2][1][RTW89_ETSI][0][49] = 127,
[2][1][RTW89_MKK][1][49] = 127,
[2][1][RTW89_MKK][0][49] = 127,
[2][1][RTW89_IC][1][49] = -16,
- [2][1][RTW89_IC][2][49] = 56,
[2][1][RTW89_KCC][1][49] = -14,
[2][1][RTW89_KCC][0][49] = 127,
[2][1][RTW89_ACMA][1][49] = 127,
@@ -58982,13 +56440,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][49] = 127,
[2][1][RTW89_THAILAND][0][49] = 127,
[2][1][RTW89_FCC][1][51] = -16,
- [2][1][RTW89_FCC][2][51] = 127,
[2][1][RTW89_ETSI][1][51] = 127,
[2][1][RTW89_ETSI][0][51] = 127,
[2][1][RTW89_MKK][1][51] = 127,
[2][1][RTW89_MKK][0][51] = 127,
[2][1][RTW89_IC][1][51] = -16,
- [2][1][RTW89_IC][2][51] = 56,
[2][1][RTW89_KCC][1][51] = -14,
[2][1][RTW89_KCC][0][51] = 127,
[2][1][RTW89_ACMA][1][51] = 127,
@@ -59001,13 +56457,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][51] = 127,
[2][1][RTW89_THAILAND][0][51] = 127,
[2][1][RTW89_FCC][1][53] = -16,
- [2][1][RTW89_FCC][2][53] = 127,
[2][1][RTW89_ETSI][1][53] = 127,
[2][1][RTW89_ETSI][0][53] = 127,
[2][1][RTW89_MKK][1][53] = 127,
[2][1][RTW89_MKK][0][53] = 127,
[2][1][RTW89_IC][1][53] = -16,
- [2][1][RTW89_IC][2][53] = 56,
[2][1][RTW89_KCC][1][53] = -14,
[2][1][RTW89_KCC][0][53] = 127,
[2][1][RTW89_ACMA][1][53] = 127,
@@ -59020,13 +56474,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][53] = 127,
[2][1][RTW89_THAILAND][0][53] = 127,
[2][1][RTW89_FCC][1][55] = -16,
- [2][1][RTW89_FCC][2][55] = 54,
[2][1][RTW89_ETSI][1][55] = 127,
[2][1][RTW89_ETSI][0][55] = 127,
[2][1][RTW89_MKK][1][55] = 127,
[2][1][RTW89_MKK][0][55] = 127,
[2][1][RTW89_IC][1][55] = -16,
- [2][1][RTW89_IC][2][55] = 54,
[2][1][RTW89_KCC][1][55] = -14,
[2][1][RTW89_KCC][0][55] = 127,
[2][1][RTW89_ACMA][1][55] = 127,
@@ -59039,13 +56491,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][55] = 127,
[2][1][RTW89_THAILAND][0][55] = 127,
[2][1][RTW89_FCC][1][57] = -16,
- [2][1][RTW89_FCC][2][57] = 54,
[2][1][RTW89_ETSI][1][57] = 127,
[2][1][RTW89_ETSI][0][57] = 127,
[2][1][RTW89_MKK][1][57] = 127,
[2][1][RTW89_MKK][0][57] = 127,
[2][1][RTW89_IC][1][57] = -16,
- [2][1][RTW89_IC][2][57] = 54,
[2][1][RTW89_KCC][1][57] = -14,
[2][1][RTW89_KCC][0][57] = 127,
[2][1][RTW89_ACMA][1][57] = 127,
@@ -59058,13 +56508,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][57] = 127,
[2][1][RTW89_THAILAND][0][57] = 127,
[2][1][RTW89_FCC][1][59] = -16,
- [2][1][RTW89_FCC][2][59] = 54,
[2][1][RTW89_ETSI][1][59] = 127,
[2][1][RTW89_ETSI][0][59] = 127,
[2][1][RTW89_MKK][1][59] = 127,
[2][1][RTW89_MKK][0][59] = 127,
[2][1][RTW89_IC][1][59] = -16,
- [2][1][RTW89_IC][2][59] = 54,
[2][1][RTW89_KCC][1][59] = -14,
[2][1][RTW89_KCC][0][59] = 127,
[2][1][RTW89_ACMA][1][59] = 127,
@@ -59077,13 +56525,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][59] = 127,
[2][1][RTW89_THAILAND][0][59] = 127,
[2][1][RTW89_FCC][1][60] = -16,
- [2][1][RTW89_FCC][2][60] = 54,
[2][1][RTW89_ETSI][1][60] = 127,
[2][1][RTW89_ETSI][0][60] = 127,
[2][1][RTW89_MKK][1][60] = 127,
[2][1][RTW89_MKK][0][60] = 127,
[2][1][RTW89_IC][1][60] = -16,
- [2][1][RTW89_IC][2][60] = 54,
[2][1][RTW89_KCC][1][60] = -14,
[2][1][RTW89_KCC][0][60] = 127,
[2][1][RTW89_ACMA][1][60] = 127,
@@ -59096,13 +56542,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][60] = 127,
[2][1][RTW89_THAILAND][0][60] = 127,
[2][1][RTW89_FCC][1][62] = -16,
- [2][1][RTW89_FCC][2][62] = 54,
[2][1][RTW89_ETSI][1][62] = 127,
[2][1][RTW89_ETSI][0][62] = 127,
[2][1][RTW89_MKK][1][62] = 127,
[2][1][RTW89_MKK][0][62] = 127,
[2][1][RTW89_IC][1][62] = -16,
- [2][1][RTW89_IC][2][62] = 54,
[2][1][RTW89_KCC][1][62] = -14,
[2][1][RTW89_KCC][0][62] = 127,
[2][1][RTW89_ACMA][1][62] = 127,
@@ -59115,13 +56559,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][62] = 127,
[2][1][RTW89_THAILAND][0][62] = 127,
[2][1][RTW89_FCC][1][64] = -16,
- [2][1][RTW89_FCC][2][64] = 54,
[2][1][RTW89_ETSI][1][64] = 127,
[2][1][RTW89_ETSI][0][64] = 127,
[2][1][RTW89_MKK][1][64] = 127,
[2][1][RTW89_MKK][0][64] = 127,
[2][1][RTW89_IC][1][64] = -16,
- [2][1][RTW89_IC][2][64] = 54,
[2][1][RTW89_KCC][1][64] = -14,
[2][1][RTW89_KCC][0][64] = 127,
[2][1][RTW89_ACMA][1][64] = 127,
@@ -59134,13 +56576,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][64] = 127,
[2][1][RTW89_THAILAND][0][64] = 127,
[2][1][RTW89_FCC][1][66] = -16,
- [2][1][RTW89_FCC][2][66] = 54,
[2][1][RTW89_ETSI][1][66] = 127,
[2][1][RTW89_ETSI][0][66] = 127,
[2][1][RTW89_MKK][1][66] = 127,
[2][1][RTW89_MKK][0][66] = 127,
[2][1][RTW89_IC][1][66] = -16,
- [2][1][RTW89_IC][2][66] = 54,
[2][1][RTW89_KCC][1][66] = -14,
[2][1][RTW89_KCC][0][66] = 127,
[2][1][RTW89_ACMA][1][66] = 127,
@@ -59153,13 +56593,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][66] = 127,
[2][1][RTW89_THAILAND][0][66] = 127,
[2][1][RTW89_FCC][1][68] = -16,
- [2][1][RTW89_FCC][2][68] = 54,
[2][1][RTW89_ETSI][1][68] = 127,
[2][1][RTW89_ETSI][0][68] = 127,
[2][1][RTW89_MKK][1][68] = 127,
[2][1][RTW89_MKK][0][68] = 127,
[2][1][RTW89_IC][1][68] = -16,
- [2][1][RTW89_IC][2][68] = 54,
[2][1][RTW89_KCC][1][68] = -14,
[2][1][RTW89_KCC][0][68] = 127,
[2][1][RTW89_ACMA][1][68] = 127,
@@ -59172,13 +56610,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][68] = 127,
[2][1][RTW89_THAILAND][0][68] = 127,
[2][1][RTW89_FCC][1][70] = -16,
- [2][1][RTW89_FCC][2][70] = 56,
[2][1][RTW89_ETSI][1][70] = 127,
[2][1][RTW89_ETSI][0][70] = 127,
[2][1][RTW89_MKK][1][70] = 127,
[2][1][RTW89_MKK][0][70] = 127,
[2][1][RTW89_IC][1][70] = -16,
- [2][1][RTW89_IC][2][70] = 56,
[2][1][RTW89_KCC][1][70] = -14,
[2][1][RTW89_KCC][0][70] = 127,
[2][1][RTW89_ACMA][1][70] = 127,
@@ -59191,13 +56627,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][70] = 127,
[2][1][RTW89_THAILAND][0][70] = 127,
[2][1][RTW89_FCC][1][72] = -16,
- [2][1][RTW89_FCC][2][72] = 56,
[2][1][RTW89_ETSI][1][72] = 127,
[2][1][RTW89_ETSI][0][72] = 127,
[2][1][RTW89_MKK][1][72] = 127,
[2][1][RTW89_MKK][0][72] = 127,
[2][1][RTW89_IC][1][72] = -16,
- [2][1][RTW89_IC][2][72] = 56,
[2][1][RTW89_KCC][1][72] = -14,
[2][1][RTW89_KCC][0][72] = 127,
[2][1][RTW89_ACMA][1][72] = 127,
@@ -59210,13 +56644,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][72] = 127,
[2][1][RTW89_THAILAND][0][72] = 127,
[2][1][RTW89_FCC][1][74] = -16,
- [2][1][RTW89_FCC][2][74] = 56,
[2][1][RTW89_ETSI][1][74] = 127,
[2][1][RTW89_ETSI][0][74] = 127,
[2][1][RTW89_MKK][1][74] = 127,
[2][1][RTW89_MKK][0][74] = 127,
[2][1][RTW89_IC][1][74] = -16,
- [2][1][RTW89_IC][2][74] = 56,
[2][1][RTW89_KCC][1][74] = -14,
[2][1][RTW89_KCC][0][74] = 127,
[2][1][RTW89_ACMA][1][74] = 127,
@@ -59229,13 +56661,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][74] = 127,
[2][1][RTW89_THAILAND][0][74] = 127,
[2][1][RTW89_FCC][1][75] = -16,
- [2][1][RTW89_FCC][2][75] = 56,
[2][1][RTW89_ETSI][1][75] = 127,
[2][1][RTW89_ETSI][0][75] = 127,
[2][1][RTW89_MKK][1][75] = 127,
[2][1][RTW89_MKK][0][75] = 127,
[2][1][RTW89_IC][1][75] = -16,
- [2][1][RTW89_IC][2][75] = 56,
[2][1][RTW89_KCC][1][75] = -14,
[2][1][RTW89_KCC][0][75] = 127,
[2][1][RTW89_ACMA][1][75] = 127,
@@ -59248,13 +56678,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][75] = 127,
[2][1][RTW89_THAILAND][0][75] = 127,
[2][1][RTW89_FCC][1][77] = -16,
- [2][1][RTW89_FCC][2][77] = 56,
[2][1][RTW89_ETSI][1][77] = 127,
[2][1][RTW89_ETSI][0][77] = 127,
[2][1][RTW89_MKK][1][77] = 127,
[2][1][RTW89_MKK][0][77] = 127,
[2][1][RTW89_IC][1][77] = -16,
- [2][1][RTW89_IC][2][77] = 56,
[2][1][RTW89_KCC][1][77] = -14,
[2][1][RTW89_KCC][0][77] = 127,
[2][1][RTW89_ACMA][1][77] = 127,
@@ -59267,13 +56695,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][77] = 127,
[2][1][RTW89_THAILAND][0][77] = 127,
[2][1][RTW89_FCC][1][79] = -16,
- [2][1][RTW89_FCC][2][79] = 56,
[2][1][RTW89_ETSI][1][79] = 127,
[2][1][RTW89_ETSI][0][79] = 127,
[2][1][RTW89_MKK][1][79] = 127,
[2][1][RTW89_MKK][0][79] = 127,
[2][1][RTW89_IC][1][79] = -16,
- [2][1][RTW89_IC][2][79] = 56,
[2][1][RTW89_KCC][1][79] = -14,
[2][1][RTW89_KCC][0][79] = 127,
[2][1][RTW89_ACMA][1][79] = 127,
@@ -59286,13 +56712,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][79] = 127,
[2][1][RTW89_THAILAND][0][79] = 127,
[2][1][RTW89_FCC][1][81] = -16,
- [2][1][RTW89_FCC][2][81] = 56,
[2][1][RTW89_ETSI][1][81] = 127,
[2][1][RTW89_ETSI][0][81] = 127,
[2][1][RTW89_MKK][1][81] = 127,
[2][1][RTW89_MKK][0][81] = 127,
[2][1][RTW89_IC][1][81] = -16,
- [2][1][RTW89_IC][2][81] = 56,
[2][1][RTW89_KCC][1][81] = -14,
[2][1][RTW89_KCC][0][81] = 127,
[2][1][RTW89_ACMA][1][81] = 127,
@@ -59305,13 +56729,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][81] = 127,
[2][1][RTW89_THAILAND][0][81] = 127,
[2][1][RTW89_FCC][1][83] = -16,
- [2][1][RTW89_FCC][2][83] = 56,
[2][1][RTW89_ETSI][1][83] = 127,
[2][1][RTW89_ETSI][0][83] = 127,
[2][1][RTW89_MKK][1][83] = 127,
[2][1][RTW89_MKK][0][83] = 127,
[2][1][RTW89_IC][1][83] = -16,
- [2][1][RTW89_IC][2][83] = 56,
[2][1][RTW89_KCC][1][83] = -14,
[2][1][RTW89_KCC][0][83] = 127,
[2][1][RTW89_ACMA][1][83] = 127,
@@ -59324,13 +56746,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][83] = 127,
[2][1][RTW89_THAILAND][0][83] = 127,
[2][1][RTW89_FCC][1][85] = -18,
- [2][1][RTW89_FCC][2][85] = 56,
[2][1][RTW89_ETSI][1][85] = 127,
[2][1][RTW89_ETSI][0][85] = 127,
[2][1][RTW89_MKK][1][85] = 127,
[2][1][RTW89_MKK][0][85] = 127,
[2][1][RTW89_IC][1][85] = -18,
- [2][1][RTW89_IC][2][85] = 56,
[2][1][RTW89_KCC][1][85] = -14,
[2][1][RTW89_KCC][0][85] = 127,
[2][1][RTW89_ACMA][1][85] = 127,
@@ -59343,13 +56763,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][85] = 127,
[2][1][RTW89_THAILAND][0][85] = 127,
[2][1][RTW89_FCC][1][87] = -16,
- [2][1][RTW89_FCC][2][87] = 127,
[2][1][RTW89_ETSI][1][87] = 127,
[2][1][RTW89_ETSI][0][87] = 127,
[2][1][RTW89_MKK][1][87] = 127,
[2][1][RTW89_MKK][0][87] = 127,
[2][1][RTW89_IC][1][87] = -16,
- [2][1][RTW89_IC][2][87] = 127,
[2][1][RTW89_KCC][1][87] = -14,
[2][1][RTW89_KCC][0][87] = 127,
[2][1][RTW89_ACMA][1][87] = 127,
@@ -59362,13 +56780,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][87] = 127,
[2][1][RTW89_THAILAND][0][87] = 127,
[2][1][RTW89_FCC][1][89] = -16,
- [2][1][RTW89_FCC][2][89] = 127,
[2][1][RTW89_ETSI][1][89] = 127,
[2][1][RTW89_ETSI][0][89] = 127,
[2][1][RTW89_MKK][1][89] = 127,
[2][1][RTW89_MKK][0][89] = 127,
[2][1][RTW89_IC][1][89] = -16,
- [2][1][RTW89_IC][2][89] = 127,
[2][1][RTW89_KCC][1][89] = -14,
[2][1][RTW89_KCC][0][89] = 127,
[2][1][RTW89_ACMA][1][89] = 127,
@@ -59381,13 +56797,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][89] = 127,
[2][1][RTW89_THAILAND][0][89] = 127,
[2][1][RTW89_FCC][1][90] = -16,
- [2][1][RTW89_FCC][2][90] = 127,
[2][1][RTW89_ETSI][1][90] = 127,
[2][1][RTW89_ETSI][0][90] = 127,
[2][1][RTW89_MKK][1][90] = 127,
[2][1][RTW89_MKK][0][90] = 127,
[2][1][RTW89_IC][1][90] = -16,
- [2][1][RTW89_IC][2][90] = 127,
[2][1][RTW89_KCC][1][90] = -14,
[2][1][RTW89_KCC][0][90] = 127,
[2][1][RTW89_ACMA][1][90] = 127,
@@ -59400,13 +56814,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][90] = 127,
[2][1][RTW89_THAILAND][0][90] = 127,
[2][1][RTW89_FCC][1][92] = -16,
- [2][1][RTW89_FCC][2][92] = 127,
[2][1][RTW89_ETSI][1][92] = 127,
[2][1][RTW89_ETSI][0][92] = 127,
[2][1][RTW89_MKK][1][92] = 127,
[2][1][RTW89_MKK][0][92] = 127,
[2][1][RTW89_IC][1][92] = -16,
- [2][1][RTW89_IC][2][92] = 127,
[2][1][RTW89_KCC][1][92] = -14,
[2][1][RTW89_KCC][0][92] = 127,
[2][1][RTW89_ACMA][1][92] = 127,
@@ -59419,13 +56831,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][92] = 127,
[2][1][RTW89_THAILAND][0][92] = 127,
[2][1][RTW89_FCC][1][94] = -16,
- [2][1][RTW89_FCC][2][94] = 127,
[2][1][RTW89_ETSI][1][94] = 127,
[2][1][RTW89_ETSI][0][94] = 127,
[2][1][RTW89_MKK][1][94] = 127,
[2][1][RTW89_MKK][0][94] = 127,
[2][1][RTW89_IC][1][94] = -16,
- [2][1][RTW89_IC][2][94] = 127,
[2][1][RTW89_KCC][1][94] = -14,
[2][1][RTW89_KCC][0][94] = 127,
[2][1][RTW89_ACMA][1][94] = 127,
@@ -59438,13 +56848,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][94] = 127,
[2][1][RTW89_THAILAND][0][94] = 127,
[2][1][RTW89_FCC][1][96] = -16,
- [2][1][RTW89_FCC][2][96] = 127,
[2][1][RTW89_ETSI][1][96] = 127,
[2][1][RTW89_ETSI][0][96] = 127,
[2][1][RTW89_MKK][1][96] = 127,
[2][1][RTW89_MKK][0][96] = 127,
[2][1][RTW89_IC][1][96] = -16,
- [2][1][RTW89_IC][2][96] = 127,
[2][1][RTW89_KCC][1][96] = -14,
[2][1][RTW89_KCC][0][96] = 127,
[2][1][RTW89_ACMA][1][96] = 127,
@@ -59457,13 +56865,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][96] = 127,
[2][1][RTW89_THAILAND][0][96] = 127,
[2][1][RTW89_FCC][1][98] = -16,
- [2][1][RTW89_FCC][2][98] = 127,
[2][1][RTW89_ETSI][1][98] = 127,
[2][1][RTW89_ETSI][0][98] = 127,
[2][1][RTW89_MKK][1][98] = 127,
[2][1][RTW89_MKK][0][98] = 127,
[2][1][RTW89_IC][1][98] = -16,
- [2][1][RTW89_IC][2][98] = 127,
[2][1][RTW89_KCC][1][98] = -14,
[2][1][RTW89_KCC][0][98] = 127,
[2][1][RTW89_ACMA][1][98] = 127,
@@ -59476,13 +56882,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][98] = 127,
[2][1][RTW89_THAILAND][0][98] = 127,
[2][1][RTW89_FCC][1][100] = -16,
- [2][1][RTW89_FCC][2][100] = 127,
[2][1][RTW89_ETSI][1][100] = 127,
[2][1][RTW89_ETSI][0][100] = 127,
[2][1][RTW89_MKK][1][100] = 127,
[2][1][RTW89_MKK][0][100] = 127,
[2][1][RTW89_IC][1][100] = -16,
- [2][1][RTW89_IC][2][100] = 127,
[2][1][RTW89_KCC][1][100] = -14,
[2][1][RTW89_KCC][0][100] = 127,
[2][1][RTW89_ACMA][1][100] = 127,
@@ -59495,13 +56899,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][100] = 127,
[2][1][RTW89_THAILAND][0][100] = 127,
[2][1][RTW89_FCC][1][102] = -16,
- [2][1][RTW89_FCC][2][102] = 127,
[2][1][RTW89_ETSI][1][102] = 127,
[2][1][RTW89_ETSI][0][102] = 127,
[2][1][RTW89_MKK][1][102] = 127,
[2][1][RTW89_MKK][0][102] = 127,
[2][1][RTW89_IC][1][102] = -16,
- [2][1][RTW89_IC][2][102] = 127,
[2][1][RTW89_KCC][1][102] = -14,
[2][1][RTW89_KCC][0][102] = 127,
[2][1][RTW89_ACMA][1][102] = 127,
@@ -59514,13 +56916,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][102] = 127,
[2][1][RTW89_THAILAND][0][102] = 127,
[2][1][RTW89_FCC][1][104] = -16,
- [2][1][RTW89_FCC][2][104] = 127,
[2][1][RTW89_ETSI][1][104] = 127,
[2][1][RTW89_ETSI][0][104] = 127,
[2][1][RTW89_MKK][1][104] = 127,
[2][1][RTW89_MKK][0][104] = 127,
[2][1][RTW89_IC][1][104] = -16,
- [2][1][RTW89_IC][2][104] = 127,
[2][1][RTW89_KCC][1][104] = -14,
[2][1][RTW89_KCC][0][104] = 127,
[2][1][RTW89_ACMA][1][104] = 127,
@@ -59533,13 +56933,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][104] = 127,
[2][1][RTW89_THAILAND][0][104] = 127,
[2][1][RTW89_FCC][1][105] = -16,
- [2][1][RTW89_FCC][2][105] = 127,
[2][1][RTW89_ETSI][1][105] = 127,
[2][1][RTW89_ETSI][0][105] = 127,
[2][1][RTW89_MKK][1][105] = 127,
[2][1][RTW89_MKK][0][105] = 127,
[2][1][RTW89_IC][1][105] = -16,
- [2][1][RTW89_IC][2][105] = 127,
[2][1][RTW89_KCC][1][105] = -14,
[2][1][RTW89_KCC][0][105] = 127,
[2][1][RTW89_ACMA][1][105] = 127,
@@ -59552,13 +56950,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][105] = 127,
[2][1][RTW89_THAILAND][0][105] = 127,
[2][1][RTW89_FCC][1][107] = -12,
- [2][1][RTW89_FCC][2][107] = 127,
[2][1][RTW89_ETSI][1][107] = 127,
[2][1][RTW89_ETSI][0][107] = 127,
[2][1][RTW89_MKK][1][107] = 127,
[2][1][RTW89_MKK][0][107] = 127,
[2][1][RTW89_IC][1][107] = -12,
- [2][1][RTW89_IC][2][107] = 127,
[2][1][RTW89_KCC][1][107] = -14,
[2][1][RTW89_KCC][0][107] = 127,
[2][1][RTW89_ACMA][1][107] = 127,
@@ -59571,13 +56967,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][107] = 127,
[2][1][RTW89_THAILAND][0][107] = 127,
[2][1][RTW89_FCC][1][109] = -10,
- [2][1][RTW89_FCC][2][109] = 127,
[2][1][RTW89_ETSI][1][109] = 127,
[2][1][RTW89_ETSI][0][109] = 127,
[2][1][RTW89_MKK][1][109] = 127,
[2][1][RTW89_MKK][0][109] = 127,
[2][1][RTW89_IC][1][109] = -10,
- [2][1][RTW89_IC][2][109] = 127,
[2][1][RTW89_KCC][1][109] = 127,
[2][1][RTW89_KCC][0][109] = 127,
[2][1][RTW89_ACMA][1][109] = 127,
@@ -59590,13 +56984,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][109] = 127,
[2][1][RTW89_THAILAND][0][109] = 127,
[2][1][RTW89_FCC][1][111] = 127,
- [2][1][RTW89_FCC][2][111] = 127,
[2][1][RTW89_ETSI][1][111] = 127,
[2][1][RTW89_ETSI][0][111] = 127,
[2][1][RTW89_MKK][1][111] = 127,
[2][1][RTW89_MKK][0][111] = 127,
[2][1][RTW89_IC][1][111] = 127,
- [2][1][RTW89_IC][2][111] = 127,
[2][1][RTW89_KCC][1][111] = 127,
[2][1][RTW89_KCC][0][111] = 127,
[2][1][RTW89_ACMA][1][111] = 127,
@@ -59609,13 +57001,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][111] = 127,
[2][1][RTW89_THAILAND][0][111] = 127,
[2][1][RTW89_FCC][1][113] = 127,
- [2][1][RTW89_FCC][2][113] = 127,
[2][1][RTW89_ETSI][1][113] = 127,
[2][1][RTW89_ETSI][0][113] = 127,
[2][1][RTW89_MKK][1][113] = 127,
[2][1][RTW89_MKK][0][113] = 127,
[2][1][RTW89_IC][1][113] = 127,
- [2][1][RTW89_IC][2][113] = 127,
[2][1][RTW89_KCC][1][113] = 127,
[2][1][RTW89_KCC][0][113] = 127,
[2][1][RTW89_ACMA][1][113] = 127,
@@ -59628,13 +57018,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][113] = 127,
[2][1][RTW89_THAILAND][0][113] = 127,
[2][1][RTW89_FCC][1][115] = 127,
- [2][1][RTW89_FCC][2][115] = 127,
[2][1][RTW89_ETSI][1][115] = 127,
[2][1][RTW89_ETSI][0][115] = 127,
[2][1][RTW89_MKK][1][115] = 127,
[2][1][RTW89_MKK][0][115] = 127,
[2][1][RTW89_IC][1][115] = 127,
- [2][1][RTW89_IC][2][115] = 127,
[2][1][RTW89_KCC][1][115] = 127,
[2][1][RTW89_KCC][0][115] = 127,
[2][1][RTW89_ACMA][1][115] = 127,
@@ -59647,13 +57035,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][115] = 127,
[2][1][RTW89_THAILAND][0][115] = 127,
[2][1][RTW89_FCC][1][117] = 127,
- [2][1][RTW89_FCC][2][117] = 127,
[2][1][RTW89_ETSI][1][117] = 127,
[2][1][RTW89_ETSI][0][117] = 127,
[2][1][RTW89_MKK][1][117] = 127,
[2][1][RTW89_MKK][0][117] = 127,
[2][1][RTW89_IC][1][117] = 127,
- [2][1][RTW89_IC][2][117] = 127,
[2][1][RTW89_KCC][1][117] = 127,
[2][1][RTW89_KCC][0][117] = 127,
[2][1][RTW89_ACMA][1][117] = 127,
@@ -59666,13 +57052,11 @@ const s8 rtw89_8852c_txpwr_lmt_ru_6g[RTW89_RU_NUM][RTW89_NTX_NUM]
[2][1][RTW89_THAILAND][1][117] = 127,
[2][1][RTW89_THAILAND][0][117] = 127,
[2][1][RTW89_FCC][1][119] = 127,
- [2][1][RTW89_FCC][2][119] = 127,
[2][1][RTW89_ETSI][1][119] = 127,
[2][1][RTW89_ETSI][0][119] = 127,
[2][1][RTW89_MKK][1][119] = 127,
[2][1][RTW89_MKK][0][119] = 127,
[2][1][RTW89_IC][1][119] = 127,
- [2][1][RTW89_IC][2][119] = 127,
[2][1][RTW89_KCC][1][119] = 127,
[2][1][RTW89_KCC][0][119] = 127,
[2][1][RTW89_ACMA][1][119] = 127,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c
index 583ea673a4f5..5d864fd5974e 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c
@@ -36,6 +36,7 @@ static const struct rtw89_pci_info rtw8852c_pci_info = {
.io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS,
.rx_ring_eq_is_full = false,
.check_rx_tag = false,
+ .no_rxbd_fs = false,
.init_cfg_reg = R_AX_HAXI_INIT_CFG1,
.txhci_en_bit = B_AX_TXHCI_EN_V1,
@@ -55,6 +56,7 @@ static const struct rtw89_pci_info rtw8852c_pci_info = {
.rpwm_addr = R_AX_PCIE_HRPWM_V1,
.cpwm_addr = R_AX_PCIE_CRPWM,
.mit_addr = R_AX_INT_MIT_RX_V1,
+ .wp_sel_addr = R_AX_WP_ADDR_H_SEL0_3,
.tx_dma_ch_mask = 0,
.bd_idx_addr_low_power = &rtw8852c_bd_idx_addr_low_power,
.dma_addr_set = &rtw89_pci_ch_dma_addr_set_v1,
@@ -66,10 +68,36 @@ static const struct rtw89_pci_info rtw8852c_pci_info = {
.enable_intr = rtw89_pci_enable_intr_v1,
.disable_intr = rtw89_pci_disable_intr_v1,
.recognize_intrs = rtw89_pci_recognize_intrs_v1,
+
+ .ssid_quirks = NULL,
+};
+
+static const struct dmi_system_id rtw8852c_pci_quirks[] = {
+ {
+ .ident = "Dell Inc. Vostro 16 5640",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 16 5640"),
+ DMI_MATCH(DMI_PRODUCT_SKU, "0CA0"),
+ },
+ .driver_data = (void *)RTW89_QUIRK_PCI_BER,
+ },
+ {
+ .ident = "Dell Inc. Inspiron 16 5640",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 16 5640"),
+ DMI_MATCH(DMI_PRODUCT_SKU, "0C9F"),
+ },
+ .driver_data = (void *)RTW89_QUIRK_PCI_BER,
+ },
+ {},
};
static const struct rtw89_driver_info rtw89_8852ce_info = {
.chip = &rtw8852c_chip_info,
+ .variant = NULL,
+ .quirks = rtw8852c_pci_quirks,
.bus = {
.pci = &rtw8852c_pci_info,
},
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
index 708132d5be2a..1d0f6e7df497 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
@@ -2,6 +2,7 @@
/* Copyright(c) 2023 Realtek Corporation
*/
+#include "chan.h"
#include "coex.h"
#include "debug.h"
#include "efuse.h"
@@ -11,12 +12,13 @@
#include "reg.h"
#include "rtw8922a.h"
#include "rtw8922a_rfk.h"
+#include "sar.h"
#include "util.h"
-#define RTW8922A_FW_FORMAT_MAX 0
+#define RTW8922A_FW_FORMAT_MAX 3
#define RTW8922A_FW_BASENAME "rtw89/rtw8922a_fw"
#define RTW8922A_MODULE_FIRMWARE \
- RTW8922A_FW_BASENAME ".bin"
+ RTW8922A_FW_BASENAME "-" __stringify(RTW8922A_FW_FORMAT_MAX) ".bin"
#define HE_N_USER_MAX_8922A 4
@@ -85,6 +87,10 @@ static const u32 rtw8922a_c2h_regs[RTW89_H2CREG_MAX] = {
R_BE_C2HREG_DATA3
};
+static const u32 rtw8922a_wow_wakeup_regs[RTW89_WOW_REASON_NUM] = {
+ R_AX_C2HREG_DATA3_V1 + 3, R_BE_DBG_WOW,
+};
+
static const struct rtw89_page_regs rtw8922a_page_regs = {
.hci_fc_ctrl = R_BE_HCI_FC_CTRL,
.ch_page_ctrl = R_BE_CH_PAGE_CTRL,
@@ -161,6 +167,15 @@ static const struct rtw89_rrsr_cfgs rtw8922a_rrsr_cfgs = {
.rsc = {R_BE_PTCL_RRSR1, B_BE_RSC_MASK, 2},
};
+static const struct rtw89_rfkill_regs rtw8922a_rfkill_regs = {
+ .pinmux = {R_BE_GPIO8_15_FUNC_SEL,
+ B_BE_PINMUX_GPIO9_FUNC_SEL_MASK,
+ 0xf},
+ .mode = {R_BE_GPIO_EXT_CTRL + 2,
+ (B_BE_GPIO_MOD_9 | B_BE_GPIO_IO_SEL_9) >> 16,
+ 0x0},
+};
+
static const struct rtw89_dig_regs rtw8922a_dig_regs = {
.seg0_pd_reg = R_SEG0R_PD_V2,
.pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
@@ -191,10 +206,17 @@ static const struct rtw89_edcca_regs rtw8922a_edcca_regs = {
.edcca_p_mask = B_EDCCA_LVL_MSK1,
.ppdu_level = R_SEG0R_PPDU_LVL_BE,
.ppdu_mask = B_EDCCA_LVL_MSK1,
- .rpt_a = R_EDCCA_RPT_A_BE,
- .rpt_b = R_EDCCA_RPT_B_BE,
- .rpt_sel = R_EDCCA_RPT_SEL_BE,
- .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ .p = {{
+ .rpt_a = R_EDCCA_RPT_A_BE,
+ .rpt_b = R_EDCCA_RPT_B_BE,
+ .rpt_sel = R_EDCCA_RPT_SEL_BE,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
+ }, {
+ .rpt_a = R_EDCCA_RPT_P1_A_BE,
+ .rpt_b = R_EDCCA_RPT_P1_B_BE,
+ .rpt_sel = R_EDCCA_RPT_SEL_BE,
+ .rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK,
+ }},
.rpt_sel_be = R_EDCCA_RPTREG_SEL_BE,
.rpt_sel_be_mask = B_EDCCA_RPTREG_SEL_BE_MSK,
.tx_collision_t2r_st = R_TX_COLLISION_T2R_ST_BE,
@@ -385,9 +407,6 @@ static int rtw8922a_pwr_on_func(struct rtw89_dev *rtwdev)
rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_FEN_BB_IP_RSTN |
B_BE_FEN_BBPLAT_RSTB);
- if (!test_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags))
- rtw89_efuse_read_fw_secure_be(rtwdev);
-
return 0;
}
@@ -952,6 +971,42 @@ static const struct rtw8922a_bb_gain bb_gain_tia[TIA_GAIN_NUM] = {
.gain_g_mask = 0x1FF, .gain_a_mask = 0x3FE00 },
};
+static const struct rtw8922a_bb_gain bb_op1db_lna[LNA_GAIN_NUM] = {
+ { .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x4078, 0x4478},
+ .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF000000},
+ { .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x407c, 0x447c},
+ .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF},
+ { .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x407c, 0x447c},
+ .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF00},
+ { .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x407c, 0x447c},
+ .gain_g_mask = 0xFF, .gain_a_mask = 0xFF0000},
+ { .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x407c, 0x447c},
+ .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF000000},
+ { .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x4080, 0x4480},
+ .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF},
+ { .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x4080, 0x4480},
+ .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF00},
+};
+
+static const struct rtw8922a_bb_gain bb_op1db_tia_lna[TIA_LNA_OP1DB_NUM] = {
+ { .gain_g = {0x40b4, 0x44b4}, .gain_a = {0x4080, 0x4480},
+ .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF000000},
+ { .gain_g = {0x40b4, 0x44b4}, .gain_a = {0x4084, 0x4484},
+ .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF},
+ { .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484},
+ .gain_g_mask = 0xFF, .gain_a_mask = 0xFF00},
+ { .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484},
+ .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF0000},
+ { .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484},
+ .gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF000000},
+ { .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4088, 0x4488},
+ .gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF},
+ { .gain_g = {0x40bc, 0x44bc}, .gain_a = {0x4088, 0x4488},
+ .gain_g_mask = 0xFF, .gain_a_mask = 0xFF00},
+ { .gain_g = {0x40bc, 0x44bc}, .gain_a = {0x4088, 0x4488},
+ .gain_g_mask = 0xFF00, .gain_a_mask = 0xFF0000},
+};
+
struct rtw8922a_bb_gain_bypass {
u32 gain_g[BB_PATH_NUM_8922A];
u32 gain_a[BB_PATH_NUM_8922A];
@@ -1043,6 +1098,30 @@ static void rtw8922a_set_lna_tia_gain(struct rtw89_dev *rtwdev,
val = gain->tia_gain[gain_band][bw_type][path][i];
rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
}
+
+ for (i = 0; i < LNA_GAIN_NUM; i++) {
+ if (chan->band_type == RTW89_BAND_2G) {
+ reg = bb_op1db_lna[i].gain_g[path];
+ mask = bb_op1db_lna[i].gain_g_mask;
+ } else {
+ reg = bb_op1db_lna[i].gain_a[path];
+ mask = bb_op1db_lna[i].gain_a_mask;
+ }
+ val = gain->lna_op1db[gain_band][bw_type][path][i];
+ rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
+ }
+
+ for (i = 0; i < TIA_LNA_OP1DB_NUM; i++) {
+ if (chan->band_type == RTW89_BAND_2G) {
+ reg = bb_op1db_tia_lna[i].gain_g[path];
+ mask = bb_op1db_tia_lna[i].gain_g_mask;
+ } else {
+ reg = bb_op1db_tia_lna[i].gain_a[path];
+ mask = bb_op1db_tia_lna[i].gain_a_mask;
+ }
+ val = gain->tia_lna_op1db[gain_band][bw_type][path][i];
+ rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
+ }
}
static void rtw8922a_set_gain(struct rtw89_dev *rtwdev,
@@ -1676,9 +1755,63 @@ static int rtw8922a_ctrl_rx_path_tmac(struct rtw89_dev *rtwdev,
return 0;
}
+#define DIGITAL_PWR_COMP_REG_NUM 22
+static const u32 rtw8922a_digital_pwr_comp_val[][DIGITAL_PWR_COMP_REG_NUM] = {
+ {0x012C0096, 0x044C02BC, 0x00322710, 0x015E0096, 0x03C8028A,
+ 0x0BB80708, 0x17701194, 0x02020100, 0x03030303, 0x01000303,
+ 0x05030302, 0x06060605, 0x06050300, 0x0A090807, 0x02000B0B,
+ 0x09080604, 0x0D0D0C0B, 0x08060400, 0x110F0C0B, 0x05001111,
+ 0x0D0C0907, 0x12121210},
+ {0x012C0096, 0x044C02BC, 0x00322710, 0x015E0096, 0x03C8028A,
+ 0x0BB80708, 0x17701194, 0x04030201, 0x05050505, 0x01000505,
+ 0x07060504, 0x09090908, 0x09070400, 0x0E0D0C0B, 0x03000E0E,
+ 0x0D0B0907, 0x1010100F, 0x0B080500, 0x1512100D, 0x05001515,
+ 0x100D0B08, 0x15151512},
+};
+
+static void rtw8922a_set_digital_pwr_comp(struct rtw89_dev *rtwdev,
+ bool enable, u8 nss,
+ enum rtw89_rf_path path)
+{
+ static const u32 ltpc_t0[2] = {R_BE_LTPC_T0_PATH0, R_BE_LTPC_T0_PATH1};
+ const u32 *digital_pwr_comp;
+ u32 addr, val;
+ u32 i;
+
+ if (nss == 1)
+ digital_pwr_comp = rtw8922a_digital_pwr_comp_val[0];
+ else
+ digital_pwr_comp = rtw8922a_digital_pwr_comp_val[1];
+
+ addr = ltpc_t0[path];
+ for (i = 0; i < DIGITAL_PWR_COMP_REG_NUM; i++, addr += 4) {
+ val = enable ? digital_pwr_comp[i] : 0;
+ rtw89_phy_write32(rtwdev, addr, val);
+ }
+}
+
+static void rtw8922a_digital_pwr_comp(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
+{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
+ bool enable = chan->band_type != RTW89_BAND_2G;
+ u8 path;
+
+ if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) {
+ if (phy_idx == RTW89_PHY_0)
+ path = RF_PATH_A;
+ else
+ path = RF_PATH_B;
+ rtw8922a_set_digital_pwr_comp(rtwdev, enable, 1, path);
+ } else {
+ rtw8922a_set_digital_pwr_comp(rtwdev, enable, 2, RF_PATH_A);
+ rtw8922a_set_digital_pwr_comp(rtwdev, enable, 2, RF_PATH_B);
+ }
+}
+
static int rtw8922a_ctrl_mlo(struct rtw89_dev *rtwdev, enum rtw89_mlo_dbcc_mode mode)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan0, *chan1;
if (mode == MLO_1_PLUS_1_1RF || mode == DBCC_LEGACY) {
rtw89_phy_write32_mask(rtwdev, R_DBCC, B_DBCC_EN, 0x1);
@@ -1691,13 +1824,20 @@ static int rtw8922a_ctrl_mlo(struct rtw89_dev *rtwdev, enum rtw89_mlo_dbcc_mode
return -EOPNOTSUPP;
}
- if (mode == MLO_2_PLUS_0_1RF) {
- rtw8922a_ctrl_afe_dac(rtwdev, chan->band_width, RF_PATH_A);
- rtw8922a_ctrl_afe_dac(rtwdev, chan->band_width, RF_PATH_B);
+ if (mode == MLO_1_PLUS_1_1RF) {
+ chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
+ chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
+ } else if (mode == MLO_0_PLUS_2_1RF) {
+ chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
+ chan0 = chan1;
} else {
- rtw89_warn(rtwdev, "unsupported MLO mode %d\n", mode);
+ chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
+ chan1 = chan0;
}
+ rtw8922a_ctrl_afe_dac(rtwdev, chan0->band_width, RF_PATH_A);
+ rtw8922a_ctrl_afe_dac(rtwdev, chan1->band_width, RF_PATH_B);
+
rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x6180);
if (mode == MLO_2_PLUS_0_1RF) {
@@ -1797,11 +1937,13 @@ static void rtw8922a_pre_set_channel_bb(struct rtw89_dev *rtwdev,
}
static void rtw8922a_post_set_channel_bb(struct rtw89_dev *rtwdev,
- enum rtw89_mlo_dbcc_mode mode)
+ enum rtw89_mlo_dbcc_mode mode,
+ enum rtw89_phy_idx phy_idx)
{
if (!rtwdev->dbcc_en)
return;
+ rtw8922a_digital_pwr_comp(rtwdev, phy_idx);
rtw8922a_ctrl_mlo(rtwdev, mode);
}
@@ -1908,7 +2050,7 @@ static void rtw8922a_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
rtw8922a_hal_reset(rtwdev, phy_idx, mac_idx, chan->band_type, &p->tx_en, enter);
if (!enter) {
- rtw8922a_post_set_channel_bb(rtwdev, rtwdev->mlo_dbcc_mode);
+ rtw8922a_post_set_channel_bb(rtwdev, rtwdev->mlo_dbcc_mode, phy_idx);
rtw8922a_post_set_channel_rf(rtwdev, phy_idx);
}
}
@@ -1922,12 +2064,24 @@ static void rtw8922a_rfk_init(struct rtw89_dev *rtwdev)
memset(rfk_mcc, 0, sizeof(*rfk_mcc));
}
+static void __rtw8922a_rfk_init_late(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan)
+{
+ rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5);
+
+ rtw89_phy_rfk_dack_and_wait(rtwdev, phy_idx, chan, 58);
+ if (!test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags))
+ rtw89_phy_rfk_rxdck_and_wait(rtwdev, phy_idx, chan, false, 128);
+}
+
static void rtw8922a_rfk_init_late(struct rtw89_dev *rtwdev)
{
- rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, RTW89_PHY_0, 5);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
- rtw89_phy_rfk_dack_and_wait(rtwdev, RTW89_PHY_0, 58);
- rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, 32);
+ __rtw8922a_rfk_init_late(rtwdev, RTW89_PHY_0, chan);
+ if (rtwdev->dbcc_en)
+ __rtw8922a_rfk_init_late(rtwdev, RTW89_PHY_1, chan);
}
static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
@@ -1949,10 +2103,13 @@ static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
}
}
-static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev)
+static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
- enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
- u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB);
+ enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
+ enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
+ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx);
u32 tx_en;
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_START);
@@ -1960,23 +2117,26 @@ static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev)
_wait_rx_mode(rtwdev, RF_AB);
rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5);
- rtw89_phy_rfk_txgapk_and_wait(rtwdev, phy_idx, 54);
- rtw89_phy_rfk_iqk_and_wait(rtwdev, phy_idx, 84);
- rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, RTW89_TSSI_NORMAL, 6);
- rtw89_phy_rfk_dpk_and_wait(rtwdev, phy_idx, 34);
- rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, 32);
+ rtw89_phy_rfk_txgapk_and_wait(rtwdev, phy_idx, chan, 54);
+ rtw89_phy_rfk_iqk_and_wait(rtwdev, phy_idx, chan, 84);
+ rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_NORMAL, 20);
+ rtw89_phy_rfk_dpk_and_wait(rtwdev, phy_idx, chan, 34);
+ rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, true, 32);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_STOP);
}
static void rtw8922a_rfk_band_changed(struct rtw89_dev *rtwdev,
- enum rtw89_phy_idx phy_idx)
+ enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan)
{
- rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, RTW89_TSSI_SCAN, 6);
+ rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_SCAN, 6);
}
-static void rtw8922a_rfk_scan(struct rtw89_dev *rtwdev, bool start)
+static void rtw8922a_rfk_scan(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ bool start)
{
}
@@ -1998,6 +2158,56 @@ static void rtw8922a_set_txpwr_ref(struct rtw89_dev *rtwdev,
B_BE_PWR_REF_CTRL_CCK, ref_cck);
}
+static const struct rtw89_reg_def rtw8922a_txpwr_ref[][3] = {
+ {{ .addr = R_TXAGC_REF_DBM_P0, .mask = B_TXAGC_OFDM_REF_DBM_P0},
+ { .addr = R_TXAGC_REF_DBM_P0, .mask = B_TXAGC_CCK_REF_DBM_P0},
+ { .addr = R_TSSI_K_P0, .mask = B_TSSI_K_OFDM_P0}
+ },
+ {{ .addr = R_TXAGC_REF_DBM_RF1_P0, .mask = B_TXAGC_OFDM_REF_DBM_RF1_P0},
+ { .addr = R_TXAGC_REF_DBM_RF1_P0, .mask = B_TXAGC_CCK_REF_DBM_RF1_P0},
+ { .addr = R_TSSI_K_RF1_P0, .mask = B_TSSI_K_OFDM_RF1_P0}
+ },
+};
+
+static void rtw8922a_set_txpwr_diff(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+{
+ s16 pwr_ofst = rtw89_phy_ant_gain_pwr_offset(rtwdev, chan);
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ static const u32 path_ofst[] = {0x0, 0x100};
+ const struct rtw89_reg_def *txpwr_ref;
+ static const s16 tssi_k_base = 0x12;
+ s16 tssi_k_ofst = abs(pwr_ofst) + tssi_k_base;
+ s16 ofst_dec[RF_PATH_NUM_8922A];
+ s16 tssi_k[RF_PATH_NUM_8922A];
+ s16 pwr_ref_ofst;
+ s16 pwr_ref = 0;
+ u8 i;
+
+ if (rtwdev->hal.cv == CHIP_CAV)
+ pwr_ref = 16;
+
+ pwr_ref <<= chip->txpwr_factor_rf;
+ pwr_ref_ofst = pwr_ref - rtw89_phy_txpwr_bb_to_rf(rtwdev, abs(pwr_ofst));
+
+ ofst_dec[RF_PATH_A] = pwr_ofst > 0 ? pwr_ref : pwr_ref_ofst;
+ ofst_dec[RF_PATH_B] = pwr_ofst > 0 ? pwr_ref_ofst : pwr_ref;
+ tssi_k[RF_PATH_A] = pwr_ofst > 0 ? tssi_k_base : tssi_k_ofst;
+ tssi_k[RF_PATH_B] = pwr_ofst > 0 ? tssi_k_ofst : tssi_k_base;
+
+ for (i = 0; i < RF_PATH_NUM_8922A; i++) {
+ txpwr_ref = rtw8922a_txpwr_ref[phy_idx];
+
+ rtw89_phy_write32_mask(rtwdev, txpwr_ref[0].addr + path_ofst[i],
+ txpwr_ref[0].mask, ofst_dec[i]);
+ rtw89_phy_write32_mask(rtwdev, txpwr_ref[1].addr + path_ofst[i],
+ txpwr_ref[1].mask, ofst_dec[i]);
+ rtw89_phy_write32_mask(rtwdev, txpwr_ref[2].addr + path_ofst[i],
+ txpwr_ref[2].mask, tssi_k[i]);
+ }
+}
+
static void rtw8922a_bb_tx_triangular(struct rtw89_dev *rtwdev, bool en,
enum rtw89_phy_idx phy_idx)
{
@@ -2025,6 +2235,31 @@ static void rtw8922a_set_tx_shape(struct rtw89_dev *rtwdev,
rtw8922a_bb_tx_triangular(rtwdev, true, phy_idx);
}
+static void rtw8922a_set_txpwr_sar_diff(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
+{
+ struct rtw89_sar_parm sar_parm = {
+ .center_freq = chan->freq,
+ .force_path = true,
+ };
+ s16 sar_rf;
+ s8 sar_mac;
+
+ if (phy_idx != RTW89_PHY_0)
+ return;
+
+ sar_parm.path = RF_PATH_A;
+ sar_mac = rtw89_query_sar(rtwdev, &sar_parm);
+ sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac);
+ rtw89_phy_write32_mask(rtwdev, R_P0_TXPWRB_BE, B_TXPWRB_MAX_BE, sar_rf);
+
+ sar_parm.path = RF_PATH_B;
+ sar_mac = rtw89_query_sar(rtwdev, &sar_parm);
+ sar_rf = rtw89_phy_txpwr_mac_to_rf(rtwdev, sar_mac);
+ rtw89_phy_write32_mask(rtwdev, R_P1_TXPWRB_BE, B_TXPWRB_MAX_BE, sar_rf);
+}
+
static void rtw8922a_set_txpwr(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
@@ -2034,6 +2269,9 @@ static void rtw8922a_set_txpwr(struct rtw89_dev *rtwdev,
rtw8922a_set_tx_shape(rtwdev, chan, phy_idx);
rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx);
rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
+ rtw8922a_set_txpwr_diff(rtwdev, chan, phy_idx);
+ rtw8922a_set_txpwr_ref(rtwdev, phy_idx);
+ rtw8922a_set_txpwr_sar_diff(rtwdev, chan, phy_idx);
}
static void rtw8922a_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
@@ -2105,7 +2343,7 @@ static void rtw8922a_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en,
static void rtw8922a_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
enum rtw89_band band = chan->band_type;
struct rtw89_hal *hal = &rtwdev->hal;
u8 ntx_path = RF_PATH_AB;
@@ -2126,16 +2364,18 @@ static void rtw8922a_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
rtw8922a_hal_reset(rtwdev, RTW89_PHY_0, RTW89_MAC_0, band, &tx_en0, false);
if (rtwdev->dbcc_en)
rtw8922a_hal_reset(rtwdev, RTW89_PHY_1, RTW89_MAC_1, band,
- &tx_en0, false);
+ &tx_en1, false);
}
static u8 rtw8922a_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
{
struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
+ struct rtw89_hal *hal = &rtwdev->hal;
int th;
- /* read thermal only if debugging */
- if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_CFO | RTW89_DBG_RFK_TRACK))
+ /* read thermal only if debugging or thermal protection enabled */
+ if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_CFO | RTW89_DBG_RFK_TRACK) &&
+ !hal->thermal_prot_th)
return 80;
rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
@@ -2257,6 +2497,138 @@ static void rtw8922a_btc_init_cfg(struct rtw89_dev *rtwdev)
btc->cx.wl.status.map.init_ok = true;
}
+static void
+rtw8922a_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val)
+{
+ u16 ctrl_all_time = u32_get_bits(txpwr_val, GENMASK(15, 0));
+ u16 ctrl_gnt_bt = u32_get_bits(txpwr_val, GENMASK(31, 16));
+
+ switch (ctrl_all_time) {
+ case 0xffff:
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL,
+ B_BE_FORCE_PWR_BY_RATE_EN, 0x0);
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL,
+ B_BE_FORCE_PWR_BY_RATE_VAL, 0x0);
+ break;
+ default:
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL,
+ B_BE_FORCE_PWR_BY_RATE_VAL, ctrl_all_time);
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL,
+ B_BE_FORCE_PWR_BY_RATE_EN, 0x1);
+ break;
+ }
+
+ switch (ctrl_gnt_bt) {
+ case 0xffff:
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_REG_CTRL,
+ B_BE_PWR_BT_EN, 0x0);
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_COEX_CTRL,
+ B_BE_PWR_BT_VAL, 0x0);
+ break;
+ default:
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_COEX_CTRL,
+ B_BE_PWR_BT_VAL, ctrl_gnt_bt);
+ rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_REG_CTRL,
+ B_BE_PWR_BT_EN, 0x1);
+ break;
+ }
+}
+
+static
+s8 rtw8922a_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val)
+{
+ return clamp_t(s8, val, -100, 0) + 100;
+}
+
+static const struct rtw89_btc_rf_trx_para rtw89_btc_8922a_rf_ul[] = {
+ {255, 0, 0, 7}, /* 0 -> original */
+ {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */
+ {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
+ {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
+ {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
+ {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */
+ {6, 1, 0, 7},
+ {13, 1, 0, 7},
+ {13, 1, 0, 7}
+};
+
+static const struct rtw89_btc_rf_trx_para rtw89_btc_8922a_rf_dl[] = {
+ {255, 0, 0, 7}, /* 0 -> original */
+ {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */
+ {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */
+ {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */
+ {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */
+ {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */
+ {255, 1, 0, 7},
+ {255, 1, 0, 7},
+ {255, 1, 0, 7}
+};
+
+static const u8 rtw89_btc_8922a_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {60, 50, 40, 30};
+static const u8 rtw89_btc_8922a_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20};
+
+static const struct rtw89_btc_fbtc_mreg rtw89_btc_8922a_mon_reg[] = {
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe300),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe320),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe324),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe328),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe32c),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe330),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe334),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe338),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe344),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe348),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe34c),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe350),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x11a2c),
+ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x11a50),
+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980),
+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x660),
+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x1660),
+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x418c),
+ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x518c),
+};
+
+static
+void rtw8922a_btc_update_bt_cnt(struct rtw89_dev *rtwdev)
+{
+ /* Feature move to firmware */
+}
+
+static
+void rtw8922a_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state)
+{
+ if (!state) {
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x0c110);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x01018);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x00000);
+
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x1);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c110);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x01018);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000);
+ } else {
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x0c110);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x09018);
+ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x00000);
+
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x1);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c110);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x09018);
+ rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000);
+ }
+}
+
+static void rtw8922a_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level)
+{
+}
+
static void rtw8922a_fill_freq_with_ppdu(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu,
struct ieee80211_rx_status *status)
@@ -2280,8 +2652,10 @@ static void rtw8922a_query_ppdu(struct rtw89_dev *rtwdev,
u8 path;
u8 *rx_power = phy_ppdu->rssi;
- status->signal =
- RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A], rx_power[RF_PATH_B]));
+ if (!status->signal)
+ status->signal = RTW89_RSSI_RAW_TO_DBM(max(rx_power[RF_PATH_A],
+ rx_power[RF_PATH_B]));
+
for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
status->chains |= BIT(path);
status->chain_signal[path] = RTW89_RSSI_RAW_TO_DBM(rx_power[path]);
@@ -2290,6 +2664,48 @@ static void rtw8922a_query_ppdu(struct rtw89_dev *rtwdev,
rtw8922a_fill_freq_with_ppdu(rtwdev, phy_ppdu, status);
}
+static void rtw8922a_convert_rpl_to_rssi(struct rtw89_dev *rtwdev,
+ struct rtw89_rx_phy_ppdu *phy_ppdu)
+{
+ /* Mapping to BW: 5, 10, 20, 40, 80, 160, 80_80 */
+ static const u8 bw_compensate[] = {0, 0, 0, 6, 12, 18, 0};
+ u8 *rssi = phy_ppdu->rssi;
+ u8 compensate = 0;
+ u16 rpl_tmp;
+ u8 i;
+
+ if (phy_ppdu->bw_idx < ARRAY_SIZE(bw_compensate))
+ compensate = bw_compensate[phy_ppdu->bw_idx];
+
+ for (i = 0; i < RF_PATH_NUM_8922A; i++) {
+ if (!(phy_ppdu->rx_path_en & BIT(i))) {
+ rssi[i] = 0;
+ phy_ppdu->rpl_path[i] = 0;
+ phy_ppdu->rpl_fd[i] = 0;
+ }
+ if (phy_ppdu->rate >= RTW89_HW_RATE_OFDM6) {
+ rpl_tmp = phy_ppdu->rpl_fd[i];
+ if (rpl_tmp)
+ rpl_tmp += compensate;
+
+ phy_ppdu->rpl_path[i] = rpl_tmp;
+ }
+ rssi[i] = phy_ppdu->rpl_path[i];
+ }
+
+ phy_ppdu->rssi_avg = phy_ppdu->rpl_avg;
+}
+
+static void rtw8922a_phy_rpt_to_rssi(struct rtw89_dev *rtwdev,
+ struct rtw89_rx_desc_info *desc_info,
+ struct ieee80211_rx_status *rx_status)
+{
+ if (desc_info->rssi <= 0x1 || (desc_info->rssi >> 2) > MAX_RSSI)
+ return;
+
+ rx_status->signal = (desc_info->rssi >> 2) - MAX_RSSI;
+}
+
static int rtw8922a_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
{
rtw89_write8_set(rtwdev, R_BE_FEN_RST_ENABLE,
@@ -2309,10 +2725,12 @@ static int rtw8922a_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
#ifdef CONFIG_PM
static const struct wiphy_wowlan_support rtw_wowlan_stub_8922a = {
- .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
+ .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
+ WIPHY_WOWLAN_NET_DETECT,
.n_patterns = RTW89_MAX_PATTERN_NUM,
.pattern_max_len = RTW89_MAX_PATTERN_SIZE,
.pattern_min_len = 1,
+ .max_nd_match_sets = RTW89_SCANOFLD_MAX_SSID,
};
#endif
@@ -2345,9 +2763,12 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = {
.get_thermal = rtw8922a_get_thermal,
.ctrl_btg_bt_rx = rtw8922a_ctrl_btg_bt_rx,
.query_ppdu = rtw8922a_query_ppdu,
+ .convert_rpl_to_rssi = rtw8922a_convert_rpl_to_rssi,
+ .phy_rpt_to_rssi = rtw8922a_phy_rpt_to_rssi,
.ctrl_nbtg_bt_tx = rtw8922a_ctrl_nbtg_bt_tx,
.cfg_txrx_path = rtw8922a_bb_cfg_txrx_path,
.set_txpwr_ul_tb_offset = NULL,
+ .digital_pwr_comp = rtw8922a_digital_pwr_comp,
.pwr_on_func = rtw8922a_pwr_on_func,
.pwr_off_func = rtw8922a_pwr_off_func,
.query_rxdesc = rtw89_core_query_rxdesc_v2,
@@ -2361,12 +2782,20 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = {
.h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl_g7,
.h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl_g7,
.h2c_ampdu_cmac_tbl = rtw89_fw_h2c_ampdu_cmac_tbl_g7,
+ .h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl_g7,
.h2c_default_dmac_tbl = rtw89_fw_h2c_default_dmac_tbl_v2,
.h2c_update_beacon = rtw89_fw_h2c_update_beacon_be,
.h2c_ba_cam = rtw89_fw_h2c_ba_cam_v1,
.btc_set_rfe = rtw8922a_btc_set_rfe,
.btc_init_cfg = rtw8922a_btc_init_cfg,
+ .btc_set_wl_pri = NULL,
+ .btc_set_wl_txpwr_ctrl = rtw8922a_btc_set_wl_txpwr_ctrl,
+ .btc_get_bt_rssi = rtw8922a_btc_get_bt_rssi,
+ .btc_update_bt_cnt = rtw8922a_btc_update_bt_cnt,
+ .btc_wl_s1_standby = rtw8922a_btc_wl_s1_standby,
+ .btc_set_wl_rx_gain = rtw8922a_btc_set_wl_rx_gain,
+ .btc_set_policy = rtw89_btc_set_policy_v1,
};
const struct rtw89_chip_info rtw8922a_chip_info = {
@@ -2380,6 +2809,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.try_ce_fw = false,
.bbmcu_nr = 1,
.needed_fw_elms = RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS,
+ .fw_blacklist = &rtw89_fw_blacklist_default,
.fifo_size = 589824,
.small_fifo_size = false,
.dle_scc_rsvd_size = 0,
@@ -2391,6 +2821,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.wde_qempty_acq_grpnum = 4,
.wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000, 0xf000},
+ .thermal_th = {0xad, 0xb4},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
.bb_table = NULL,
@@ -2400,12 +2831,16 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.nctl_post_table = NULL,
.dflt_parms = NULL, /* load parm from fw */
.rfe_parms_conf = NULL, /* load parm from fw */
+ .txpwr_factor_bb = 3,
.txpwr_factor_rf = 2,
.txpwr_factor_mac = 1,
.dig_table = NULL,
.dig_regs = &rtw8922a_dig_regs,
.tssi_dbw_table = NULL,
+ .support_macid_num = 32,
+ .support_link_num = 2,
.support_chanctx_num = 2,
+ .support_rnr = true,
.support_bands = BIT(NL80211_BAND_2GHZ) |
BIT(NL80211_BAND_5GHZ) |
BIT(NL80211_BAND_6GHZ),
@@ -2414,9 +2849,16 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
BIT(NL80211_CHAN_WIDTH_80) |
BIT(NL80211_CHAN_WIDTH_160),
.support_unii4 = true,
+ .support_ant_gain = true,
+ .support_tas = false,
+ .support_sar_by_ant = true,
.ul_tb_waveform_ctrl = false,
.ul_tb_pwr_diff = false,
+ .rx_freq_frome_ie = false,
.hw_sec_hdr = true,
+ .hw_mgmt_tx_encrypt = true,
+ .hw_tkip_crypto = true,
+ .hw_mlo_bmc_crypto = false,
.rf_path_num = 2,
.tx_nss = 2,
.rx_nss = 2,
@@ -2436,7 +2878,22 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.efuse_blocks = rtw8922a_efuse_blocks,
.phycap_addr = 0x1700,
.phycap_size = 0x38,
-
+ .para_ver = 0xf,
+ .wlcx_desired = 0x07110000,
+ .btcx_desired = 0x7,
+ .scbd = 0x1,
+ .mailbox = 0x1,
+
+ .afh_guard_ch = 6,
+ .wl_rssi_thres = rtw89_btc_8922a_wl_rssi_thres,
+ .bt_rssi_thres = rtw89_btc_8922a_bt_rssi_thres,
+ .rssi_tol = 2,
+ .mon_reg_num = ARRAY_SIZE(rtw89_btc_8922a_mon_reg),
+ .mon_reg = rtw89_btc_8922a_mon_reg,
+ .rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8922a_rf_ul),
+ .rf_para_ulink = rtw89_btc_8922a_rf_ul,
+ .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8922a_rf_dl),
+ .rf_para_dlink = rtw89_btc_8922a_rf_dl,
.ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) |
BIT(RTW89_PS_MODE_CLK_GATED) |
BIT(RTW89_PS_MODE_PWR_GATED),
@@ -2453,7 +2910,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.c2h_counter_reg = {R_BE_UDM1 + 1, B_BE_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8},
.c2h_regs = rtw8922a_c2h_regs,
.page_regs = &rtw8922a_page_regs,
- .wow_reason_reg = R_AX_C2HREG_DATA3_V1 + 3,
+ .wow_reason_reg = rtw8922a_wow_wakeup_regs,
.cfo_src_fd = true,
.cfo_hw_comp = true,
.dcfo_comp = NULL,
@@ -2464,6 +2921,8 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.rrsr_cfgs = &rtw8922a_rrsr_cfgs,
.bss_clr_vld = {R_BSS_CLR_VLD_V2, B_BSS_CLR_VLD0_V2},
.bss_clr_map_reg = R_BSS_CLR_MAP_V2,
+ .rfkill_init = &rtw8922a_rfkill_regs,
+ .rfkill_get = {R_BE_GPIO_EXT_CTRL, B_BE_GPIO_IN_9},
.dma_ch_mask = 0,
.edcca_regs = &rtw8922a_edcca_regs,
#ifdef CONFIG_PM
@@ -2473,6 +2932,12 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
};
EXPORT_SYMBOL(rtw8922a_chip_info);
+const struct rtw89_chip_variant rtw8922ae_vs_variant = {
+ .no_mcs_12_13 = true,
+ .fw_min_ver_code = RTW89_FW_VER_CODE(0, 35, 54, 0),
+};
+EXPORT_SYMBOL(rtw8922ae_vs_variant);
+
MODULE_FIRMWARE(RTW8922A_MODULE_FIRMWARE);
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11be wireless 8922A driver");
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.h b/drivers/net/wireless/realtek/rtw89/rtw8922a.h
index 597317ab6af7..a29cfa5b4291 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a.h
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.h
@@ -69,5 +69,6 @@ struct rtw8922a_efuse {
} __packed;
extern const struct rtw89_chip_info rtw8922a_chip_info;
+extern const struct rtw89_chip_variant rtw8922ae_vs_variant;
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c
index 2a371829268c..1659ea64ade1 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c
@@ -77,11 +77,6 @@ void rtw8922a_ctl_band_ch_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
RR_CFGCH_BAND0 | RR_CFGCH_CH);
rf_reg[path][i] |= u32_encode_bits(central_ch, RR_CFGCH_CH);
- if (band == RTW89_BAND_2G)
- rtw89_write_rf(rtwdev, path, RR_SMD, RR_VCO2, 0x0);
- else
- rtw89_write_rf(rtwdev, path, RR_SMD, RR_VCO2, 0x1);
-
switch (band) {
case RTW89_BAND_2G:
default:
@@ -252,36 +247,58 @@ static void rtw8922a_chlk_ktbl_sel(struct rtw89_dev *rtwdev, u8 kpath, u8 idx)
}
}
-static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev)
+static u8 rtw8922a_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan, u8 path)
{
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
- enum rtw89_sub_entity_idx sub_entity_idx;
- const struct rtw89_chan *chan;
- enum rtw89_entity_mode mode;
- u8 s0_tbl, s1_tbl;
+ struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {};
u8 tbl_sel;
- mode = rtw89_get_entity_mode(rtwdev);
- switch (mode) {
- case RTW89_ENTITY_MODE_MCC_PREPARE:
- sub_entity_idx = RTW89_SUB_ENTITY_1;
- tbl_sel = 1;
- break;
- default:
- sub_entity_idx = RTW89_SUB_ENTITY_0;
- tbl_sel = 0;
- break;
+ for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) {
+ struct rtw89_rfk_chan_desc *p = &desc[tbl_sel];
+
+ p->ch = rfk_mcc->data[path].ch[tbl_sel];
+
+ p->has_band = true;
+ p->band = rfk_mcc->data[path].band[tbl_sel];
+
+ p->has_bw = true;
+ p->bw = rfk_mcc->data[path].bw[tbl_sel];
}
- chan = rtw89_chan_get(rtwdev, sub_entity_idx);
+ tbl_sel = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan);
+
+ rfk_mcc->data[path].ch[tbl_sel] = chan->channel;
+ rfk_mcc->data[path].band[tbl_sel] = chan->band_type;
+ rfk_mcc->data[path].bw[tbl_sel] = chan->band_width;
+ rfk_mcc->data[path].table_idx = tbl_sel;
- rfk_mcc->ch[tbl_sel] = chan->channel;
- rfk_mcc->band[tbl_sel] = chan->band_type;
- rfk_mcc->bw[tbl_sel] = chan->band_width;
- rfk_mcc->table_idx = tbl_sel;
+ return tbl_sel;
+}
+
+static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_chan *chan0, *chan1;
+ u8 s0_tbl, s1_tbl;
+
+ switch (rtwdev->mlo_dbcc_mode) {
+ default:
+ case MLO_2_PLUS_0_1RF:
+ chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
+ chan1 = chan0;
+ break;
+ case MLO_0_PLUS_2_1RF:
+ chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
+ chan0 = chan1;
+ break;
+ case MLO_1_PLUS_1_1RF:
+ chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
+ chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
+ break;
+ }
- s0_tbl = tbl_sel;
- s1_tbl = tbl_sel;
+ s0_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, chan0, 0);
+ s1_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, chan1, 1);
rtw8922a_chlk_ktbl_sel(rtwdev, RF_A, s0_tbl);
rtw8922a_chlk_ktbl_sel(rtwdev, RF_B, s1_tbl);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922ae.c b/drivers/net/wireless/realtek/rtw89/rtw8922ae.c
index 4981b657bd7b..0ea8d5281c10 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922ae.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922ae.c
@@ -9,6 +9,12 @@
#include "reg.h"
#include "rtw8922a.h"
+static const struct rtw89_pci_ssid_quirk rtw8922a_pci_ssid_quirks[] = {
+ {RTW89_PCI_SSID(PCI_VENDOR_ID_REALTEK, 0x8922, 0x10EC, 0xA891, DELL),
+ .bitmap = BIT(RTW89_QUIRK_THERMAL_PROT_120C)},
+ {},
+};
+
static const struct rtw89_pci_info rtw8922a_pci_info = {
.gen_def = &rtw89_pci_gen_be,
.txbd_trunc_mode = MAC_AX_BD_TRUNC,
@@ -27,6 +33,7 @@ static const struct rtw89_pci_info rtw8922a_pci_info = {
.io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_DEF,
.rx_ring_eq_is_full = true,
.check_rx_tag = true,
+ .no_rxbd_fs = true,
.init_cfg_reg = R_BE_HAXI_INIT_CFG1,
.txhci_en_bit = B_BE_TXDMA_EN,
@@ -46,6 +53,7 @@ static const struct rtw89_pci_info rtw8922a_pci_info = {
.rpwm_addr = R_BE_PCIE_HRPWM,
.cpwm_addr = R_BE_PCIE_CRPWM,
.mit_addr = R_BE_PCIE_MIT_CH_EN,
+ .wp_sel_addr = R_BE_WP_ADDR_H_SEL0_3_V1,
.tx_dma_ch_mask = 0,
.bd_idx_addr_low_power = NULL,
.dma_addr_set = &rtw89_pci_ch_dma_addr_set_be,
@@ -57,10 +65,23 @@ static const struct rtw89_pci_info rtw8922a_pci_info = {
.enable_intr = rtw89_pci_enable_intr_v2,
.disable_intr = rtw89_pci_disable_intr_v2,
.recognize_intrs = rtw89_pci_recognize_intrs_v2,
+
+ .ssid_quirks = rtw8922a_pci_ssid_quirks,
};
static const struct rtw89_driver_info rtw89_8922ae_info = {
.chip = &rtw8922a_chip_info,
+ .variant = NULL,
+ .quirks = NULL,
+ .bus = {
+ .pci = &rtw8922a_pci_info,
+ },
+};
+
+static const struct rtw89_driver_info rtw89_8922ae_vs_info = {
+ .chip = &rtw8922a_chip_info,
+ .variant = &rtw8922ae_vs_variant,
+ .quirks = NULL,
.bus = {
.pci = &rtw8922a_pci_info,
},
@@ -71,6 +92,10 @@ static const struct pci_device_id rtw89_8922ae_id_table[] = {
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8922),
.driver_data = (kernel_ulong_t)&rtw89_8922ae_info,
},
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x892B),
+ .driver_data = (kernel_ulong_t)&rtw89_8922ae_vs_info,
+ },
{},
};
MODULE_DEVICE_TABLE(pci, rtw89_8922ae_id_table);
@@ -85,5 +110,5 @@ static struct pci_driver rtw89_8922ae_driver = {
module_pci_driver(rtw89_8922ae_driver);
MODULE_AUTHOR("Realtek Corporation");
-MODULE_DESCRIPTION("Realtek 802.11be wireless 8922AE driver");
+MODULE_DESCRIPTION("Realtek 802.11be wireless 8922AE/8922AE-VS driver");
MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw89/sar.c b/drivers/net/wireless/realtek/rtw89/sar.c
index 1b2a400406ae..517b66022f18 100644
--- a/drivers/net/wireless/realtek/rtw89/sar.c
+++ b/drivers/net/wireless/realtek/rtw89/sar.c
@@ -7,10 +7,16 @@
#include "phy.h"
#include "reg.h"
#include "sar.h"
+#include "util.h"
#define RTW89_TAS_FACTOR 2 /* unit: 0.25 dBm */
+#define RTW89_TAS_SAR_GAP (1 << RTW89_TAS_FACTOR)
#define RTW89_TAS_DPR_GAP (1 << RTW89_TAS_FACTOR)
#define RTW89_TAS_DELTA (2 << RTW89_TAS_FACTOR)
+#define RTW89_TAS_TX_RATIO_THRESHOLD 70
+#define RTW89_TAS_DFLT_TX_RATIO 80
+#define RTW89_TAS_DPR_ON_OFFSET (RTW89_TAS_DELTA + RTW89_TAS_SAR_GAP)
+#define RTW89_TAS_DPR_OFF_OFFSET (4 << RTW89_TAS_FACTOR)
static enum rtw89_sar_subband rtw89_sar_get_subband(struct rtw89_dev *rtwdev,
u32 center_freq)
@@ -27,8 +33,8 @@ static enum rtw89_sar_subband rtw89_sar_get_subband(struct rtw89_dev *rtwdev,
return RTW89_SAR_5GHZ_SUBBAND_1_2;
case 5500 ... 5720:
return RTW89_SAR_5GHZ_SUBBAND_2_E;
- case 5745 ... 5825:
- return RTW89_SAR_5GHZ_SUBBAND_3;
+ case 5745 ... 5885:
+ return RTW89_SAR_5GHZ_SUBBAND_3_4;
case 5955 ... 6155:
return RTW89_SAR_6GHZ_SUBBAND_5_L;
case 6175 ... 6415:
@@ -42,7 +48,7 @@ static enum rtw89_sar_subband rtw89_sar_get_subband(struct rtw89_dev *rtwdev,
/* freq 6875 (ch 185, 20MHz) spans RTW89_SAR_6GHZ_SUBBAND_7_H
* and RTW89_SAR_6GHZ_SUBBAND_8, so directly describe it with
- * struct rtw89_sar_span in the following.
+ * struct rtw89_6ghz_span.
*/
case 6895 ... 7115:
@@ -50,63 +56,20 @@ static enum rtw89_sar_subband rtw89_sar_get_subband(struct rtw89_dev *rtwdev,
}
}
-struct rtw89_sar_span {
- enum rtw89_sar_subband subband_low;
- enum rtw89_sar_subband subband_high;
-};
-
-#define RTW89_SAR_SPAN_VALID(span) ((span)->subband_high)
-
-#define RTW89_SAR_6GHZ_SPAN_HEAD 6145
-#define RTW89_SAR_6GHZ_SPAN_IDX(center_freq) \
- ((((int)(center_freq) - RTW89_SAR_6GHZ_SPAN_HEAD) / 5) / 2)
-
-#define RTW89_DECL_SAR_6GHZ_SPAN(center_freq, subband_l, subband_h) \
- [RTW89_SAR_6GHZ_SPAN_IDX(center_freq)] = { \
- .subband_low = RTW89_SAR_6GHZ_ ## subband_l, \
- .subband_high = RTW89_SAR_6GHZ_ ## subband_h, \
- }
-
-/* Since 6GHz SAR subbands are not edge aligned, some cases span two SAR
- * subbands. In the following, we describe each of them with rtw89_sar_span.
- */
-static const struct rtw89_sar_span rtw89_sar_overlapping_6ghz[] = {
- RTW89_DECL_SAR_6GHZ_SPAN(6145, SUBBAND_5_L, SUBBAND_5_H),
- RTW89_DECL_SAR_6GHZ_SPAN(6165, SUBBAND_5_L, SUBBAND_5_H),
- RTW89_DECL_SAR_6GHZ_SPAN(6185, SUBBAND_5_L, SUBBAND_5_H),
- RTW89_DECL_SAR_6GHZ_SPAN(6505, SUBBAND_6, SUBBAND_7_L),
- RTW89_DECL_SAR_6GHZ_SPAN(6525, SUBBAND_6, SUBBAND_7_L),
- RTW89_DECL_SAR_6GHZ_SPAN(6545, SUBBAND_6, SUBBAND_7_L),
- RTW89_DECL_SAR_6GHZ_SPAN(6665, SUBBAND_7_L, SUBBAND_7_H),
- RTW89_DECL_SAR_6GHZ_SPAN(6705, SUBBAND_7_L, SUBBAND_7_H),
- RTW89_DECL_SAR_6GHZ_SPAN(6825, SUBBAND_7_H, SUBBAND_8),
- RTW89_DECL_SAR_6GHZ_SPAN(6865, SUBBAND_7_H, SUBBAND_8),
- RTW89_DECL_SAR_6GHZ_SPAN(6875, SUBBAND_7_H, SUBBAND_8),
- RTW89_DECL_SAR_6GHZ_SPAN(6885, SUBBAND_7_H, SUBBAND_8),
-};
-
static int rtw89_query_sar_config_common(struct rtw89_dev *rtwdev,
- u32 center_freq, s32 *cfg)
+ const struct rtw89_sar_parm *sar_parm,
+ s32 *cfg)
{
struct rtw89_sar_cfg_common *rtwsar = &rtwdev->sar.cfg_common;
- const struct rtw89_sar_span *span = NULL;
enum rtw89_sar_subband subband_l, subband_h;
- int idx;
-
- if (center_freq >= RTW89_SAR_6GHZ_SPAN_HEAD) {
- idx = RTW89_SAR_6GHZ_SPAN_IDX(center_freq);
- /* To decrease size of rtw89_sar_overlapping_6ghz[],
- * RTW89_SAR_6GHZ_SPAN_IDX() truncates the leading NULLs
- * to make first span as index 0 of the table. So, if center
- * frequency is less than the first one, it will get netative.
- */
- if (idx >= 0 && idx < ARRAY_SIZE(rtw89_sar_overlapping_6ghz))
- span = &rtw89_sar_overlapping_6ghz[idx];
- }
+ u32 center_freq = sar_parm->center_freq;
+ const struct rtw89_6ghz_span *span;
+
+ span = rtw89_get_6ghz_span(rtwdev, center_freq);
if (span && RTW89_SAR_SPAN_VALID(span)) {
- subband_l = span->subband_low;
- subband_h = span->subband_high;
+ subband_l = span->sar_subband_low;
+ subband_h = span->sar_subband_high;
} else {
subband_l = rtw89_sar_get_subband(rtwdev, center_freq);
subband_h = subband_l;
@@ -129,6 +92,93 @@ static int rtw89_query_sar_config_common(struct rtw89_dev *rtwdev,
return 0;
}
+static const struct rtw89_sar_entry_from_acpi *
+rtw89_sar_cfg_acpi_get_ent(const struct rtw89_sar_cfg_acpi *rtwsar,
+ enum rtw89_rf_path path,
+ enum rtw89_regulation_type regd)
+{
+ const struct rtw89_sar_indicator_from_acpi *ind = &rtwsar->indicator;
+ const struct rtw89_sar_table_from_acpi *tbl;
+ u8 sel;
+
+ sel = ind->tblsel[path];
+ tbl = &rtwsar->tables[sel];
+
+ return &tbl->entries[regd];
+}
+
+static
+s32 rtw89_sar_cfg_acpi_get_min(const struct rtw89_sar_entry_from_acpi *ent,
+ enum rtw89_rf_path path,
+ enum rtw89_acpi_sar_subband subband_low,
+ enum rtw89_acpi_sar_subband subband_high)
+{
+ return min(ent->v[subband_low][path], ent->v[subband_high][path]);
+}
+
+static int rtw89_query_sar_config_acpi(struct rtw89_dev *rtwdev,
+ const struct rtw89_sar_parm *sar_parm,
+ s32 *cfg)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ const struct rtw89_sar_cfg_acpi *rtwsar = &rtwdev->sar.cfg_acpi;
+ const struct rtw89_sar_entry_from_acpi *ent_a, *ent_b;
+ enum rtw89_acpi_sar_subband subband_l, subband_h;
+ u32 center_freq = sar_parm->center_freq;
+ const struct rtw89_6ghz_span *span;
+ enum rtw89_regulation_type regd;
+ enum rtw89_band band;
+ s32 cfg_a, cfg_b;
+
+ span = rtw89_get_6ghz_span(rtwdev, center_freq);
+
+ if (span && RTW89_ACPI_SAR_SPAN_VALID(span)) {
+ subband_l = span->acpi_sar_subband_low;
+ subband_h = span->acpi_sar_subband_high;
+ } else {
+ subband_l = rtw89_acpi_sar_get_subband(rtwdev, center_freq);
+ subband_h = subband_l;
+ }
+
+ band = rtw89_acpi_sar_subband_to_band(rtwdev, subband_l);
+ regd = rtw89_regd_get(rtwdev, band);
+
+ ent_a = rtw89_sar_cfg_acpi_get_ent(rtwsar, RF_PATH_A, regd);
+ ent_b = rtw89_sar_cfg_acpi_get_ent(rtwsar, RF_PATH_B, regd);
+
+ cfg_a = rtw89_sar_cfg_acpi_get_min(ent_a, RF_PATH_A, subband_l, subband_h);
+ cfg_b = rtw89_sar_cfg_acpi_get_min(ent_b, RF_PATH_B, subband_l, subband_h);
+
+ if (chip->support_sar_by_ant) {
+ /* With declaration of support_sar_by_ant, relax the general
+ * SAR querying to return the maximum between paths. However,
+ * expect chip has dealt with the corresponding SAR settings
+ * by path. (To get SAR for a given path, chip can then query
+ * with force_path.)
+ */
+ if (sar_parm->force_path) {
+ switch (sar_parm->path) {
+ default:
+ case RF_PATH_A:
+ *cfg = cfg_a;
+ break;
+ case RF_PATH_B:
+ *cfg = cfg_b;
+ break;
+ }
+ } else {
+ *cfg = max(cfg_a, cfg_b);
+ }
+ } else {
+ *cfg = min(cfg_a, cfg_b);
+ }
+
+ if (sar_parm->ntx == RTW89_2TX)
+ *cfg -= rtwsar->downgrade_2tx;
+
+ return 0;
+}
+
static const
struct rtw89_sar_handler rtw89_sar_handlers[RTW89_SAR_SOURCE_NR] = {
[RTW89_SAR_SOURCE_COMMON] = {
@@ -136,6 +186,11 @@ struct rtw89_sar_handler rtw89_sar_handlers[RTW89_SAR_SOURCE_NR] = {
.txpwr_factor_sar = 2,
.query_sar_config = rtw89_query_sar_config_common,
},
+ [RTW89_SAR_SOURCE_ACPI] = {
+ .descr_sar_source = "RTW89_SAR_SOURCE_ACPI",
+ .txpwr_factor_sar = TXPWR_FACTOR_OF_RTW89_ACPI_SAR,
+ .query_sar_config = rtw89_query_sar_config_acpi,
+ },
};
#define rtw89_sar_set_src(_dev, _src, _cfg_name, _cfg_data) \
@@ -144,7 +199,7 @@ struct rtw89_sar_handler rtw89_sar_handlers[RTW89_SAR_SOURCE_NR] = {
typeof(_dev) _d = (_dev); \
BUILD_BUG_ON(!rtw89_sar_handlers[_s].descr_sar_source); \
BUILD_BUG_ON(!rtw89_sar_handlers[_s].query_sar_config); \
- lockdep_assert_held(&_d->mutex); \
+ lockdep_assert_wiphy(_d->hw->wiphy); \
_d->sar._cfg_name = *(_cfg_data); \
_d->sar.src = _s; \
} while (0)
@@ -162,8 +217,8 @@ static s8 rtw89_txpwr_sar_to_mac(struct rtw89_dev *rtwdev, u8 fct, s32 cfg)
RTW89_SAR_TXPWR_MAC_MAX);
}
-static s8 rtw89_txpwr_tas_to_sar(const struct rtw89_sar_handler *sar_hdl,
- s8 cfg)
+static s32 rtw89_txpwr_tas_to_sar(const struct rtw89_sar_handler *sar_hdl,
+ s32 cfg)
{
const u8 fct = sar_hdl->txpwr_factor_sar;
@@ -173,8 +228,8 @@ static s8 rtw89_txpwr_tas_to_sar(const struct rtw89_sar_handler *sar_hdl,
return cfg >> (RTW89_TAS_FACTOR - fct);
}
-static s8 rtw89_txpwr_sar_to_tas(const struct rtw89_sar_handler *sar_hdl,
- s8 cfg)
+static s32 rtw89_txpwr_sar_to_tas(const struct rtw89_sar_handler *sar_hdl,
+ s32 cfg)
{
const u8 fct = sar_hdl->txpwr_factor_sar;
@@ -184,35 +239,67 @@ static s8 rtw89_txpwr_sar_to_tas(const struct rtw89_sar_handler *sar_hdl,
return cfg << (RTW89_TAS_FACTOR - fct);
}
-s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq)
+static bool rtw89_tas_is_active(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+ struct rtw89_vif *rtwvif;
+
+ if (!tas->enable)
+ return false;
+
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+ if (ieee80211_vif_is_mld(rtwvif_to_vif(rtwvif)))
+ return false;
+ }
+
+ return true;
+}
+
+static const char *rtw89_tas_state_str(enum rtw89_tas_state state)
+{
+ switch (state) {
+ case RTW89_TAS_STATE_DPR_OFF:
+ return "DPR OFF";
+ case RTW89_TAS_STATE_DPR_ON:
+ return "DPR ON";
+ case RTW89_TAS_STATE_STATIC_SAR:
+ return "STATIC SAR";
+ default:
+ return NULL;
+ }
+}
+
+s8 rtw89_query_sar(struct rtw89_dev *rtwdev, const struct rtw89_sar_parm *sar_parm)
{
const enum rtw89_sar_sources src = rtwdev->sar.src;
/* its members are protected by rtw89_sar_set_src() */
const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src];
struct rtw89_tas_info *tas = &rtwdev->tas;
- s8 delta;
+ s32 offset;
int ret;
s32 cfg;
u8 fct;
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (src == RTW89_SAR_SOURCE_NONE)
return RTW89_SAR_TXPWR_MAC_MAX;
- ret = sar_hdl->query_sar_config(rtwdev, center_freq, &cfg);
+ ret = sar_hdl->query_sar_config(rtwdev, sar_parm, &cfg);
if (ret)
return RTW89_SAR_TXPWR_MAC_MAX;
- if (tas->enable) {
+ if (rtw89_tas_is_active(rtwdev)) {
switch (tas->state) {
case RTW89_TAS_STATE_DPR_OFF:
- return RTW89_SAR_TXPWR_MAC_MAX;
+ offset = rtw89_txpwr_tas_to_sar(sar_hdl, RTW89_TAS_DPR_OFF_OFFSET);
+ cfg += offset;
+ break;
case RTW89_TAS_STATE_DPR_ON:
- delta = rtw89_txpwr_tas_to_sar(sar_hdl, tas->delta);
- cfg -= delta;
+ offset = rtw89_txpwr_tas_to_sar(sar_hdl, RTW89_TAS_DPR_ON_OFFSET);
+ cfg -= offset;
break;
- case RTW89_TAS_STATE_DPR_FORBID:
+ case RTW89_TAS_STATE_STATIC_SAR:
default:
break;
}
@@ -222,80 +309,93 @@ s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq)
return rtw89_txpwr_sar_to_mac(rtwdev, fct, cfg);
}
+EXPORT_SYMBOL(rtw89_query_sar);
-void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev, u32 center_freq)
+int rtw89_print_sar(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
+ const struct rtw89_sar_parm *sar_parm)
{
const enum rtw89_sar_sources src = rtwdev->sar.src;
/* its members are protected by rtw89_sar_set_src() */
const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src];
const u8 fct_mac = rtwdev->chip->txpwr_factor_mac;
+ char *p = buf, *end = buf + bufsz;
int ret;
s32 cfg;
u8 fct;
- lockdep_assert_held(&rtwdev->mutex);
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (src == RTW89_SAR_SOURCE_NONE) {
- seq_puts(m, "no SAR is applied\n");
- return;
+ p += scnprintf(p, end - p, "no SAR is applied\n");
+ goto out;
}
- seq_printf(m, "source: %d (%s)\n", src, sar_hdl->descr_sar_source);
+ p += scnprintf(p, end - p, "source: %d (%s)\n", src,
+ sar_hdl->descr_sar_source);
- ret = sar_hdl->query_sar_config(rtwdev, center_freq, &cfg);
+ ret = sar_hdl->query_sar_config(rtwdev, sar_parm, &cfg);
if (ret) {
- seq_printf(m, "config: return code: %d\n", ret);
- seq_printf(m, "assign: max setting: %d (unit: 1/%lu dBm)\n",
- RTW89_SAR_TXPWR_MAC_MAX, BIT(fct_mac));
- return;
+ p += scnprintf(p, end - p, "config: return code: %d\n", ret);
+ p += scnprintf(p, end - p,
+ "assign: max setting: %d (unit: 1/%lu dBm)\n",
+ RTW89_SAR_TXPWR_MAC_MAX, BIT(fct_mac));
+ goto out;
}
fct = sar_hdl->txpwr_factor_sar;
- seq_printf(m, "config: %d (unit: 1/%lu dBm)\n", cfg, BIT(fct));
+ p += scnprintf(p, end - p, "config: %d (unit: 1/%lu dBm)\n", cfg,
+ BIT(fct));
+
+ p += scnprintf(p, end - p, "support different configs by antenna: %s\n",
+ str_yes_no(rtwdev->chip->support_sar_by_ant));
+out:
+ return p - buf;
}
-void rtw89_print_tas(struct seq_file *m, struct rtw89_dev *rtwdev)
+int rtw89_print_tas(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_tas_info *tas = &rtwdev->tas;
+ char *p = buf, *end = buf + bufsz;
- if (!tas->enable) {
- seq_puts(m, "no TAS is applied\n");
- return;
+ if (!rtw89_tas_is_active(rtwdev)) {
+ p += scnprintf(p, end - p, "no TAS is applied\n");
+ goto out;
}
- seq_printf(m, "DPR gap: %d\n", tas->dpr_gap);
- seq_printf(m, "TAS delta: %d\n", tas->delta);
+ p += scnprintf(p, end - p, "State: %s\n",
+ rtw89_tas_state_str(tas->state));
+ p += scnprintf(p, end - p, "Average time: %d\n",
+ tas->window_size * 2);
+ p += scnprintf(p, end - p, "SAR gap: %d dBm\n",
+ RTW89_TAS_SAR_GAP >> RTW89_TAS_FACTOR);
+ p += scnprintf(p, end - p, "DPR gap: %d dBm\n",
+ RTW89_TAS_DPR_GAP >> RTW89_TAS_FACTOR);
+ p += scnprintf(p, end - p, "DPR ON offset: %d dBm\n",
+ RTW89_TAS_DPR_ON_OFFSET >> RTW89_TAS_FACTOR);
+ p += scnprintf(p, end - p, "DPR OFF offset: %d dBm\n",
+ RTW89_TAS_DPR_OFF_OFFSET >> RTW89_TAS_FACTOR);
+
+out:
+ return p - buf;
}
static int rtw89_apply_sar_common(struct rtw89_dev *rtwdev,
const struct rtw89_sar_cfg_common *sar)
{
- enum rtw89_sar_sources src;
- int ret = 0;
-
- mutex_lock(&rtwdev->mutex);
-
- src = rtwdev->sar.src;
- if (src != RTW89_SAR_SOURCE_NONE && src != RTW89_SAR_SOURCE_COMMON) {
- rtw89_warn(rtwdev, "SAR source: %d is in use", src);
- ret = -EBUSY;
- goto exit;
- }
-
+ /* let common SAR have the highest priority; always apply it */
rtw89_sar_set_src(rtwdev, RTW89_SAR_SOURCE_COMMON, cfg_common, sar);
rtw89_core_set_chip_txpwr(rtwdev);
+ rtw89_tas_reset(rtwdev, false);
-exit:
- mutex_unlock(&rtwdev->mutex);
- return ret;
+ return 0;
}
static const struct cfg80211_sar_freq_ranges rtw89_common_sar_freq_ranges[] = {
{ .start_freq = 2412, .end_freq = 2484, },
{ .start_freq = 5180, .end_freq = 5320, },
{ .start_freq = 5500, .end_freq = 5720, },
- { .start_freq = 5745, .end_freq = 5825, },
+ { .start_freq = 5745, .end_freq = 5885, },
{ .start_freq = 5955, .end_freq = 6155, },
{ .start_freq = 6175, .end_freq = 6415, },
{ .start_freq = 6435, .end_freq = 6515, },
@@ -324,6 +424,8 @@ int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw,
s32 power;
u32 i, idx;
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
if (sar->type != NL80211_SAR_TYPE_POWER)
return -EINVAL;
@@ -349,64 +451,256 @@ int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw,
return rtw89_apply_sar_common(rtwdev, &sar_common);
}
-static void rtw89_tas_state_update(struct rtw89_dev *rtwdev)
+static void rtw89_apply_sar_acpi(struct rtw89_dev *rtwdev,
+ const struct rtw89_sar_cfg_acpi *sar)
+{
+ const struct rtw89_sar_table_from_acpi *tbl;
+ const struct rtw89_sar_entry_from_acpi *ent;
+ enum rtw89_sar_sources src;
+ unsigned int i, j, k;
+
+ src = rtwdev->sar.src;
+ if (src != RTW89_SAR_SOURCE_NONE) {
+ rtw89_warn(rtwdev, "SAR source: %d is in use", src);
+ return;
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_SAR,
+ "SAR-ACPI downgrade 2TX: %u (unit: 1/%lu dBm)\n",
+ sar->downgrade_2tx, BIT(TXPWR_FACTOR_OF_RTW89_ACPI_SAR));
+
+ for (i = 0; i < sar->valid_num; i++) {
+ tbl = &sar->tables[i];
+
+ for (j = 0; j < RTW89_REGD_NUM; j++) {
+ ent = &tbl->entries[j];
+
+ rtw89_debug(rtwdev, RTW89_DBG_SAR,
+ "SAR-ACPI-[%u] REGD-%s (unit: 1/%lu dBm)\n",
+ i, rtw89_regd_get_string(j),
+ BIT(TXPWR_FACTOR_OF_RTW89_ACPI_SAR));
+
+ for (k = 0; k < NUM_OF_RTW89_ACPI_SAR_SUBBAND; k++)
+ rtw89_debug(rtwdev, RTW89_DBG_SAR,
+ "On subband %u, { %d, %d }\n", k,
+ ent->v[k][RF_PATH_A], ent->v[k][RF_PATH_B]);
+ }
+ }
+
+ rtw89_sar_set_src(rtwdev, RTW89_SAR_SOURCE_ACPI, cfg_acpi, sar);
+
+ /* SAR via ACPI is only configured in the early initial phase, so
+ * it does not seem necessary to reset txpwr related things here.
+ */
+}
+
+static void rtw89_set_sar_from_acpi(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_sar_cfg_acpi *cfg;
+ int ret;
+
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+ if (!cfg)
+ return;
+
+ ret = rtw89_acpi_evaluate_sar(rtwdev, cfg);
+ if (ret) {
+ rtw89_debug(rtwdev, RTW89_DBG_SAR,
+ "evaluating ACPI SAR returns %d\n", ret);
+ goto out;
+ }
+
+ if (unlikely(!cfg->valid_num)) {
+ rtw89_debug(rtwdev, RTW89_DBG_SAR, "no valid SAR table from ACPI\n");
+ goto out;
+ }
+
+ rtw89_apply_sar_acpi(rtwdev, cfg);
+
+out:
+ kfree(cfg);
+}
+
+static bool rtw89_tas_query_sar_config(struct rtw89_dev *rtwdev, s32 *cfg)
{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
const enum rtw89_sar_sources src = rtwdev->sar.src;
/* its members are protected by rtw89_sar_set_src() */
const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src];
- struct rtw89_tas_info *tas = &rtwdev->tas;
- s32 txpwr_avg = tas->total_txpwr / RTW89_TAS_MAX_WINDOW / PERCENT;
- s32 dpr_on_threshold, dpr_off_threshold, cfg;
- enum rtw89_tas_state state = tas->state;
- const struct rtw89_chan *chan;
+ struct rtw89_sar_parm sar_parm = {};
int ret;
- lockdep_assert_held(&rtwdev->mutex);
-
if (src == RTW89_SAR_SOURCE_NONE)
- return;
+ return false;
- chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
- ret = sar_hdl->query_sar_config(rtwdev, chan->freq, &cfg);
+ sar_parm.center_freq = chan->freq;
+ ret = sar_hdl->query_sar_config(rtwdev, &sar_parm, cfg);
if (ret)
+ return false;
+
+ *cfg = rtw89_txpwr_sar_to_tas(sar_hdl, *cfg);
+
+ return true;
+}
+
+static bool __rtw89_tas_state_update(struct rtw89_dev *rtwdev,
+ enum rtw89_tas_state state)
+{
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+
+ if (tas->state == state)
+ return false;
+
+ rtw89_debug(rtwdev, RTW89_DBG_SAR, "tas: switch state: %s -> %s\n",
+ rtw89_tas_state_str(tas->state), rtw89_tas_state_str(state));
+
+ tas->state = state;
+ return true;
+}
+
+static void rtw89_tas_state_update(struct rtw89_dev *rtwdev,
+ enum rtw89_tas_state state)
+{
+ if (!__rtw89_tas_state_update(rtwdev, state))
return;
- cfg = rtw89_txpwr_sar_to_tas(sar_hdl, cfg);
+ rtw89_core_set_chip_txpwr(rtwdev);
+}
+
+static u32 rtw89_tas_get_window_size(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
+ u8 band = chan->band_type;
+ u8 regd = rtw89_regd_get(rtwdev, band);
- if (tas->delta >= cfg) {
+ switch (regd) {
+ default:
rtw89_debug(rtwdev, RTW89_DBG_SAR,
- "TAS delta exceed SAR limit\n");
- state = RTW89_TAS_STATE_DPR_FORBID;
- goto out;
+ "tas: regd: %u is unhandled\n", regd);
+ fallthrough;
+ case RTW89_IC:
+ case RTW89_KCC:
+ return 180;
+ case RTW89_FCC:
+ switch (band) {
+ case RTW89_BAND_2G:
+ return 50;
+ case RTW89_BAND_5G:
+ return 30;
+ case RTW89_BAND_6G:
+ default:
+ return 15;
+ }
+ break;
+ }
+}
+
+static void rtw89_tas_window_update(struct rtw89_dev *rtwdev)
+{
+ u32 window_size = rtw89_tas_get_window_size(rtwdev);
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+ u64 total_txpwr = 0;
+ u8 head_idx;
+ u32 i, j;
+
+ WARN_ON_ONCE(tas->window_size > RTW89_TAS_TXPWR_WINDOW);
+
+ if (tas->window_size == window_size)
+ return;
+
+ rtw89_debug(rtwdev, RTW89_DBG_SAR, "tas: window update: %u -> %u\n",
+ tas->window_size, window_size);
+
+ head_idx = (tas->txpwr_tail_idx - window_size + 1 + RTW89_TAS_TXPWR_WINDOW) %
+ RTW89_TAS_TXPWR_WINDOW;
+ for (i = 0; i < window_size; i++) {
+ j = (head_idx + i) % RTW89_TAS_TXPWR_WINDOW;
+ total_txpwr += tas->txpwr_history[j];
+ }
+
+ tas->window_size = window_size;
+ tas->total_txpwr = total_txpwr;
+ tas->txpwr_head_idx = head_idx;
+}
+
+static void rtw89_tas_history_update(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, RTW89_PHY_0);
+ struct rtw89_env_monitor_info *env = &bb->env_monitor;
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+ u8 tx_ratio = env->ifs_clm_tx_ratio;
+ u64 instant_txpwr, txpwr;
+
+ /* txpwr in unit of linear(mW) multiply by percentage */
+ if (tx_ratio == 0) {
+ /* special case: idle tx power
+ * use -40 dBm * 100 tx ratio
+ */
+ instant_txpwr = rtw89_db_to_linear(-40);
+ txpwr = instant_txpwr * 100;
+ } else {
+ instant_txpwr = tas->instant_txpwr;
+ txpwr = instant_txpwr * tx_ratio;
}
- dpr_on_threshold = cfg;
- dpr_off_threshold = cfg - tas->dpr_gap;
+ tas->total_txpwr += txpwr - tas->txpwr_history[tas->txpwr_head_idx];
+ tas->total_tx_ratio += tx_ratio - tas->tx_ratio_history[tas->tx_ratio_idx];
+ tas->tx_ratio_history[tas->tx_ratio_idx] = tx_ratio;
+
+ tas->txpwr_head_idx = (tas->txpwr_head_idx + 1) % RTW89_TAS_TXPWR_WINDOW;
+ tas->txpwr_tail_idx = (tas->txpwr_tail_idx + 1) % RTW89_TAS_TXPWR_WINDOW;
+ tas->tx_ratio_idx = (tas->tx_ratio_idx + 1) % RTW89_TAS_TX_RATIO_WINDOW;
+ tas->txpwr_history[tas->txpwr_tail_idx] = txpwr;
+
rtw89_debug(rtwdev, RTW89_DBG_SAR,
- "DPR_ON thold: %d, DPR_OFF thold: %d, txpwr_avg: %d\n",
- dpr_on_threshold, dpr_off_threshold, txpwr_avg);
+ "tas: instant_txpwr: %d, tx_ratio: %u, txpwr: %d\n",
+ rtw89_linear_to_db_quarter(instant_txpwr), tx_ratio,
+ rtw89_linear_to_db_quarter(div_u64(txpwr, PERCENT)));
+}
+
+static bool rtw89_tas_rolling_average(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+ s32 dpr_on_threshold, dpr_off_threshold;
+ enum rtw89_tas_state state;
+ u16 tx_ratio_avg;
+ s32 txpwr_avg;
+ u64 linear;
+
+ linear = DIV_ROUND_DOWN_ULL(tas->total_txpwr, tas->window_size * PERCENT);
+ txpwr_avg = rtw89_linear_to_db_quarter(linear);
+ tx_ratio_avg = tas->total_tx_ratio / RTW89_TAS_TX_RATIO_WINDOW;
+ dpr_on_threshold = tas->dpr_on_threshold;
+ dpr_off_threshold = tas->dpr_off_threshold;
- if (txpwr_avg >= dpr_on_threshold)
+ rtw89_debug(rtwdev, RTW89_DBG_SAR,
+ "tas: DPR_ON: %d, DPR_OFF: %d, txpwr_avg: %d, tx_ratio_avg: %u\n",
+ dpr_on_threshold, dpr_off_threshold, txpwr_avg, tx_ratio_avg);
+
+ if (tx_ratio_avg >= RTW89_TAS_TX_RATIO_THRESHOLD)
+ state = RTW89_TAS_STATE_STATIC_SAR;
+ else if (txpwr_avg >= dpr_on_threshold)
state = RTW89_TAS_STATE_DPR_ON;
else if (txpwr_avg < dpr_off_threshold)
state = RTW89_TAS_STATE_DPR_OFF;
+ else
+ return false;
-out:
- if (tas->state == state)
- return;
-
- rtw89_debug(rtwdev, RTW89_DBG_SAR,
- "TAS old state: %d, new state: %d\n", tas->state, state);
- tas->state = state;
- rtw89_core_set_chip_txpwr(rtwdev);
+ return __rtw89_tas_state_update(rtwdev, state);
}
-void rtw89_tas_init(struct rtw89_dev *rtwdev)
+static void rtw89_tas_init(struct rtw89_dev *rtwdev)
{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_tas_info *tas = &rtwdev->tas;
+ const struct rtw89_acpi_policy_tas *ptr;
struct rtw89_acpi_dsm_result res = {};
int ret;
- u8 val;
+
+ if (!chip->support_tas)
+ return;
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_TAS_EN, &res);
if (ret) {
@@ -415,8 +709,9 @@ void rtw89_tas_init(struct rtw89_dev *rtwdev)
return;
}
- val = res.u.value;
- switch (val) {
+ ptr = res.u.policy_tas;
+
+ switch (ptr->enable) {
case 0:
tas->enable = false;
break;
@@ -429,66 +724,170 @@ void rtw89_tas_init(struct rtw89_dev *rtwdev)
if (!tas->enable) {
rtw89_debug(rtwdev, RTW89_DBG_SAR, "TAS not enable\n");
- return;
+ goto out;
}
- tas->dpr_gap = RTW89_TAS_DPR_GAP;
- tas->delta = RTW89_TAS_DELTA;
+ tas->enabled_countries = ptr->enabled_countries;
+
+out:
+ kfree(ptr);
}
-void rtw89_tas_reset(struct rtw89_dev *rtwdev)
+void rtw89_tas_reset(struct rtw89_dev *rtwdev, bool force)
{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
struct rtw89_tas_info *tas = &rtwdev->tas;
+ u64 linear;
+ s32 cfg;
+ int i;
- if (!tas->enable)
+ if (!rtw89_tas_is_active(rtwdev))
+ return;
+
+ if (!rtw89_tas_query_sar_config(rtwdev, &cfg))
return;
- memset(&tas->txpwr_history, 0, sizeof(tas->txpwr_history));
- tas->total_txpwr = 0;
- tas->cur_idx = 0;
+ tas->dpr_on_threshold = cfg - RTW89_TAS_SAR_GAP;
+ tas->dpr_off_threshold = cfg - RTW89_TAS_SAR_GAP - RTW89_TAS_DPR_GAP;
+
+ /* avoid history reset after new SAR apply */
+ if (!force && tas->keep_history)
+ return;
+
+ linear = rtw89_db_quarter_to_linear(cfg) * RTW89_TAS_DFLT_TX_RATIO;
+ for (i = 0; i < RTW89_TAS_TXPWR_WINDOW; i++)
+ tas->txpwr_history[i] = linear;
+
+ for (i = 0; i < RTW89_TAS_TX_RATIO_WINDOW; i++)
+ tas->tx_ratio_history[i] = RTW89_TAS_DFLT_TX_RATIO;
+
+ tas->total_tx_ratio = RTW89_TAS_DFLT_TX_RATIO * RTW89_TAS_TX_RATIO_WINDOW;
+ tas->total_txpwr = linear * RTW89_TAS_TXPWR_WINDOW;
+ tas->window_size = RTW89_TAS_TXPWR_WINDOW;
+ tas->txpwr_head_idx = 0;
+ tas->txpwr_tail_idx = RTW89_TAS_TXPWR_WINDOW - 1;
+ tas->tx_ratio_idx = 0;
tas->state = RTW89_TAS_STATE_DPR_OFF;
+ tas->backup_state = RTW89_TAS_STATE_DPR_OFF;
+ tas->keep_history = true;
+
+ rtw89_debug(rtwdev, RTW89_DBG_SAR,
+ "tas: band: %u, freq: %u\n", chan->band_type, chan->freq);
}
-static const struct rtw89_reg_def txpwr_regs[] = {
- {R_PATH0_TXPWR, B_PATH0_TXPWR},
- {R_PATH1_TXPWR, B_PATH1_TXPWR},
-};
+static bool rtw89_tas_track(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+ struct rtw89_hal *hal = &rtwdev->hal;
+ s32 cfg;
-void rtw89_tas_track(struct rtw89_dev *rtwdev)
+ if (hal->disabled_dm_bitmap & BIT(RTW89_DM_TAS))
+ return false;
+
+ if (!rtw89_tas_is_active(rtwdev))
+ return false;
+
+ if (!rtw89_tas_query_sar_config(rtwdev, &cfg) || tas->block_regd)
+ return __rtw89_tas_state_update(rtwdev, RTW89_TAS_STATE_STATIC_SAR);
+
+ if (tas->pause)
+ return false;
+
+ rtw89_tas_window_update(rtwdev);
+ rtw89_tas_history_update(rtwdev);
+
+ return rtw89_tas_rolling_average(rtwdev);
+}
+
+void rtw89_tas_scan(struct rtw89_dev *rtwdev, bool start)
{
- struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
- const enum rtw89_sar_sources src = rtwdev->sar.src;
- u8 max_nss_num = rtwdev->chip->rf_path_num;
struct rtw89_tas_info *tas = &rtwdev->tas;
- s16 tmp, txpwr, instant_txpwr = 0;
- u32 val;
- int i;
+ s32 cfg;
+
+ if (!rtw89_tas_is_active(rtwdev))
+ return;
+
+ if (!rtw89_tas_query_sar_config(rtwdev, &cfg))
+ return;
+
+ if (start) {
+ tas->backup_state = tas->state;
+ rtw89_tas_state_update(rtwdev, RTW89_TAS_STATE_STATIC_SAR);
+ } else {
+ rtw89_tas_state_update(rtwdev, tas->backup_state);
+ }
+}
+
+void rtw89_tas_chanctx_cb(struct rtw89_dev *rtwdev,
+ enum rtw89_chanctx_state state)
+{
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+ s32 cfg;
- if (!tas->enable || src == RTW89_SAR_SOURCE_NONE)
+ if (!rtw89_tas_is_active(rtwdev))
return;
- if (env->ccx_watchdog_result != RTW89_PHY_ENV_MON_IFS_CLM)
+ if (!rtw89_tas_query_sar_config(rtwdev, &cfg))
return;
- for (i = 0; i < max_nss_num; i++) {
- val = rtw89_phy_read32_mask(rtwdev, txpwr_regs[i].addr,
- txpwr_regs[i].mask);
- tmp = sign_extend32(val, 8);
- if (tmp <= 0)
- return;
- instant_txpwr += tmp;
+ switch (state) {
+ case RTW89_CHANCTX_STATE_MCC_START:
+ tas->pause = true;
+ rtw89_tas_state_update(rtwdev, RTW89_TAS_STATE_STATIC_SAR);
+ break;
+ case RTW89_CHANCTX_STATE_MCC_STOP:
+ tas->pause = false;
+ break;
+ default:
+ break;
}
+}
+EXPORT_SYMBOL(rtw89_tas_chanctx_cb);
+
+void rtw89_sar_init(struct rtw89_dev *rtwdev)
+{
+ rtw89_set_sar_from_acpi(rtwdev);
+ rtw89_tas_init(rtwdev);
+}
+
+static bool rtw89_sar_track_acpi(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_sar_cfg_acpi *cfg = &rtwdev->sar.cfg_acpi;
+ struct rtw89_sar_indicator_from_acpi *ind = &cfg->indicator;
+ const enum rtw89_sar_sources src = rtwdev->sar.src;
+ bool changed;
+ int ret;
+
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ if (src != RTW89_SAR_SOURCE_ACPI)
+ return false;
+
+ if (!ind->enable_sync)
+ return false;
+
+ ret = rtw89_acpi_evaluate_dynamic_sar_indicator(rtwdev, cfg, &changed);
+ if (likely(!ret))
+ return changed;
- instant_txpwr /= max_nss_num;
- /* in unit of 0.25 dBm multiply by percentage */
- txpwr = instant_txpwr * env->ifs_clm_tx_ratio;
- tas->total_txpwr += txpwr - tas->txpwr_history[tas->cur_idx];
- tas->txpwr_history[tas->cur_idx] = txpwr;
rtw89_debug(rtwdev, RTW89_DBG_SAR,
- "instant_txpwr: %d, tx_ratio: %d, txpwr: %d\n",
- instant_txpwr, env->ifs_clm_tx_ratio, txpwr);
+ "%s: failed to track indicator: %d; reset and disable\n",
+ __func__, ret);
- tas->cur_idx = (tas->cur_idx + 1) % RTW89_TAS_MAX_WINDOW;
+ memset(ind->tblsel, 0, sizeof(ind->tblsel));
+ ind->enable_sync = false;
+ return true;
+}
+
+void rtw89_sar_track(struct rtw89_dev *rtwdev)
+{
+ unsigned int changes = 0;
+
+ changes += rtw89_sar_track_acpi(rtwdev);
+ changes += rtw89_tas_track(rtwdev);
- rtw89_tas_state_update(rtwdev);
+ if (!changes)
+ return;
+
+ rtw89_core_set_chip_txpwr(rtwdev);
}
diff --git a/drivers/net/wireless/realtek/rtw89/sar.h b/drivers/net/wireless/realtek/rtw89/sar.h
index bd7a657188d9..4b7f3d44f57b 100644
--- a/drivers/net/wireless/realtek/rtw89/sar.h
+++ b/drivers/net/wireless/realtek/rtw89/sar.h
@@ -7,24 +7,37 @@
#include "core.h"
-#define RTW89_SAR_TXPWR_MAC_MAX S8_MAX
-#define RTW89_SAR_TXPWR_MAC_MIN S8_MIN
+#define RTW89_SAR_TXPWR_MAC_MAX 63
+#define RTW89_SAR_TXPWR_MAC_MIN -64
+
+struct rtw89_sar_parm {
+ u32 center_freq;
+ enum rtw89_ntx ntx;
+
+ bool force_path;
+ enum rtw89_rf_path path;
+};
struct rtw89_sar_handler {
const char *descr_sar_source;
u8 txpwr_factor_sar;
- int (*query_sar_config)(struct rtw89_dev *rtwdev, u32 center_freq, s32 *cfg);
+ int (*query_sar_config)(struct rtw89_dev *rtwdev,
+ const struct rtw89_sar_parm *sar_parm, s32 *cfg);
};
extern const struct cfg80211_sar_capa rtw89_sar_capa;
-s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq);
-void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev, u32 center_freq);
-void rtw89_print_tas(struct seq_file *m, struct rtw89_dev *rtwdev);
+s8 rtw89_query_sar(struct rtw89_dev *rtwdev, const struct rtw89_sar_parm *sar_parm);
+int rtw89_print_sar(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
+ const struct rtw89_sar_parm *sar_parm);
+int rtw89_print_tas(struct rtw89_dev *rtwdev, char *buf, size_t bufsz);
int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar);
-void rtw89_tas_init(struct rtw89_dev *rtwdev);
-void rtw89_tas_reset(struct rtw89_dev *rtwdev);
-void rtw89_tas_track(struct rtw89_dev *rtwdev);
+void rtw89_tas_reset(struct rtw89_dev *rtwdev, bool force);
+void rtw89_tas_scan(struct rtw89_dev *rtwdev, bool start);
+void rtw89_tas_chanctx_cb(struct rtw89_dev *rtwdev,
+ enum rtw89_chanctx_state state);
+void rtw89_sar_init(struct rtw89_dev *rtwdev);
+void rtw89_sar_track(struct rtw89_dev *rtwdev);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c
index 99896d85d2f8..811c91481441 100644
--- a/drivers/net/wireless/realtek/rtw89/ser.c
+++ b/drivers/net/wireless/realtek/rtw89/ser.c
@@ -156,9 +156,9 @@ static void ser_state_run(struct rtw89_ser *ser, u8 evt)
rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s receive %s\n",
ser_st_name(ser), ser_ev_name(ser, evt));
- mutex_lock(&rtwdev->mutex);
+ wiphy_lock(rtwdev->hw->wiphy);
rtw89_leave_lps(rtwdev);
- mutex_unlock(&rtwdev->mutex);
+ wiphy_unlock(rtwdev->hw->wiphy);
ser->st_tbl[ser->state].st_func(ser, evt);
}
@@ -300,33 +300,57 @@ static void drv_resume_rx(struct rtw89_ser *ser)
static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
- rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
- rtwvif->net_type = RTW89_NET_TYPE_NO_LINK;
- rtwvif->trigger = false;
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
+
rtwvif->tdls_peer = 0;
+
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+ rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif_link->port);
+ rtwvif_link->net_type = RTW89_NET_TYPE_NO_LINK;
+ rtwvif_link->trigger = false;
+ rtwvif_link->rand_tsf_done = false;
+
+ rtw89_p2p_noa_once_deinit(rtwvif_link);
+ }
}
static void ser_sta_deinit_cam_iter(void *data, struct ieee80211_sta *sta)
{
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)data;
+ struct rtw89_vif *target_rtwvif = (struct rtw89_vif *)data;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
+ struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_dev *rtwdev = rtwvif->rtwdev;
- struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_sta_link *rtwsta_link;
+ unsigned int link_id;
- if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
- rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam);
- if (sta->tdls)
- rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta->bssid_cam);
+ if (rtwvif != target_rtwvif)
+ return;
- INIT_LIST_HEAD(&rtwsta->ba_cam_list);
+ rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
+ rtwvif_link = rtwsta_link->rtwvif_link;
+
+ if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
+ rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta_link->addr_cam);
+ if (sta->tdls)
+ rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta_link->bssid_cam);
+
+ INIT_LIST_HEAD(&rtwsta_link->ba_cam_list);
+ }
}
static void ser_deinit_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
+
ieee80211_iterate_stations_atomic(rtwdev->hw,
ser_sta_deinit_cam_iter,
rtwvif);
- rtw89_cam_deinit(rtwdev, rtwvif);
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_cam_deinit(rtwdev, rtwvif_link);
bitmap_zero(rtwdev->cam_info.ba_cam_map, RTW89_MAX_BA_CAM_NUM);
}
@@ -344,6 +368,7 @@ static void ser_reset_mac_binding(struct rtw89_dev *rtwdev)
ser_reset_vif(rtwdev, rtwvif);
rtwdev->total_sta_assoc = 0;
+ refcount_set(&rtwdev->refcount_ap_info, 0);
}
/* hal function */
@@ -461,10 +486,13 @@ static void ser_l1_reset_pre_st_hdl(struct rtw89_ser *ser, u8 evt)
static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
+ struct wiphy *wiphy = rtwdev->hw->wiphy;
switch (evt) {
case SER_EV_STATE_IN:
- cancel_delayed_work_sync(&rtwdev->track_work);
+ wiphy_lock(wiphy);
+ wiphy_delayed_work_cancel(wiphy, &rtwdev->track_work);
+ wiphy_unlock(wiphy);
drv_stop_tx(ser);
if (hal_stop_dma(ser)) {
@@ -495,8 +523,8 @@ static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt)
hal_enable_dma(ser);
drv_resume_rx(ser);
drv_resume_tx(ser);
- ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work,
- RTW89_TRACK_WORK_PERIOD);
+ wiphy_delayed_work_queue(wiphy, &rtwdev->track_work,
+ RTW89_TRACK_WORK_PERIOD);
break;
default:
@@ -686,9 +714,9 @@ static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt)
switch (evt) {
case SER_EV_STATE_IN:
- mutex_lock(&rtwdev->mutex);
+ wiphy_lock(rtwdev->hw->wiphy);
ser_l2_reset_st_pre_hdl(ser);
- mutex_unlock(&rtwdev->mutex);
+ wiphy_unlock(rtwdev->hw->wiphy);
ieee80211_restart_hw(rtwdev->hw);
ser_set_alarm(ser, SER_RECFG_TIMEOUT, SER_EV_L2_RECFG_TIMEOUT);
diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h
index c467a80ffa88..94f27a9ee9f7 100644
--- a/drivers/net/wireless/realtek/rtw89/txrx.h
+++ b/drivers/net/wireless/realtek/rtw89/txrx.h
@@ -14,6 +14,7 @@
#define DATA_RATE_HT_IDX_MASK GENMASK(4, 0)
#define DATA_RATE_HT_IDX_MASK_V1 GENMASK(4, 0)
#define DATA_RATE_MODE_HT 0x1
+#define DATA_RATE_HT_NSS_MASK GENMASK(4, 3)
#define DATA_RATE_VHT_HE_NSS_MASK GENMASK(6, 4)
#define DATA_RATE_VHT_HE_IDX_MASK GENMASK(3, 0)
#define DATA_RATE_NSS_MASK_V1 GENMASK(7, 5)
@@ -51,6 +52,11 @@ static inline u8 rtw89_get_data_mcs(struct rtw89_dev *rtwdev, u16 hw_rate)
return u16_get_bits(hw_rate, DATA_RATE_VHT_HE_IDX_MASK);
}
+static inline u8 rtw89_get_data_ht_nss(struct rtw89_dev *rtwdev, u16 hw_rate)
+{
+ return u16_get_bits(hw_rate, DATA_RATE_HT_NSS_MASK);
+}
+
static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate)
{
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
@@ -113,6 +119,8 @@ static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate)
#define RTW89_TXWD_INFO0_GI_LTF GENMASK(27, 25)
#define RTW89_TXWD_INFO0_DATA_RATE GENMASK(24, 16)
#define RTW89_TXWD_INFO0_DATA_ER BIT(15)
+#define RTW89_TXWD_INFO0_DATA_STBC BIT(12)
+#define RTW89_TXWD_INFO0_DATA_LDPC BIT(11)
#define RTW89_TXWD_INFO0_DISDATAFB BIT(10)
#define RTW89_TXWD_INFO0_DATA_BW_ER BIT(8)
#define RTW89_TXWD_INFO0_MULTIPORT_ID GENMASK(6, 4)
@@ -406,7 +414,7 @@ struct rtw89_rxinfo_user {
#define RTW89_RXINFO_USER_DATA BIT(1)
#define RTW89_RXINFO_USER_CTRL BIT(2)
#define RTW89_RXINFO_USER_MGMT BIT(3)
-#define RTW89_RXINFO_USER_BCM BIT(4)
+#define RTW89_RXINFO_USER_BCN BIT(4)
#define RTW89_RXINFO_USER_MACID GENMASK(15, 8)
struct rtw89_rxinfo {
@@ -433,6 +441,7 @@ struct rtw89_phy_sts_hdr {
} __packed;
#define RTW89_PHY_STS_HDR_W0_IE_MAP GENMASK(4, 0)
+#define RTW89_PHY_STS_HDR_W0_HDR_2_EN BIT(5)
#define RTW89_PHY_STS_HDR_W0_VALID BIT(7)
#define RTW89_PHY_STS_HDR_W0_LEN GENMASK(15, 8)
#define RTW89_PHY_STS_HDR_W0_RSSI_AVG GENMASK(31, 24)
@@ -441,6 +450,13 @@ struct rtw89_phy_sts_hdr {
#define RTW89_PHY_STS_HDR_W1_RSSI_C GENMASK(23, 16)
#define RTW89_PHY_STS_HDR_W1_RSSI_D GENMASK(31, 24)
+struct rtw89_phy_sts_hdr_v2 {
+ __le32 w0;
+ __le32 w1;
+} __packed;
+
+#define RTW89_PHY_STS_HDR_V2_W0_PATH_EN GENMASK(20, 16)
+
struct rtw89_phy_sts_iehdr {
__le32 w0;
};
@@ -544,18 +560,72 @@ struct rtw89_phy_sts_iehdr {
#define BE_RXD_HDR_OFFSET_MASK GENMASK(20, 16)
#define BE_RXD_WL_HD_IV_LEN_MASK GENMASK(26, 21)
-struct rtw89_phy_sts_ie0 {
+/* BE RXD - PHY RPT dword0 */
+#define BE_RXD_PHY_RSSI GENMASK(11, 0)
+
+struct rtw89_phy_sts_ie00 {
+ __le32 w0;
+ __le32 w1;
+ __le32 w2;
+ __le32 w3;
+} __packed;
+
+#define RTW89_PHY_STS_IE00_W0_RPL GENMASK(15, 7)
+
+struct rtw89_phy_sts_ie00_v2 {
+ __le32 w0;
+ __le32 w1;
+ __le32 w2;
+ __le32 w3;
+ __le32 w4;
+ __le32 w5;
+ __le32 w6;
+ __le32 w7;
+} __packed;
+
+#define RTW89_PHY_STS_IE00_V2_W4_RPL_TD_A GENMASK(8, 0)
+#define RTW89_PHY_STS_IE00_V2_W4_RPL_TD_B GENMASK(17, 9)
+#define RTW89_PHY_STS_IE00_V2_W4_RPL_TD_C GENMASK(26, 18)
+#define RTW89_PHY_STS_IE00_V2_W5_RPL_TD_D GENMASK(8, 0)
+
+struct rtw89_phy_sts_ie01 {
__le32 w0;
__le32 w1;
__le32 w2;
+ __le32 w3;
+ __le32 w4;
+ __le32 w5;
} __packed;
#define RTW89_PHY_STS_IE01_W0_CH_IDX GENMASK(23, 16)
+#define RTW89_PHY_STS_IE01_W0_RSSI_AVG_FD GENMASK(15, 8)
+#define RTW89_PHY_STS_IE01_W0_RX_PATH_EN GENMASK(31, 28)
#define RTW89_PHY_STS_IE01_W1_FD_CFO GENMASK(19, 8)
#define RTW89_PHY_STS_IE01_W1_PREMB_CFO GENMASK(31, 20)
#define RTW89_PHY_STS_IE01_W2_AVG_SNR GENMASK(5, 0)
#define RTW89_PHY_STS_IE01_W2_EVM_MAX GENMASK(15, 8)
#define RTW89_PHY_STS_IE01_W2_EVM_MIN GENMASK(23, 16)
+#define RTW89_PHY_STS_IE01_W2_LDPC BIT(28)
+#define RTW89_PHY_STS_IE01_W2_STBC BIT(30)
+
+struct rtw89_phy_sts_ie01_v2 {
+ __le32 w0;
+ __le32 w1;
+ __le32 w2;
+ __le32 w3;
+ __le32 w4;
+ __le32 w5;
+ __le32 w6;
+ __le32 w7;
+ __le32 w8;
+ __le32 w9;
+} __packed;
+
+#define RTW89_PHY_STS_IE01_V2_W5_BW_IDX GENMASK(31, 29)
+#define RTW89_PHY_STS_IE01_V2_W8_RPL_FD_A GENMASK(11, 4)
+#define RTW89_PHY_STS_IE01_V2_W8_RPL_FD_B GENMASK(23, 16)
+#define RTW89_PHY_STS_IE01_V2_W9_RPL_FD_C GENMASK(11, 4)
+#define RTW89_PHY_STS_IE01_V2_W9_RPL_FD_D GENMASK(23, 16)
enum rtw89_tx_channel {
RTW89_TXCH_ACH0 = 0,
@@ -642,6 +712,25 @@ static inline u8 rtw89_core_get_qsel(struct rtw89_dev *rtwdev, u8 tid)
}
}
+static inline u8
+rtw89_core_get_qsel_mgmt(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req)
+{
+ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
+ struct rtw89_vif_link *rtwvif_link = tx_req->rtwvif_link;
+
+ if (desc_info->hiq) {
+ if (rtwvif_link->mac_idx == RTW89_MAC_1)
+ return RTW89_TX_QSEL_B1_HI;
+ else
+ return RTW89_TX_QSEL_B0_HI;
+ }
+
+ if (rtwvif_link->mac_idx == RTW89_MAC_1)
+ return RTW89_TX_QSEL_B1_MGMT;
+ else
+ return RTW89_TX_QSEL_B0_MGMT;
+}
+
static inline u8 rtw89_core_get_ch_dma(struct rtw89_dev *rtwdev, u8 qsel)
{
switch (qsel) {
@@ -649,12 +738,24 @@ static inline u8 rtw89_core_get_ch_dma(struct rtw89_dev *rtwdev, u8 qsel)
rtw89_warn(rtwdev, "Cannot map qsel to dma: %d\n", qsel);
fallthrough;
case RTW89_TX_QSEL_BE_0:
+ case RTW89_TX_QSEL_BE_1:
+ case RTW89_TX_QSEL_BE_2:
+ case RTW89_TX_QSEL_BE_3:
return RTW89_TXCH_ACH0;
case RTW89_TX_QSEL_BK_0:
+ case RTW89_TX_QSEL_BK_1:
+ case RTW89_TX_QSEL_BK_2:
+ case RTW89_TX_QSEL_BK_3:
return RTW89_TXCH_ACH1;
case RTW89_TX_QSEL_VI_0:
+ case RTW89_TX_QSEL_VI_1:
+ case RTW89_TX_QSEL_VI_2:
+ case RTW89_TX_QSEL_VI_3:
return RTW89_TXCH_ACH2;
case RTW89_TX_QSEL_VO_0:
+ case RTW89_TX_QSEL_VO_1:
+ case RTW89_TX_QSEL_VO_2:
+ case RTW89_TX_QSEL_VO_3:
return RTW89_TXCH_ACH3;
case RTW89_TX_QSEL_B0_MGMT:
return RTW89_TXCH_CH8;
diff --git a/drivers/net/wireless/realtek/rtw89/util.c b/drivers/net/wireless/realtek/rtw89/util.c
new file mode 100644
index 000000000000..073714db26f2
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw89/util.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2024 Realtek Corporation
+ */
+
+#include "util.h"
+
+#define RTW89_DBM_QUARTER_FACTOR 2
+#define RTW89_MIN_DBM (-41.25 * (1 << RTW89_DBM_QUARTER_FACTOR))
+#define RTW89_MAX_DBM (96 * (1 << RTW89_DBM_QUARTER_FACTOR))
+#define RTW89_DB_INVERT_TABLE_OFFSET (-RTW89_MIN_DBM)
+
+static const u64 db_invert_table[] = {
+ /* in unit of 0.000001 */
+ 75, 79, 84, 89, 94, 100, 106, 112, 119, 126, 133, 141, 150, 158, 168, 178, 188,
+ 200, 211, 224, 237, 251, 266, 282, 299, 316, 335, 355, 376, 398, 422, 447, 473,
+ 501, 531, 562, 596, 631, 668, 708, 750, 794, 841, 891, 944, 1000, 1059, 1122, 1189,
+ 1259, 1334, 1413, 1496, 1585, 1679, 1778, 1884, 1995, 2113, 2239, 2371, 2512, 2661,
+ 2818, 2985, 3162, 3350, 3548, 3758, 3981, 4217, 4467, 4732, 5012, 5309, 5623, 5957,
+ 6310, 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, 10593, 11220, 11885, 12589,
+ 13335, 14125, 14962, 15849, 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
+ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, 42170, 44668, 47315, 50119,
+ 53088, 56234, 59566, 63096, 66834, 70795, 74989, 79433, 84140, 89125, 94406, 100000,
+ 105925, 112202, 118850, 125893, 133352, 141254, 149624, 158489, 167880, 177828,
+ 188365, 199526, 211349, 223872, 237137, 251189, 266073, 281838, 298538, 316228,
+ 334965, 354813, 375837, 398107, 421697, 446684, 473151, 501187, 530884, 562341,
+ 595662, 630957, 668344, 707946, 749894, 794328, 841395, 891251, 944061, 1000000,
+ 1059254, 1122018, 1188502, 1258925, 1333521, 1412538, 1496236, 1584893, 1678804,
+ 1778279, 1883649, 1995262, 2113489, 2238721, 2371374, 2511886, 2660725, 2818383,
+ 2985383, 3162278, 3349654, 3548134, 3758374, 3981072, 4216965, 4466836, 4731513,
+ 5011872, 5308844, 5623413, 5956621, 6309573, 6683439, 7079458, 7498942, 7943282,
+ 8413951, 8912509, 9440609, 10000000, 10592537, 11220185, 11885022, 12589254,
+ 13335214, 14125375, 14962357, 15848932, 16788040, 17782794, 18836491, 19952623,
+ 21134890, 22387211, 23713737, 25118864, 26607251, 28183829, 29853826, 31622777,
+ 33496544, 35481339, 37583740, 39810717, 42169650, 44668359, 47315126, 50118723,
+ 53088444, 56234133, 59566214, 63095734, 66834392, 70794578, 74989421, 79432823,
+ 84139514, 89125094, 94406088, 100000000, 105925373, 112201845, 118850223, 125892541,
+ 133352143, 141253754, 149623566, 158489319, 167880402, 177827941, 188364909, 199526231,
+ 211348904, 223872114, 237137371, 251188643, 266072506, 281838293, 298538262, 316227766,
+ 334965439, 354813389, 375837404, 398107171, 421696503, 446683592, 473151259, 501187234,
+ 530884444, 562341325, 595662144, 630957344, 668343918, 707945784, 749894209, 794328235,
+ 841395142, 891250938, 944060876, 1000000000, 1059253725, 1122018454, 1188502227,
+ 1258925412, 1333521432, 1412537545, 1496235656, 1584893192, 1678804018, 1778279410,
+ 1883649089, 1995262315, 2113489040, 2238721139, 2371373706, 2511886432, 2660725060,
+ 2818382931, 2985382619, 3162277660, 3349654392, 3548133892, 3758374043, 3981071706,
+ 4216965034, 4466835922ULL, 4731512590ULL, 5011872336ULL, 5308844442ULL, 5623413252ULL,
+ 5956621435ULL, 6309573445ULL, 6683439176ULL, 7079457844ULL, 7498942093ULL,
+ 7943282347ULL, 8413951416ULL, 8912509381ULL, 9440608763ULL, 10000000000ULL,
+ 10592537252ULL, 11220184543ULL, 11885022274ULL, 12589254118ULL, 13335214322ULL,
+ 14125375446ULL, 14962356561ULL, 15848931925ULL, 16788040181ULL, 17782794100ULL,
+ 18836490895ULL, 19952623150ULL, 21134890398ULL, 22387211386ULL, 23713737057ULL,
+ 25118864315ULL, 26607250598ULL, 28183829313ULL, 29853826189ULL, 31622776602ULL,
+ 33496543916ULL, 35481338923ULL, 37583740429ULL, 39810717055ULL, 42169650343ULL,
+ 44668359215ULL, 47315125896ULL, 50118723363ULL, 53088444423ULL, 56234132519ULL,
+ 59566214353ULL, 63095734448ULL, 66834391757ULL, 70794578438ULL, 74989420933ULL,
+ 79432823472ULL, 84139514165ULL, 89125093813ULL, 94406087629ULL, 100000000000ULL,
+ 105925372518ULL, 112201845430ULL, 118850222744ULL, 125892541179ULL, 133352143216ULL,
+ 141253754462ULL, 149623565609ULL, 158489319246ULL, 167880401812ULL, 177827941004ULL,
+ 188364908949ULL, 199526231497ULL, 211348903984ULL, 223872113857ULL, 237137370566ULL,
+ 251188643151ULL, 266072505980ULL, 281838293126ULL, 298538261892ULL, 316227766017ULL,
+ 334965439158ULL, 354813389234ULL, 375837404288ULL, 398107170553ULL, 421696503429ULL,
+ 446683592151ULL, 473151258961ULL, 501187233627ULL, 530884444231ULL, 562341325190ULL,
+ 595662143529ULL, 630957344480ULL, 668343917569ULL, 707945784384ULL, 749894209332ULL,
+ 794328234724ULL, 841395141645ULL, 891250938134ULL, 944060876286ULL, 1000000000000ULL,
+ 1059253725177ULL, 1122018454302ULL, 1188502227437ULL, 1258925411794ULL,
+ 1333521432163ULL, 1412537544623ULL, 1496235656094ULL, 1584893192461ULL,
+ 1678804018123ULL, 1778279410039ULL, 1883649089490ULL, 1995262314969ULL,
+ 2113489039837ULL, 2238721138568ULL, 2371373705662ULL, 2511886431510ULL,
+ 2660725059799ULL, 2818382931264ULL, 2985382618918ULL, 3162277660168ULL,
+ 3349654391578ULL, 3548133892336ULL, 3758374042884ULL, 3981071705535ULL,
+ 4216965034286ULL, 4466835921510ULL, 4731512589615ULL, 5011872336273ULL,
+ 5308844442310ULL, 5623413251904ULL, 5956621435290ULL, 6309573444802ULL,
+ 6683439175686ULL, 7079457843841ULL, 7498942093325ULL, 7943282347243ULL,
+ 8413951416452ULL, 8912509381337ULL, 9440608762859ULL, 10000000000000ULL,
+ 10592537251773ULL, 11220184543020ULL, 11885022274370ULL, 12589254117942ULL,
+ 13335214321633ULL, 14125375446228ULL, 14962356560944ULL, 15848931924611ULL,
+ 16788040181226ULL, 17782794100389ULL, 18836490894898ULL, 19952623149689ULL,
+ 21134890398367ULL, 22387211385683ULL, 23713737056617ULL, 25118864315096ULL,
+ 26607250597988ULL, 28183829312645ULL, 29853826189180ULL, 31622776601684ULL,
+ 33496543915783ULL, 35481338923358ULL, 37583740428845ULL, 39810717055350ULL,
+ 42169650342858ULL, 44668359215096ULL, 47315125896148ULL, 50118723362727ULL,
+ 53088444423099ULL, 56234132519035ULL, 59566214352901ULL, 63095734448019ULL,
+ 66834391756862ULL, 70794578438414ULL, 74989420933246ULL, 79432823472428ULL,
+ 84139514164520ULL, 89125093813375ULL, 94406087628593ULL, 100000000000000ULL,
+ 105925372517729ULL, 112201845430197ULL, 118850222743702ULL, 125892541179417ULL,
+ 133352143216332ULL, 141253754462276ULL, 149623565609444ULL, 158489319246111ULL,
+ 167880401812256ULL, 177827941003893ULL, 188364908948981ULL, 199526231496888ULL,
+ 211348903983664ULL, 223872113856834ULL, 237137370566166ULL, 251188643150958ULL,
+ 266072505979882ULL, 281838293126446ULL, 298538261891796ULL, 316227766016838ULL,
+ 334965439157829ULL, 354813389233577ULL, 375837404288444ULL, 398107170553497ULL,
+ 421696503428583ULL, 446683592150964ULL, 473151258961482ULL, 501187233627272ULL,
+ 530884444230989ULL, 562341325190350ULL, 595662143529011ULL, 630957344480196ULL,
+ 668343917568615ULL, 707945784384138ULL, 749894209332456ULL, 794328234724284ULL,
+ 841395141645198ULL, 891250938133745ULL, 944060876285923ULL, 1000000000000000ULL,
+ 1059253725177290ULL, 1122018454301970ULL, 1188502227437020ULL, 1258925411794170ULL,
+ 1333521432163330ULL, 1412537544622760ULL, 1496235656094440ULL, 1584893192461110ULL,
+ 1678804018122560ULL, 1778279410038920ULL, 1883649089489810ULL, 1995262314968890ULL,
+ 2113489039836650ULL, 2238721138568340ULL, 2371373705661660ULL, 2511886431509590ULL,
+ 2660725059798820ULL, 2818382931264460ULL, 2985382618917960ULL, 3162277660168380ULL,
+ 3349654391578280ULL, 3548133892335770ULL, 3758374042884440ULL, 3981071705534970ULL
+};
+
+s32 rtw89_linear_to_db_quarter(u64 val)
+{
+ int r = ARRAY_SIZE(db_invert_table) - 1;
+ int l = 0;
+ int m;
+
+ while (l <= r) {
+ m = l + (r - l) / 2;
+
+ if (db_invert_table[m] == val)
+ return m - (s32)RTW89_DB_INVERT_TABLE_OFFSET;
+
+ if (db_invert_table[m] > val)
+ r = m - 1;
+ else
+ l = m + 1;
+ }
+
+ if (l >= ARRAY_SIZE(db_invert_table))
+ return RTW89_MAX_DBM;
+ else if (r < 0)
+ return RTW89_MIN_DBM;
+ else if (val - db_invert_table[r] <= db_invert_table[l] - val)
+ return r - (s32)RTW89_DB_INVERT_TABLE_OFFSET;
+ else
+ return l - (s32)RTW89_DB_INVERT_TABLE_OFFSET;
+}
+EXPORT_SYMBOL(rtw89_linear_to_db_quarter);
+
+s32 rtw89_linear_to_db(u64 val)
+{
+ return rtw89_linear_to_db_quarter(val) >> RTW89_DBM_QUARTER_FACTOR;
+}
+EXPORT_SYMBOL(rtw89_linear_to_db);
+
+u64 rtw89_db_quarter_to_linear(s32 db)
+{
+ /* supported range -41.25 to 96 dBm, in unit of 0.25 dBm */
+ db = clamp_t(s32, db, RTW89_MIN_DBM, RTW89_MAX_DBM);
+ db += (s32)RTW89_DB_INVERT_TABLE_OFFSET;
+
+ return db_invert_table[db];
+}
+EXPORT_SYMBOL(rtw89_db_quarter_to_linear);
+
+u64 rtw89_db_to_linear(s32 db)
+{
+ return rtw89_db_quarter_to_linear(db << RTW89_DBM_QUARTER_FACTOR);
+}
+EXPORT_SYMBOL(rtw89_db_to_linear);
+
+void rtw89_might_trailing_ellipsis(char *buf, size_t size, ssize_t used)
+{
+ static const char ellipsis[] = "...";
+
+ /* length of null terminiator isn't included in 'used' */
+ if (used + 1 < size || size < sizeof(ellipsis))
+ return;
+
+ memcpy(buf + size - sizeof(ellipsis), ellipsis, sizeof(ellipsis));
+}
diff --git a/drivers/net/wireless/realtek/rtw89/util.h b/drivers/net/wireless/realtek/rtw89/util.h
index e2ed4565025d..bd08495301e4 100644
--- a/drivers/net/wireless/realtek/rtw89/util.h
+++ b/drivers/net/wireless/realtek/rtw89/util.h
@@ -10,10 +10,28 @@
ieee80211_iterate_active_interfaces_atomic((rtwdev)->hw, \
IEEE80211_IFACE_ITER_NORMAL, iterator, data)
-/* call this function with rtwdev->mutex is held */
+/* call this function with wiphy mutex is held */
#define rtw89_for_each_rtwvif(rtwdev, rtwvif) \
list_for_each_entry(rtwvif, &(rtwdev)->rtwvifs_list, list)
+/* Before adding rtwvif to list, we need to check if it already exist, beacase
+ * in some case such as SER L2 happen during WoWLAN flow, calling reconfig
+ * twice cause the list to be added twice.
+ */
+static inline bool rtw89_rtwvif_in_list(struct rtw89_dev *rtwdev,
+ struct rtw89_vif *new)
+{
+ struct rtw89_vif *rtwvif;
+
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ rtw89_for_each_rtwvif(rtwdev, rtwvif)
+ if (rtwvif == new)
+ return true;
+
+ return false;
+}
+
/* The result of negative dividend and positive divisor is undefined, but it
* should be one case of round-down or round-up. So, make it round-down if the
* result is round-up.
@@ -55,4 +73,10 @@ static inline void ether_addr_copy_mask(u8 *dst, const u8 *src, u8 mask)
}
}
+s32 rtw89_linear_to_db_quarter(u64 val);
+s32 rtw89_linear_to_db(u64 val);
+u64 rtw89_db_quarter_to_linear(s32 db);
+u64 rtw89_db_to_linear(s32 db);
+void rtw89_might_trailing_ellipsis(char *buf, size_t size, ssize_t used);
+
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c
index ccad026defb5..34a0ab49bd7a 100644
--- a/drivers/net/wireless/realtek/rtw89/wow.c
+++ b/drivers/net/wireless/realtek/rtw89/wow.c
@@ -12,6 +12,678 @@
#include "util.h"
#include "wow.h"
+void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb)
+{
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ const u8 *rsn, *ies = mgmt->u.assoc_req.variable;
+ struct rtw89_rsn_ie *rsn_ie;
+
+ rsn = cfg80211_find_ie(WLAN_EID_RSN, ies, skb->len);
+ if (!rsn)
+ return;
+
+ rsn_ie = (struct rtw89_rsn_ie *)rsn;
+ rtw_wow->akm = rsn_ie->akm_cipher_suite.type;
+}
+
+#define RTW89_CIPHER_INFO_DEF(cipher) \
+ {WLAN_CIPHER_SUITE_ ## cipher, .fw_alg = RTW89_WOW_FW_ALG_ ## cipher, \
+ .len = WLAN_KEY_LEN_ ## cipher}
+
+static const struct rtw89_cipher_info rtw89_cipher_info_defs[] = {
+ RTW89_CIPHER_INFO_DEF(WEP40),
+ RTW89_CIPHER_INFO_DEF(WEP104),
+ RTW89_CIPHER_INFO_DEF(TKIP),
+ RTW89_CIPHER_INFO_DEF(CCMP),
+ RTW89_CIPHER_INFO_DEF(GCMP),
+ RTW89_CIPHER_INFO_DEF(CCMP_256),
+ RTW89_CIPHER_INFO_DEF(GCMP_256),
+ RTW89_CIPHER_INFO_DEF(AES_CMAC),
+};
+
+#undef RTW89_CIPHER_INFO_DEF
+
+static const
+struct rtw89_cipher_info *rtw89_cipher_alg_recognize(u32 cipher)
+{
+ const struct rtw89_cipher_info *cipher_info_defs;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(rtw89_cipher_info_defs); i++) {
+ cipher_info_defs = &rtw89_cipher_info_defs[i];
+ if (cipher_info_defs->cipher == cipher)
+ return cipher_info_defs;
+ }
+
+ return NULL;
+}
+
+static int _pn_to_iv(struct rtw89_dev *rtwdev, struct ieee80211_key_conf *key,
+ u8 *iv, u64 pn, u8 key_idx)
+{
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_TKIP:
+ iv[0] = u64_get_bits(pn, RTW89_KEY_PN_1);
+ iv[1] = (u64_get_bits(pn, RTW89_KEY_PN_1) | 0x20) & 0x7f;
+ iv[2] = u64_get_bits(pn, RTW89_KEY_PN_0);
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ case WLAN_CIPHER_SUITE_GCMP:
+ case WLAN_CIPHER_SUITE_CCMP_256:
+ case WLAN_CIPHER_SUITE_GCMP_256:
+ iv[0] = u64_get_bits(pn, RTW89_KEY_PN_0);
+ iv[1] = u64_get_bits(pn, RTW89_KEY_PN_1);
+ iv[2] = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ iv[3] = BIT(5) | ((key_idx & 0x3) << 6);
+ iv[4] = u64_get_bits(pn, RTW89_KEY_PN_2);
+ iv[5] = u64_get_bits(pn, RTW89_KEY_PN_3);
+ iv[6] = u64_get_bits(pn, RTW89_KEY_PN_4);
+ iv[7] = u64_get_bits(pn, RTW89_KEY_PN_5);
+
+ return 0;
+}
+
+static int rtw89_rx_pn_to_iv(struct rtw89_dev *rtwdev,
+ struct ieee80211_key_conf *key,
+ u8 *iv)
+{
+ struct ieee80211_key_seq seq;
+ int err;
+ u64 pn;
+
+ ieee80211_get_key_rx_seq(key, 0, &seq);
+
+ /* seq.ccmp.pn[] is BE order array */
+ pn = u64_encode_bits(seq.ccmp.pn[0], RTW89_KEY_PN_5) |
+ u64_encode_bits(seq.ccmp.pn[1], RTW89_KEY_PN_4) |
+ u64_encode_bits(seq.ccmp.pn[2], RTW89_KEY_PN_3) |
+ u64_encode_bits(seq.ccmp.pn[3], RTW89_KEY_PN_2) |
+ u64_encode_bits(seq.ccmp.pn[4], RTW89_KEY_PN_1) |
+ u64_encode_bits(seq.ccmp.pn[5], RTW89_KEY_PN_0);
+
+ err = _pn_to_iv(rtwdev, key, iv, pn, key->keyidx);
+ if (err)
+ return err;
+
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx to iv-%*ph\n",
+ __func__, key->keyidx, pn, 8, iv);
+
+ return 0;
+}
+
+static int rtw89_tx_pn_to_iv(struct rtw89_dev *rtwdev,
+ struct ieee80211_key_conf *key,
+ u8 *iv)
+{
+ int err;
+ u64 pn;
+
+ pn = atomic64_inc_return(&key->tx_pn);
+ err = _pn_to_iv(rtwdev, key, iv, pn, key->keyidx);
+ if (err)
+ return err;
+
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx to iv-%*ph\n",
+ __func__, key->keyidx, pn, 8, iv);
+
+ return 0;
+}
+
+static int _iv_to_pn(struct rtw89_dev *rtwdev, u8 *iv, u64 *pn, u8 *key_id,
+ struct ieee80211_key_conf *key)
+{
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_TKIP:
+ *pn = u64_encode_bits(iv[2], RTW89_KEY_PN_0) |
+ u64_encode_bits(iv[0], RTW89_KEY_PN_1);
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ case WLAN_CIPHER_SUITE_GCMP:
+ case WLAN_CIPHER_SUITE_CCMP_256:
+ case WLAN_CIPHER_SUITE_GCMP_256:
+ *pn = u64_encode_bits(iv[0], RTW89_KEY_PN_0) |
+ u64_encode_bits(iv[1], RTW89_KEY_PN_1);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ *pn |= u64_encode_bits(iv[4], RTW89_KEY_PN_2) |
+ u64_encode_bits(iv[5], RTW89_KEY_PN_3) |
+ u64_encode_bits(iv[6], RTW89_KEY_PN_4) |
+ u64_encode_bits(iv[7], RTW89_KEY_PN_5);
+
+ if (key_id)
+ *key_id = *(iv + 3) >> 6;
+
+ return 0;
+}
+
+static int rtw89_rx_iv_to_pn(struct rtw89_dev *rtwdev,
+ struct ieee80211_key_conf *key,
+ u8 *iv)
+{
+ struct ieee80211_key_seq seq;
+ int err;
+ u64 pn;
+
+ err = _iv_to_pn(rtwdev, iv, &pn, NULL, key);
+ if (err)
+ return err;
+
+ /* seq.ccmp.pn[] is BE order array */
+ seq.ccmp.pn[0] = u64_get_bits(pn, RTW89_KEY_PN_5);
+ seq.ccmp.pn[1] = u64_get_bits(pn, RTW89_KEY_PN_4);
+ seq.ccmp.pn[2] = u64_get_bits(pn, RTW89_KEY_PN_3);
+ seq.ccmp.pn[3] = u64_get_bits(pn, RTW89_KEY_PN_2);
+ seq.ccmp.pn[4] = u64_get_bits(pn, RTW89_KEY_PN_1);
+ seq.ccmp.pn[5] = u64_get_bits(pn, RTW89_KEY_PN_0);
+
+ ieee80211_set_key_rx_seq(key, 0, &seq);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d iv-%*ph to pn-%*ph\n",
+ __func__, key->keyidx, 8, iv, 6, seq.ccmp.pn);
+
+ return 0;
+}
+
+static int rtw89_tx_iv_to_pn(struct rtw89_dev *rtwdev,
+ struct ieee80211_key_conf *key,
+ u8 *iv)
+{
+ int err;
+ u64 pn;
+
+ err = _iv_to_pn(rtwdev, iv, &pn, NULL, key);
+ if (err)
+ return err;
+
+ atomic64_set(&key->tx_pn, pn);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d iv-%*ph to pn-%llx\n",
+ __func__, key->keyidx, 8, iv, pn);
+
+ return 0;
+}
+
+static int rtw89_rx_pn_get_pmf(struct rtw89_dev *rtwdev,
+ struct ieee80211_key_conf *key,
+ struct rtw89_wow_gtk_info *gtk_info)
+{
+ struct ieee80211_key_seq seq;
+ u64 pn;
+
+ if (key->keyidx == 4)
+ memcpy(gtk_info->igtk[0], key->key, key->keylen);
+ else if (key->keyidx == 5)
+ memcpy(gtk_info->igtk[1], key->key, key->keylen);
+ else
+ return -EINVAL;
+
+ ieee80211_get_key_rx_seq(key, 0, &seq);
+
+ /* seq.ccmp.pn[] is BE order array */
+ pn = u64_encode_bits(seq.ccmp.pn[0], RTW89_KEY_PN_5) |
+ u64_encode_bits(seq.ccmp.pn[1], RTW89_KEY_PN_4) |
+ u64_encode_bits(seq.ccmp.pn[2], RTW89_KEY_PN_3) |
+ u64_encode_bits(seq.ccmp.pn[3], RTW89_KEY_PN_2) |
+ u64_encode_bits(seq.ccmp.pn[4], RTW89_KEY_PN_1) |
+ u64_encode_bits(seq.ccmp.pn[5], RTW89_KEY_PN_0);
+ gtk_info->ipn = cpu_to_le64(pn);
+ gtk_info->igtk_keyid = cpu_to_le32(key->keyidx);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx\n",
+ __func__, key->keyidx, pn);
+
+ return 0;
+}
+
+static int rtw89_rx_pn_set_pmf(struct rtw89_dev *rtwdev,
+ struct ieee80211_key_conf *key,
+ u64 pn)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
+ struct ieee80211_key_seq seq;
+
+ if (key->keyidx != aoac_rpt->igtk_key_id)
+ return 0;
+
+ /* seq.ccmp.pn[] is BE order array */
+ seq.ccmp.pn[0] = u64_get_bits(pn, RTW89_KEY_PN_5);
+ seq.ccmp.pn[1] = u64_get_bits(pn, RTW89_KEY_PN_4);
+ seq.ccmp.pn[2] = u64_get_bits(pn, RTW89_KEY_PN_3);
+ seq.ccmp.pn[3] = u64_get_bits(pn, RTW89_KEY_PN_2);
+ seq.ccmp.pn[4] = u64_get_bits(pn, RTW89_KEY_PN_1);
+ seq.ccmp.pn[5] = u64_get_bits(pn, RTW89_KEY_PN_0);
+
+ ieee80211_set_key_rx_seq(key, 0, &seq);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%*ph\n",
+ __func__, key->keyidx, 6, seq.ccmp.pn);
+
+ return 0;
+}
+
+static void rtw89_wow_get_key_info_iter(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key,
+ void *data)
+{
+ struct rtw89_dev *rtwdev = hw->priv;
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_wow_key_info *key_info = &rtw_wow->key_info;
+ struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info;
+ const struct rtw89_cipher_info *cipher_info;
+ bool *err = data;
+ int ret;
+
+ cipher_info = rtw89_cipher_alg_recognize(key->cipher);
+
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_TKIP:
+ case WLAN_CIPHER_SUITE_CCMP:
+ case WLAN_CIPHER_SUITE_GCMP:
+ case WLAN_CIPHER_SUITE_CCMP_256:
+ case WLAN_CIPHER_SUITE_GCMP_256:
+ if (sta) {
+ ret = rtw89_tx_pn_to_iv(rtwdev, key,
+ key_info->ptk_tx_iv);
+ if (ret)
+ goto err;
+ ret = rtw89_rx_pn_to_iv(rtwdev, key,
+ key_info->ptk_rx_iv);
+ if (ret)
+ goto err;
+
+ rtw_wow->ptk_alg = cipher_info->fw_alg;
+ rtw_wow->ptk_keyidx = key->keyidx;
+ } else {
+ ret = rtw89_rx_pn_to_iv(rtwdev, key,
+ key_info->gtk_rx_iv[key->keyidx]);
+ if (ret)
+ goto err;
+
+ rtw_wow->gtk_alg = cipher_info->fw_alg;
+ key_info->gtk_keyidx = key->keyidx;
+ }
+ break;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ ret = rtw89_rx_pn_get_pmf(rtwdev, key, gtk_info);
+ if (ret)
+ goto err;
+ break;
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ /* WEP only set group key in mac80211, but fw need to set
+ * both of pairwise key and group key.
+ */
+ rtw_wow->ptk_alg = cipher_info->fw_alg;
+ rtw_wow->ptk_keyidx = key->keyidx;
+ rtw_wow->gtk_alg = cipher_info->fw_alg;
+ key_info->gtk_keyidx = key->keyidx;
+ break;
+ default:
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "unsupport cipher %x\n",
+ key->cipher);
+ goto err;
+ }
+
+ return;
+err:
+ *err = true;
+}
+
+static void rtw89_wow_set_key_info_iter(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key,
+ void *data)
+{
+ struct rtw89_dev *rtwdev = hw->priv;
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
+ struct rtw89_set_key_info_iter_data *iter_data = data;
+ bool update_tx_key_info = iter_data->rx_ready;
+ int ret;
+
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_TKIP:
+ case WLAN_CIPHER_SUITE_CCMP:
+ case WLAN_CIPHER_SUITE_GCMP:
+ case WLAN_CIPHER_SUITE_CCMP_256:
+ case WLAN_CIPHER_SUITE_GCMP_256:
+ if (sta && !update_tx_key_info) {
+ ret = rtw89_rx_iv_to_pn(rtwdev, key,
+ aoac_rpt->ptk_rx_iv);
+ if (ret)
+ goto err;
+ }
+
+ if (sta && update_tx_key_info) {
+ ret = rtw89_tx_iv_to_pn(rtwdev, key,
+ aoac_rpt->ptk_tx_iv);
+ if (ret)
+ goto err;
+ }
+
+ if (!sta && !update_tx_key_info) {
+ ret = rtw89_rx_iv_to_pn(rtwdev, key,
+ aoac_rpt->gtk_rx_iv[key->keyidx]);
+ if (ret)
+ goto err;
+ }
+
+ if (!sta && update_tx_key_info && aoac_rpt->rekey_ok)
+ iter_data->gtk_cipher = key->cipher;
+ break;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ if (update_tx_key_info) {
+ if (aoac_rpt->rekey_ok)
+ iter_data->igtk_cipher = key->cipher;
+ } else {
+ ret = rtw89_rx_pn_set_pmf(rtwdev, key,
+ aoac_rpt->igtk_ipn);
+ if (ret)
+ goto err;
+ }
+ break;
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ break;
+ default:
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "unsupport cipher %x\n",
+ key->cipher);
+ goto err;
+ }
+
+ return;
+
+err:
+ iter_data->error = true;
+}
+
+static void rtw89_wow_key_clear(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+
+ memset(&rtw_wow->aoac_rpt, 0, sizeof(rtw_wow->aoac_rpt));
+ memset(&rtw_wow->gtk_info, 0, sizeof(rtw_wow->gtk_info));
+ memset(&rtw_wow->key_info, 0, sizeof(rtw_wow->key_info));
+ rtw_wow->ptk_alg = 0;
+ rtw_wow->gtk_alg = 0;
+}
+
+static void rtw89_wow_construct_key_info(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_wow_key_info *key_info = &rtw_wow->key_info;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
+ struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
+ bool err = false;
+
+ rcu_read_lock();
+ ieee80211_iter_keys_rcu(rtwdev->hw, wow_vif,
+ rtw89_wow_get_key_info_iter, &err);
+ rcu_read_unlock();
+
+ if (err) {
+ rtw89_wow_key_clear(rtwdev);
+ return;
+ }
+
+ key_info->valid_check = RTW89_WOW_VALID_CHECK;
+ key_info->symbol_check_en = RTW89_WOW_SYMBOL_CHK_PTK |
+ RTW89_WOW_SYMBOL_CHK_GTK;
+}
+
+static void rtw89_wow_debug_aoac_rpt(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
+
+ if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_WOW))
+ return;
+
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] rpt_ver = %d\n",
+ aoac_rpt->rpt_ver);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] sec_type = %d\n",
+ aoac_rpt->sec_type);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] key_idx = %d\n",
+ aoac_rpt->key_idx);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] pattern_idx = %d\n",
+ aoac_rpt->pattern_idx);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] rekey_ok = %d\n",
+ aoac_rpt->rekey_ok);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] ptk_tx_iv = %*ph\n",
+ 8, aoac_rpt->ptk_tx_iv);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW,
+ "[aoac_rpt] eapol_key_replay_count = %*ph\n",
+ 8, aoac_rpt->eapol_key_replay_count);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] ptk_rx_iv = %*ph\n",
+ 8, aoac_rpt->ptk_rx_iv);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[0] = %*ph\n",
+ 8, aoac_rpt->gtk_rx_iv[0]);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[1] = %*ph\n",
+ 8, aoac_rpt->gtk_rx_iv[1]);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[2] = %*ph\n",
+ 8, aoac_rpt->gtk_rx_iv[2]);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[3] = %*ph\n",
+ 8, aoac_rpt->gtk_rx_iv[3]);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] igtk_key_id = %llu\n",
+ aoac_rpt->igtk_key_id);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] igtk_ipn = %llu\n",
+ aoac_rpt->igtk_ipn);
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] igtk = %*ph\n",
+ 32, aoac_rpt->igtk);
+}
+
+static int rtw89_wow_get_aoac_rpt_reg(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
+ struct rtw89_mac_c2h_info c2h_info = {};
+ struct rtw89_mac_h2c_info h2c_info = {};
+ u8 igtk_ipn[8];
+ u8 key_idx;
+ int ret;
+
+ h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_1;
+ h2c_info.content_len = 2;
+ ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info);
+ if (ret)
+ return ret;
+
+ aoac_rpt->key_idx =
+ u32_get_bits(c2h_info.u.c2hreg[0], RTW89_C2HREG_AOAC_RPT_1_W0_KEY_IDX);
+ key_idx = aoac_rpt->key_idx;
+ aoac_rpt->gtk_rx_iv[key_idx][0] =
+ u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_0);
+ aoac_rpt->gtk_rx_iv[key_idx][1] =
+ u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_1);
+ aoac_rpt->gtk_rx_iv[key_idx][2] =
+ u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_2);
+ aoac_rpt->gtk_rx_iv[key_idx][3] =
+ u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_3);
+ aoac_rpt->gtk_rx_iv[key_idx][4] =
+ u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_4);
+ aoac_rpt->gtk_rx_iv[key_idx][5] =
+ u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_5);
+ aoac_rpt->gtk_rx_iv[key_idx][6] =
+ u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_6);
+ aoac_rpt->gtk_rx_iv[key_idx][7] =
+ u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_7);
+ aoac_rpt->ptk_rx_iv[0] =
+ u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_0);
+ aoac_rpt->ptk_rx_iv[1] =
+ u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_1);
+ aoac_rpt->ptk_rx_iv[2] =
+ u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_2);
+ aoac_rpt->ptk_rx_iv[3] =
+ u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_3);
+
+ h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_2;
+ h2c_info.content_len = 2;
+ ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info);
+ if (ret)
+ return ret;
+
+ aoac_rpt->ptk_rx_iv[4] =
+ u32_get_bits(c2h_info.u.c2hreg[0], RTW89_C2HREG_AOAC_RPT_2_W0_PTK_IV_4);
+ aoac_rpt->ptk_rx_iv[5] =
+ u32_get_bits(c2h_info.u.c2hreg[0], RTW89_C2HREG_AOAC_RPT_2_W0_PTK_IV_5);
+ aoac_rpt->ptk_rx_iv[6] =
+ u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_PTK_IV_6);
+ aoac_rpt->ptk_rx_iv[7] =
+ u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_PTK_IV_7);
+ igtk_ipn[0] =
+ u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_IGTK_IPN_IV_0);
+ igtk_ipn[1] =
+ u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_IGTK_IPN_IV_1);
+ igtk_ipn[2] =
+ u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_2);
+ igtk_ipn[3] =
+ u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_3);
+ igtk_ipn[4] =
+ u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_4);
+ igtk_ipn[5] =
+ u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_5);
+ igtk_ipn[6] =
+ u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_6);
+ igtk_ipn[7] =
+ u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_7);
+ aoac_rpt->igtk_ipn = u64_encode_bits(igtk_ipn[0], RTW89_IGTK_IPN_0) |
+ u64_encode_bits(igtk_ipn[1], RTW89_IGTK_IPN_1) |
+ u64_encode_bits(igtk_ipn[2], RTW89_IGTK_IPN_2) |
+ u64_encode_bits(igtk_ipn[3], RTW89_IGTK_IPN_3) |
+ u64_encode_bits(igtk_ipn[4], RTW89_IGTK_IPN_4) |
+ u64_encode_bits(igtk_ipn[5], RTW89_IGTK_IPN_5) |
+ u64_encode_bits(igtk_ipn[6], RTW89_IGTK_IPN_6) |
+ u64_encode_bits(igtk_ipn[7], RTW89_IGTK_IPN_7);
+
+ return 0;
+}
+
+static int rtw89_wow_get_aoac_rpt(struct rtw89_dev *rtwdev, bool rx_ready)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ int ret;
+
+ if (!rtw_wow->ptk_alg)
+ return -EPERM;
+
+ if (!rx_ready) {
+ ret = rtw89_wow_get_aoac_rpt_reg(rtwdev);
+ if (ret) {
+ rtw89_err(rtwdev, "wow: failed to get aoac rpt by reg\n");
+ return ret;
+ }
+ } else {
+ ret = rtw89_fw_h2c_wow_request_aoac(rtwdev);
+ if (ret) {
+ rtw89_err(rtwdev, "wow: failed to get aoac rpt by pkt\n");
+ return ret;
+ }
+ }
+
+ rtw89_wow_debug_aoac_rpt(rtwdev);
+
+ return 0;
+}
+
+static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev,
+ u32 cipher, u8 keyidx, u8 *gtk)
+{
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
+ struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
+ const struct rtw89_cipher_info *cipher_info;
+ struct ieee80211_key_conf *rekey_conf;
+ struct ieee80211_key_conf *key;
+ u8 sz;
+
+ lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+ cipher_info = rtw89_cipher_alg_recognize(cipher);
+ sz = struct_size(rekey_conf, key, cipher_info->len);
+ rekey_conf = kmalloc(sz, GFP_KERNEL);
+ if (!rekey_conf)
+ return NULL;
+
+ rekey_conf->cipher = cipher;
+ rekey_conf->keyidx = keyidx;
+ rekey_conf->keylen = cipher_info->len;
+ memcpy(rekey_conf->key, gtk,
+ flex_array_size(rekey_conf, key, cipher_info->len));
+
+ if (ieee80211_vif_is_mld(wow_vif))
+ key = ieee80211_gtk_rekey_add(wow_vif, rekey_conf, rtwvif_link->link_id);
+ else
+ key = ieee80211_gtk_rekey_add(wow_vif, rekey_conf, -1);
+
+ kfree(rekey_conf);
+ if (IS_ERR(key)) {
+ rtw89_err(rtwdev, "ieee80211_gtk_rekey_add failed\n");
+ return NULL;
+ }
+
+ return key;
+}
+
+static void rtw89_wow_update_key_info(struct rtw89_dev *rtwdev, bool rx_ready)
+{
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
+ struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
+ struct rtw89_set_key_info_iter_data data = {.error = false,
+ .rx_ready = rx_ready};
+ struct ieee80211_bss_conf *bss_conf;
+ struct ieee80211_key_conf *key;
+
+ rcu_read_lock();
+ ieee80211_iter_keys_rcu(rtwdev->hw, wow_vif,
+ rtw89_wow_set_key_info_iter, &data);
+ rcu_read_unlock();
+
+ if (data.error) {
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s error\n", __func__);
+ return;
+ }
+
+ if (!data.gtk_cipher)
+ return;
+
+ key = rtw89_wow_gtk_rekey(rtwdev, data.gtk_cipher, aoac_rpt->key_idx,
+ aoac_rpt->gtk);
+ if (!key)
+ return;
+
+ rtw89_rx_iv_to_pn(rtwdev, key,
+ aoac_rpt->gtk_rx_iv[key->keyidx]);
+
+ if (!data.igtk_cipher)
+ return;
+
+ key = rtw89_wow_gtk_rekey(rtwdev, data.igtk_cipher, aoac_rpt->igtk_key_id,
+ aoac_rpt->igtk);
+ if (!key)
+ return;
+
+ rtw89_rx_pn_set_pmf(rtwdev, key, aoac_rpt->igtk_ipn);
+
+ rcu_read_lock();
+
+ bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+ ieee80211_gtk_rekey_notify(wow_vif, bss_conf->bssid,
+ aoac_rpt->eapol_key_replay_count,
+ GFP_ATOMIC);
+
+ rcu_read_unlock();
+}
+
static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev)
{
__rtw89_leave_ps_mode(rtwdev);
@@ -19,23 +691,31 @@ static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev)
static void rtw89_wow_enter_deep_ps(struct rtw89_dev *rtwdev)
{
- struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
-
- __rtw89_enter_ps_mode(rtwdev, rtwvif);
+ __rtw89_enter_ps_mode(rtwdev);
}
-static void rtw89_wow_enter_lps(struct rtw89_dev *rtwdev)
+static void rtw89_wow_enter_ps(struct rtw89_dev *rtwdev)
{
- struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
- rtw89_enter_lps(rtwdev, rtwvif, false);
+ if (rtw89_wow_mgd_linked(rtwdev))
+ rtw89_enter_lps(rtwdev, rtwvif_link->rtwvif, false);
+ else if (rtw89_wow_no_link(rtwdev))
+ rtw89_fw_h2c_fwips(rtwdev, rtwvif_link, true);
}
-static void rtw89_wow_leave_lps(struct rtw89_dev *rtwdev)
+static void rtw89_wow_leave_ps(struct rtw89_dev *rtwdev, bool enable_wow)
{
- rtw89_leave_lps(rtwdev);
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
+
+ if (rtw89_wow_mgd_linked(rtwdev)) {
+ rtw89_leave_lps(rtwdev);
+ } else if (rtw89_wow_no_link(rtwdev)) {
+ if (enable_wow)
+ rtw89_leave_ips(rtwdev);
+ else
+ rtw89_fw_h2c_fwips(rtwdev, rtwvif_link, false);
+ }
}
static int rtw89_wow_config_mac(struct rtw89_dev *rtwdev, bool enable_wow)
@@ -59,13 +739,22 @@ static void rtw89_wow_set_rx_filter(struct rtw89_dev *rtwdev, bool enable)
static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev)
{
- u32 wow_reason_reg = rtwdev->chip->wow_reason_reg;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
+ struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
struct cfg80211_wowlan_nd_info nd_info;
struct cfg80211_wowlan_wakeup wakeup = {
.pattern_idx = -1,
};
+ u32 wow_reason_reg;
u8 reason;
+ if (RTW89_CHK_FW_FEATURE(WOW_REASON_V1, &rtwdev->fw))
+ wow_reason_reg = rtwdev->chip->wow_reason_reg[RTW89_WOW_REASON_V1];
+ else
+ wow_reason_reg = rtwdev->chip->wow_reason_reg[RTW89_WOW_REASON_V0];
+
reason = rtw89_read8(rtwdev, wow_reason_reg);
switch (reason) {
case RTW89_WOW_RSN_RX_DEAUTH:
@@ -85,10 +774,7 @@ static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx gtk rekey\n");
break;
case RTW89_WOW_RSN_RX_PATTERN_MATCH:
- /* Current firmware and driver don't report pattern index
- * Use pattern_idx to 0 defaultly.
- */
- wakeup.pattern_idx = 0;
+ wakeup.pattern_idx = aoac_rpt->pattern_idx;
rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx pattern match packet\n");
break;
case RTW89_WOW_RSN_RX_NLO:
@@ -101,31 +787,35 @@ static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev)
break;
default:
rtw89_warn(rtwdev, "Unknown wakeup reason %x\n", reason);
- ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, NULL,
- GFP_KERNEL);
+ ieee80211_report_wowlan_wakeup(wow_vif, NULL, GFP_KERNEL);
return;
}
- ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, &wakeup,
- GFP_KERNEL);
+ ieee80211_report_wowlan_wakeup(wow_vif, &wakeup, GFP_KERNEL);
}
-static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
+static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
- /* Current wowlan function support setting of only one STATION vif.
- * So when one suitable vif is found, stop the iteration.
+ /* Current WoWLAN function support setting of only vif in
+ * infra mode or no link mode. When one suitable vif is found,
+ * stop the iteration.
*/
- if (rtw_wow->wow_vif || vif->type != NL80211_IFTYPE_STATION)
+ if (rtw_wow->rtwvif_link || vif->type != NL80211_IFTYPE_STATION)
return;
- switch (rtwvif->net_type) {
+ switch (rtwvif_link->net_type) {
case RTW89_NET_TYPE_INFRA:
- rtw_wow->wow_vif = vif;
+ if (rtw_wow_has_mgd_features(rtwdev))
+ rtw_wow->rtwvif_link = rtwvif_link;
break;
case RTW89_NET_TYPE_NO_LINK:
+ if (rtw_wow->pno_inited)
+ rtw_wow->rtwvif_link = rtwvif_link;
+ break;
default:
break;
}
@@ -181,7 +871,7 @@ static u16 rtw89_calc_crc(u8 *pdata, int length)
return ~crc;
}
-static int rtw89_wow_pattern_get_type(struct rtw89_vif *rtwvif,
+static int rtw89_wow_pattern_get_type(struct rtw89_vif_link *rtwvif_link,
struct rtw89_wow_cam_info *rtw_pattern,
const u8 *pattern, u8 da_mask)
{
@@ -201,7 +891,7 @@ static int rtw89_wow_pattern_get_type(struct rtw89_vif *rtwvif,
rtw_pattern->bc = true;
else if (is_multicast_ether_addr(da))
rtw_pattern->mc = true;
- else if (ether_addr_equal(da, rtwvif->mac_addr) &&
+ else if (ether_addr_equal(da, rtwvif_link->mac_addr) &&
da_mask == GENMASK(5, 0))
rtw_pattern->uc = true;
else if (!da_mask) /*da_mask == 0 mean wildcard*/
@@ -213,7 +903,7 @@ static int rtw89_wow_pattern_get_type(struct rtw89_vif *rtwvif,
}
static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
const struct cfg80211_pkt_pattern *pkt_pattern,
struct rtw89_wow_cam_info *rtw_pattern)
{
@@ -232,7 +922,7 @@ static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev,
mask_len = DIV_ROUND_UP(len, 8);
memset(rtw_pattern, 0, sizeof(*rtw_pattern));
- ret = rtw89_wow_pattern_get_type(rtwvif, rtw_pattern, pattern,
+ ret = rtw89_wow_pattern_get_type(rtwvif_link, rtw_pattern, pattern,
mask[0] & GENMASK(5, 0));
if (ret)
return ret;
@@ -286,7 +976,7 @@ static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev,
}
static int rtw89_wow_parse_patterns(struct rtw89_dev *rtwdev,
- struct rtw89_vif *rtwvif,
+ struct rtw89_vif_link *rtwvif_link,
struct cfg80211_wowlan *wowlan)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
@@ -299,7 +989,7 @@ static int rtw89_wow_parse_patterns(struct rtw89_dev *rtwdev,
for (i = 0; i < wowlan->n_patterns; i++) {
rtw_pattern = &rtw_wow->patterns[i];
- ret = rtw89_wow_pattern_generate(rtwdev, rtwvif,
+ ret = rtw89_wow_pattern_generate(rtwdev, rtwvif_link,
&wowlan->patterns[i],
rtw_pattern);
if (ret) {
@@ -356,63 +1046,122 @@ static void rtw89_wow_clear_wakeups(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- rtw_wow->wow_vif = NULL;
+ rtw_wow->rtwvif_link = NULL;
rtw89_core_release_all_bits_map(rtw_wow->flags, RTW89_WOW_FLAG_NUM);
rtw_wow->pattern_cnt = 0;
+ rtw_wow->pno_inited = false;
+}
+
+static void rtw89_wow_init_pno(struct rtw89_dev *rtwdev,
+ struct cfg80211_sched_scan_request *nd_config)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+
+ if (!nd_config->n_match_sets || !nd_config->n_channels)
+ return;
+
+ rtw_wow->nd_config = nd_config;
+ rtw_wow->pno_inited = true;
+
+ INIT_LIST_HEAD(&rtw_wow->pno_pkt_list);
+
+ rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: net-detect is enabled\n");
}
static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev,
struct cfg80211_wowlan *wowlan)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
if (wowlan->disconnect)
set_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags);
if (wowlan->magic_pkt)
set_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags);
+ if (wowlan->n_patterns && wowlan->patterns)
+ set_bit(RTW89_WOW_FLAG_EN_PATTERN, rtw_wow->flags);
- rtw89_for_each_rtwvif(rtwdev, rtwvif)
- rtw89_wow_vif_iter(rtwdev, rtwvif);
+ if (wowlan->nd_config)
+ rtw89_wow_init_pno(rtwdev, wowlan->nd_config);
- if (!rtw_wow->wow_vif)
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+ rtwvif_link = rtw89_get_designated_link(rtwvif);
+ if (!rtwvif_link)
+ continue;
+
+ rtw89_wow_vif_iter(rtwdev, rtwvif_link);
+ }
+
+ rtwvif_link = rtw_wow->rtwvif_link;
+ if (!rtwvif_link)
return -EPERM;
- rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv;
- return rtw89_wow_parse_patterns(rtwdev, rtwvif, wowlan);
+ return rtw89_wow_parse_patterns(rtwdev, rtwvif_link, wowlan);
+}
+
+static int rtw89_wow_cfg_wake_pno(struct rtw89_dev *rtwdev, bool wow)
+{
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
+ int ret;
+
+ ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif_link, true);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to config pno\n");
+ return ret;
+ }
+
+ ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif_link, wow);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n");
+ return ret;
+ }
+
+ ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif_link, wow);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to fw wow global\n");
+ return ret;
+ }
+
+ return 0;
}
static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link;
+ struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
struct ieee80211_sta *wow_sta;
- struct rtw89_sta *rtwsta = NULL;
+ struct rtw89_sta_link *rtwsta_link = NULL;
+ struct rtw89_sta *rtwsta;
int ret;
- wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid);
- if (wow_sta)
- rtwsta = (struct rtw89_sta *)wow_sta->drv_priv;
+ wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr);
+ if (wow_sta) {
+ rtwsta = sta_to_rtwsta(wow_sta);
+ rtwsta_link = rtwsta->links[rtwvif_link->link_id];
+ if (!rtwsta_link)
+ return -ENOLINK;
+ }
if (wow) {
if (rtw_wow->pattern_cnt)
- rtwvif->wowlan_pattern = true;
+ rtwvif_link->wowlan_pattern = true;
if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags))
- rtwvif->wowlan_magic = true;
+ rtwvif_link->wowlan_magic = true;
} else {
- rtwvif->wowlan_pattern = false;
- rtwvif->wowlan_magic = false;
+ rtwvif_link->wowlan_pattern = false;
+ rtwvif_link->wowlan_magic = false;
}
- ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif, wow);
+ ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif_link, wow);
if (ret) {
rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n");
return ret;
}
if (wow) {
- ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
+ ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link);
if (ret) {
rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n",
ret);
@@ -420,13 +1169,13 @@ static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow)
}
}
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cam\n");
return ret;
}
- ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif, wow);
+ ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif_link, wow);
if (ret) {
rtw89_err(rtwdev, "failed to fw wow global\n");
return ret;
@@ -454,23 +1203,35 @@ static int rtw89_wow_check_fw_status(struct rtw89_dev *rtwdev, bool wow_enable)
static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
{
enum rtw89_fw_type fw_type = wow ? RTW89_FW_WOWLAN : RTW89_FW_NORMAL;
+ enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link;
+ struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
+ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
const struct rtw89_chip_info *chip = rtwdev->chip;
bool include_bb = !!chip->bbmcu_nr;
+ bool disable_intr_for_dlfw = false;
struct ieee80211_sta *wow_sta;
- struct rtw89_sta *rtwsta = NULL;
+ struct rtw89_sta_link *rtwsta_link = NULL;
+ struct rtw89_sta *rtwsta;
bool is_conn = true;
int ret;
- rtw89_hci_disable_intr(rtwdev);
+ if (chip_id == RTL8852C || chip_id == RTL8922A)
+ disable_intr_for_dlfw = true;
- wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid);
- if (wow_sta)
- rtwsta = (struct rtw89_sta *)wow_sta->drv_priv;
- else
+ wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr);
+ if (wow_sta) {
+ rtwsta = sta_to_rtwsta(wow_sta);
+ rtwsta_link = rtwsta->links[rtwvif_link->link_id];
+ if (!rtwsta_link)
+ return -ENOLINK;
+ } else {
is_conn = false;
+ }
+
+ if (disable_intr_for_dlfw)
+ rtw89_hci_disable_intr(rtwdev);
ret = rtw89_fw_download(rtwdev, fw_type, include_bb);
if (ret) {
@@ -478,16 +1239,19 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
return ret;
}
+ if (disable_intr_for_dlfw)
+ rtw89_hci_enable_intr(rtwdev);
+
rtw89_phy_init_rf_reg(rtwdev, true);
- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta,
+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link,
RTW89_ROLE_FW_RESTORE);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c role maintain\n");
return ret;
}
- ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, wow_vif, wow_sta);
+ ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c assoc cmac tbl\n");
return ret;
@@ -496,31 +1260,33 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
if (!is_conn)
rtw89_cam_reset_keys(rtwdev);
- ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, !is_conn);
+ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta_link, !is_conn);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c join info\n");
return ret;
}
- ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cam\n");
return ret;
}
if (is_conn) {
- ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id);
+ ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta_link->mac_id);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c general packet\n");
return ret;
}
- rtw89_phy_ra_assoc(rtwdev, wow_sta);
- rtw89_phy_set_bss_color(rtwdev, wow_vif);
- rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, wow_vif);
+ rtw89_phy_ra_assoc(rtwdev, rtwsta_link);
+ rtw89_phy_set_bss_color(rtwdev, rtwvif_link);
+ rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, rtwvif_link);
}
+ if (chip_gen == RTW89_CHIP_BE)
+ rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, RTW89_PHY_0, 5);
+
rtw89_mac_hw_mgnt_sec(rtwdev, wow);
- rtw89_hci_enable_intr(rtwdev);
return 0;
}
@@ -595,94 +1361,270 @@ static int rtw89_wow_disable_trx_pre(struct rtw89_dev *rtwdev)
rtw89_err(rtwdev, "failed to config mac\n");
return ret;
}
+
+ /* Before enabling interrupt, we need to get AOAC report by reg due to RX
+ * not enabled yet. Also, we need to sync RX related IV from firmware to
+ * mac80211 before receiving RX packets from driver.
+ * After enabling interrupt, we can get AOAC report from h2c and c2h, and
+ * can get TX IV and complete rekey info. We need to update TX related IV
+ * and new GTK info if rekey happened.
+ */
+ ret = rtw89_wow_get_aoac_rpt(rtwdev, false);
+ if (!ret)
+ rtw89_wow_update_key_info(rtwdev, false);
+
rtw89_hci_enable_intr(rtwdev);
+ ret = rtw89_wow_get_aoac_rpt(rtwdev, true);
+ if (!ret)
+ rtw89_wow_update_key_info(rtwdev, true);
return 0;
}
static int rtw89_wow_disable_trx_post(struct rtw89_dev *rtwdev)
{
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
int ret;
ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true);
if (ret)
rtw89_err(rtwdev, "cfg ppdu status\n");
+ rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
+
return ret;
}
-static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev)
+static void rtw89_fw_release_pno_pkt_list(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv;
+ struct list_head *pkt_list = &rtw_wow->pno_pkt_list;
+ struct rtw89_pktofld_info *info, *tmp;
+
+ list_for_each_entry_safe(info, tmp, pkt_list, list) {
+ rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id);
+ list_del(&info->list);
+ kfree(info);
+ }
+}
+
+static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config;
+ u8 num = nd_config->n_match_sets, i;
+ struct rtw89_pktofld_info *info;
+ struct sk_buff *skb;
int ret;
- rtw89_wow_pattern_write(rtwdev);
+ for (i = 0; i < num; i++) {
+ skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr,
+ nd_config->match_sets[i].ssid.ssid,
+ nd_config->match_sets[i].ssid.ssid_len,
+ nd_config->ie_len);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_put_data(skb, nd_config->ie, nd_config->ie_len);
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info) {
+ kfree_skb(skb);
+ rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link);
+ return -ENOMEM;
+ }
- ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, true);
- if (ret) {
- rtw89_err(rtwdev, "wow: failed to enable keep alive\n");
- return ret;
+ ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb);
+ if (ret) {
+ kfree_skb(skb);
+ kfree(info);
+ rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link);
+ return ret;
+ }
+
+ list_add_tail(&info->list, &rtw_wow->pno_pkt_list);
+ kfree_skb(skb);
}
- ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, true);
- if (ret) {
- rtw89_err(rtwdev, "wow: failed to enable disconnect detect\n");
- goto out;
+ return 0;
+}
+
+static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
+ int interval = rtw_wow->nd_config->scan_plans[0].interval;
+ struct rtw89_scan_option opt = {};
+ int ret;
+
+ if (enable) {
+ ret = rtw89_pno_scan_update_probe_req(rtwdev, rtwvif_link);
+ if (ret) {
+ rtw89_err(rtwdev, "Update probe request failed\n");
+ return ret;
+ }
+
+ ret = mac->add_chan_list_pno(rtwdev, rtwvif_link);
+ if (ret) {
+ rtw89_err(rtwdev, "Update channel list failed\n");
+ return ret;
+ }
}
- ret = rtw89_wow_cfg_wake(rtwdev, true);
- if (ret) {
- rtw89_err(rtwdev, "wow: failed to config wake\n");
- goto out;
+ opt.enable = enable;
+ opt.repeat = RTW89_SCAN_NORMAL;
+ opt.norm_pd = max(interval, 1) * 10; /* in unit of 100ms */
+ opt.delay = max(rtw_wow->nd_config->delay, 1);
+
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
+ opt.operation = enable ? RTW89_SCAN_OP_START : RTW89_SCAN_OP_STOP;
+ opt.scan_mode = RTW89_SCAN_MODE_SA;
+ opt.band = RTW89_PHY_0;
+ opt.num_macc_role = 0;
+ opt.mlo_mode = rtwdev->mlo_dbcc_mode;
+ opt.num_opch = 0;
+ opt.opch_end = RTW89_CHAN_INVALID;
+ }
+
+ mac->scan_offload(rtwdev, &opt, rtwvif_link, true);
+
+ return 0;
+}
+
+static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link;
+ int ret;
+
+ if (rtw89_wow_no_link(rtwdev)) {
+ ret = rtw89_pno_scan_offload(rtwdev, false);
+ if (ret) {
+ rtw89_err(rtwdev, "wow: failed to disable pno scan offload\n");
+ return ret;
+ }
+
+ ret = rtw89_pno_scan_offload(rtwdev, true);
+ if (ret) {
+ rtw89_err(rtwdev, "wow: failed to enable pno scan offload\n");
+ return ret;
+ }
+ } else {
+ rtw89_wow_pattern_write(rtwdev);
+ rtw89_wow_construct_key_info(rtwdev);
+
+ ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif_link, true);
+ if (ret) {
+ rtw89_err(rtwdev, "wow: failed to enable keep alive\n");
+ return ret;
+ }
+
+ ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif_link, true);
+ if (ret) {
+ rtw89_err(rtwdev, "wow: failed to enable disconnect detect\n");
+ return ret;
+ }
+
+ ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif_link, true);
+ if (ret) {
+ rtw89_err(rtwdev, "wow: failed to enable GTK offload\n");
+ return ret;
+ }
+
+ ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif_link, true);
+ if (ret)
+ rtw89_warn(rtwdev, "wow: failed to enable arp offload\n");
+ }
+
+ if (rtw89_wow_no_link(rtwdev)) {
+ ret = rtw89_wow_cfg_wake_pno(rtwdev, true);
+ if (ret) {
+ rtw89_err(rtwdev, "wow: failed to config wake PNO\n");
+ return ret;
+ }
+ } else {
+ ret = rtw89_wow_cfg_wake(rtwdev, true);
+ if (ret) {
+ rtw89_err(rtwdev, "wow: failed to config wake\n");
+ return ret;
+ }
}
ret = rtw89_wow_check_fw_status(rtwdev, true);
if (ret) {
rtw89_err(rtwdev, "wow: failed to check enable fw ready\n");
- goto out;
+ return ret;
}
-out:
- return ret;
+ return 0;
}
static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
- struct rtw89_vif *rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv;
+ struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link;
int ret;
- rtw89_wow_pattern_clear(rtwdev);
+ if (rtw89_wow_no_link(rtwdev)) {
+ ret = rtw89_pno_scan_offload(rtwdev, false);
+ if (ret) {
+ rtw89_err(rtwdev, "wow: failed to disable pno scan offload\n");
+ return ret;
+ }
- ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, false);
- if (ret) {
- rtw89_err(rtwdev, "wow: failed to disable keep alive\n");
- goto out;
- }
+ ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif_link, false);
+ if (ret) {
+ rtw89_err(rtwdev, "wow: failed to disable pno\n");
+ return ret;
+ }
- ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, false);
- if (ret) {
- rtw89_err(rtwdev, "wow: failed to disable disconnect detect\n");
- goto out;
+ rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link);
+ } else {
+ rtw89_wow_pattern_clear(rtwdev);
+
+ ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif_link, false);
+ if (ret) {
+ rtw89_err(rtwdev, "wow: failed to disable keep alive\n");
+ return ret;
+ }
+
+ ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif_link, false);
+ if (ret) {
+ rtw89_err(rtwdev, "wow: failed to disable disconnect detect\n");
+ return ret;
+ }
+
+ ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif_link, false);
+ if (ret) {
+ rtw89_err(rtwdev, "wow: failed to disable GTK offload\n");
+ return ret;
+ }
+
+ ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif_link, false);
+ if (ret)
+ rtw89_warn(rtwdev, "wow: failed to disable arp offload\n");
+
+ rtw89_wow_key_clear(rtwdev);
+ rtw89_fw_release_general_pkt_list(rtwdev, true);
}
- rtw89_fw_release_general_pkt_list(rtwdev, true);
ret = rtw89_wow_cfg_wake(rtwdev, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable config wake\n");
- goto out;
+ return ret;
}
ret = rtw89_wow_check_fw_status(rtwdev, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to check disable fw ready\n");
- goto out;
+ return ret;
}
-out:
- return ret;
+ return 0;
}
static int rtw89_wow_enable(struct rtw89_dev *rtwdev)
@@ -711,7 +1653,7 @@ static int rtw89_wow_enable(struct rtw89_dev *rtwdev)
goto out;
}
- rtw89_wow_enter_lps(rtwdev);
+ rtw89_wow_enter_ps(rtwdev);
ret = rtw89_wow_enable_trx_post(rtwdev);
if (ret) {
@@ -736,7 +1678,7 @@ static int rtw89_wow_disable(struct rtw89_dev *rtwdev)
goto out;
}
- rtw89_wow_leave_lps(rtwdev);
+ rtw89_wow_leave_ps(rtwdev, false);
ret = rtw89_wow_fw_stop(rtwdev);
if (ret) {
@@ -761,6 +1703,12 @@ out:
return ret;
}
+static void rtw89_wow_restore_ps(struct rtw89_dev *rtwdev)
+{
+ if (rtw89_wow_no_link(rtwdev))
+ rtw89_enter_ips(rtwdev);
+}
+
int rtw89_wow_resume(struct rtw89_dev *rtwdev)
{
int ret;
@@ -785,6 +1733,7 @@ int rtw89_wow_resume(struct rtw89_dev *rtwdev)
if (ret)
rtw89_err(rtwdev, "failed to disable wow\n");
+ rtw89_wow_restore_ps(rtwdev);
out:
rtw89_wow_clear_wakeups(rtwdev);
return ret;
@@ -800,7 +1749,7 @@ int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan)
return ret;
}
- rtw89_wow_leave_lps(rtwdev);
+ rtw89_wow_leave_ps(rtwdev, true);
ret = rtw89_wow_enable(rtwdev);
if (ret) {
diff --git a/drivers/net/wireless/realtek/rtw89/wow.h b/drivers/net/wireless/realtek/rtw89/wow.h
index a2f7b2e3cdb4..f91991e8f2e3 100644
--- a/drivers/net/wireless/realtek/rtw89/wow.h
+++ b/drivers/net/wireless/realtek/rtw89/wow.h
@@ -5,6 +5,26 @@
#ifndef __RTW89_WOW_H__
#define __RTW89_WOW_H__
+#define RTW89_KEY_PN_0 GENMASK_ULL(7, 0)
+#define RTW89_KEY_PN_1 GENMASK_ULL(15, 8)
+#define RTW89_KEY_PN_2 GENMASK_ULL(23, 16)
+#define RTW89_KEY_PN_3 GENMASK_ULL(31, 24)
+#define RTW89_KEY_PN_4 GENMASK_ULL(39, 32)
+#define RTW89_KEY_PN_5 GENMASK_ULL(47, 40)
+
+#define RTW89_IGTK_IPN_0 GENMASK_ULL(7, 0)
+#define RTW89_IGTK_IPN_1 GENMASK_ULL(15, 8)
+#define RTW89_IGTK_IPN_2 GENMASK_ULL(23, 16)
+#define RTW89_IGTK_IPN_3 GENMASK_ULL(31, 24)
+#define RTW89_IGTK_IPN_4 GENMASK_ULL(39, 32)
+#define RTW89_IGTK_IPN_5 GENMASK_ULL(47, 40)
+#define RTW89_IGTK_IPN_6 GENMASK_ULL(55, 48)
+#define RTW89_IGTK_IPN_7 GENMASK_ULL(63, 56)
+
+#define RTW89_WOW_VALID_CHECK 0xDD
+#define RTW89_WOW_SYMBOL_CHK_PTK BIT(0)
+#define RTW89_WOW_SYMBOL_CHK_GTK BIT(1)
+
enum rtw89_wake_reason {
RTW89_WOW_RSN_RX_PTK_REKEY = 0x1,
RTW89_WOW_RSN_RX_GTK_REKEY = 0x2,
@@ -15,7 +35,95 @@ enum rtw89_wake_reason {
RTW89_WOW_RSN_RX_NLO = 0x55,
};
+enum rtw89_fw_alg {
+ RTW89_WOW_FW_ALG_WEP40 = 0x1,
+ RTW89_WOW_FW_ALG_WEP104 = 0x2,
+ RTW89_WOW_FW_ALG_TKIP = 0x3,
+ RTW89_WOW_FW_ALG_CCMP = 0x6,
+ RTW89_WOW_FW_ALG_CCMP_256 = 0x7,
+ RTW89_WOW_FW_ALG_GCMP = 0x8,
+ RTW89_WOW_FW_ALG_GCMP_256 = 0x9,
+ RTW89_WOW_FW_ALG_AES_CMAC = 0xa,
+};
+
+struct rtw89_cipher_suite {
+ u8 oui[3];
+ u8 type;
+} __packed;
+
+struct rtw89_rsn_ie {
+ u8 tag_number;
+ u8 tag_length;
+ __le16 rsn_version;
+ struct rtw89_cipher_suite group_cipher_suite;
+ __le16 pairwise_cipher_suite_cnt;
+ struct rtw89_cipher_suite pairwise_cipher_suite;
+ __le16 akm_cipher_suite_cnt;
+ struct rtw89_cipher_suite akm_cipher_suite;
+} __packed;
+
+struct rtw89_cipher_info {
+ u32 cipher;
+ u8 fw_alg;
+ enum ieee80211_key_len len;
+};
+
+struct rtw89_set_key_info_iter_data {
+ u32 gtk_cipher;
+ u32 igtk_cipher;
+ bool rx_ready;
+ bool error;
+};
+
+static inline int rtw89_wow_get_sec_hdr_len(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+
+ if (!(rtwdev->chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)))
+ return 0;
+
+ switch (rtw_wow->ptk_alg) {
+ case RTW89_WOW_FW_ALG_WEP40:
+ return 4;
+ case RTW89_WOW_FW_ALG_TKIP:
+ case RTW89_WOW_FW_ALG_CCMP:
+ case RTW89_WOW_FW_ALG_GCMP_256:
+ return 8;
+ default:
+ return 0;
+ }
+}
+
+#ifdef CONFIG_PM
+static inline bool rtw89_wow_mgd_linked(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
+
+ return rtwvif_link->net_type == RTW89_NET_TYPE_INFRA;
+}
+
+static inline bool rtw89_wow_no_link(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
+
+ return rtwvif_link->net_type == RTW89_NET_TYPE_NO_LINK;
+}
+
+static inline bool rtw_wow_has_mgd_features(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+
+ return !bitmap_empty(rtw_wow->flags, RTW89_WOW_FLAG_NUM);
+}
+
int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan);
int rtw89_wow_resume(struct rtw89_dev *rtwdev);
+void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb);
+#else
+static inline
+void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb)
+{
+}
+#endif
#endif