Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,193 @@
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
menuconfig RTW89
tristate "Realtek 802.11ax wireless chips support"
depends on MAC80211
help
This module adds support for mac80211-based wireless drivers that
enables Realtek IEEE 802.11ax wireless chipsets.
If you choose to build a module, it'll be called rtw89.
if RTW89
config RTW89_CORE
tristate
select WANT_DEV_COREDUMP
config RTW89_PCI
tristate
config RTW89_USB
tristate
config RTW89_8851B
tristate
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
select RTW89_CORE
select RTW89_PCI
select RTW89_8851B
help
Select this option will enable support for 8851BE chipset
802.11ax PCIe wireless network (Wi-Fi 6) adapter
config RTW89_8851BU
tristate "Realtek 8851BU USB wireless network (Wi-Fi 6) adapter"
depends on USB
select RTW89_CORE
select RTW89_USB
select RTW89_8851B
help
Select this option will enable support for 8851BU chipset
802.11ax USB wireless network (Wi-Fi 6) adapter
config RTW89_8852AE
tristate "Realtek 8852AE PCI wireless network (Wi-Fi 6) adapter"
depends on PCI
select RTW89_CORE
select RTW89_PCI
select RTW89_8852A
help
Select this option will enable support for 8852AE chipset
802.11ax PCIe wireless network (Wi-Fi 6) adapter
config RTW89_8852AU
tristate "Realtek 8852AU USB wireless network (Wi-Fi 6) adapter"
depends on USB
select RTW89_CORE
select RTW89_USB
select RTW89_8852A
help
Select this option will enable support for 8852AU chipset
802.11ax USB wireless network (Wi-Fi 6) adapter
config RTW89_8852BE
tristate "Realtek 8852BE PCI wireless network (Wi-Fi 6) adapter"
depends on PCI
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_8852BU
tristate "Realtek 8852BU USB wireless network (Wi-Fi 6) adapter"
depends on USB
select RTW89_CORE
select RTW89_USB
select RTW89_8852B
select RTW89_8852B_COMMON
help
Select this option will enable support for 8852BU chipset
802.11ax USB 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
select RTW89_CORE
select RTW89_PCI
select RTW89_8852C
help
Select this option will enable support for 8852CE chipset
802.11ax PCIe wireless network (Wi-Fi 6E) adapter
config RTW89_8852CU
tristate "Realtek 8852CU USB wireless network (Wi-Fi 6E) adapter"
depends on USB
select RTW89_CORE
select RTW89_USB
select RTW89_8852C
help
Select this option will enable support for 8852CU chipset
802.11ax USB 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_8922AU
tristate "Realtek 8922AU USB wireless network (Wi-Fi 7) adapter"
depends on USB
select RTW89_CORE
select RTW89_USB
select RTW89_8922A
help
Select this option will enable support for 8922AU chipset
802.11be USB wireless network (Wi-Fi 7) adapter
supporting 2x2 2GHz/5GHz/6GHz 4096-QAM 160MHz channels.
config RTW89_DEBUG
bool
config RTW89_DEBUGMSG
bool "Realtek rtw89 debug message support"
depends on RTW89_CORE
select RTW89_DEBUG
help
Enable debug message support
If unsure, say Y to simplify debug problems
config RTW89_DEBUGFS
bool "Realtek rtw89 debugfs support"
depends on RTW89_CORE && CFG80211_DEBUGFS
select RTW89_DEBUG
help
Enable debugfs support
If unsure, say Y to simplify debug problems
endif
@@ -0,0 +1,101 @@
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
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 \
util.o
rtw89_core-$(CONFIG_PM) += wow.o
obj-$(CONFIG_RTW89_8851B) += rtw89_8851b.o
rtw89_8851b-objs := rtw8851b.o \
rtw8851b_table.o \
rtw8851b_rfk.o \
rtw8851b_rfk_table.o
obj-$(CONFIG_RTW89_8851BE) += rtw89_8851be.o
rtw89_8851be-objs := rtw8851be.o
obj-$(CONFIG_RTW89_8851BU) += rtw89_8851bu.o
rtw89_8851bu-objs := rtw8851bu.o
obj-$(CONFIG_RTW89_8852A) += rtw89_8852a.o
rtw89_8852a-objs := rtw8852a.o \
rtw8852a_table.o \
rtw8852a_rfk.o \
rtw8852a_rfk_table.o
obj-$(CONFIG_RTW89_8852AE) += rtw89_8852ae.o
rtw89_8852ae-objs := rtw8852ae.o
obj-$(CONFIG_RTW89_8852AU) += rtw89_8852au.o
rtw89_8852au-objs := rtw8852au.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 \
rtw8852b_rfk.o \
rtw8852b_rfk_table.o
obj-$(CONFIG_RTW89_8852BE) += rtw89_8852be.o
rtw89_8852be-objs := rtw8852be.o
obj-$(CONFIG_RTW89_8852BU) += rtw89_8852bu.o
rtw89_8852bu-objs := rtw8852bu.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 \
rtw8852c_rfk.o \
rtw8852c_rfk_table.o
obj-$(CONFIG_RTW89_8852CE) += rtw89_8852ce.o
rtw89_8852ce-objs := rtw8852ce.o
obj-$(CONFIG_RTW89_8852CU) += rtw89_8852cu.o
rtw89_8852cu-objs := rtw8852cu.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
obj-$(CONFIG_RTW89_8922AU) += rtw89_8922au.o
rtw89_8922au-objs := rtw8922au.o
rtw89_core-$(CONFIG_RTW89_DEBUG) += debug.o
obj-$(CONFIG_RTW89_PCI) += rtw89_pci.o
rtw89_pci-y := pci.o pci_be.o
obj-$(CONFIG_RTW89_USB) += rtw89_usb.o
rtw89_usb-y := usb.o
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,298 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2021-2023 Realtek Corporation
*/
#ifndef __RTW89_ACPI_H__
#define __RTW89_ACPI_H__
#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_UNII4_SUP = 6,
RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP = 7,
RTW89_ACPI_DSM_FUNC_REG_RULES_EN = 10,
RTW89_ACPI_DSM_FUNC_6GHZ_VLP_SUP = 11,
};
enum rtw89_acpi_conf_unii4 {
RTW89_ACPI_CONF_UNII4_US = BIT(0),
RTW89_ACPI_CONF_UNII4_CA = BIT(1),
};
enum rtw89_acpi_policy_mode {
RTW89_ACPI_POLICY_BLOCK = 0,
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
* * EU for countries in Europe
*/
char alpha2[2];
} __packed;
struct rtw89_acpi_policy_6ghz {
u8 signature[3];
u8 rsvd;
u8 policy_mode;
u8 country_count;
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),
RTW89_ACPI_CONF_6GHZ_SP_CA = BIT(1),
};
struct rtw89_acpi_policy_6ghz_sp {
u8 signature[4];
u8 revision;
u8 override;
u8 conf;
u8 rsvd;
} __packed;
enum rtw89_acpi_conf_6ghz_vlp {
RTW89_ACPI_CONF_6GHZ_VLP_US = BIT(0),
RTW89_ACPI_CONF_6GHZ_VLP_CA = BIT(1),
};
struct rtw89_acpi_policy_6ghz_vlp {
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;
enum rtw89_acpi_conf_reg_rules {
RTW89_ACPI_CONF_REG_RULE_REGD_UK = BIT(0),
};
struct rtw89_acpi_policy_reg_rules {
u8 signature[4];
u8 revision;
u8 conf;
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_6ghz_vlp *policy_6ghz_vlp;
struct rtw89_acpi_policy_tas *policy_tas;
struct rtw89_acpi_policy_reg_rules *policy_reg_rules;
} 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
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,481 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __RTW89_CAM_H__
#define __RTW89_CAM_H__
#include "core.h"
#define RTW89_SEC_CAM_LEN 20
#define RTW89_BSSID_MATCH_ALL GENMASK(5, 0)
#define RTW89_BSSID_MATCH_5_BYTES GENMASK(4, 0)
struct rtw89_h2c_addr_cam_v0 {
__le32 w0;
__le32 w1;
__le32 w2;
__le32 w3;
__le32 w4;
__le32 w5;
__le32 w6;
__le32 w7;
__le32 w8;
__le32 w9;
__le32 w10;
__le32 w11;
__le32 w12;
__le32 w13;
__le32 w14;
} __packed;
struct rtw89_h2c_addr_cam {
struct rtw89_h2c_addr_cam_v0 v0;
__le32 w15;
} __packed;
#define ADDR_CAM_W1_IDX GENMASK(7, 0)
#define ADDR_CAM_W1_OFFSET GENMASK(15, 8)
#define ADDR_CAM_W1_LEN GENMASK(23, 16)
#define ADDR_CAM_W1_V1_IDX GENMASK(9, 0)
#define ADDR_CAM_W1_V1_OFFSET GENMASK(23, 16)
#define ADDR_CAM_W1_V1_LEN GENMASK(31, 24)
#define ADDR_CAM_W2_VALID BIT(0)
#define ADDR_CAM_W2_NET_TYPE GENMASK(2, 1)
#define ADDR_CAM_W2_BCN_HIT_COND GENMASK(4, 3)
#define ADDR_CAM_W2_HIT_RULE GENMASK(6, 5)
#define ADDR_CAM_W2_BB_SEL BIT(7)
#define ADDR_CAM_W2_ADDR_MASK GENMASK(13, 8)
#define ADDR_CAM_W2_MASK_SEL GENMASK(15, 14)
#define ADDR_CAM_W2_SMA_HASH GENMASK(23, 16)
#define ADDR_CAM_W2_TMA_HASH GENMASK(31, 24)
#define ADDR_CAM_W3_BSSID_CAM_IDX GENMASK(5, 0)
#define ADDR_CAM_W4_SMA0 GENMASK(7, 0)
#define ADDR_CAM_W4_SMA1 GENMASK(15, 8)
#define ADDR_CAM_W4_SMA2 GENMASK(23, 16)
#define ADDR_CAM_W4_SMA3 GENMASK(31, 24)
#define ADDR_CAM_W5_SMA4 GENMASK(7, 0)
#define ADDR_CAM_W5_SMA5 GENMASK(15, 8)
#define ADDR_CAM_W5_TMA0 GENMASK(23, 16)
#define ADDR_CAM_W5_TMA1 GENMASK(31, 24)
#define ADDR_CAM_W6_TMA2 GENMASK(7, 0)
#define ADDR_CAM_W6_TMA3 GENMASK(15, 8)
#define ADDR_CAM_W6_TMA4 GENMASK(23, 16)
#define ADDR_CAM_W6_TMA5 GENMASK(31, 24)
#define ADDR_CAM_W8_MACID GENMASK(7, 0)
#define ADDR_CAM_W8_PORT_INT GENMASK(10, 8)
#define ADDR_CAM_W8_TSF_SYNC GENMASK(13, 11)
#define ADDR_CAM_W8_TF_TRS BIT(14)
#define ADDR_CAM_W8_LSIG_TXOP BIT(15)
#define ADDR_CAM_W8_TGT_IND GENMASK(26, 24)
#define ADDR_CAM_W8_FRM_TGT_IND GENMASK(29, 27)
#define ADDR_CAM_W8_V1_MACID GENMASK(9, 0)
#define ADDR_CAM_W8_V1_PORT_INT GENMASK(18, 16)
#define ADDR_CAM_W8_V1_TSF_SYNC GENMASK(21, 19)
#define ADDR_CAM_W8_V1_TF_TRS BIT(22)
#define ADDR_CAM_W8_V1_LSIG_TXOP BIT(23)
#define ADDR_CAM_W8_V1_TB_RANGING BIT(24)
#define ADDR_CAM_W8_V1_TB_SENSING BIT(25)
#define ADDR_CAM_W8_V1_SENS_EN BIT(26)
#define ADDR_CAM_W9_AID12 GENMASK(11, 0)
#define ADDR_CAM_W9_AID12_0 GENMASK(7, 0)
#define ADDR_CAM_W9_AID12_1 GENMASK(11, 8)
#define ADDR_CAM_W9_WOL_PATTERN BIT(12)
#define ADDR_CAM_W9_WOL_UC BIT(13)
#define ADDR_CAM_W9_WOL_MAGIC BIT(14)
#define ADDR_CAM_W9_WAPI BIT(15)
#define ADDR_CAM_W9_SEC_ENT_MODE GENMASK(17, 16)
#define ADDR_CAM_W9_SEC_ENT0_KEYID GENMASK(19, 18)
#define ADDR_CAM_W9_SEC_ENT1_KEYID GENMASK(21, 20)
#define ADDR_CAM_W9_SEC_ENT2_KEYID GENMASK(23, 22)
#define ADDR_CAM_W9_SEC_ENT3_KEYID GENMASK(25, 24)
#define ADDR_CAM_W9_SEC_ENT4_KEYID GENMASK(27, 26)
#define ADDR_CAM_W9_SEC_ENT5_KEYID GENMASK(29, 28)
#define ADDR_CAM_W9_SEC_ENT6_KEYID GENMASK(31, 30)
#define ADDR_CAM_W10_SEC_ENT_VALID GENMASK(7, 0)
#define ADDR_CAM_W10_SEC_ENT0 GENMASK(15, 8)
#define ADDR_CAM_W10_SEC_ENT1 GENMASK(23, 16)
#define ADDR_CAM_W10_SEC_ENT2 GENMASK(31, 24)
#define ADDR_CAM_W11_SEC_ENT3 GENMASK(7, 0)
#define ADDR_CAM_W11_SEC_ENT4 GENMASK(15, 8)
#define ADDR_CAM_W11_SEC_ENT5 GENMASK(23, 16)
#define ADDR_CAM_W11_SEC_ENT6 GENMASK(31, 24)
#define ADDR_CAM_W12_BSSID_IDX GENMASK(7, 0)
#define ADDR_CAM_W12_BSSID_OFFSET GENMASK(15, 8)
#define ADDR_CAM_W12_BSSID_LEN GENMASK(23, 16)
#define ADDR_CAM_W13_BSSID_VALID BIT(0)
#define ADDR_CAM_W13_BSSID_BB_SEL BIT(1)
#define ADDR_CAM_W13_BSSID_MASK GENMASK(7, 2)
#define ADDR_CAM_W13_BSSID_BSS_COLOR GENMASK(13, 8)
#define ADDR_CAM_W13_BSSID_BSSID0 GENMASK(23, 16)
#define ADDR_CAM_W13_BSSID_BSSID1 GENMASK(31, 24)
#define ADDR_CAM_W14_BSSID_BSSID2 GENMASK(7, 0)
#define ADDR_CAM_W14_BSSID_BSSID3 GENMASK(15, 8)
#define ADDR_CAM_W14_BSSID_BSSID4 GENMASK(23, 16)
#define ADDR_CAM_W14_BSSID_BSSID5 GENMASK(31, 24)
#define ADDR_CAM_W15_UPD_MODE GENMASK(2, 0)
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;
__le32 w1;
__le32 w2;
__le32 w3;
__le32 w4;
__le32 w5;
__le32 w6;
__le32 w7;
__le32 w8;
__le32 w9;
__le32 w10;
__le32 w11;
__le32 w12;
__le32 w13;
__le32 w14;
__le32 w15;
__le32 m0;
__le32 m1;
__le32 m2;
__le32 m3;
__le32 m4;
__le32 m5;
__le32 m6;
__le32 m7;
__le32 m8;
__le32 m9;
__le32 m10;
__le32 m11;
__le32 m12;
__le32 m13;
__le32 m14;
__le32 m15;
} __packed;
#define DCTLINFO_V2_C0_MACID GENMASK(6, 0)
#define DCTLINFO_V2_C0_OP BIT(7)
#define DCTLINFO_V2_W0_QOS_FIELD_H GENMASK(7, 0)
#define DCTLINFO_V2_W0_HW_EXSEQ_MACID GENMASK(14, 8)
#define DCTLINFO_V2_W0_QOS_DATA BIT(15)
#define DCTLINFO_V2_W0_AES_IV_L GENMASK(31, 16)
#define DCTLINFO_V2_W0_ALL GENMASK(31, 0)
#define DCTLINFO_V2_W1_AES_IV_H GENMASK(31, 0)
#define DCTLINFO_V2_W1_ALL GENMASK(31, 0)
#define DCTLINFO_V2_W2_SEQ0 GENMASK(11, 0)
#define DCTLINFO_V2_W2_SEQ1 GENMASK(23, 12)
#define DCTLINFO_V2_W2_AMSDU_MAX_LEN GENMASK(26, 24)
#define DCTLINFO_V2_W2_STA_AMSDU_EN BIT(27)
#define DCTLINFO_V2_W2_CHKSUM_OFLD_EN BIT(28)
#define DCTLINFO_V2_W2_WITH_LLC BIT(29)
#define DCTLINFO_V2_W2_NAT25_EN BIT(30)
#define DCTLINFO_V2_W2_IS_MLD BIT(31)
#define DCTLINFO_V2_W2_ALL GENMASK(31, 0)
#define DCTLINFO_V2_W3_SEQ2 GENMASK(11, 0)
#define DCTLINFO_V2_W3_SEQ3 GENMASK(23, 12)
#define DCTLINFO_V2_W3_TGT_IND GENMASK(27, 24)
#define DCTLINFO_V2_W3_TGT_IND_EN BIT(28)
#define DCTLINFO_V2_W3_HTC_LB GENMASK(31, 29)
#define DCTLINFO_V2_W3_ALL GENMASK(31, 0)
#define DCTLINFO_V2_W4_VLAN_TAG_SEL GENMASK(7, 5)
#define DCTLINFO_V2_W4_HTC_ORDER BIT(8)
#define DCTLINFO_V2_W4_SEC_KEY_ID GENMASK(10, 9)
#define DCTLINFO_V2_W4_VLAN_RX_DYNAMIC_PCP_EN BIT(11)
#define DCTLINFO_V2_W4_VLAN_RX_PKT_DROP BIT(12)
#define DCTLINFO_V2_W4_VLAN_RX_VALID BIT(13)
#define DCTLINFO_V2_W4_VLAN_TX_VALID BIT(14)
#define DCTLINFO_V2_W4_WAPI BIT(15)
#define DCTLINFO_V2_W4_SEC_ENT_MODE GENMASK(17, 16)
#define DCTLINFO_V2_W4_SEC_ENT0_KEYID GENMASK(19, 18)
#define DCTLINFO_V2_W4_SEC_ENT1_KEYID GENMASK(21, 20)
#define DCTLINFO_V2_W4_SEC_ENT2_KEYID GENMASK(23, 22)
#define DCTLINFO_V2_W4_SEC_ENT3_KEYID GENMASK(25, 24)
#define DCTLINFO_V2_W4_SEC_ENT4_KEYID GENMASK(27, 26)
#define DCTLINFO_V2_W4_SEC_ENT5_KEYID GENMASK(29, 28)
#define DCTLINFO_V2_W4_SEC_ENT6_KEYID GENMASK(31, 30)
#define DCTLINFO_V2_W4_ALL GENMASK(31, 5)
#define DCTLINFO_V2_W5_SEC_ENT7_KEYID GENMASK(1, 0)
#define DCTLINFO_V2_W5_SEC_ENT8_KEYID GENMASK(3, 2)
#define DCTLINFO_V2_W5_SEC_ENT_VALID_V1 GENMASK(23, 8)
#define DCTLINFO_V2_W5_SEC_ENT0_V1 GENMASK(31, 24)
#define DCTLINFO_V2_W5_ALL (GENMASK(31, 8) | GENMASK(3, 0))
#define DCTLINFO_V2_W6_SEC_ENT1_V1 GENMASK(7, 0)
#define DCTLINFO_V2_W6_SEC_ENT2_V1 GENMASK(15, 8)
#define DCTLINFO_V2_W6_SEC_ENT3_V1 GENMASK(23, 16)
#define DCTLINFO_V2_W6_SEC_ENT4_V1 GENMASK(31, 24)
#define DCTLINFO_V2_W6_ALL GENMASK(31, 0)
#define DCTLINFO_V2_W7_SEC_ENT5_V1 GENMASK(7, 0)
#define DCTLINFO_V2_W7_SEC_ENT6_V1 GENMASK(15, 8)
#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_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_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_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_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_BSSID_4 GENMASK(7, 0)
#define DCTLINFO_V2_W12_MLD_BSSID_5 GENMASK(15, 8)
#define DCTLINFO_V2_W12_ALL GENMASK(15, 0)
struct rtw89_h2c_dctlinfo_ud_v3 {
__le32 c0;
__le32 w0;
__le32 w1;
__le32 w2;
__le32 w3;
__le32 w4;
__le32 w5;
__le32 w6;
__le32 w7;
__le32 w8;
__le32 w9;
__le32 w10;
__le32 w11;
__le32 w12;
__le32 w13;
__le32 w14;
__le32 w15;
__le32 m0;
__le32 m1;
__le32 m2;
__le32 m3;
__le32 m4;
__le32 m5;
__le32 m6;
__le32 m7;
__le32 m8;
__le32 m9;
__le32 m10;
__le32 m11;
__le32 m12;
__le32 m13;
__le32 m14;
__le32 m15;
} __packed;
#define DCTLINFO_V3_C0_MACID GENMASK(15, 0)
#define DCTLINFO_V3_C0_OP BIT(16)
#define DCTLINFO_V3_W0_QOS_FIELD_H GENMASK(7, 0)
#define DCTLINFO_V3_W0_HW_EXSEQ_MACID GENMASK(14, 8)
#define DCTLINFO_V3_W0_QOS_DATA BIT(15)
#define DCTLINFO_V3_W0_AES_IV_L GENMASK(31, 16)
#define DCTLINFO_V3_W0_ALL GENMASK(31, 0)
#define DCTLINFO_V3_W1_AES_IV_H GENMASK(31, 0)
#define DCTLINFO_V3_W1_ALL GENMASK(31, 0)
#define DCTLINFO_V3_W2_SEQ0 GENMASK(11, 0)
#define DCTLINFO_V3_W2_SEQ1 GENMASK(23, 12)
#define DCTLINFO_V3_W2_AMSDU_MAX_LEN GENMASK(26, 24)
#define DCTLINFO_V3_W2_STA_AMSDU_EN BIT(27)
#define DCTLINFO_V3_W2_CHKSUM_OFLD_EN BIT(28)
#define DCTLINFO_V3_W2_WITH_LLC BIT(29)
#define DCTLINFO_V3_W2_NAT25_EN BIT(30)
#define DCTLINFO_V3_W2_IS_MLD BIT(31)
#define DCTLINFO_V3_W2_ALL GENMASK(31, 0)
#define DCTLINFO_V3_W3_SEQ2 GENMASK(11, 0)
#define DCTLINFO_V3_W3_SEQ3 GENMASK(23, 12)
#define DCTLINFO_V3_W3_TGT_IND GENMASK(27, 24)
#define DCTLINFO_V3_W3_TGT_IND_EN BIT(28)
#define DCTLINFO_V3_W3_HTC_LB GENMASK(31, 29)
#define DCTLINFO_V3_W3_ALL GENMASK(31, 0)
#define DCTLINFO_V3_W4_VLAN_TAG_SEL GENMASK(7, 5)
#define DCTLINFO_V3_W4_HTC_ORDER BIT(8)
#define DCTLINFO_V3_W4_SEC_KEY_ID GENMASK(10, 9)
#define DCTLINFO_V3_W4_VLAN_RX_DYNAMIC_PCP_EN BIT(11)
#define DCTLINFO_V3_W4_VLAN_RX_PKT_DROP BIT(12)
#define DCTLINFO_V3_W4_VLAN_RX_VALID BIT(13)
#define DCTLINFO_V3_W4_VLAN_TX_VALID BIT(14)
#define DCTLINFO_V3_W4_WAPI BIT(15)
#define DCTLINFO_V3_W4_SEC_ENT_MODE GENMASK(17, 16)
#define DCTLINFO_V3_W4_SEC_ENT0_KEYID GENMASK(19, 18)
#define DCTLINFO_V3_W4_SEC_ENT1_KEYID GENMASK(21, 20)
#define DCTLINFO_V3_W4_SEC_ENT2_KEYID GENMASK(23, 22)
#define DCTLINFO_V3_W4_SEC_ENT3_KEYID GENMASK(25, 24)
#define DCTLINFO_V3_W4_SEC_ENT4_KEYID GENMASK(27, 26)
#define DCTLINFO_V3_W4_SEC_ENT5_KEYID GENMASK(29, 28)
#define DCTLINFO_V3_W4_SEC_ENT6_KEYID GENMASK(31, 30)
#define DCTLINFO_V3_W4_ALL GENMASK(31, 5)
#define DCTLINFO_V3_W5_SEC_ENT7_KEYID GENMASK(1, 0)
#define DCTLINFO_V3_W5_SEC_ENT8_KEYID GENMASK(3, 2)
#define DCTLINFO_V3_W5_SEC_ENT_VALID_V1 GENMASK(23, 8)
#define DCTLINFO_V3_W5_ALL (GENMASK(23, 8) | GENMASK(3, 0))
#define DCTLINFO_V3_W6_SEC_ENT0_V2 GENMASK(8, 0)
#define DCTLINFO_V3_W6_SEC_ENT1_V2 GENMASK(18, 10)
#define DCTLINFO_V3_W6_SEC_ENT2_V2 GENMASK(28, 20)
#define DCTLINFO_V3_W6_ALL GENMASK(28, 0)
#define DCTLINFO_V3_W7_SEC_ENT3_V2 GENMASK(8, 0)
#define DCTLINFO_V3_W7_SEC_ENT4_V2 GENMASK(18, 10)
#define DCTLINFO_V3_W7_SEC_ENT5_V2 GENMASK(28, 20)
#define DCTLINFO_V3_W7_ALL GENMASK(28, 0)
#define DCTLINFO_V3_W8_SEC_ENT6_V2 GENMASK(8, 0)
#define DCTLINFO_V3_W8_SEC_ENT7_V1 GENMASK(18, 10)
#define DCTLINFO_V3_W8_SEC_ENT8_V1 GENMASK(28, 20)
#define DCTLINFO_V3_W8_ALL GENMASK(28, 0)
#define DCTLINFO_V3_W9_MLD_SMA_0_V2 GENMASK(7, 0)
#define DCTLINFO_V3_W9_MLD_SMA_1_V2 GENMASK(15, 8)
#define DCTLINFO_V3_W9_MLD_SMA_2_V2 GENMASK(23, 16)
#define DCTLINFO_V3_W9_MLD_SMA_3_V2 GENMASK(31, 24)
#define DCTLINFO_V3_W9_MLD_SMA_L_V2 GENMASK(31, 0)
#define DCTLINFO_V3_W9_ALL GENMASK(31, 0)
#define DCTLINFO_V3_W10_MLD_SMA_4_V2 GENMASK(7, 0)
#define DCTLINFO_V3_W10_MLD_SMA_5_V2 GENMASK(15, 8)
#define DCTLINFO_V3_W10_MLD_SMA_H_V2 GENMASK(15, 0)
#define DCTLINFO_V3_W10_MLD_TMA_0_V2 GENMASK(23, 16)
#define DCTLINFO_V3_W10_MLD_TMA_1_V2 GENMASK(31, 24)
#define DCTLINFO_V3_W10_MLD_TMA_L_V2 GENMASK(31, 16)
#define DCTLINFO_V3_W10_ALL GENMASK(31, 0)
#define DCTLINFO_V3_W11_MLD_TMA_2_V2 GENMASK(7, 0)
#define DCTLINFO_V3_W11_MLD_TMA_3_V2 GENMASK(15, 8)
#define DCTLINFO_V3_W11_MLD_TMA_4_V2 GENMASK(23, 16)
#define DCTLINFO_V3_W11_MLD_TMA_5_V2 GENMASK(31, 24)
#define DCTLINFO_V3_W11_MLD_TMA_H_V2 GENMASK(31, 0)
#define DCTLINFO_V3_W11_ALL GENMASK(31, 0)
#define DCTLINFO_V3_W12_MLD_TA_BSSID_0_V2 GENMASK(7, 0)
#define DCTLINFO_V3_W12_MLD_TA_BSSID_1_V2 GENMASK(15, 8)
#define DCTLINFO_V3_W12_MLD_TA_BSSID_2_V2 GENMASK(23, 16)
#define DCTLINFO_V3_W12_MLD_TA_BSSID_3_V2 GENMASK(31, 24)
#define DCTLINFO_V3_W12_MLD_TA_BSSID_L_V2 GENMASK(31, 0)
#define DCTLINFO_V3_W12_ALL GENMASK(31, 0)
#define DCTLINFO_V3_W13_MLD_TA_BSSID_4_V2 GENMASK(7, 0)
#define DCTLINFO_V3_W13_MLD_TA_BSSID_5_V2 GENMASK(15, 8)
#define DCTLINFO_V3_W13_MLD_TA_BSSID_H_V2 GENMASK(15, 0)
#define DCTLINFO_V3_W13_HW_EXSEQ_MACID_V1 GENMASK(24, 16)
#define DCTLINFO_V3_W13_ALL GENMASK(24, 0)
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_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_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
const u8 *scan_mac_addr,
struct rtw89_h2c_addr_cam_v0 *h2c);
void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
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_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_dctlinfo_ud_v2 *h2c);
void rtw89_cam_fill_dctl_sec_cam_info_v3(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_dctlinfo_ud_v3 *h2c);
int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_addr_cam_v0 *h2c);
int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key);
int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key,
bool inform_fw);
void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev,
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
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,220 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
* Copyright(c) 2020-2022 Realtek Corporation
*/
#ifndef __RTW89_CHAN_H__
#define __RTW89_CHAN_H__
#include "core.h"
/* The dwell time in TU before doing rtw89_chanctx_work(). */
#define RTW89_CHANCTX_TIME_MCC_PREPARE 100
#define RTW89_CHANCTX_TIME_MCC 100
/* various MCC setting time in TU */
#define RTW89_MCC_LONG_TRIGGER_TIME 300
#define RTW89_MCC_SHORT_TRIGGER_TIME 100
#define RTW89_MCC_EARLY_TX_BCN_TIME 10
#define RTW89_MCC_EARLY_RX_BCN_TIME 5
#define RTW89_MCC_MIN_RX_BCN_TIME 10
#define RTW89_MCC_DFLT_BCN_OFST_TIME 40
#define RTW89_MCC_SWITCH_CH_TIME 3
#define RTW89_MCC_PROBE_TIMEOUT 100
#define RTW89_MCC_PROBE_MAX_TRIES 3
#define RTW89_MCC_DETECT_BCN_MAX_TRIES 2
#define RTW89_MCC_MIN_GO_DURATION \
(RTW89_MCC_EARLY_TX_BCN_TIME + RTW89_MCC_MIN_RX_BCN_TIME)
#define RTW89_MCC_MIN_STA_DURATION \
(RTW89_MCC_EARLY_RX_BCN_TIME + RTW89_MCC_MIN_RX_BCN_TIME)
#define RTW89_MCC_MIN_RX_BCN_WITH_SWITCH_CH_TIME \
(RTW89_MCC_MIN_RX_BCN_TIME + RTW89_MCC_SWITCH_CH_TIME)
#define RTW89_MCC_DFLT_GROUP 0
#define RTW89_MCC_NEXT_GROUP(cur) (((cur) + 1) % 4)
#define RTW89_MCC_DFLT_TX_NULL_EARLY 7
#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_mr_wtype {
RTW89_MR_WTYPE_NONE,
RTW89_MR_WTYPE_NONMLD,
RTW89_MR_WTYPE_MLD1L1R,
RTW89_MR_WTYPE_MLD2L1R,
RTW89_MR_WTYPE_MLD2L2R,
RTW89_MR_WTYPE_NONMLD_NONMLD,
RTW89_MR_WTYPE_MLD1L1R_NONMLD,
RTW89_MR_WTYPE_MLD2L1R_NONMLD,
RTW89_MR_WTYPE_MLD2L2R_NONMLD,
RTW89_MR_WTYPE_UNKNOWN,
};
enum rtw89_mr_wmode {
RTW89_MR_WMODE_NONE,
RTW89_MR_WMODE_1CLIENT,
RTW89_MR_WMODE_1AP,
RTW89_MR_WMODE_1AP_1CLIENT,
RTW89_MR_WMODE_2CLIENTS,
RTW89_MR_WMODE_2APS,
RTW89_MR_WMODE_UNKNOWN,
};
enum rtw89_mr_ctxtype {
RTW89_MR_CTX_NONE,
RTW89_MR_CTX1_2GHZ,
RTW89_MR_CTX1_5GHZ,
RTW89_MR_CTX1_6GHZ,
RTW89_MR_CTX2_2GHZ,
RTW89_MR_CTX2_5GHZ,
RTW89_MR_CTX2_6GHZ,
RTW89_MR_CTX2_2GHZ_5GHZ,
RTW89_MR_CTX2_2GHZ_6GHZ,
RTW89_MR_CTX2_5GHZ_6GHZ,
RTW89_MR_CTX_UNKNOWN,
};
struct rtw89_mr_chanctx_info {
enum rtw89_mr_wtype wtype;
enum rtw89_mr_wmode wmode;
enum rtw89_mr_ctxtype ctxtype;
};
enum rtw89_chanctx_pause_reasons {
RTW89_CHANCTX_PAUSE_REASON_HW_SCAN,
RTW89_CHANCTX_PAUSE_REASON_ROC,
RTW89_CHANCTX_PAUSE_REASON_GC_BCN_LOSS,
};
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 registered_chanctxs;
unsigned int active_chanctxs;
unsigned int active_roles;
};
struct rtw89_entity_conf {
bool is_mld;
bool en_emlsr;
DECLARE_BITMAP(hw_bitmap, __RTW89_MLD_MAX_LINK_NUM);
const struct rtw89_chan *chans[__RTW89_MLD_MAX_LINK_NUM];
};
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[phy_idx]);
}
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[phy_idx], active);
}
static inline
enum rtw89_entity_mode rtw89_get_entity_mode(struct rtw89_dev *rtwdev)
{
struct rtw89_hal *hal = &rtwdev->hal;
return READ_ONCE(hal->entity_mode);
}
static inline void rtw89_set_entity_mode(struct rtw89_dev *rtwdev,
enum rtw89_entity_mode mode)
{
struct rtw89_hal *hal = &rtwdev->hal;
WRITE_ONCE(hal->entity_mode, mode);
}
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_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_chanctx_idx idx,
const struct cfg80211_chan_def *chandef);
void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
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);
bool rtw89_entity_check_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
void rtw89_entity_force_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
void rtw89_entity_get_conf(struct rtw89_dev *rtwdev, struct rtw89_entity_conf *conf);
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_query_mr_chanctx_info(struct rtw89_dev *rtwdev, u8 inst_idx,
struct rtw89_mr_chanctx_info *info);
void rtw89_chanctx_track(struct rtw89_dev *rtwdev);
void rtw89_chanctx_pause(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);
struct rtw89_mcc_links_info {
struct rtw89_vif_link *links[NUM_OF_RTW89_MCC_ROLES];
};
void rtw89_mcc_get_links(struct rtw89_dev *rtwdev, struct rtw89_mcc_links_info *info);
void rtw89_mcc_prepare_done_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_mcc_gc_detect_beacon_work(struct wiphy *wiphy, struct wiphy_work *work);
bool rtw89_mcc_detect_go_bcn(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link);
int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx);
void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx);
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_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx);
void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx);
int rtw89_chanctx_ops_reassign_vif(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *old_ctx,
struct ieee80211_chanctx_conf *new_ctx,
bool replace);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,387 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __RTW89_COEX_H__
#define __RTW89_COEX_H__
#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,
BTC_MODE_WL,
BTC_MODE_BT,
BTC_MODE_WLOFF,
BTC_MODE_MAX
};
enum btc_wl_rfk_type {
BTC_WRFKT_IQK = 0,
BTC_WRFKT_LCK = 1,
BTC_WRFKT_DPK = 2,
BTC_WRFKT_TXGAPK = 3,
BTC_WRFKT_DACK = 4,
BTC_WRFKT_RXDCK = 5,
BTC_WRFKT_TSSI = 6,
BTC_WRFKT_CHLK = 7,
};
#define NM_EXEC false
#define FC_EXEC true
#define RTW89_COEX_ACT1_WORK_PERIOD round_jiffies_relative(HZ * 4)
#define RTW89_COEX_BT_DEVINFO_WORK_PERIOD round_jiffies_relative(HZ * 16)
#define RTW89_COEX_RFK_CHK_WORK_PERIOD msecs_to_jiffies(300)
#define BTC_RFK_PATH_MAP GENMASK(3, 0)
#define BTC_RFK_PHY_MAP GENMASK(5, 4)
#define BTC_RFK_BAND_MAP GENMASK(7, 6)
enum btc_wl_rfk_state {
BTC_WRFK_STOP = 0,
BTC_WRFK_START = 1,
BTC_WRFK_ONESHOT_START = 2,
BTC_WRFK_ONESHOT_STOP = 3,
};
enum btc_pri {
BTC_PRI_MASK_RX_RESP = 0,
BTC_PRI_MASK_TX_RESP,
BTC_PRI_MASK_BEACON,
BTC_PRI_MASK_RX_CCK,
BTC_PRI_MASK_TX_MNGQ,
BTC_PRI_MASK_MAX,
};
enum btc_bt_trs {
BTC_BT_SS_GROUP = 0x0,
BTC_BT_TX_GROUP = 0x2,
BTC_BT_RX_GROUP = 0x3,
BTC_BT_MAX_GROUP,
};
enum btc_rssi_st {
BTC_RSSI_ST_LOW = 0x0,
BTC_RSSI_ST_HIGH,
BTC_RSSI_ST_STAY_LOW,
BTC_RSSI_ST_STAY_HIGH,
BTC_RSSI_ST_MAX
};
enum btc_fddt_en {
BTC_FDDT_DISABLE,
BTC_FDDT_ENABLE,
};
#define BTC_RSSI_HIGH(_rssi_) \
({typeof(_rssi_) __rssi = (_rssi_); \
((__rssi == BTC_RSSI_ST_HIGH || \
__rssi == BTC_RSSI_ST_STAY_HIGH) ? 1 : 0); })
#define BTC_RSSI_LOW(_rssi_) \
({typeof(_rssi_) __rssi = (_rssi_); \
((__rssi == BTC_RSSI_ST_LOW || \
__rssi == BTC_RSSI_ST_STAY_LOW) ? 1 : 0); })
#define BTC_RSSI_CHANGE(_rssi_) \
({typeof(_rssi_) __rssi = (_rssi_); \
((__rssi == BTC_RSSI_ST_LOW || \
__rssi == BTC_RSSI_ST_HIGH) ? 1 : 0); })
enum btc_ant {
BTC_ANT_SHARED = 0,
BTC_ANT_DEDICATED,
BTC_ANTTYPE_MAX
};
enum btc_bt_btg {
BTC_BT_ALONE = 0,
BTC_BT_BTG
};
enum btc_switch {
BTC_SWITCH_INTERNAL = 0,
BTC_SWITCH_EXTERNAL
};
enum btc_pkt_type {
PACKET_DHCP,
PACKET_ARP,
PACKET_EAPOL,
PACKET_EAPOL_END,
PACKET_ICMP,
PACKET_MAX
};
enum btc_bt_mailbox_id {
BTC_BTINFO_REPLY = 0x23,
BTC_BTINFO_AUTO = 0x27
};
enum btc_role_state {
BTC_ROLE_START,
BTC_ROLE_STOP,
BTC_ROLE_CHG_TYPE,
BTC_ROLE_MSTS_STA_CONN_START,
BTC_ROLE_MSTS_STA_CONN_END,
BTC_ROLE_MSTS_STA_DIS_CONN,
BTC_ROLE_MSTS_AP_START,
BTC_ROLE_MSTS_AP_STOP,
BTC_ROLE_STATE_UNKNOWN
};
enum btc_rfctrl {
BTC_RFCTRL_WL_OFF,
BTC_RFCTRL_WL_ON,
BTC_RFCTRL_LPS_WL_ON,
BTC_RFCTRL_FW_CTRL,
BTC_RFCTRL_MAX
};
enum btc_lps_state {
BTC_LPS_OFF = 0,
BTC_LPS_RF_OFF = 1,
BTC_LPS_RF_ON = 2
};
#define R_BTC_BB_BTG_RX 0x980
#define R_BTC_BB_PRE_AGC_S1 0x476C
#define R_BTC_BB_PRE_AGC_S0 0x4688
#define B_BTC_BB_GNT_MUX GENMASK(20, 17)
#define B_BTC_BB_PRE_AGC_MASK GENMASK(31, 24)
#define B_BTC_BB_PRE_AGC_VAL BIT(31)
#define BTC_REG_NOTFOUND 0xff
#define R_BTC_ZB_COEX_TBL_0 0xE328
#define R_BTC_ZB_COEX_TBL_1 0xE32c
#define R_BTC_ZB_BREAK_TBL 0xE350
enum btc_ant_div_pos {
BTC_ANT_DIV_MAIN = 0,
BTC_ANT_DIV_AUX = 1,
};
enum btc_get_reg_status {
BTC_CSTATUS_TXDIV_POS = 0,
BTC_CSTATUS_RXDIV_POS = 1,
BTC_CSTATUS_BB_GNT_MUX = 2,
BTC_CSTATUS_BB_GNT_MUX_MON = 3,
BTC_CSTATUS_BB_PRE_AGC = 4,
BTC_CSTATUS_BB_PRE_AGC_MON = 5,
};
enum btc_preagc_type {
BTC_PREAGC_DISABLE,
BTC_PREAGC_ENABLE,
BTC_PREAGC_BB_FWCTRL,
BTC_PREAGC_NOTFOUND,
};
enum btc_btgctrl_type {
BTC_BTGCTRL_DISABLE,
BTC_BTGCTRL_ENABLE,
BTC_BTGCTRL_BB_GNT_FWCTRL,
BTC_BTGCTRL_BB_GNT_NOTFOUND,
};
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 {
BTC_3CX_NONE = 0,
BTC_3CX_BT2 = BIT(0),
BTC_3CX_ZB = BIT(1),
BTC_3CX_LTE = BIT(2),
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_mlo_rf_combin {
BTC_MLO_RF_2_PLUS_0 = 0,
BTC_MLO_RF_0_PLUS_2 = 1,
BTC_MLO_RF_1_PLUS_1 = 2,
BTC_MLO_RF_2_PLUS_2 = 3,
};
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);
void rtw89_btc_ntfy_scan_start(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band);
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 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,
enum btc_wl_rfk_state state);
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);
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_chanctx_idx chanctx_idx)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
u8 phy_map;
phy_map = FIELD_PREP(BTC_RFK_PATH_MAP, paths) |
FIELD_PREP(BTC_RFK_PHY_MAP, BIT(phy_idx)) |
FIELD_PREP(BTC_RFK_BAND_MAP, chan->band_type);
return phy_map;
}
static inline u8 rtw89_btc_path_phymap(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
enum rtw89_rf_path path,
enum rtw89_chanctx_idx chanctx_idx)
{
return rtw89_btc_phymap(rtwdev, phy_idx, BIT(path), chanctx_idx);
}
/* return bt req len in TU */
static inline u16 rtw89_coex_query_bt_req_len(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
struct rtw89_btc *btc = &rtwdev->btc;
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
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,101 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __RTW89_DEBUG_H__
#define __RTW89_DEBUG_H__
#include "core.h"
enum rtw89_debug_mask {
RTW89_DBG_TXRX = BIT(0),
RTW89_DBG_RFK = BIT(1),
RTW89_DBG_RFK_TRACK = BIT(2),
RTW89_DBG_CFO = BIT(3),
RTW89_DBG_TSSI = BIT(4),
RTW89_DBG_TXPWR = BIT(5),
RTW89_DBG_HCI = BIT(6),
RTW89_DBG_RA = BIT(7),
RTW89_DBG_REGD = BIT(8),
RTW89_DBG_PHY_TRACK = BIT(9),
RTW89_DBG_DIG = BIT(10),
RTW89_DBG_SER = BIT(11),
RTW89_DBG_FW = BIT(12),
RTW89_DBG_BTC = BIT(13),
RTW89_DBG_BF = BIT(14),
RTW89_DBG_HW_SCAN = BIT(15),
RTW89_DBG_SAR = BIT(16),
RTW89_DBG_STATE = BIT(17),
RTW89_DBG_WOW = BIT(18),
RTW89_DBG_UL_TB = BIT(19),
RTW89_DBG_CHAN = BIT(20),
RTW89_DBG_ACPI = BIT(21),
RTW89_DBG_EDCCA = BIT(22),
RTW89_DBG_PS = BIT(23),
RTW89_DBG_UNEXP = BIT(31),
};
enum rtw89_debug_mac_reg_sel {
RTW89_DBG_SEL_MAC_00,
RTW89_DBG_SEL_MAC_30,
RTW89_DBG_SEL_MAC_40,
RTW89_DBG_SEL_MAC_80,
RTW89_DBG_SEL_MAC_C0,
RTW89_DBG_SEL_MAC_E0,
RTW89_DBG_SEL_BB,
RTW89_DBG_SEL_IQK,
RTW89_DBG_SEL_RFC,
};
#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)
#define rtw89_info_once(rtwdev, a...) dev_info_once((rtwdev)->dev, ##a)
#define rtw89_warn(rtwdev, a...) dev_warn((rtwdev)->dev, ##a)
#define rtw89_err(rtwdev, a...) dev_err((rtwdev)->dev, ##a)
#ifdef CONFIG_RTW89_DEBUGMSG
extern unsigned int rtw89_debug_mask;
__printf(3, 4)
void rtw89_debug(struct rtw89_dev *rtwdev, enum rtw89_debug_mask mask,
const char *fmt, ...);
static inline void rtw89_hex_dump(struct rtw89_dev *rtwdev,
enum rtw89_debug_mask mask,
const char *prefix_str,
const void *buf, size_t len)
{
if (!(rtw89_debug_mask & mask))
return;
print_hex_dump_bytes(prefix_str, DUMP_PREFIX_OFFSET, buf, len);
}
static inline bool rtw89_debug_is_enabled(struct rtw89_dev *rtwdev,
enum rtw89_debug_mask mask)
{
return !!(rtw89_debug_mask & mask);
}
#else
static inline void rtw89_debug(struct rtw89_dev *rtwdev,
enum rtw89_debug_mask mask,
const char *fmt, ...) {}
static inline void rtw89_hex_dump(struct rtw89_dev *rtwdev,
enum rtw89_debug_mask mask,
const char *prefix_str,
const void *buf, size_t len) {}
static inline bool rtw89_debug_is_enabled(struct rtw89_dev *rtwdev,
enum rtw89_debug_mask mask)
{
return false;
}
#endif
#endif
@@ -0,0 +1,521 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#include "debug.h"
#include "efuse.h"
#include "mac.h"
#include "reg.h"
#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)
{
u8 val;
if (rtwdev->chip->chip_id != RTL8852A)
return 0;
val = rtw89_read32_mask(rtwdev, R_AX_EFUSE_CTRL_1,
B_AX_EF_CELL_SEL_MASK);
if (bank == val)
return 0;
rtw89_write32_mask(rtwdev, R_AX_EFUSE_CTRL_1, B_AX_EF_CELL_SEL_MASK,
bank);
val = rtw89_read32_mask(rtwdev, R_AX_EFUSE_CTRL_1,
B_AX_EF_CELL_SEL_MASK);
if (bank == val)
return 0;
return -EBUSY;
}
static void rtw89_enable_otp_burst_mode(struct rtw89_dev *rtwdev, bool en)
{
if (en)
rtw89_write32_set(rtwdev, R_AX_EFUSE_CTRL_1_V1, B_AX_EF_BURST);
else
rtw89_write32_clr(rtwdev, R_AX_EFUSE_CTRL_1_V1, B_AX_EF_BURST);
}
static void rtw89_enable_efuse_pwr_cut_ddv(struct rtw89_dev *rtwdev)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
struct rtw89_hal *hal = &rtwdev->hal;
if (chip_id == RTL8852A)
return;
rtw89_write8_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
rtw89_write16_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14);
fsleep(1000);
rtw89_write16_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15);
rtw89_write16_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE);
if (chip_id == RTL8852B && hal->cv == CHIP_CAV)
rtw89_enable_otp_burst_mode(rtwdev, true);
}
static void rtw89_disable_efuse_pwr_cut_ddv(struct rtw89_dev *rtwdev)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
struct rtw89_hal *hal = &rtwdev->hal;
if (chip_id == RTL8852A)
return;
if (chip_id == RTL8852B && hal->cv == CHIP_CAV)
rtw89_enable_otp_burst_mode(rtwdev, false);
rtw89_write16_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE);
rtw89_write16_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15);
fsleep(1000);
rtw89_write16_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14);
rtw89_write8_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
}
static int rtw89_dump_physical_efuse_map_ddv(struct rtw89_dev *rtwdev, u8 *map,
u32 dump_addr, u32 dump_size)
{
u32 efuse_ctl;
u32 addr;
int ret;
rtw89_enable_efuse_pwr_cut_ddv(rtwdev);
for (addr = dump_addr; addr < dump_addr + dump_size; addr++) {
efuse_ctl = u32_encode_bits(addr, B_AX_EF_ADDR_MASK);
rtw89_write32(rtwdev, R_AX_EFUSE_CTRL, efuse_ctl & ~B_AX_EF_RDY);
ret = read_poll_timeout_atomic(rtw89_read32, efuse_ctl,
efuse_ctl & B_AX_EF_RDY, 1, 1000000,
true, rtwdev, R_AX_EFUSE_CTRL);
if (ret)
return -EBUSY;
*map++ = (u8)(efuse_ctl & 0xff);
}
rtw89_disable_efuse_pwr_cut_ddv(rtwdev);
return 0;
}
int rtw89_cnv_efuse_state_ax(struct rtw89_dev *rtwdev, bool idle)
{
return 0;
}
static int rtw89_dump_physical_efuse_map_dav(struct rtw89_dev *rtwdev, u8 *map,
u32 dump_addr, u32 dump_size)
{
u32 addr;
u8 val8;
int err;
int ret;
for (addr = dump_addr; addr < dump_addr + dump_size; addr++) {
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, 0x40, FULL_BIT_MASK);
if (ret)
return ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_LOW_ADDR,
addr & 0xff, XTAL_SI_LOW_ADDR_MASK);
if (ret)
return ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, addr >> 8,
XTAL_SI_HIGH_ADDR_MASK);
if (ret)
return ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, 0,
XTAL_SI_MODE_SEL_MASK);
if (ret)
return ret;
ret = read_poll_timeout_atomic(rtw89_mac_read_xtal_si, err,
!err && (val8 & XTAL_SI_RDY),
1, 10000, false,
rtwdev, XTAL_SI_CTRL, &val8);
if (ret) {
rtw89_warn(rtwdev, "failed to read dav efuse\n");
return ret;
}
ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_READ_VAL, &val8);
if (ret)
return ret;
*map++ = val8;
}
return 0;
}
static int __rtw89_dump_physical_efuse_map(struct rtw89_dev *rtwdev, u8 *map,
u32 dump_addr, u32 dump_size, bool dav)
{
int ret;
if (!map || dump_size == 0)
return 0;
rtw89_switch_efuse_bank(rtwdev, RTW89_EFUSE_BANK_WIFI);
if (dav) {
ret = rtw89_dump_physical_efuse_map_dav(rtwdev, map, dump_addr, dump_size);
if (ret)
return ret;
} else {
ret = rtw89_dump_physical_efuse_map_ddv(rtwdev, map, dump_addr, dump_size);
if (ret)
return ret;
}
return 0;
}
static int rtw89_dump_physical_efuse_map(struct rtw89_dev *rtwdev, u8 *map,
u32 dump_addr, u32 dump_size, bool dav)
{
int retry;
int ret;
for (retry = 0; retry < 5; retry++) {
ret = __rtw89_dump_physical_efuse_map(rtwdev, map, dump_addr,
dump_size, dav);
if (!ret)
return 0;
rtw89_warn(rtwdev, "efuse dump (dav=%d) failed, retrying (%d)\n",
dav, retry);
}
return ret;
}
#define invalid_efuse_header(hdr1, hdr2) \
((hdr1) == 0xff || (hdr2) == 0xff)
#define invalid_efuse_content(word_en, i) \
(((word_en) & BIT(i)) != 0x0)
#define get_efuse_blk_idx(hdr1, hdr2) \
((((hdr2) & 0xf0) >> 4) | (((hdr1) & 0x0f) << 4))
#define block_idx_to_logical_idx(blk_idx, i) \
(((blk_idx) << 3) + ((i) << 1))
static int rtw89_dump_logical_efuse_map(struct rtw89_dev *rtwdev, u8 *phy_map,
u8 *log_map)
{
u32 physical_size = rtwdev->chip->physical_efuse_size;
u32 logical_size = rtwdev->chip->logical_efuse_size;
u8 sec_ctrl_size = rtwdev->chip->sec_ctrl_efuse_size;
u32 phy_idx = sec_ctrl_size;
u32 log_idx;
u8 hdr1, hdr2;
u8 blk_idx;
u8 word_en;
int i;
if (!phy_map)
return 0;
while (phy_idx < physical_size - sec_ctrl_size) {
hdr1 = phy_map[phy_idx];
hdr2 = phy_map[phy_idx + 1];
if (invalid_efuse_header(hdr1, hdr2))
break;
blk_idx = get_efuse_blk_idx(hdr1, hdr2);
word_en = hdr2 & 0xf;
phy_idx += 2;
for (i = 0; i < 4; i++) {
if (invalid_efuse_content(word_en, i))
continue;
log_idx = block_idx_to_logical_idx(blk_idx, i);
if (phy_idx + 1 > physical_size - sec_ctrl_size - 1 ||
log_idx + 1 > logical_size)
return -EINVAL;
log_map[log_idx] = phy_map[phy_idx];
log_map[log_idx + 1] = phy_map[phy_idx + 1];
phy_idx += 2;
}
}
return 0;
}
int rtw89_parse_efuse_map_ax(struct rtw89_dev *rtwdev)
{
u32 phy_size = rtwdev->chip->physical_efuse_size;
u32 log_size = rtwdev->chip->logical_efuse_size;
u32 dav_phy_size = rtwdev->chip->dav_phy_efuse_size;
u32 dav_log_size = rtwdev->chip->dav_log_efuse_size;
u32 full_log_size = log_size + dav_log_size;
u8 *phy_map = NULL;
u8 *log_map = NULL;
u8 *dav_phy_map = NULL;
u8 *dav_log_map = NULL;
int ret;
if (rtw89_read16(rtwdev, R_AX_SYS_WL_EFUSE_CTRL) & B_AX_AUTOLOAD_SUS)
rtwdev->efuse.valid = true;
else
rtw89_warn(rtwdev, "failed to check efuse autoload\n");
phy_map = kmalloc(phy_size, GFP_KERNEL);
log_map = kmalloc(full_log_size, GFP_KERNEL);
if (dav_phy_size && dav_log_size) {
dav_phy_map = kmalloc(dav_phy_size, GFP_KERNEL);
dav_log_map = log_map + log_size;
}
if (!phy_map || !log_map || (dav_phy_size && !dav_phy_map)) {
ret = -ENOMEM;
goto out_free;
}
ret = rtw89_dump_physical_efuse_map(rtwdev, phy_map, 0, phy_size, false);
if (ret) {
rtw89_warn(rtwdev, "failed to dump efuse physical map\n");
goto out_free;
}
ret = rtw89_dump_physical_efuse_map(rtwdev, dav_phy_map, 0, dav_phy_size, true);
if (ret) {
rtw89_warn(rtwdev, "failed to dump efuse dav physical map\n");
goto out_free;
}
memset(log_map, 0xff, full_log_size);
ret = rtw89_dump_logical_efuse_map(rtwdev, phy_map, log_map);
if (ret) {
rtw89_warn(rtwdev, "failed to dump efuse logical map\n");
goto out_free;
}
ret = rtw89_dump_logical_efuse_map(rtwdev, dav_phy_map, dav_log_map);
if (ret) {
rtw89_warn(rtwdev, "failed to dump efuse dav logical map\n");
goto out_free;
}
rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "log_map: ", log_map, full_log_size);
ret = rtwdev->chip->ops->read_efuse(rtwdev, log_map, RTW89_EFUSE_BLOCK_IGNORE);
if (ret) {
rtw89_warn(rtwdev, "failed to read efuse map\n");
goto out_free;
}
out_free:
kfree(dav_phy_map);
kfree(log_map);
kfree(phy_map);
return ret;
}
int rtw89_parse_phycap_map_ax(struct rtw89_dev *rtwdev)
{
u32 phycap_addr = rtwdev->chip->phycap_addr;
u32 phycap_size = rtwdev->chip->phycap_size;
u8 *phycap_map = NULL;
int ret = 0;
if (!phycap_size)
return 0;
phycap_map = kmalloc(phycap_size, GFP_KERNEL);
if (!phycap_map)
return -ENOMEM;
ret = rtw89_dump_physical_efuse_map(rtwdev, phycap_map,
phycap_addr, phycap_size, false);
if (ret) {
rtw89_warn(rtwdev, "failed to dump phycap map\n");
goto out_free;
}
ret = rtwdev->chip->ops->read_phycap(rtwdev, phycap_map);
if (ret) {
rtw89_warn(rtwdev, "failed to read phycap map\n");
goto out_free;
}
out_free:
kfree(phycap_map);
return ret;
}
int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *ecv)
{
int ret;
u8 val;
ret = rtw89_dump_physical_efuse_map(rtwdev, &val, EF_FV_OFSET, 1, false);
if (ret)
return ret;
*ecv = u8_get_bits(val, EF_CV_MASK);
if (*ecv == EF_CV_INV)
return -ENOENT;
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;
}
@@ -0,0 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __RTW89_EFUSE_H__
#define __RTW89_EFUSE_H__
#include "core.h"
#define RTW89_EFUSE_BLOCK_ID_MASK GENMASK(31, 16)
#define RTW89_EFUSE_BLOCK_SIZE_MASK GENMASK(15, 0)
#define RTW89_EFUSE_MAX_BLOCK_SIZE 0x10000
#define EF_FV_OFSET 0x5EA
#define EF_FV_OFSET_BE_V1 0x17CA
#define EF_CV_MASK GENMASK(7, 4)
#define EF_CV_INV 15
struct rtw89_efuse_block_cfg {
u32 offset;
u32 size;
};
int rtw89_parse_efuse_map_ax(struct rtw89_dev *rtwdev);
int rtw89_parse_phycap_map_ax(struct rtw89_dev *rtwdev);
int rtw89_cnv_efuse_state_ax(struct rtw89_dev *rtwdev, bool idle);
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);
int rtw89_efuse_read_ecv_be(struct rtw89_dev *rtwdev);
#endif
@@ -0,0 +1,540 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2023 Realtek Corporation
*/
#include "debug.h"
#include "efuse.h"
#include "mac.h"
#include "reg.h"
#define EFUSE_EXTERNALPN_ADDR_BE 0x1580
#define EFUSE_SERIALNUM_ADDR_BE 0x1581
#define EFUSE_SB_CRYP_SEL_ADDR 0x1582
#define EFUSE_SB_CRYP_SEL_SIZE 2
#define EFUSE_SB_CRYP_SEL_DEFAULT 0xFFFF
#define SB_SEL_MGN_MAX_SIZE 2
#define EFUSE_SEC_BE_START 0x1580
#define EFUSE_SEC_BE_SIZE 4
static const u32 sb_sel_mgn[SB_SEL_MGN_MAX_SIZE] = {
0x8000100, 0xC000180
};
static void rtw89_enable_efuse_pwr_cut_ddv_be(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_hal *hal = &rtwdev->hal;
bool aphy_patch = true;
if (chip->chip_id == RTL8922A && hal->cv == CHIP_CAV)
aphy_patch = false;
rtw89_write8_set(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK);
if (aphy_patch) {
rtw89_write16_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_S);
mdelay(1);
rtw89_write16_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_B);
rtw89_write16_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_ISO_EB2CORE);
}
rtw89_write32_set(rtwdev, R_BE_EFUSE_CTRL_2_V1, B_BE_EF_BURST);
}
static void rtw89_disable_efuse_pwr_cut_ddv_be(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_hal *hal = &rtwdev->hal;
bool aphy_patch = true;
if (chip->chip_id == RTL8922A && hal->cv == CHIP_CAV)
aphy_patch = false;
if (aphy_patch) {
rtw89_write16_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_ISO_EB2CORE);
rtw89_write16_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_B);
mdelay(1);
rtw89_write16_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_S);
}
rtw89_write8_clr(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK);
rtw89_write32_clr(rtwdev, R_BE_EFUSE_CTRL_2_V1, B_BE_EF_BURST);
}
static int rtw89_dump_physical_efuse_map_ddv_be(struct rtw89_dev *rtwdev, u8 *map,
u32 dump_addr, u32 dump_size)
{
u32 efuse_ctl;
u32 addr;
u32 data;
int ret;
if (!IS_ALIGNED(dump_addr, 4) || !IS_ALIGNED(dump_size, 4)) {
rtw89_err(rtwdev, "Efuse addr 0x%x or size 0x%x not aligned\n",
dump_addr, dump_size);
return -EINVAL;
}
rtw89_enable_efuse_pwr_cut_ddv_be(rtwdev);
for (addr = dump_addr; addr < dump_addr + dump_size; addr += 4, map += 4) {
efuse_ctl = u32_encode_bits(addr, B_BE_EF_ADDR_MASK);
rtw89_write32(rtwdev, R_BE_EFUSE_CTRL, efuse_ctl & ~B_BE_EF_RDY);
ret = read_poll_timeout_atomic(rtw89_read32, efuse_ctl,
efuse_ctl & B_BE_EF_RDY, 1, 1000000,
true, rtwdev, R_BE_EFUSE_CTRL);
if (ret)
return -EBUSY;
data = rtw89_read32(rtwdev, R_BE_EFUSE_CTRL_1_V1);
*((__le32 *)map) = cpu_to_le32(data);
}
rtw89_disable_efuse_pwr_cut_ddv_be(rtwdev);
return 0;
}
static int rtw89_dump_physical_efuse_map_dav_be(struct rtw89_dev *rtwdev, u8 *map,
u32 dump_addr, u32 dump_size)
{
u32 addr;
u8 val8;
int err;
int ret;
for (addr = dump_addr; addr < dump_addr + dump_size; addr++) {
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, 0x40,
FULL_BIT_MASK);
if (ret)
return ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_LOW_ADDR, addr & 0xff,
XTAL_SI_LOW_ADDR_MASK);
if (ret)
return ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, addr >> 8,
XTAL_SI_HIGH_ADDR_MASK);
if (ret)
return ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, 0,
XTAL_SI_MODE_SEL_MASK);
if (ret)
return ret;
ret = read_poll_timeout_atomic(rtw89_mac_read_xtal_si, err,
!err && (val8 & XTAL_SI_RDY),
1, 10000, false,
rtwdev, XTAL_SI_CTRL, &val8);
if (ret) {
rtw89_warn(rtwdev, "failed to read dav efuse\n");
return ret;
}
ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_READ_VAL, &val8);
if (ret)
return ret;
*map++ = val8;
}
return 0;
}
int rtw89_cnv_efuse_state_be(struct rtw89_dev *rtwdev, bool idle)
{
u32 val;
int ret = 0;
if (idle) {
rtw89_write32_set(rtwdev, R_BE_WL_BT_PWR_CTRL, B_BE_BT_DISN_EN);
} else {
rtw89_write32_clr(rtwdev, R_BE_WL_BT_PWR_CTRL, B_BE_BT_DISN_EN);
ret = read_poll_timeout(rtw89_read32_mask, val,
val == MAC_AX_SYS_ACT, 50, 5000,
false, rtwdev, R_BE_IC_PWR_STATE,
B_BE_WHOLE_SYS_PWR_STE_MASK);
if (ret)
rtw89_warn(rtwdev, "failed to convert efuse state\n");
}
return ret;
}
static int rtw89_dump_physical_efuse_map_be(struct rtw89_dev *rtwdev, u8 *map,
u32 dump_addr, u32 dump_size, bool dav)
{
int ret;
if (!map || dump_size == 0)
return 0;
rtw89_cnv_efuse_state_be(rtwdev, false);
if (dav) {
ret = rtw89_dump_physical_efuse_map_dav_be(rtwdev, map,
dump_addr, dump_size);
if (ret)
return ret;
rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "phy_map dav: ", map, dump_size);
} else {
ret = rtw89_dump_physical_efuse_map_ddv_be(rtwdev, map,
dump_addr, dump_size);
if (ret)
return ret;
rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "phy_map ddv: ", map, dump_size);
}
rtw89_cnv_efuse_state_be(rtwdev, true);
return 0;
}
#define EFUSE_HDR_CONST_MASK GENMASK(23, 20)
#define EFUSE_HDR_PAGE_MASK GENMASK(19, 17)
#define EFUSE_HDR_OFFSET_MASK GENMASK(16, 4)
#define EFUSE_HDR_OFFSET_DAV_MASK GENMASK(11, 4)
#define EFUSE_HDR_WORD_EN_MASK GENMASK(3, 0)
#define invalid_efuse_header_be(hdr1, hdr2, hdr3) \
((hdr1) == 0xff || (hdr2) == 0xff || (hdr3) == 0xff)
#define invalid_efuse_content_be(word_en, i) \
(((word_en) & BIT(i)) != 0x0)
#define get_efuse_blk_idx_be(hdr1, hdr2, hdr3) \
(((hdr1) << 16) | ((hdr2) << 8) | (hdr3))
#define block_idx_to_logical_idx_be(blk_idx, i) \
(((blk_idx) << 3) + ((i) << 1))
#define invalid_efuse_header_dav_be(hdr1, hdr2) \
((hdr1) == 0xff || (hdr2) == 0xff)
#define get_efuse_blk_idx_dav_be(hdr1, hdr2) \
(((hdr1) << 8) | (hdr2))
static int rtw89_eeprom_parser_be(struct rtw89_dev *rtwdev,
const u8 *phy_map, u32 phy_size, u8 *log_map,
const struct rtw89_efuse_block_cfg *efuse_block)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
enum rtw89_efuse_block blk_page, page;
u32 size = efuse_block->size;
u32 phy_idx, log_idx;
u32 hdr, page_offset;
u8 hdr1, hdr2, hdr3;
u8 i, val0, val1;
u32 min, max;
u16 blk_idx;
u8 word_en;
page = u32_get_bits(efuse_block->offset, RTW89_EFUSE_BLOCK_ID_MASK);
page_offset = u32_get_bits(efuse_block->offset, RTW89_EFUSE_BLOCK_SIZE_MASK);
min = ALIGN_DOWN(page_offset, 2);
max = ALIGN(page_offset + size, 2);
memset(log_map, 0xff, size);
phy_idx = chip->sec_ctrl_efuse_size;
do {
if (page == RTW89_EFUSE_BLOCK_ADIE) {
hdr1 = phy_map[phy_idx];
hdr2 = phy_map[phy_idx + 1];
if (invalid_efuse_header_dav_be(hdr1, hdr2))
break;
phy_idx += 2;
hdr = get_efuse_blk_idx_dav_be(hdr1, hdr2);
blk_page = RTW89_EFUSE_BLOCK_ADIE;
blk_idx = u32_get_bits(hdr, EFUSE_HDR_OFFSET_DAV_MASK);
word_en = u32_get_bits(hdr, EFUSE_HDR_WORD_EN_MASK);
} else {
hdr1 = phy_map[phy_idx];
hdr2 = phy_map[phy_idx + 1];
hdr3 = phy_map[phy_idx + 2];
if (invalid_efuse_header_be(hdr1, hdr2, hdr3))
break;
phy_idx += 3;
hdr = get_efuse_blk_idx_be(hdr1, hdr2, hdr3);
blk_page = u32_get_bits(hdr, EFUSE_HDR_PAGE_MASK);
blk_idx = u32_get_bits(hdr, EFUSE_HDR_OFFSET_MASK);
word_en = u32_get_bits(hdr, EFUSE_HDR_WORD_EN_MASK);
}
if (blk_idx >= RTW89_EFUSE_MAX_BLOCK_SIZE >> 3) {
rtw89_err(rtwdev, "[ERR]efuse idx:0x%X\n", phy_idx - 3);
rtw89_err(rtwdev, "[ERR]read hdr:0x%X\n", hdr);
return -EINVAL;
}
for (i = 0; i < 4; i++) {
if (invalid_efuse_content_be(word_en, i))
continue;
if (phy_idx >= phy_size - 1)
return -EINVAL;
log_idx = block_idx_to_logical_idx_be(blk_idx, i);
if (blk_page == page && log_idx >= min && log_idx < max) {
val0 = phy_map[phy_idx];
val1 = phy_map[phy_idx + 1];
if (log_idx == min && page_offset > min) {
log_map[log_idx - page_offset + 1] = val1;
} else if (log_idx + 2 == max &&
page_offset + size < max) {
log_map[log_idx - page_offset] = val0;
} else {
log_map[log_idx - page_offset] = val0;
log_map[log_idx - page_offset + 1] = val1;
}
}
phy_idx += 2;
}
} while (phy_idx < phy_size);
return 0;
}
static int rtw89_parse_logical_efuse_block_be(struct rtw89_dev *rtwdev,
const u8 *phy_map, u32 phy_size,
enum rtw89_efuse_block block)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_efuse_block_cfg *efuse_block;
u8 *log_map;
int ret;
efuse_block = &chip->efuse_blocks[block];
log_map = kmalloc(efuse_block->size, GFP_KERNEL);
if (!log_map)
return -ENOMEM;
ret = rtw89_eeprom_parser_be(rtwdev, phy_map, phy_size, log_map, efuse_block);
if (ret) {
rtw89_warn(rtwdev, "failed to dump efuse logical block %d\n", block);
goto out_free;
}
rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "log_map: ", log_map, efuse_block->size);
ret = rtwdev->chip->ops->read_efuse(rtwdev, log_map, block);
if (ret) {
rtw89_warn(rtwdev, "failed to read efuse map\n");
goto out_free;
}
out_free:
kfree(log_map);
return ret;
}
int rtw89_parse_efuse_map_be(struct rtw89_dev *rtwdev)
{
u32 phy_size = rtwdev->chip->physical_efuse_size;
u32 dav_phy_size = rtwdev->chip->dav_phy_efuse_size;
enum rtw89_efuse_block block;
u8 *phy_map = NULL;
u8 *dav_phy_map = NULL;
int ret;
if (rtw89_read16(rtwdev, R_BE_SYS_WL_EFUSE_CTRL) & B_BE_AUTOLOAD_SUS)
rtwdev->efuse.valid = true;
else
rtw89_warn(rtwdev, "failed to check efuse autoload\n");
phy_map = kmalloc(phy_size, GFP_KERNEL);
if (dav_phy_size)
dav_phy_map = kmalloc(dav_phy_size, GFP_KERNEL);
if (!phy_map || (dav_phy_size && !dav_phy_map)) {
ret = -ENOMEM;
goto out_free;
}
ret = rtw89_dump_physical_efuse_map_be(rtwdev, phy_map, 0, phy_size, false);
if (ret) {
rtw89_warn(rtwdev, "failed to dump efuse physical map\n");
goto out_free;
}
ret = rtw89_dump_physical_efuse_map_be(rtwdev, dav_phy_map, 0, dav_phy_size, true);
if (ret) {
rtw89_warn(rtwdev, "failed to dump efuse dav physical map\n");
goto out_free;
}
if (rtwdev->hci.type == RTW89_HCI_TYPE_USB)
block = RTW89_EFUSE_BLOCK_HCI_DIG_USB;
else
block = RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO;
ret = rtw89_parse_logical_efuse_block_be(rtwdev, phy_map, phy_size, block);
if (ret) {
rtw89_warn(rtwdev, "failed to parse efuse logic block %d\n",
RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO);
goto out_free;
}
ret = rtw89_parse_logical_efuse_block_be(rtwdev, phy_map, phy_size,
RTW89_EFUSE_BLOCK_RF);
if (ret) {
rtw89_warn(rtwdev, "failed to parse efuse logic block %d\n",
RTW89_EFUSE_BLOCK_RF);
goto out_free;
}
out_free:
kfree(dav_phy_map);
kfree(phy_map);
return ret;
}
int rtw89_parse_phycap_map_be(struct rtw89_dev *rtwdev)
{
u32 phycap_addr = rtwdev->chip->phycap_addr;
u32 phycap_size = rtwdev->chip->phycap_size;
u8 *phycap_map = NULL;
int ret = 0;
if (!phycap_size)
return 0;
phycap_map = kmalloc(phycap_size, GFP_KERNEL);
if (!phycap_map)
return -ENOMEM;
ret = rtw89_dump_physical_efuse_map_be(rtwdev, phycap_map,
phycap_addr, phycap_size, false);
if (ret) {
rtw89_warn(rtwdev, "failed to dump phycap map\n");
goto out_free;
}
ret = rtwdev->chip->ops->read_phycap(rtwdev, phycap_map);
if (ret) {
rtw89_warn(rtwdev, "failed to read phycap map\n");
goto out_free;
}
out_free:
kfree(phycap_map);
return ret;
}
static u16 get_sb_cryp_sel_idx(u16 sb_cryp_sel)
{
u8 low_bit, high_bit, cnt_zero = 0;
u8 idx, sel_form_v, sel_idx_v;
u16 sb_cryp_sel_v = 0x0;
sel_form_v = u16_get_bits(sb_cryp_sel, MASKBYTE0);
sel_idx_v = u16_get_bits(sb_cryp_sel, MASKBYTE1);
for (idx = 0; idx < 4; idx++) {
low_bit = !!(sel_form_v & BIT(idx));
high_bit = !!(sel_form_v & BIT(7 - idx));
if (low_bit != high_bit)
return U16_MAX;
if (low_bit)
continue;
cnt_zero++;
if (cnt_zero == 1)
sb_cryp_sel_v = idx * 16;
else if (cnt_zero > 1)
return U16_MAX;
}
low_bit = u8_get_bits(sel_idx_v, 0x0F);
high_bit = u8_get_bits(sel_idx_v, 0xF0);
if ((low_bit ^ high_bit) != 0xF)
return U16_MAX;
return sb_cryp_sel_v + low_bit;
}
int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
{
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
u32 sec_addr = EFUSE_SEC_BE_START;
u32 sec_size = EFUSE_SEC_BE_SIZE;
u16 sb_cryp_sel, sb_cryp_sel_idx;
u8 sec_map[EFUSE_SEC_BE_SIZE];
u8 b1, b2;
int ret;
ret = rtw89_dump_physical_efuse_map_be(rtwdev, sec_map,
sec_addr, sec_size, false);
if (ret) {
rtw89_warn(rtwdev, "failed to dump secsel map\n");
return ret;
}
sb_cryp_sel = sec_map[EFUSE_SB_CRYP_SEL_ADDR - sec_addr] |
sec_map[EFUSE_SB_CRYP_SEL_ADDR - sec_addr + 1] << 8;
if (sb_cryp_sel == EFUSE_SB_CRYP_SEL_DEFAULT)
goto out;
sb_cryp_sel_idx = get_sb_cryp_sel_idx(sb_cryp_sel);
if (sb_cryp_sel_idx >= SB_SEL_MGN_MAX_SIZE) {
rtw89_warn(rtwdev, "invalid SB cryp sel idx %d\n", sb_cryp_sel_idx);
goto out;
}
sec->sb_sel_mgn = sb_sel_mgn[sb_cryp_sel_idx];
b1 = sec_map[EFUSE_EXTERNALPN_ADDR_BE - sec_addr];
b2 = sec_map[EFUSE_SERIALNUM_ADDR_BE - sec_addr];
ret = rtw89_efuse_recognize_mss_info_v1(rtwdev, b1, b2);
if (ret)
goto out;
sec->secure_boot = true;
out:
rtw89_debug(rtwdev, RTW89_DBG_FW,
"MSS secure_boot=%d dev_type=%d cust_idx=%d key_num=%d\n",
sec->secure_boot, sec->mss_dev_type, sec->mss_cust_idx,
sec->mss_key_num);
return 0;
}
int rtw89_efuse_read_ecv_be(struct rtw89_dev *rtwdev)
{
u32 dump_addr;
u8 buff[4]; /* efuse access must 4 bytes align */
int ret;
u8 ecv;
u8 val;
dump_addr = ALIGN_DOWN(EF_FV_OFSET_BE_V1, 4);
ret = rtw89_dump_physical_efuse_map_be(rtwdev, buff, dump_addr, 4, false);
if (ret)
return ret;
val = buff[EF_FV_OFSET_BE_V1 & 0x3];
ecv = u8_get_bits(val, EF_CV_MASK);
if (ecv == EF_CV_INV)
return -ENOENT;
rtwdev->hal.cv = ecv;
return 0;
}
EXPORT_SYMBOL(rtw89_efuse_read_ecv_be);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,901 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2023 Realtek Corporation
*/
#include <linux/pci.h>
#include "mac.h"
#include "pci.h"
#include "reg.h"
enum pcie_rxbd_mode {
PCIE_RXBD_NORM = 0,
PCIE_RXBD_SEP,
PCIE_RXBD_EXT,
};
#define PL0_TMR_SCALE_ASIC 1
#define PL0_TMR_ANA_172US 0x800
#define PL0_TMR_MAC_1MS 0x27100
#define PL0_TMR_AUX_1MS 0x1E848
static void rtw89_pci_aspm_set_be(struct rtw89_dev *rtwdev, bool enable)
{
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
struct pci_dev *pdev = rtwpci->pdev;
u8 value = 0;
int ret;
ret = pci_read_config_byte(pdev, RTW89_PCIE_ASPM_CTRL, &value);
if (ret)
rtw89_warn(rtwdev, "failed to read ASPM Delay\n");
u8p_replace_bits(&value, PCIE_L1DLY_16US, RTW89_L1DLY_MASK);
ret = pci_write_config_byte(pdev, RTW89_PCIE_ASPM_CTRL, value);
if (ret)
rtw89_warn(rtwdev, "failed to write ASPM Delay\n");
if (enable)
rtw89_write32_set(rtwdev, R_AX_PCIE_MIX_CFG_V1,
B_BE_ASPM_CTRL_L1);
else
rtw89_write32_clr(rtwdev, R_AX_PCIE_MIX_CFG_V1,
B_BE_ASPM_CTRL_L1);
}
static void rtw89_pci_l1ss_set_be(struct rtw89_dev *rtwdev, bool enable)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
struct rtw89_hal *hal = &rtwdev->hal;
if (enable && chip_id == RTL8922D && hal->cid == RTL8922D_CID7090)
rtw89_write32_set(rtwdev, R_BE_PCIE_PS_CTRL,
B_BE_ASPM_L11_EN | B_BE_ASPM_L12_EN |
B_BE_PCIPM_L11_EN | B_BE_PCIPM_L12_EN);
if (enable)
rtw89_write32_set(rtwdev, R_BE_PCIE_MIX_CFG,
B_BE_L1SUB_ENABLE);
else
rtw89_write32_clr(rtwdev, R_BE_PCIE_MIX_CFG,
B_BE_L1SUB_ENABLE);
}
static void rtw89_pci_clkreq_set_be(struct rtw89_dev *rtwdev, bool enable)
{
rtw89_write32_mask(rtwdev, R_BE_PCIE_LAT_CTRL, B_BE_CLK_REQ_LAT_MASK,
PCIE_CLKDLY_HW_V1_0);
if (enable)
rtw89_write32_set(rtwdev, R_BE_L1_CLK_CTRL,
B_BE_CLK_PM_EN);
else
rtw89_write32_clr(rtwdev, R_AX_L1_CLK_CTRL,
B_BE_CLK_PM_EN);
}
static void _patch_pcie_power_wake_be(struct rtw89_dev *rtwdev, bool power_up)
{
if (power_up)
rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, BIT_WAKE_CTRL_V1);
else
rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, BIT_WAKE_CTRL_V1);
}
static void _patch_pre_init_be(struct rtw89_dev *rtwdev)
{
struct rtw89_hal *hal = &rtwdev->hal;
if (!(rtwdev->chip->chip_id == RTL8922D && hal->cid == RTL8922D_CID7090))
return;
rtw89_write16_clr(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G2 +
RAC_ANA14 * RAC_MULT, EIEOS_L1SS_WAIT_CLKRDY);
}
static void rtw89_pci_set_io_rcy_be(struct rtw89_dev *rtwdev)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
u32 scale = PL0_TMR_SCALE_ASIC;
u32 val32;
if (info->io_rcy_en == MAC_AX_PCIE_ENABLE) {
val32 = info->io_rcy_tmr == MAC_AX_IO_RCY_ANA_TMR_DEF ?
PL0_TMR_ANA_172US : info->io_rcy_tmr;
val32 /= scale;
rtw89_write32(rtwdev, R_BE_AON_WDT_TMR, val32);
rtw89_write32(rtwdev, R_BE_MDIO_WDT_TMR, val32);
rtw89_write32(rtwdev, R_BE_LA_MODE_WDT_TMR, val32);
rtw89_write32(rtwdev, R_BE_WDT_AR_TMR, val32);
rtw89_write32(rtwdev, R_BE_WDT_AW_TMR, val32);
rtw89_write32(rtwdev, R_BE_WDT_W_TMR, val32);
rtw89_write32(rtwdev, R_BE_WDT_B_TMR, val32);
rtw89_write32(rtwdev, R_BE_WDT_R_TMR, val32);
val32 = info->io_rcy_tmr == MAC_AX_IO_RCY_ANA_TMR_DEF ?
PL0_TMR_MAC_1MS : info->io_rcy_tmr;
val32 /= scale;
rtw89_write32(rtwdev, R_BE_WLAN_WDT_TMR, val32);
rtw89_write32(rtwdev, R_BE_AXIDMA_WDT_TMR, val32);
val32 = info->io_rcy_tmr == MAC_AX_IO_RCY_ANA_TMR_DEF ?
PL0_TMR_AUX_1MS : info->io_rcy_tmr;
val32 /= scale;
rtw89_write32(rtwdev, R_BE_LOCAL_WDT_TMR, val32);
} else {
rtw89_write32_clr(rtwdev, R_BE_WLAN_WDT, B_BE_WLAN_WDT_ENABLE);
rtw89_write32_clr(rtwdev, R_BE_AXIDMA_WDT, B_BE_AXIDMA_WDT_ENABLE);
rtw89_write32_clr(rtwdev, R_BE_AON_WDT, B_BE_AON_WDT_ENABLE);
rtw89_write32_clr(rtwdev, R_BE_LOCAL_WDT, B_BE_LOCAL_WDT_ENABLE);
rtw89_write32_clr(rtwdev, R_BE_MDIO_WDT, B_BE_MDIO_WDT_ENABLE);
rtw89_write32_clr(rtwdev, R_BE_LA_MODE_WDT, B_BE_LA_MODE_WDT_ENABLE);
rtw89_write32_clr(rtwdev, R_BE_WDT_AR, B_BE_WDT_AR_ENABLE);
rtw89_write32_clr(rtwdev, R_BE_WDT_AW, B_BE_WDT_AW_ENABLE);
rtw89_write32_clr(rtwdev, R_BE_WDT_W, B_BE_WDT_W_ENABLE);
rtw89_write32_clr(rtwdev, R_BE_WDT_B, B_BE_WDT_B_ENABLE);
rtw89_write32_clr(rtwdev, R_BE_WDT_R, B_BE_WDT_R_ENABLE);
}
}
static void rtw89_pci_ctrl_wpdma_pcie_be(struct rtw89_dev *rtwdev, bool en)
{
if (en)
rtw89_write32_clr(rtwdev, R_BE_HAXI_DMA_STOP1, B_BE_STOP_WPDMA);
else
rtw89_write32_set(rtwdev, R_BE_HAXI_DMA_STOP1, B_BE_STOP_WPDMA);
}
static void rtw89_pci_ctrl_trxdma_pcie_be(struct rtw89_dev *rtwdev,
enum mac_ax_pcie_func_ctrl tx_en,
enum mac_ax_pcie_func_ctrl rx_en,
enum mac_ax_pcie_func_ctrl io_en)
{
u32 val;
val = rtw89_read32(rtwdev, R_BE_HAXI_INIT_CFG1);
if (tx_en == MAC_AX_PCIE_ENABLE)
val |= B_BE_TXDMA_EN;
else if (tx_en == MAC_AX_PCIE_DISABLE)
val &= ~B_BE_TXDMA_EN;
if (rx_en == MAC_AX_PCIE_ENABLE)
val |= B_BE_RXDMA_EN;
else if (rx_en == MAC_AX_PCIE_DISABLE)
val &= ~B_BE_RXDMA_EN;
if (io_en == MAC_AX_PCIE_ENABLE)
val &= ~B_BE_STOP_AXI_MST;
else if (io_en == MAC_AX_PCIE_DISABLE)
val |= B_BE_STOP_AXI_MST;
rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val);
if (io_en == MAC_AX_PCIE_ENABLE && rtwdev->chip->chip_id == RTL8922A)
rtw89_write32_mask(rtwdev, R_BE_HAXI_MST_WDT_TIMEOUT_SEL_V1,
B_BE_HAXI_MST_WDT_TIMEOUT_SEL_MASK, 4);
}
static void rtw89_pci_clr_idx_all_be(struct rtw89_dev *rtwdev)
{
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_pci_rx_ring *rx_ring;
u32 val;
if (chip->chip_id == RTL8922A)
val = B_BE_CLR_ALL_IDX_MASK;
else
val = B_BE_CLR_ALL_IDX_MASK_V1;
rtw89_write32(rtwdev, R_BE_TXBD_RWPTR_CLR1, val);
rtw89_write32(rtwdev, R_BE_RXBD_RWPTR_CLR1_V1,
B_BE_CLR_RXQ0_IDX | B_BE_CLR_RPQ0_IDX);
rx_ring = &rtwpci->rx.rings[RTW89_RXCH_RXQ];
rtw89_write16(rtwdev, R_BE_RXQ0_RXBD_IDX_V1, rx_ring->bd_ring.len - 1);
rx_ring = &rtwpci->rx.rings[RTW89_RXCH_RPQ];
rtw89_write16(rtwdev, R_BE_RPQ0_RXBD_IDX_V1, rx_ring->bd_ring.len - 1);
}
static int rtw89_pci_poll_txdma_ch_idle_be(struct rtw89_dev *rtwdev)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
u32 dma_busy1 = info->dma_busy1.addr;
u32 check = info->dma_busy1.mask;
u32 val;
return read_poll_timeout(rtw89_read32, val, (val & check) == 0,
10, 1000, false, rtwdev, dma_busy1);
}
static int rtw89_pci_poll_rxdma_ch_idle_be(struct rtw89_dev *rtwdev)
{
u32 check;
u32 val;
check = B_BE_RXQ0_BUSY_V1 | B_BE_RPQ0_BUSY_V1;
return read_poll_timeout(rtw89_read32, val, (val & check) == 0,
10, 1000, false, rtwdev, R_BE_HAXI_DMA_BUSY1);
}
static int rtw89_pci_poll_dma_all_idle_be(struct rtw89_dev *rtwdev)
{
int ret;
ret = rtw89_pci_poll_txdma_ch_idle_be(rtwdev);
if (ret) {
rtw89_err(rtwdev, "txdma ch busy\n");
return ret;
}
ret = rtw89_pci_poll_rxdma_ch_idle_be(rtwdev);
if (ret) {
rtw89_err(rtwdev, "rxdma ch busy\n");
return ret;
}
return 0;
}
static void rtw89_pci_mode_op_be(struct rtw89_dev *rtwdev)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
const struct rtw89_chip_info *chip = rtwdev->chip;
u32 val32_init1, val32_rxapp, val32_exp;
val32_init1 = rtw89_read32(rtwdev, R_BE_HAXI_INIT_CFG1);
if (chip->chip_id == RTL8922A)
val32_rxapp = rtw89_read32(rtwdev, R_BE_RX_APPEND_MODE);
val32_exp = rtw89_read32(rtwdev, R_BE_HAXI_EXP_CTRL_V1);
if (chip->chip_id == RTL8922A) {
if (info->rxbd_mode == MAC_AX_RXBD_PKT) {
val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_NORM,
B_BE_RXQ_RXBD_MODE_MASK);
} else if (info->rxbd_mode == MAC_AX_RXBD_SEP) {
val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_SEP,
B_BE_RXQ_RXBD_MODE_MASK);
val32_rxapp = u32_replace_bits(val32_rxapp, 0,
B_BE_APPEND_LEN_MASK);
}
}
val32_init1 = u32_replace_bits(val32_init1, info->tx_burst,
B_BE_MAX_TXDMA_MASK);
val32_init1 = u32_replace_bits(val32_init1, info->rx_burst,
B_BE_MAX_RXDMA_MASK);
val32_exp = u32_replace_bits(val32_exp, info->multi_tag_num,
B_BE_MAX_TAG_NUM_MASK);
val32_init1 = u32_replace_bits(val32_init1, info->wd_dma_idle_intvl,
B_BE_CFG_WD_PERIOD_IDLE_MASK);
val32_init1 = u32_replace_bits(val32_init1, info->wd_dma_act_intvl,
B_BE_CFG_WD_PERIOD_ACTIVE_MASK);
rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val32_init1);
if (chip->chip_id == RTL8922A)
rtw89_write32(rtwdev, R_BE_RX_APPEND_MODE, val32_rxapp);
rtw89_write32(rtwdev, R_BE_HAXI_EXP_CTRL_V1, val32_exp);
}
static int rtw89_pci_rst_bdram_be(struct rtw89_dev *rtwdev)
{
u32 val;
rtw89_write32_set(rtwdev, R_BE_HAXI_INIT_CFG1, B_BE_SET_BDRAM_BOUND);
return read_poll_timeout(rtw89_read32, val, !(val & B_BE_SET_BDRAM_BOUND),
50, 500000, false, rtwdev, R_BE_HAXI_INIT_CFG1);
}
static void rtw89_pci_debounce_be(struct rtw89_dev *rtwdev)
{
u32 val32;
val32 = rtw89_read32(rtwdev, R_BE_SYS_PAGE_CLK_GATED);
val32 = u32_replace_bits(val32, 0, B_BE_PCIE_PRST_DEBUNC_PERIOD_MASK);
val32 |= B_BE_SYM_PRST_DEBUNC_SEL;
rtw89_write32(rtwdev, R_BE_SYS_PAGE_CLK_GATED, val32);
}
static void rtw89_pci_ldo_low_pwr_be(struct rtw89_dev *rtwdev)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
struct rtw89_hal *hal = &rtwdev->hal;
u32 clr;
rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_PSUS_OFF_CAPC_EN);
rtw89_write32_set(rtwdev, R_BE_SYS_PAGE_CLK_GATED,
B_BE_SOP_OFFPOOBS_PC | B_BE_CPHY_AUXCLK_OP |
B_BE_CPHY_POWER_READY_CHK);
rtw89_write32_clr(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_PCIE_FORCE_IBX_EN |
B_BE_PCIE_DIS_L2_RTK_PERST |
B_BE_PCIE_DIS_L2__CTRL_LDO_HCI);
if (chip_id == RTL8922D && hal->cid == RTL8922D_CID7090)
clr = B_BE_PCIE_DIS_L1_2_CTRL_HCILDO |
B_BE_PCIE_DIS_L1_2_CTRL_APHY_SUSB |
B_BE_PCIE_DIS_RTK_PRST_N_L1_2 |
B_BE_PCIE_DIS_L2_CTRL_APHY_SUSB;
else
clr = B_BE_PCIE_DIS_L1_2_CTRL_HCILDO;
rtw89_write32_clr(rtwdev, R_BE_L1_2_CTRL_HCILDO, clr);
}
static void rtw89_pci_pcie_setting_be(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_hal *hal = &rtwdev->hal;
rtw89_write32_set(rtwdev, R_BE_PCIE_FRZ_CLK, B_BE_PCIE_EN_AUX_CLK);
rtw89_write32_clr(rtwdev, R_BE_PCIE_PS_CTRL, B_BE_CMAC_EXIT_L1_EN);
if (chip->chip_id == RTL8922A && hal->cv == CHIP_CAV)
return;
rtw89_write32_set(rtwdev, R_BE_EFUSE_CTRL_2_V1, B_BE_R_SYM_AUTOLOAD_WITH_PMC_SEL);
rtw89_write32_set(rtwdev, R_BE_PCIE_LAT_CTRL, B_BE_SYM_AUX_CLK_SEL);
if (chip->chip_id != RTL8922D)
return;
rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_R_SYM_PRST_CPHY_RST);
rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_USUS_OFFCAPC_EN);
rtw89_write32(rtwdev, R_BE_PCIE_HCI2FW_ISR, 0xFFFFFFFF);
}
static void rtw89_pci_ser_setting_be(struct rtw89_dev *rtwdev)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
struct rtw89_hal *hal = &rtwdev->hal;
u32 val32;
int ret;
if (chip_id == RTL8922D)
goto be2_chips;
else if (chip_id != RTL8922A)
return;
rtw89_write32(rtwdev, R_BE_PL1_DBG_INFO, 0x0);
switch (hal->cv) {
case CHIP_CAV:
case CHIP_CBV:
rtw89_write32_clr(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
rtw89_write32_mask(rtwdev, R_BE_SER_PL1_CTRL,
B_BE_PL1_TIMER_UNIT_MASK, PCIE_SER_TIMER_UNIT);
val32 = rtw89_read32(rtwdev, R_BE_REG_PL1_MASK);
val32 &= ~(B_BE_SER_PMU_IMR | B_BE_SER_L1SUB_IMR |
B_BE_SER_PM_MASTER_IMR | B_BE_SER_LTSSM_IMR |
B_BE_SER_PM_CLK_MASK | B_BE_SER_PCLKREQ_ACK_MASK);
rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32);
break;
case CHIP_CCV:
default:
rtw89_write32_clr(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
ret = read_poll_timeout_atomic(rtw89_read32, val32, !val32,
1, 1000, false, rtwdev, R_BE_REG_PL1_ISR);
if (ret)
rtw89_warn(rtwdev, "[ERR] PCIE SER clear poll fail\n");
rtw89_write32_mask(rtwdev, R_BE_SER_PL1_CTRL,
B_BE_PL1_TIMER_UNIT_MASK, PCIE_SER_TIMER_UNIT);
rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
val32 = rtw89_read32(rtwdev, R_BE_REG_PL1_MASK);
val32 |= (B_BE_SER_PMU_IMR | B_BE_SER_PM_MASTER_IMR |
B_BE_SER_LTSSM_IMR | B_BE_SER_PM_CLK_MASK |
B_BE_SER_PCLKREQ_ACK_MASK);
val32 &= ~B_BE_SER_L1SUB_IMR;
rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32);
break;
}
return;
be2_chips:
rtw89_write32_clr(rtwdev, R_BE_PCIE_SER_DBG, B_BE_PCIE_SER_FLUSH_RSTB);
rtw89_write32_set(rtwdev, R_BE_PCIE_SER_DBG, B_BE_PCIE_SER_FLUSH_RSTB);
rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G1 +
RAC_ANA40 * RAC_MULT, PHY_ERR_IMR_DIS);
rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G2 +
RAC_ANA40 * RAC_MULT, PHY_ERR_IMR_DIS);
rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G1 +
RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN);
rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G2 +
RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN);
rtw89_write16_set(rtwdev, RAC_DIRECT_OFFESET_L0_G1 +
RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN);
rtw89_write16_set(rtwdev, RAC_DIRECT_OFFESET_L0_G2 +
RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN);
val32 = rtw89_read32(rtwdev, R_BE_SER_PL1_CTRL);
val32 &= ~B_BE_PL1_SER_PL1_EN;
rtw89_write32(rtwdev, R_BE_SER_PL1_CTRL, val32);
rtw89_write32(rtwdev, R_BE_REG_PL1_ISR, B_PCIE_SER_ALL_ISR);
ret = read_poll_timeout_atomic(rtw89_read32, val32, !val32,
1, 1000, false, rtwdev, R_BE_REG_PL1_ISR);
if (ret)
rtw89_warn(rtwdev, "[ERR] PCIE SER clear poll fail\n");
val32 = rtw89_read32(rtwdev, R_BE_REG_PL1_MASK);
val32 |= B_BE_SER_PMU_IMR | B_BE_SER_PM_MASTER_IMR |
B_BE_SER_LTSSM_IMR | B_BE_SER_PM_CLK_MASK | B_BE_SER_PCLKREQ_ACK_MASK |
B_BE_SER_LTSSM_UNSTABLE_MASK;
val32 &= ~B_BE_SER_L1SUB_IMR;
rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32);
rtw89_write32_mask(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_TIMER_UNIT_MASK,
PCIE_SER_TIMER_UNIT);
rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
if (hal->cid == RTL8922D_CID7090)
rtw89_write32_set(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_SER_DETECT_EN);
}
static void rtw89_pci_ctrl_txdma_ch_be(struct rtw89_dev *rtwdev, bool enable)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
u32 mask_all;
u32 val;
mask_all = B_BE_STOP_CH0 | B_BE_STOP_CH1 | B_BE_STOP_CH2 |
B_BE_STOP_CH3 | B_BE_STOP_CH4 | B_BE_STOP_CH5 |
B_BE_STOP_CH6 | B_BE_STOP_CH7 | B_BE_STOP_CH8 |
B_BE_STOP_CH9 | B_BE_STOP_CH10 | B_BE_STOP_CH11;
/* mask out unsupported channels for certains chips */
mask_all &= info->dma_stop1.mask;
val = rtw89_read32(rtwdev, R_BE_HAXI_DMA_STOP1);
val |= B_BE_STOP_CH13 | B_BE_STOP_CH14;
if (enable)
val &= ~mask_all;
else
val |= mask_all;
rtw89_write32(rtwdev, R_BE_HAXI_DMA_STOP1, val);
}
static void rtw89_pci_ctrl_txdma_fw_ch_be(struct rtw89_dev *rtwdev, bool enable)
{
u32 val = rtw89_read32(rtwdev, R_BE_HAXI_DMA_STOP1);
if (enable)
val &= ~B_BE_STOP_CH12;
else
val |= B_BE_STOP_CH12;
rtw89_write32(rtwdev, R_BE_HAXI_DMA_STOP1, val);
}
static int rtw89_pci_ops_mac_pre_init_be(struct rtw89_dev *rtwdev)
{
int ret;
rtw89_pci_set_io_rcy_be(rtwdev);
_patch_pcie_power_wake_be(rtwdev, true);
_patch_pre_init_be(rtwdev);
rtw89_pci_ctrl_wpdma_pcie_be(rtwdev, false);
rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_DISABLE,
MAC_AX_PCIE_DISABLE, MAC_AX_PCIE_DISABLE);
rtw89_pci_clr_idx_all_be(rtwdev);
ret = rtw89_pci_poll_dma_all_idle_be(rtwdev);
if (ret) {
rtw89_err(rtwdev, "[ERR] poll pcie dma all idle\n");
return ret;
}
rtw89_pci_mode_op_be(rtwdev);
rtw89_pci_ops_reset(rtwdev);
ret = rtw89_pci_rst_bdram_be(rtwdev);
if (ret) {
rtw89_err(rtwdev, "[ERR]pcie rst bdram\n");
return ret;
}
rtw89_pci_debounce_be(rtwdev);
rtw89_pci_ldo_low_pwr_be(rtwdev);
rtw89_pci_pcie_setting_be(rtwdev);
rtw89_pci_ser_setting_be(rtwdev);
rtw89_pci_ctrl_txdma_ch_be(rtwdev, false);
rtw89_pci_ctrl_txdma_fw_ch_be(rtwdev, true);
rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_ENABLE,
MAC_AX_PCIE_ENABLE, MAC_AX_PCIE_ENABLE);
return 0;
}
static int rtw89_pci_ops_mac_pre_deinit_be(struct rtw89_dev *rtwdev)
{
u32 val;
_patch_pcie_power_wake_be(rtwdev, false);
val = rtw89_read32_mask(rtwdev, R_BE_IC_PWR_STATE, B_BE_WLMAC_PWR_STE_MASK);
if (val == 0)
return 0;
rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_DISABLE,
MAC_AX_PCIE_DISABLE, MAC_AX_PCIE_DISABLE);
rtw89_pci_clr_idx_all_be(rtwdev);
return 0;
}
int rtw89_pci_ltr_set_v2(struct rtw89_dev *rtwdev, bool en)
{
u32 ctrl0, cfg0, cfg1, dec_ctrl, idle_ltcy, act_ltcy, dis_ltcy;
u32 ltr_idle_lat_ctrl, ltr_act_lat_ctrl;
ctrl0 = rtw89_read32(rtwdev, R_BE_LTR_CTRL_0);
if (rtw89_pci_ltr_is_err_reg_val(ctrl0))
return -EINVAL;
cfg0 = rtw89_read32(rtwdev, R_BE_LTR_CFG_0);
if (rtw89_pci_ltr_is_err_reg_val(cfg0))
return -EINVAL;
cfg1 = rtw89_read32(rtwdev, R_BE_LTR_CFG_1);
if (rtw89_pci_ltr_is_err_reg_val(cfg1))
return -EINVAL;
dec_ctrl = rtw89_read32(rtwdev, R_BE_LTR_DECISION_CTRL_V1);
if (rtw89_pci_ltr_is_err_reg_val(dec_ctrl))
return -EINVAL;
idle_ltcy = rtw89_read32(rtwdev, R_BE_LTR_LATENCY_IDX3_V1);
if (rtw89_pci_ltr_is_err_reg_val(idle_ltcy))
return -EINVAL;
act_ltcy = rtw89_read32(rtwdev, R_BE_LTR_LATENCY_IDX1_V1);
if (rtw89_pci_ltr_is_err_reg_val(act_ltcy))
return -EINVAL;
dis_ltcy = rtw89_read32(rtwdev, R_BE_LTR_LATENCY_IDX0_V1);
if (rtw89_pci_ltr_is_err_reg_val(dis_ltcy))
return -EINVAL;
if (en) {
dec_ctrl |= B_BE_ENABLE_LTR_CTL_DECISION | B_BE_LTR_HW_DEC_EN_V1;
ctrl0 |= B_BE_LTR_HW_EN;
} else {
dec_ctrl &= ~(B_BE_ENABLE_LTR_CTL_DECISION | B_BE_LTR_HW_DEC_EN_V1 |
B_BE_LTR_EN_PORT_V1_MASK);
ctrl0 &= ~B_BE_LTR_HW_EN;
}
dec_ctrl = u32_replace_bits(dec_ctrl, PCI_LTR_SPC_500US,
B_BE_LTR_SPACE_IDX_MASK);
cfg0 = u32_replace_bits(cfg0, PCI_LTR_IDLE_TIMER_3_2MS,
B_BE_LTR_IDLE_TIMER_IDX_MASK);
cfg1 = u32_replace_bits(cfg1, 0xC0, B_BE_LTR_CMAC0_RX_USE_PG_TH_MASK);
cfg1 = u32_replace_bits(cfg1, 0xC0, B_BE_LTR_CMAC1_RX_USE_PG_TH_MASK);
cfg0 = u32_replace_bits(cfg0, 1, B_BE_LTR_IDX_ACTIVE_MASK);
cfg0 = u32_replace_bits(cfg0, 3, B_BE_LTR_IDX_IDLE_MASK);
dec_ctrl = u32_replace_bits(dec_ctrl, 0, B_BE_LTR_IDX_DISABLE_V1_MASK);
if (rtwdev->chip->chip_id == RTL8922A) {
ltr_idle_lat_ctrl = 0x90039003;
ltr_act_lat_ctrl = 0x880b880b;
} else {
ltr_idle_lat_ctrl = 0x90019001;
ltr_act_lat_ctrl = 0x88018801;
}
rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX3_V1, ltr_idle_lat_ctrl);
rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX1_V1, ltr_act_lat_ctrl);
rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX0_V1, 0);
rtw89_write32(rtwdev, R_BE_LTR_DECISION_CTRL_V1, dec_ctrl);
rtw89_write32(rtwdev, R_BE_LTR_CFG_0, cfg0);
rtw89_write32(rtwdev, R_BE_LTR_CFG_1, cfg1);
rtw89_write32(rtwdev, R_BE_LTR_CTRL_0, ctrl0);
return 0;
}
EXPORT_SYMBOL(rtw89_pci_ltr_set_v2);
static void rtw89_pci_configure_mit_be(struct rtw89_dev *rtwdev)
{
u32 cnt;
u32 val;
rtw89_write32_mask(rtwdev, R_BE_PCIE_MIT0_TMR,
B_BE_PCIE_MIT0_RX_TMR_MASK, BE_MIT0_TMR_UNIT_1MS);
val = rtw89_read32(rtwdev, R_BE_PCIE_MIT0_CNT);
cnt = min_t(u32, U8_MAX, RTW89_PCI_RXBD_NUM_MAX / 2);
val = u32_replace_bits(val, cnt, B_BE_PCIE_RX_MIT0_CNT_MASK);
val = u32_replace_bits(val, 2, B_BE_PCIE_RX_MIT0_TMR_CNT_MASK);
rtw89_write32(rtwdev, R_BE_PCIE_MIT0_CNT, val);
}
static int rtw89_pci_ops_mac_post_init_be(struct rtw89_dev *rtwdev)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
int ret;
ret = info->ltr_set(rtwdev, true);
if (ret) {
rtw89_err(rtwdev, "pci ltr set fail\n");
return ret;
}
rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_IGNORE,
MAC_AX_PCIE_IGNORE, MAC_AX_PCIE_ENABLE);
rtw89_pci_ctrl_wpdma_pcie_be(rtwdev, true);
rtw89_pci_ctrl_txdma_ch_be(rtwdev, true);
rtw89_pci_ctrl_txdma_fw_ch_be(rtwdev, true);
rtw89_pci_configure_mit_be(rtwdev);
return 0;
}
static int rtw89_pci_poll_io_idle_be(struct rtw89_dev *rtwdev)
{
u32 sts;
int ret;
ret = read_poll_timeout_atomic(rtw89_read32, sts,
!(sts & B_BE_HAXI_MST_BUSY),
10, 1000, false, rtwdev,
R_BE_HAXI_DMA_BUSY1);
if (ret) {
rtw89_err(rtwdev, "pci dmach busy1 0x%X\n", sts);
return ret;
}
return 0;
}
static int rtw89_pci_lv1rst_stop_dma_be(struct rtw89_dev *rtwdev)
{
int ret;
rtw89_pci_ctrl_dma_all(rtwdev, false);
ret = rtw89_pci_poll_io_idle_be(rtwdev);
if (!ret)
return 0;
rtw89_debug(rtwdev, RTW89_DBG_HCI,
"[PCIe] poll_io_idle fail; reset hci dma trx\n");
rtw89_mac_ctrl_hci_dma_trx(rtwdev, false);
rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
return rtw89_pci_poll_io_idle_be(rtwdev);
}
static int rtw89_pci_lv1rst_start_dma_be(struct rtw89_dev *rtwdev)
{
int ret;
rtw89_mac_ctrl_hci_dma_trx(rtwdev, false);
rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
rtw89_pci_clr_idx_all(rtwdev);
ret = rtw89_pci_rst_bdram_be(rtwdev);
if (ret)
return ret;
rtw89_pci_ctrl_dma_all(rtwdev, true);
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);
struct rtw89_dev *rtwdev = hw->priv;
u32 val32;
rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6);
rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_R_DIS_PRST);
rtw89_write32_clr(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6);
rtw89_write32_set(rtwdev, R_BE_PCIE_FRZ_CLK, B_BE_PCIE_FRZ_REG_RST);
val32 = rtw89_read32(rtwdev, R_BE_SER_PL1_CTRL);
if (val32 & B_BE_PL1_SER_PL1_EN) {
val32 = u32_replace_bits(val32, PCIE_SER_WOW_TIMER_UNIT,
B_BE_PL1_TIMER_UNIT_MASK);
rtw89_write32(rtwdev, R_BE_SER_PL1_CTRL, val32);
if (rtwdev->chip->chip_id == RTL8922A)
rtw89_write32_clr(rtwdev, R_BE_REG_PL1_MASK,
B_BE_SER_PM_MASTER_IMR);
}
return 0;
}
static int __maybe_unused rtw89_pci_resume_be(struct device *dev)
{
struct ieee80211_hw *hw = dev_get_drvdata(dev);
struct rtw89_dev *rtwdev = hw->priv;
u32 polling;
u32 val32;
u16 val16;
int ret;
rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6);
rtw89_write32_clr(rtwdev, R_BE_RSV_CTRL, B_BE_R_DIS_PRST);
rtw89_write32_clr(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6);
rtw89_write32_clr(rtwdev, R_BE_PCIE_FRZ_CLK, B_BE_PCIE_FRZ_REG_RST);
val32 = rtw89_read32(rtwdev, R_BE_SER_PL1_CTRL);
if (!(val32 & B_BE_PL1_SER_PL1_EN))
goto clear_phy_isr;
rtw89_write32_clr(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
if (rtwdev->chip->chip_id == RTL8922D)
rtw89_write32(rtwdev, R_BE_REG_PL1_ISR, B_PCIE_SER_ALL_ISR);
ret = read_poll_timeout_atomic(rtw89_read32, polling, !polling, 1, 1000,
false, rtwdev, R_BE_REG_PL1_ISR);
if (ret)
rtw89_warn(rtwdev, "[ERR] PCIE SER clear polling fail\n");
if (rtwdev->chip->chip_id == RTL8922A)
rtw89_write32_set(rtwdev, R_BE_REG_PL1_MASK,
B_BE_SER_PM_MASTER_IMR | B_BE_SER_PCLKREQ_ACK_MASK);
val32 = rtw89_read32(rtwdev, R_BE_SER_PL1_CTRL);
val32 = u32_replace_bits(val32, PCIE_SER_TIMER_UNIT, B_BE_PL1_TIMER_UNIT_MASK);
val32 |= B_BE_PL1_SER_PL1_EN;
rtw89_write32(rtwdev, R_BE_SER_PL1_CTRL, val32);
clear_phy_isr:
if (rtwdev->chip->chip_id == RTL8922D) {
val16 = rtw89_read16(rtwdev, RAC_DIRECT_OFFESET_L0_G2 +
RAC_ANA41 * RAC_MULT);
if (val16 & PHY_ERR_FLAG_EN) {
rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G2 +
RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN);
rtw89_write16_set(rtwdev, RAC_DIRECT_OFFESET_L0_G2 +
RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN);
}
val16 = rtw89_read16(rtwdev, RAC_DIRECT_OFFESET_L0_G1 +
RAC_ANA41 * RAC_MULT);
if (val16 & PHY_ERR_FLAG_EN) {
rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G1 +
RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN);
rtw89_write16_set(rtwdev, RAC_DIRECT_OFFESET_L0_G1 +
RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN);
}
rtw89_write32(rtwdev, R_BE_PCIE_HCI2FW_ISR, 0xFFFFFFFF);
}
rtw89_pci_basic_cfg(rtwdev, true);
return 0;
}
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_isr_def rtw89_pci_isr_be = {
.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_sps_ocp = 0,
.isr_clear_rpq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RPQ0_ISR_V1},
.isr_clear_rxq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RX0P2_ISR_V1},
};
EXPORT_SYMBOL(rtw89_pci_isr_be);
const struct rtw89_pci_isr_def rtw89_pci_isr_be_v1 = {
.isr_rdu = B_BE_PCIE_RDU_CH1_INT | B_BE_PCIE_RDU_CH0_INT,
.isr_halt_c2h = B_BE_HALT_C2H_INT,
.isr_wdt_timeout = B_BE_WDT_TIMEOUT_INT,
.isr_sps_ocp = B_BE_SPS_OCP_INT | B_BE_SPSANA_OCP_INT,
.isr_clear_rpq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RPQ0_ISR_V1},
.isr_clear_rxq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RX0P2_ISR_V1},
};
EXPORT_SYMBOL(rtw89_pci_isr_be_v1);
const struct rtw89_pci_gen_def rtw89_pci_gen_be = {
.mac_pre_init = rtw89_pci_ops_mac_pre_init_be,
.mac_pre_deinit = rtw89_pci_ops_mac_pre_deinit_be,
.mac_post_init = rtw89_pci_ops_mac_post_init_be,
.clr_idx_all = rtw89_pci_clr_idx_all_be,
.rst_bdram = rtw89_pci_rst_bdram_be,
.lv1rst_stop_dma = rtw89_pci_lv1rst_stop_dma_be,
.lv1rst_start_dma = rtw89_pci_lv1rst_start_dma_be,
.ctrl_txdma_ch = rtw89_pci_ctrl_txdma_ch_be,
.ctrl_txdma_fw_ch = rtw89_pci_ctrl_txdma_fw_ch_be,
.poll_txdma_ch_idle = rtw89_pci_poll_txdma_ch_idle_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);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,601 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#include "chan.h"
#include "coex.h"
#include "core.h"
#include "debug.h"
#include "fw.h"
#include "mac.h"
#include "phy.h"
#include "ps.h"
#include "reg.h"
#include "ser.h"
#include "util.h"
static int rtw89_fw_receive_lps_h2c_check(struct rtw89_dev *rtwdev, u8 macid)
{
struct rtw89_mac_c2h_info c2h_info = {.timeout = 5000};
u16 c2hreg_macid;
u32 c2hreg_ret;
int ret;
if (!RTW89_CHK_FW_FEATURE(LPS_DACK_BY_C2H_REG, &rtwdev->fw))
return 0;
c2h_info.id = RTW89_FWCMD_C2HREG_FUNC_PS_LEAVE_ACK;
ret = rtw89_fw_msg_reg(rtwdev, NULL, &c2h_info);
if (ret)
goto fw_fail;
c2hreg_macid = u32_get_bits(c2h_info.u.c2hreg[0],
RTW89_C2HREG_PS_LEAVE_ACK_MACID);
c2hreg_ret = u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_PS_LEAVE_ACK_RET);
if (macid != c2hreg_macid || c2hreg_ret) {
rtw89_warn(rtwdev, "rtw89: check lps h2c received by firmware fail\n");
ret = -EINVAL;
goto fw_fail;
}
rtwdev->ps_hang_cnt = 0;
return 0;
fw_fail:
rtwdev->ps_hang_cnt++;
if (rtwdev->ps_hang_cnt >= RTW89_PS_HANG_MAX_CNT)
rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION);
return ret;
}
static int rtw89_fw_leave_lps_check(struct rtw89_dev *rtwdev, u8 macid)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u32 pwr_en_bit = 0xE;
u32 chk_msk = pwr_en_bit << (4 * macid);
u32 polling;
int ret;
ret = read_poll_timeout_atomic(rtw89_read32_mask, polling, !polling,
1000, 50000, false, rtwdev,
mac->ps_status, chk_msk);
if (ret) {
rtw89_info(rtwdev, "rtw89: failed to leave lps state\n");
rtwdev->ps_hang_cnt++;
if (rtwdev->ps_hang_cnt >= RTW89_PS_HANG_MAX_CNT)
rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION);
return -EBUSY;
}
rtwdev->ps_hang_cnt = 0;
return 0;
}
static void rtw89_ps_power_mode_change_with_hci(struct rtw89_dev *rtwdev,
bool enter)
{
ieee80211_stop_queues(rtwdev->hw);
rtwdev->hci.paused = true;
flush_work(&rtwdev->txq_work);
ieee80211_wake_queues(rtwdev->hw);
rtw89_hci_pause(rtwdev, true);
rtw89_mac_power_mode_change(rtwdev, enter);
rtw89_hci_switch_mode(rtwdev, enter);
rtw89_hci_pause(rtwdev, false);
rtwdev->hci.paused = false;
if (!enter) {
local_bh_disable();
napi_schedule(&rtwdev->napi);
local_bh_enable();
}
}
static void rtw89_ps_power_mode_change(struct rtw89_dev *rtwdev, bool enter)
{
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)
{
if (!rtwdev->ps_mode)
return;
if (test_and_set_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags))
return;
rtw89_ps_power_mode_change(rtwdev, true);
}
void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
{
if (!rtwdev->ps_mode)
return;
if (test_and_clear_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags))
rtw89_ps_power_mode_change(rtwdev, false);
}
static void __rtw89_enter_lps_link(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_lps_parm lps_param = {
.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);
if (RTW89_CHK_FW_FEATURE(BEACON_TRACKING, &rtwdev->fw))
rtw89_fw_h2c_pwr_lvl(rtwdev, rtwvif_link);
}
static void __rtw89_leave_lps(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_lps_parm lps_param = {
.macid = rtwvif_link->mac_id,
.psmode = RTW89_MAC_AX_PS_MODE_ACTIVE,
.lastrpwm = RTW89_LAST_RPWM_ACTIVE,
};
rtw89_fw_h2c_lps_parm(rtwdev, &lps_param);
rtw89_fw_receive_lps_h2c_check(rtwdev, rtwvif_link->mac_id);
rtw89_fw_leave_lps_check(rtwdev, rtwvif_link->mac_id);
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_wiphy(rtwdev->hw->wiphy);
__rtw89_leave_ps_mode(rtwdev);
}
void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
bool ps_mode)
{
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_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;
}
rtw89_fw_h2c_rf_ps_info(rtwdev, rtwvif);
if (RTW89_CHK_FW_FEATURE(LPS_CH_INFO, &rtwdev->fw))
rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif);
else if (RTW89_CHK_FW_FEATURE(LPS_ML_INFO_V1, &rtwdev->fw))
rtw89_fw_h2c_lps_ml_cmn_info_v1(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_link *rtwvif_link)
{
if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION &&
rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT)
return;
__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_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_vif_for_each_link(rtwvif, rtwvif_link, link_id)
rtw89_leave_lps_vif(rtwdev, rtwvif_link);
rtw89_fw_h2c_init_trx_protect(rtwdev);
}
void rtw89_enter_ips(struct rtw89_dev *rtwdev)
{
struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
struct rtw89_hal *hal = &rtwdev->hal;
unsigned int link_id;
if (hal->disabled_dm_bitmap & BIT(RTW89_DM_INACTIVE_PS)) {
rtw89_debug(rtwdev, RTW89_DBG_PS, "skip enter IPS due to disabled_dm\n");
return;
}
set_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags);
if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
return;
rtw89_for_each_rtwvif(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))
return;
ret = rtw89_core_start(rtwdev);
if (ret)
rtw89_err(rtwdev, "failed to leave idle state\n");
rtw89_set_channel(rtwdev);
rtw89_for_each_rtwvif(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);
}
void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl)
{
if (btc_ctrl)
rtw89_leave_lps(rtwdev);
}
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_link, true);
else if (act == RTW89_P2P_ACT_TERMINATE)
rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif_link, false);
}
void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf)
{
enum rtw89_p2pps_action act;
u8 oppps_ctwindow;
u8 noa_id;
rcu_read_lock();
if (!bss_conf)
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
oppps_ctwindow = bss_conf->p2p_noa_attr.oppps_ctwindow;
rcu_read_unlock();
if (rtwvif_link->last_noa_nr == 0)
return;
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_link, act);
rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, NULL,
act, noa_id, oppps_ctwindow);
}
}
static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf)
{
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 = &bss_conf->p2p_noa_attr.desc[noa_id];
if (!desc->count || !desc->duration)
break;
if (noa_id == 0)
act = RTW89_P2P_ACT_INIT;
else
act = RTW89_P2P_ACT_UPDATE;
rtw89_tsf32_toggle(rtwdev, rtwvif_link, act);
rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, desc, act, noa_id,
bss_conf->p2p_noa_attr.oppps_ctwindow);
}
rtwvif_link->last_noa_nr = noa_id;
}
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, rtwvif_link, bss_conf);
rtw89_p2p_update_noa(rtwdev, rtwvif_link, bss_conf);
}
void rtw89_recalc_lps(struct rtw89_dev *rtwdev)
{
struct ieee80211_vif *vif, *found_vif = NULL;
struct rtw89_vif *rtwvif;
enum rtw89_entity_mode mode;
int count = 0;
mode = rtw89_get_entity_mode(rtwdev);
if (mode == RTW89_ENTITY_MODE_MCC)
goto disable_lps;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
vif = rtwvif_to_vif(rtwvif);
if (vif->type != NL80211_IFTYPE_STATION) {
count = 0;
break;
}
count++;
found_vif = vif;
}
if (count == 1 && found_vif->cfg.ps) {
rtwdev->lps_enabled = true;
return;
}
disable_lps:
rtw89_leave_lps(rtwdev);
rtwdev->lps_enabled = false;
}
void rtw89_p2p_noa_renew(struct rtw89_vif_link *rtwvif_link)
{
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;
if (setter->noa_count) {
setter->noa_index++;
setter->noa_count = 0;
}
memset(ie, 0, sizeof(*ie));
p2p_head->eid = WLAN_EID_VENDOR_SPECIFIC;
p2p_head->ie_len = 4 + sizeof(*noa_head);
p2p_head->oui[0] = (WLAN_OUI_WFA >> 16) & 0xff;
p2p_head->oui[1] = (WLAN_OUI_WFA >> 8) & 0xff;
p2p_head->oui[2] = (WLAN_OUI_WFA >> 0) & 0xff;
p2p_head->oui_type = WLAN_OUI_TYPE_WFA_P2P;
noa_head->attr_type = IEEE80211_P2P_ATTR_ABSENCE_NOTICE;
noa_head->attr_len = cpu_to_le16(2);
noa_head->index = setter->noa_index;
noa_head->oppps_ctwindow = 0;
}
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_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;
if (!desc->count || !desc->duration)
return;
if (setter->noa_count >= RTW89_P2P_MAX_NOA_NUM)
return;
p2p_head->ie_len += sizeof(*desc);
le16_add_cpu(&noa_head->attr_len, sizeof(*desc));
ie->noa_desc[setter->noa_count++] = *desc;
}
u8 rtw89_p2p_noa_fetch(struct rtw89_vif_link *rtwvif_link, void **data)
{
struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa;
struct rtw89_p2p_noa_ie *ie = &setter->ie;
void *tail;
if (!setter->noa_count)
return 0;
*data = ie;
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;
}
@@ -0,0 +1,52 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __RTW89_PS_H_
#define __RTW89_PS_H_
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);
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 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_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_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);
void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf);
static inline void rtw89_leave_ips_by_hwflags(struct rtw89_dev *rtwdev)
{
struct ieee80211_hw *hw = rtwdev->hw;
if (hw->conf.flags & IEEE80211_CONF_IDLE)
rtw89_leave_ips(rtwdev);
}
static inline void rtw89_enter_ips_by_hwflags(struct rtw89_dev *rtwdev)
{
struct ieee80211_hw *hw = rtwdev->hw;
/* prevent entering IPS after ROC, but it is scanning */
if (rtwdev->scanning)
return;
if (hw->conf.flags & IEEE80211_CONF_IDLE)
rtw89_enter_ips(rtwdev);
}
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,76 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2022-2023 Realtek Corporation
*/
#ifndef __RTW89_8851B_H__
#define __RTW89_8851B_H__
#include "core.h"
#define RF_PATH_NUM_8851B 1
#define BB_PATH_NUM_8851B 1
struct rtw8851bu_efuse {
u8 rsvd[0x88];
u8 mac_addr[ETH_ALEN];
};
struct rtw8851be_efuse {
u8 mac_addr[ETH_ALEN];
};
struct rtw8851b_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 rtw8851b_efuse {
u8 rsvd[0x210];
struct rtw8851b_tssi_offset path_a_tssi;
u8 rsvd1[136];
u8 channel_plan;
u8 xtal_k;
u8 rsvd2;
u8 iqk_lck;
u8 rsvd3[8];
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 rsvd4[3];
u8 path_a_therm;
u8 rsvd5[3];
u8 rx_gain_2g_ofdm;
u8 rsvd6;
u8 rx_gain_2g_cck;
u8 rsvd7;
u8 rx_gain_5g_low;
u8 rsvd8;
u8 rx_gain_5g_mid;
u8 rsvd9;
u8 rx_gain_5g_high;
u8 rsvd10[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 rsvd11[0xf2];
union {
struct rtw8851bu_efuse u;
struct rtw8851be_efuse e;
};
} __packed;
extern const struct rtw89_chip_info rtw8851b_chip_info;
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,34 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2022-2023 Realtek Corporation
*/
#ifndef __RTW89_8851B_RFK_H__
#define __RTW89_8851B_RFK_H__
#include "core.h"
void rtw8851b_aack(struct rtw89_dev *rtwdev);
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,
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_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, 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_chanctx_idx chanctx_idx);
void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
#endif
@@ -0,0 +1,499 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2022-2023 Realtek Corporation
*/
#include "rtw8851b_rfk_table.h"
static const struct rtw89_reg5_def rtw8851b_dadck_setup_defs[] = {
RTW89_DECL_RFK_WM(0xc210, 0x003fc000, 0x80),
RTW89_DECL_RFK_WM(0xc224, 0x003fc000, 0x80),
RTW89_DECL_RFK_WM(0xc0f8, 0x30000000, 0x3),
RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1),
RTW89_DECL_RFK_WM(0x030c, 0x1f000000, 0x1f),
RTW89_DECL_RFK_WM(0x032c, 0xc0000000, 0x0),
RTW89_DECL_RFK_WM(0x032c, BIT(22), 0x0),
RTW89_DECL_RFK_WM(0x032c, BIT(22), 0x1),
RTW89_DECL_RFK_WM(0x032c, BIT(16), 0x0),
RTW89_DECL_RFK_WM(0x032c, BIT(20), 0x1),
RTW89_DECL_RFK_WM(0x030c, 0x0f000000, 0x3),
RTW89_DECL_RFK_WM(0xc0f4, BIT(2), 0x0),
RTW89_DECL_RFK_WM(0xc0f4, BIT(4), 0x0),
RTW89_DECL_RFK_WM(0xc0f4, BIT(11), 0x1),
RTW89_DECL_RFK_WM(0xc0f4, BIT(11), 0x0),
RTW89_DECL_RFK_DELAY(1),
RTW89_DECL_RFK_WM(0xc0f4, 0x300, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_dadck_setup_defs);
static const struct rtw89_reg5_def rtw8851b_dadck_post_defs[] = {
RTW89_DECL_RFK_WM(0x032c, BIT(16), 0x1),
RTW89_DECL_RFK_WM(0x032c, BIT(20), 0x0),
RTW89_DECL_RFK_WM(0x030c, 0x1f000000, 0xc),
RTW89_DECL_RFK_WM(0x032c, 0xc0000000, 0x1),
RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_dadck_post_defs);
static const struct rtw89_reg5_def rtw8851b_dack_s0_1_defs[] = {
RTW89_DECL_RFK_WM(0x12a0, BIT(15), 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x7000, 0x3),
RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1),
RTW89_DECL_RFK_WM(0x030c, BIT(28), 0x1),
RTW89_DECL_RFK_WM(0x032c, 0x80000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_dack_s0_1_defs);
static const struct rtw89_reg5_def rtw8851b_dack_s0_2_defs[] = {
RTW89_DECL_RFK_WM(0xc004, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0x12a0, BIT(15), 0x0),
RTW89_DECL_RFK_WM(0x12a0, 0x7000, 0x7),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_dack_s0_2_defs);
static const struct rtw89_reg5_def rtw8851b_dack_manual_off_defs[] = {
RTW89_DECL_RFK_WM(0xc0f8, 0x30000000, 0x0),
RTW89_DECL_RFK_WM(0xc210, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0xc224, BIT(0), 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_dack_manual_off_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_rxclk_80_defs[] = {
RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x1),
RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x0),
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0f),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x03),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041),
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x1101),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_rxclk_80_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_rxclk_others_defs[] = {
RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x0),
RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x2),
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0f),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x03),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041),
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x1101),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_rxclk_others_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_txk_2ghz_defs[] = {
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x51, 0x80000, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x51, 0x00800, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x52, 0x00800, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x55, 0x0001f, 0x4),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0xef, 0x00004, 0x1),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x00, 0xffff0, 0x403e),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00003, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00070, 0x6),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x1f000, 0x10),
RTW89_DECL_RFK_DELAY(1),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_txk_2ghz_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_txk_5ghz_defs[] = {
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x60, 0x00007, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x55, 0x0001f, 0x4),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0xef, 0x00004, 0x1),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x00, 0xffff0, 0x403e),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00003, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x00070, 0x7),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x11, 0x1f000, 0x7),
RTW89_DECL_RFK_DELAY(1),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_txk_5ghz_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_afebb_restore_defs[] = {
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x0),
RTW89_DECL_RFK_WM(0x5670, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x12a0, 0x000ff000, 0x00),
RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x10005, 0x00001, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_afebb_restore_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_macbb_defs[] = {
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x10005, 0x00001, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x0),
RTW89_DECL_RFK_WM(0x5670, MASKDWORD, 0xf801fffd),
RTW89_DECL_RFK_WM(0x5670, 0x00004000, 0x1),
RTW89_DECL_RFK_WM(0x5670, 0x80000000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_macbb_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_macbb_bh_defs[] = {
RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x2),
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1),
RTW89_DECL_RFK_DELAY(2),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x1f),
RTW89_DECL_RFK_DELAY(10),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13),
RTW89_DECL_RFK_DELAY(2),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001),
RTW89_DECL_RFK_DELAY(2),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041),
RTW89_DECL_RFK_DELAY(10),
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1),
RTW89_DECL_RFK_DELAY(2),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x1f),
RTW89_DECL_RFK_DELAY(10),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13),
RTW89_DECL_RFK_DELAY(2),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001),
RTW89_DECL_RFK_DELAY(2),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041),
RTW89_DECL_RFK_DELAY(10),
RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_macbb_bh_defs);
static const struct rtw89_reg5_def rtw8851b_tssi_sys_defs[] = {
RTW89_DECL_RFK_WM(0x12bc, 0x000ffff0, 0xb5b5),
RTW89_DECL_RFK_WM(0x32bc, 0x000ffff0, 0xb5b5),
RTW89_DECL_RFK_WM(0x0300, 0xff000000, 0x16),
RTW89_DECL_RFK_WM(0x0304, 0x0000ffff, 0x1f19),
RTW89_DECL_RFK_WM(0x0308, 0xff000000, 0x1c),
RTW89_DECL_RFK_WM(0x0314, 0xffff0000, 0x2041),
RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x20012041),
RTW89_DECL_RFK_WM(0x0324, 0xffff0000, 0x2001),
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(rtw8851b_tssi_sys_defs);
static const struct rtw89_reg5_def rtw8851b_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(0x5814, 0x20000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_sys_a_defs_2g);
static const struct rtw89_reg5_def rtw8851b_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(0x5814, 0x20000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_sys_a_defs_5g);
static const struct rtw89_reg5_def rtw8851b_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, 0x026d000),
RTW89_DECL_RFK_WM(0x5814, 0xf8000000, 0x00),
RTW89_DECL_RFK_WM(0x5818, 0x00ffffff, 0x2c18e8),
RTW89_DECL_RFK_WM(0x5818, 0x07000000, 0x0),
RTW89_DECL_RFK_WM(0x5818, 0xf0000000, 0x0),
RTW89_DECL_RFK_WM(0x581c, 0x3fffffff, 0x3dc80280),
RTW89_DECL_RFK_WM(0x5820, 0xffffffff, 0x00000080),
RTW89_DECL_RFK_WM(0x58e8, 0x0000003f, 0x04),
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, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x589c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x58a4, 0x000000ff, 0x16),
RTW89_DECL_RFK_WM(0x58b0, MASKDWORD, 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, MASKDWORD, 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, 0x800),
RTW89_DECL_RFK_WM(0x58f0, 0x0003ffff, 0x001ff),
RTW89_DECL_RFK_WM(0x58f4, 0x000fffff, 0x00000),
RTW89_DECL_RFK_WM(0x58f8, 0x000fffff, 0x00000),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_init_txpwr_defs_a);
static const struct rtw89_reg5_def rtw8851b_tssi_init_txpwr_he_tb_defs_a[] = {
RTW89_DECL_RFK_WM(0x58a0, MASKDWORD, 0x000000fe),
RTW89_DECL_RFK_WM(0x58e4, 0x0000007f, 0x1f),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_init_txpwr_he_tb_defs_a);
static const struct rtw89_reg5_def rtw8851b_tssi_dck_defs_a[] = {
RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000),
RTW89_DECL_RFK_WM(0x5814, 0x00001000, 0x1),
RTW89_DECL_RFK_WM(0x5814, 0x00002000, 0x1),
RTW89_DECL_RFK_WM(0x5814, 0x00004000, 0x1),
RTW89_DECL_RFK_WM(0x5814, 0x00038000, 0x3),
RTW89_DECL_RFK_WM(0x5814, 0x003c0000, 0x5),
RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_dck_defs_a);
static const struct rtw89_reg5_def rtw8851b_tssi_dac_gain_defs_a[] = {
RTW89_DECL_RFK_WM(0x58b0, 0x00000fff, 0x000),
RTW89_DECL_RFK_WM(0x5a00, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a04, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a08, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a0c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a10, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a14, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a18, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a1c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a20, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a24, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a28, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a2c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a30, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a34, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a38, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a3c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a40, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a44, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a48, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a4c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a50, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a54, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a58, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a5c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a60, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a64, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a68, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a6c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a70, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a74, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a78, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a7c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a80, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a84, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a88, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a8c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a90, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a94, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a98, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5a9c, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5aa0, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5aa4, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5aa8, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5aac, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5ab0, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5ab4, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5ab8, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5abc, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x5ac0, MASKDWORD, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_dac_gain_defs_a);
static const struct rtw89_reg5_def rtw8851b_tssi_slope_a_defs_2g[] = {
RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0200e08),
RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x007),
RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808),
RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08080808),
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(rtw8851b_tssi_slope_a_defs_2g);
static const struct rtw89_reg5_def rtw8851b_tssi_slope_a_defs_5g[] = {
RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0341a08),
RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201417),
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, 0x0e0e0808),
RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x08080d18),
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(rtw8851b_tssi_slope_a_defs_5g);
static const struct rtw89_reg5_def rtw8851b_tssi_align_a_2g_defs[] = {
RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000),
RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x2d2400),
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x000),
RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x3fa),
RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x02e),
RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0x09c),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x3fb00000),
RTW89_DECL_RFK_WM(0x5644, 0x000003ff, 0x02f),
RTW89_DECL_RFK_WM(0x5644, 0x000ffc00, 0x09c),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_align_a_2g_defs);
static const struct rtw89_reg5_def rtw8851b_tssi_align_a_5g_defs[] = {
RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000),
RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x3b2d24),
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x3cb),
RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x030),
RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x73),
RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0xd4),
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(rtw8851b_tssi_align_a_5g_defs);
static const struct rtw89_reg5_def rtw8851b_tssi_slope_defs_a[] = {
RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x0),
RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x1),
RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1),
RTW89_DECL_RFK_WM(0x5820, 0x0000f000, 0xf),
RTW89_DECL_RFK_WM(0x581c, 0x000003ff, 0x280),
RTW89_DECL_RFK_WM(0x581c, 0x000ffc00, 0x200),
RTW89_DECL_RFK_WM(0x58b8, 0x007f0000, 0x00),
RTW89_DECL_RFK_WM(0x58b8, 0x7f000000, 0x00),
RTW89_DECL_RFK_WM(0x58b4, 0x7f000000, 0x0a),
RTW89_DECL_RFK_WM(0x58b8, 0x0000007f, 0x28),
RTW89_DECL_RFK_WM(0x58b8, 0x00007f00, 0x76),
RTW89_DECL_RFK_WM(0x5810, 0x20000000, 0x0),
RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1),
RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x5834, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x5834, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5838, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5838, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x5854, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x5854, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5858, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5858, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x5824, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x5824, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5828, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5828, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x582c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x582c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5830, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5830, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x583c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x583c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5840, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5840, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x5844, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x5844, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5848, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5848, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x584c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x584c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5850, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5850, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x585c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x585c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5860, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5860, 0x003ff000, 0x000),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_slope_defs_a);
static const struct rtw89_reg5_def rtw8851b_tssi_track_defs_a[] = {
RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x0),
RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x0),
RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1),
RTW89_DECL_RFK_WM(0x5864, 0x000003ff, 0x1ff),
RTW89_DECL_RFK_WM(0x5864, 0x000ffc00, 0x200),
RTW89_DECL_RFK_WM(0x5820, 0x00000fff, 0x080),
RTW89_DECL_RFK_WM(0x5814, 0x01000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_track_defs_a);
static const struct rtw89_reg5_def rtw8851b_tssi_mv_avg_defs_a[] = {
RTW89_DECL_RFK_WM(0x58e4, 0x00003800, 0x1),
RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x0),
RTW89_DECL_RFK_WM(0x58e4, 0x00008000, 0x1),
RTW89_DECL_RFK_WM(0x58e4, 0x000f0000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_tssi_mv_avg_defs_a);
static const struct rtw89_reg5_def rtw8851b_nctl_post_defs[] = {
RTW89_DECL_RFK_WM(0x5864, 0x18000000, 0x3),
RTW89_DECL_RFK_WM(0x7864, 0x18000000, 0x3),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041),
RTW89_DECL_RFK_WM(0x12b8, 0x10000000, 0x1),
RTW89_DECL_RFK_WM(0x2008, 0x01ffffff, 0x00fffff),
RTW89_DECL_RFK_WM(0x0c60, 0x00000003, 0x3),
RTW89_DECL_RFK_WM(0x0c6c, 0x00000001, 0x1),
RTW89_DECL_RFK_WM(0x58ac, 0x08000000, 0x1),
RTW89_DECL_RFK_WM(0x78ac, 0x08000000, 0x1),
RTW89_DECL_RFK_WM(0x0730, 0x00003800, 0x7),
RTW89_DECL_RFK_WM(0x2730, 0x00003800, 0x7),
RTW89_DECL_RFK_WM(0x0c7c, 0x00e00000, 0x1),
RTW89_DECL_RFK_WM(0x58c0, 0x0001ffff, 0x00000),
RTW89_DECL_RFK_WM(0x78c0, 0x0001ffff, 0x00000),
RTW89_DECL_RFK_WM(0x58fc, 0x3f000000, 0x00),
RTW89_DECL_RFK_WM(0x78fc, 0x3f000000, 0x00),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_nctl_post_defs);
@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2022-2023 Realtek Corporation
*/
#ifndef __RTW89_8851B_RFK_TABLE_H__
#define __RTW89_8851B_RFK_TABLE_H__
#include "phy.h"
extern const struct rtw89_rfk_tbl rtw8851b_dadck_setup_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_dadck_post_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_dack_s0_1_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_dack_s0_2_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_dack_manual_off_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_iqk_rxclk_80_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_iqk_rxclk_others_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_iqk_txk_2ghz_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_iqk_txk_5ghz_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_iqk_afebb_restore_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_iqk_macbb_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_iqk_macbb_bh_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_sys_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_sys_a_defs_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_sys_a_defs_5g_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_init_txpwr_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_init_txpwr_he_tb_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_dck_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_dac_gain_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_slope_a_defs_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_slope_a_defs_5g_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_align_a_2g_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_align_a_5g_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_slope_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_track_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_tssi_mv_avg_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8851b_nctl_post_defs_tbl;
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2022-2023 Realtek Corporation
*/
#ifndef __RTW89_8851B_TABLE_H__
#define __RTW89_8851B_TABLE_H__
#include "core.h"
extern const struct rtw89_phy_table rtw89_8851b_phy_bb_table;
extern const struct rtw89_phy_table rtw89_8851b_phy_bb_gain_table;
extern const struct rtw89_phy_table rtw89_8851b_phy_radioa_table;
extern const struct rtw89_phy_table rtw89_8851b_phy_nctl_table;
extern const struct rtw89_txpwr_track_cfg rtw89_8851b_trk_cfg;
extern const struct rtw89_rfe_parms rtw89_8851b_dflt_parms;
extern const struct rtw89_rfe_parms_conf rtw89_8851b_rfe_parms_conf[];
#endif
@@ -0,0 +1,103 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2022-2023 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/pci.h>
#include "pci.h"
#include "reg.h"
#include "rtw8851b.h"
static const struct rtw89_pci_info rtw8851b_pci_info = {
.gen_def = &rtw89_pci_gen_ax,
.isr_def = &rtw89_pci_isr_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,
.group_bd_addr = false,
.rpp_fmt_size = sizeof(struct rtw89_pci_rpp_fmt),
.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,
.parse_rpp = rtw89_pci_parse_rpp,
.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 = NULL,
};
static const struct rtw89_driver_info rtw89_8851be_info = {
.chip = &rtw8851b_chip_info,
.variant = NULL,
.quirks = NULL,
.dev_id_quirks = 0,
.bus = {
.pci = &rtw8851b_pci_info,
},
};
static const struct pci_device_id rtw89_8851be_id_table[] = {
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb851),
.driver_data = (kernel_ulong_t)&rtw89_8851be_info,
},
{},
};
MODULE_DEVICE_TABLE(pci, rtw89_8851be_id_table);
static struct pci_driver rtw89_8851be_driver = {
.name = "rtw89_8851be",
.id_table = rtw89_8851be_id_table,
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops,
.err_handler = &rtw89_pci_err_handler,
};
module_pci_driver(rtw89_8851be_driver);
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8851BE driver");
MODULE_LICENSE("Dual BSD/GPL");
@@ -0,0 +1,71 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2025 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/usb.h>
#include "rtw8851b.h"
#include "reg.h"
#include "usb.h"
static const struct rtw89_usb_info rtw8851b_usb_info = {
.usb_host_request_2 = R_AX_USB_HOST_REQUEST_2,
.usb_wlan0_1 = R_AX_USB_WLAN0_1,
.hci_func_en = R_AX_HCI_FUNC_EN,
.usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0,
.usb_endpoint_0 = R_AX_USB_ENDPOINT_0,
.usb_endpoint_2 = R_AX_USB_ENDPOINT_2,
.rx_agg_alignment = 8,
.bulkout_id = {
[RTW89_DMA_ACH0] = 3,
[RTW89_DMA_ACH1] = 4,
[RTW89_DMA_ACH2] = 5,
[RTW89_DMA_ACH3] = 6,
[RTW89_DMA_B0MG] = 0,
[RTW89_DMA_B0HI] = 1,
[RTW89_DMA_H2C] = 2,
},
};
static const struct rtw89_driver_info rtw89_8851bu_info = {
.chip = &rtw8851b_chip_info,
.variant = NULL,
.quirks = NULL,
.dev_id_quirks = 0,
.bus = {
.usb = &rtw8851b_usb_info,
}
};
static const struct usb_device_id rtw_8851bu_id_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb831, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8851bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb851, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8851bu_info },
/* D-Link AX9U rev. A1 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x332a, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8851bu_info },
/* Mercusys MA60XNB */
{ USB_DEVICE_AND_INTERFACE_INFO(0x2C4E, 0x0128, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8851bu_info },
/* TP-Link Archer TX10UB Nano */
{ USB_DEVICE_AND_INTERFACE_INFO(0x3625, 0x010b, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8851bu_info },
/* Edimax EW-7611UXB */
{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xe611, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8851bu_info },
{},
};
MODULE_DEVICE_TABLE(usb, rtw_8851bu_id_table);
static struct usb_driver rtw_8851bu_driver = {
.name = KBUILD_MODNAME,
.id_table = rtw_8851bu_id_table,
.probe = rtw89_usb_probe,
.disconnect = rtw89_usb_disconnect,
};
module_usb_driver(rtw_8851bu_driver);
MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8851BU driver");
MODULE_LICENSE("Dual BSD/GPL");
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,110 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __RTW89_8852A_H__
#define __RTW89_8852A_H__
#include "core.h"
#define RF_PATH_NUM_8852A 2
enum rtw8852a_pmac_mode {
NONE_TEST,
PKTS_TX,
PKTS_RX,
CONT_TX
};
struct rtw8852au_efuse {
u8 rsvd[0x38];
u8 mac_addr[ETH_ALEN];
};
struct rtw8852ae_efuse {
u8 mac_addr[ETH_ALEN];
};
struct rtw8852a_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 rtw8852a_efuse {
u8 rsvd[0x210];
struct rtw8852a_tssi_offset path_a_tssi;
u8 rsvd1[10];
struct rtw8852a_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[46];
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 rsvd9[0xf2];
union {
struct rtw8852au_efuse u;
struct rtw8852ae_efuse e;
};
} __packed;
struct rtw8852a_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;
};
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, 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, 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);
void rtw8852a_bb_tx_mode_switch(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx idx, u8 mode);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __RTW89_8852A_RFK_H__
#define __RTW89_8852A_RFK_H__
#include "core.h"
void rtw8852a_rck(struct rtw89_dev *rtwdev);
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, 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,
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);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,86 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __RTW89_8852A_RFK_TABLE_H__
#define __RTW89_8852A_RFK_TABLE_H__
#include "phy.h"
extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_5g_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_5g_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_dck_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_dck_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_dac_gain_tbl_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_dac_gain_tbl_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_cal_org_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_cal_org_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_rf_gap_tbl_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_rf_gap_tbl_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_track_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_track_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txagc_ofst_mv_avg_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_txagc_ofst_mv_avg_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_1_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_3_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_4_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_1_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_3_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_4_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_ab_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_disable_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_tssi_tracking_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_afe_init_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_reload_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_reload_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_addc_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_addc_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_reset_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_trigger_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_restore_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_reset_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_trigger_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_restore_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_f_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_f_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_r_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_r_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_f_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_m_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_r_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_f_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_m_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_r_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sf_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sr_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sf_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sr_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_s_defs_ab_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_ab_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_lbk_rxiqk_defs_f_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_lbk_rxiqk_defs_r_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_pas_read_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_nondbcc_path01_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_dbcc_path0_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_dbcc_path1_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_nondbcc_path01_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_dbcc_path0_tbl;
extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_dbcc_path1_tbl;
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __RTW89_8852A_TABLE_H__
#define __RTW89_8852A_TABLE_H__
#include "core.h"
extern const struct rtw89_phy_table rtw89_8852a_phy_bb_table;
extern const struct rtw89_phy_table rtw89_8852a_phy_radioa_table;
extern const struct rtw89_phy_table rtw89_8852a_phy_radiob_table;
extern const struct rtw89_phy_table rtw89_8852a_phy_nctl_table;
extern const struct rtw89_txpwr_track_cfg rtw89_8852a_trk_cfg;
extern const struct rtw89_rfe_parms rtw89_8852a_dflt_parms;
#endif
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2020-2021 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/pci.h>
#include "pci.h"
#include "reg.h"
#include "rtw8852a.h"
static const struct rtw89_pci_info rtw8852a_pci_info = {
.gen_def = &rtw89_pci_gen_ax,
.isr_def = &rtw89_pci_isr_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,
.group_bd_addr = false,
.rpp_fmt_size = sizeof(struct rtw89_pci_rpp_fmt),
.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 = R_AX_TXBD_RWPTR_CLR2,
.dma_io_stop = {R_AX_PCIE_DMA_STOP1, B_AX_STOP_PCIEIO},
.dma_stop1 = {R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_MASK},
.dma_stop2 = {R_AX_PCIE_DMA_STOP2, B_AX_TX_STOP2_ALL},
.dma_busy1 = {R_AX_PCIE_DMA_BUSY1, DMA_BUSY1_CHECK},
.dma_busy2_reg = R_AX_PCIE_DMA_BUSY2,
.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 = 0,
.bd_idx_addr_low_power = NULL,
.dma_addr_set = &rtw89_pci_ch_dma_addr_set,
.bd_ram_table = &rtw89_bd_ram_table_dual,
.ltr_set = rtw89_pci_ltr_set,
.fill_txaddr_info = rtw89_pci_fill_txaddr_info,
.parse_rpp = rtw89_pci_parse_rpp,
.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 = NULL,
};
static const struct rtw89_driver_info rtw89_8852ae_info = {
.chip = &rtw8852a_chip_info,
.variant = NULL,
.quirks = NULL,
.dev_id_quirks = 0,
.bus = {
.pci = &rtw8852a_pci_info,
},
};
static const struct pci_device_id rtw89_8852ae_id_table[] = {
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8852),
.driver_data = (kernel_ulong_t)&rtw89_8852ae_info,
},
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xa85a),
.driver_data = (kernel_ulong_t)&rtw89_8852ae_info,
},
{},
};
MODULE_DEVICE_TABLE(pci, rtw89_8852ae_id_table);
static struct pci_driver rtw89_8852ae_driver = {
.name = "rtw89_8852ae",
.id_table = rtw89_8852ae_id_table,
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops,
.err_handler = &rtw89_pci_err_handler,
};
module_pci_driver(rtw89_8852ae_driver);
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852AE driver");
MODULE_LICENSE("Dual BSD/GPL");
@@ -0,0 +1,85 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2025 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/usb.h>
#include "rtw8852a.h"
#include "reg.h"
#include "usb.h"
static const struct rtw89_usb_info rtw8852a_usb_info = {
.usb_host_request_2 = R_AX_USB_HOST_REQUEST_2,
.usb_wlan0_1 = R_AX_USB_WLAN0_1,
.hci_func_en = R_AX_HCI_FUNC_EN,
.usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0,
.usb_endpoint_0 = R_AX_USB_ENDPOINT_0,
.usb_endpoint_2 = R_AX_USB_ENDPOINT_2,
.rx_agg_alignment = 8,
.bulkout_id = {
[RTW89_DMA_ACH0] = 3,
[RTW89_DMA_ACH2] = 5,
[RTW89_DMA_ACH4] = 4,
[RTW89_DMA_ACH6] = 6,
[RTW89_DMA_B0MG] = 0,
[RTW89_DMA_B0HI] = 0,
[RTW89_DMA_B1MG] = 1,
[RTW89_DMA_B1HI] = 1,
[RTW89_DMA_H2C] = 2,
},
};
static const struct rtw89_driver_info rtw89_8852au_info = {
.chip = &rtw8852a_chip_info,
.variant = NULL,
.quirks = NULL,
.dev_id_quirks = 0,
.bus = {
.usb = &rtw8852a_usb_info,
}
};
static const struct usb_device_id rtw_8852au_id_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x0312, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4020, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1997, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0x8832, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0x885a, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0x885c, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3321, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3323, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x332c, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x013f, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0140, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0141, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x3625, 0x010d, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x3625, 0x010f, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852au_info },
{},
};
MODULE_DEVICE_TABLE(usb, rtw_8852au_id_table);
static struct usb_driver rtw_8852au_driver = {
.name = KBUILD_MODNAME,
.id_table = rtw_8852au_id_table,
.probe = rtw89_usb_probe,
.disconnect = rtw89_usb_disconnect,
};
module_usb_driver(rtw_8852au_driver);
MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852AU driver");
MODULE_LICENSE("Dual BSD/GPL");
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2022 Realtek Corporation
*/
#ifndef __RTW89_8852B_H__
#define __RTW89_8852B_H__
#include "core.h"
#define RF_PATH_NUM_8852B 2
#define BB_PATH_NUM_8852B 2
extern const struct rtw89_chip_info rtw8852b_chip_info;
#endif
File diff suppressed because it is too large Load Diff
@@ -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
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,34 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2022 Realtek Corporation
*/
#ifndef __RTW89_8852B_RFK_H__
#define __RTW89_8852B_RFK_H__
#include "core.h"
void rtw8852b_rck(struct rtw89_dev *rtwdev);
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_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, 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_chanctx_idx chanctx_idx);
void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
void rtw8852b_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
void rtw8852b_rfk_chanctx_cb(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_state state);
#endif
@@ -0,0 +1,794 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#include "rtw8852b_rfk_table.h"
static const struct rtw89_reg5_def rtw8852b_afe_init_defs[] = {
RTW89_DECL_RFK_WM(0xC0D4, 0xffffffff, 0x4486888c),
RTW89_DECL_RFK_WM(0xC0D8, 0xffffffff, 0xc6ba10e0),
RTW89_DECL_RFK_WM(0xc0dc, 0xffffffff, 0x30c52868),
RTW89_DECL_RFK_WM(0xc0e0, 0xffffffff, 0x05008128),
RTW89_DECL_RFK_WM(0xc0e4, 0xffffffff, 0x0000272b),
RTW89_DECL_RFK_WM(0xC1D4, 0xffffffff, 0x4486888c),
RTW89_DECL_RFK_WM(0xC1D8, 0xffffffff, 0xc6ba10e0),
RTW89_DECL_RFK_WM(0xc1dc, 0xffffffff, 0x30c52868),
RTW89_DECL_RFK_WM(0xc1e0, 0xffffffff, 0x05008128),
RTW89_DECL_RFK_WM(0xc1e4, 0xffffffff, 0x0000272b),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_afe_init_defs);
static const struct rtw89_reg5_def rtw8852b_check_addc_defs_a[] = {
RTW89_DECL_RFK_WM(0x20f4, BIT(24), 0x0),
RTW89_DECL_RFK_WM(0x20f8, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x20f0, 0xff0000, 0x1),
RTW89_DECL_RFK_WM(0x20f0, 0xf00, 0x2),
RTW89_DECL_RFK_WM(0x20f0, 0xf, 0x0),
RTW89_DECL_RFK_WM(0x20f0, 0xc0, 0x2),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_check_addc_defs_a);
static const struct rtw89_reg5_def rtw8852b_check_addc_defs_b[] = {
RTW89_DECL_RFK_WM(0x20f4, BIT(24), 0x0),
RTW89_DECL_RFK_WM(0x20f8, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x20f0, 0xff0000, 0x1),
RTW89_DECL_RFK_WM(0x20f0, 0xf00, 0x2),
RTW89_DECL_RFK_WM(0x20f0, 0xf, 0x0),
RTW89_DECL_RFK_WM(0x20f0, 0xc0, 0x3),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_check_addc_defs_b);
static const struct rtw89_reg5_def rtw8852b_check_dadc_en_defs_a[] = {
RTW89_DECL_RFK_WM(0x032C, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0xf),
RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0x3),
RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x0),
RTW89_DECL_RFK_WM(0x12dc, BIT(0), 0x1),
RTW89_DECL_RFK_WM(0x12e8, BIT(2), 0x1),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x8f, BIT(13), 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_en_defs_a);
static const struct rtw89_reg5_def rtw8852b_check_dadc_en_defs_b[] = {
RTW89_DECL_RFK_WM(0x032C, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0xf),
RTW89_DECL_RFK_WM(0x030C, 0x0f000000, 0x3),
RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x0),
RTW89_DECL_RFK_WM(0x32dc, BIT(0), 0x1),
RTW89_DECL_RFK_WM(0x32e8, BIT(2), 0x1),
RTW89_DECL_RFK_WRF(RF_PATH_B, 0x8f, BIT(13), 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_en_defs_b);
static const struct rtw89_reg5_def rtw8852b_check_dadc_dis_defs_a[] = {
RTW89_DECL_RFK_WM(0x12dc, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0x12e8, BIT(2), 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x8f, BIT(13), 0x0),
RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_dis_defs_a);
static const struct rtw89_reg5_def rtw8852b_check_dadc_dis_defs_b[] = {
RTW89_DECL_RFK_WM(0x32dc, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0x32e8, BIT(2), 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_B, 0x8f, BIT(13), 0x0),
RTW89_DECL_RFK_WM(0x032C, BIT(16), 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_check_dadc_dis_defs_b);
static const struct rtw89_reg5_def rtw8852b_dack_s0_1_defs[] = {
RTW89_DECL_RFK_WM(0x12A0, BIT(15), 0x1),
RTW89_DECL_RFK_WM(0x12A0, 0x00007000, 0x3),
RTW89_DECL_RFK_WM(0x12B8, BIT(30), 0x1),
RTW89_DECL_RFK_WM(0x030C, BIT(28), 0x1),
RTW89_DECL_RFK_WM(0x032C, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0xC0D8, BIT(16), 0x1),
RTW89_DECL_RFK_WM(0xc0dc, 0x0c000000, 0x3),
RTW89_DECL_RFK_WM(0xC004, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0xc024, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0xC004, 0x3ff00000, 0x30),
RTW89_DECL_RFK_WM(0xC004, 0xc0000000, 0x0),
RTW89_DECL_RFK_WM(0xC004, BIT(17), 0x1),
RTW89_DECL_RFK_WM(0xc024, BIT(17), 0x1),
RTW89_DECL_RFK_WM(0xc00c, BIT(2), 0x0),
RTW89_DECL_RFK_WM(0xc02c, BIT(2), 0x0),
RTW89_DECL_RFK_WM(0xC004, BIT(0), 0x1),
RTW89_DECL_RFK_WM(0xc024, BIT(0), 0x1),
RTW89_DECL_RFK_DELAY(1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s0_1_defs);
static const struct rtw89_reg5_def rtw8852b_dack_s0_2_defs[] = {
RTW89_DECL_RFK_WM(0xc0dc, 0x0c000000, 0x0),
RTW89_DECL_RFK_WM(0xc00c, BIT(2), 0x1),
RTW89_DECL_RFK_WM(0xc02c, BIT(2), 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s0_2_defs);
static const struct rtw89_reg5_def rtw8852b_dack_s0_3_defs[] = {
RTW89_DECL_RFK_WM(0xC004, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0xc024, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0xC0D8, BIT(16), 0x0),
RTW89_DECL_RFK_WM(0x12A0, BIT(15), 0x0),
RTW89_DECL_RFK_WM(0x12A0, 0x00007000, 0x7),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s0_3_defs);
static const struct rtw89_reg5_def rtw8852b_dack_s1_1_defs[] = {
RTW89_DECL_RFK_WM(0x32a0, BIT(15), 0x1),
RTW89_DECL_RFK_WM(0x32a0, 0x7000, 0x3),
RTW89_DECL_RFK_WM(0x32B8, BIT(30), 0x1),
RTW89_DECL_RFK_WM(0x030C, BIT(28), 0x1),
RTW89_DECL_RFK_WM(0x032C, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0xC1D8, BIT(16), 0x1),
RTW89_DECL_RFK_WM(0xc1dc, 0x0c000000, 0x3),
RTW89_DECL_RFK_WM(0xc104, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0xc124, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0xc104, 0x3ff00000, 0x30),
RTW89_DECL_RFK_WM(0xc104, 0xc0000000, 0x0),
RTW89_DECL_RFK_WM(0xc104, BIT(17), 0x1),
RTW89_DECL_RFK_WM(0xc124, BIT(17), 0x1),
RTW89_DECL_RFK_WM(0xc10c, BIT(2), 0x0),
RTW89_DECL_RFK_WM(0xc12c, BIT(2), 0x0),
RTW89_DECL_RFK_WM(0xc104, BIT(0), 0x1),
RTW89_DECL_RFK_WM(0xc124, BIT(0), 0x1),
RTW89_DECL_RFK_DELAY(1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s1_1_defs);
static const struct rtw89_reg5_def rtw8852b_dack_s1_2_defs[] = {
RTW89_DECL_RFK_WM(0xc1dc, 0x0c000000, 0x0),
RTW89_DECL_RFK_WM(0xc10c, BIT(2), 0x1),
RTW89_DECL_RFK_WM(0xc12c, BIT(2), 0x1),
RTW89_DECL_RFK_DELAY(1),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s1_2_defs);
static const struct rtw89_reg5_def rtw8852b_dack_s1_3_defs[] = {
RTW89_DECL_RFK_WM(0xc104, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0xc124, BIT(0), 0x0),
RTW89_DECL_RFK_WM(0xC1D8, BIT(16), 0x0),
RTW89_DECL_RFK_WM(0x32a0, BIT(15), 0x0),
RTW89_DECL_RFK_WM(0x32a0, 0x7000, 0x7),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dack_s1_3_defs);
static const struct rtw89_reg5_def rtw8852b_dpk_afe_defs[] = {
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0303),
RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1),
RTW89_DECL_RFK_WM(0x32b8, BIT(30), 0x1),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041),
RTW89_DECL_RFK_WM(0x12b8, BIT(28), 0x1),
RTW89_DECL_RFK_WM(0x58c8, BIT(24), 0x1),
RTW89_DECL_RFK_WM(0x78c8, BIT(24), 0x1),
RTW89_DECL_RFK_WM(0x5864, 0xc0000000, 0x3),
RTW89_DECL_RFK_WM(0x7864, 0xc0000000, 0x3),
RTW89_DECL_RFK_WM(0x2008, 0x01FFFFFF, 0x1ffffff),
RTW89_DECL_RFK_WM(0x0c1c, BIT(2), 0x1),
RTW89_DECL_RFK_WM(0x0700, BIT(27), 0x1),
RTW89_DECL_RFK_WM(0x0c70, 0x000003FF, 0x3ff),
RTW89_DECL_RFK_WM(0x0c60, 0x00000003, 0x3),
RTW89_DECL_RFK_WM(0x0c6c, BIT(0), 0x1),
RTW89_DECL_RFK_WM(0x58ac, BIT(27), 0x1),
RTW89_DECL_RFK_WM(0x78ac, BIT(27), 0x1),
RTW89_DECL_RFK_WM(0x0c3c, BIT(9), 0x1),
RTW89_DECL_RFK_WM(0x2344, BIT(31), 0x1),
RTW89_DECL_RFK_WM(0x4490, BIT(31), 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x000ff000, 0xbf),
RTW89_DECL_RFK_WM(0x32a0, 0x000f0000, 0xb),
RTW89_DECL_RFK_WM(0x0700, 0x07000000, 0x5),
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x3333),
RTW89_DECL_RFK_WM(0x580c, BIT(15), 0x1),
RTW89_DECL_RFK_WM(0x5800, 0x0000ffff, 0x0000),
RTW89_DECL_RFK_WM(0x780c, BIT(15), 0x1),
RTW89_DECL_RFK_WM(0x7800, 0x0000ffff, 0x0000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dpk_afe_defs);
static const struct rtw89_reg5_def rtw8852b_dpk_afe_restore_defs[] = {
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0303),
RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0x32b8, BIT(30), 0x0),
RTW89_DECL_RFK_WM(0x5864, 0xc0000000, 0x0),
RTW89_DECL_RFK_WM(0x7864, 0xc0000000, 0x0),
RTW89_DECL_RFK_WM(0x2008, 0x01FFFFFF, 0x0),
RTW89_DECL_RFK_WM(0x0c1c, BIT(2), 0x0),
RTW89_DECL_RFK_WM(0x0700, BIT(27), 0x0),
RTW89_DECL_RFK_WM(0x0c70, 0x000003FF, 0x63),
RTW89_DECL_RFK_WM(0x12a0, 0x000FF000, 0x00),
RTW89_DECL_RFK_WM(0x32a0, 0x000FF000, 0x00),
RTW89_DECL_RFK_WM(0x0700, 0x07000000, 0x0),
RTW89_DECL_RFK_WM(0x5864, BIT(29), 0x0),
RTW89_DECL_RFK_WM(0x7864, BIT(29), 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0000),
RTW89_DECL_RFK_WM(0x58c8, BIT(24), 0x0),
RTW89_DECL_RFK_WM(0x78c8, BIT(24), 0x0),
RTW89_DECL_RFK_WM(0x0c3c, BIT(9), 0x0),
RTW89_DECL_RFK_WM(0x580c, BIT(15), 0x0),
RTW89_DECL_RFK_WM(0x58e4, 0x18000000, 0x1),
RTW89_DECL_RFK_WM(0x58e4, 0x18000000, 0x2),
RTW89_DECL_RFK_WM(0x780c, BIT(15), 0x0),
RTW89_DECL_RFK_WM(0x78e4, 0x18000000, 0x1),
RTW89_DECL_RFK_WM(0x78e4, 0x18000000, 0x2),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dpk_afe_restore_defs);
static const struct rtw89_reg5_def rtw8852b_dpk_kip_defs[] = {
RTW89_DECL_RFK_WM(0x8008, 0xffffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x8088, 0xffffffff, 0x80000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_dpk_kip_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_sys_defs[] = {
RTW89_DECL_RFK_WM(0x12a8, 0x0000000f, 0x5),
RTW89_DECL_RFK_WM(0x32a8, 0x0000000f, 0x5),
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(rtw8852b_tssi_sys_defs);
static const struct rtw89_reg5_def rtw8852b_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(rtw8852b_tssi_sys_a_defs_2g);
static const struct rtw89_reg5_def rtw8852b_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(rtw8852b_tssi_sys_a_defs_5g);
static const struct rtw89_reg5_def rtw8852b_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(rtw8852b_tssi_sys_b_defs_2g);
static const struct rtw89_reg5_def rtw8852b_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(rtw8852b_tssi_sys_b_defs_5g);
static const struct rtw89_reg5_def rtw8852b_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, 0x800),
RTW89_DECL_RFK_WM(0x58f0, 0x0003ffff, 0x001ff),
RTW89_DECL_RFK_WM(0x58f4, 0x000fffff, 0x000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_init_txpwr_defs_a);
static const struct rtw89_reg5_def rtw8852b_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, 0x800),
RTW89_DECL_RFK_WM(0x78f0, 0x0003ffff, 0x001ff),
RTW89_DECL_RFK_WM(0x78f4, 0x000fffff, 0x000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_init_txpwr_defs_b);
static const struct rtw89_reg5_def rtw8852b_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(rtw8852b_tssi_init_txpwr_he_tb_defs_a);
static const struct rtw89_reg5_def rtw8852b_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(rtw8852b_tssi_init_txpwr_he_tb_defs_b);
static const struct rtw89_reg5_def rtw8852b_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(rtw8852b_tssi_dck_defs_a);
static const struct rtw89_reg5_def rtw8852b_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(rtw8852b_tssi_dck_defs_b);
static const struct rtw89_reg5_def rtw8852b_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(rtw8852b_tssi_dac_gain_defs_a);
static const struct rtw89_reg5_def rtw8852b_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(rtw8852b_tssi_dac_gain_defs_b);
static const struct rtw89_reg5_def rtw8852b_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(rtw8852b_tssi_slope_a_defs_2g);
static const struct rtw89_reg5_def rtw8852b_tssi_slope_a_defs_5g[] = {
RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201020),
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, 0x08081e08),
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(rtw8852b_tssi_slope_a_defs_5g);
static const struct rtw89_reg5_def rtw8852b_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(rtw8852b_tssi_slope_b_defs_2g);
static const struct rtw89_reg5_def rtw8852b_tssi_slope_b_defs_5g[] = {
RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201020),
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, 0x08081e08),
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(rtw8852b_tssi_slope_b_defs_5g);
static const struct rtw89_reg5_def rtw8852b_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, 0x01ef27af),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000075),
RTW89_DECL_RFK_WM(0x5638, 0x000fffff, 0x00000),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x017f13ae),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x0000006e),
RTW89_DECL_RFK_WM(0x5644, 0x000fffff, 0x00000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_2g_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_a_2g_part_defs[] = {
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01ef27af),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000075),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x017f13ae),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x0000006e),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_2g_part_defs);
static const struct rtw89_reg5_def rtw8852b_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, 0x016037e7),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x0000006f),
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(rtw8852b_tssi_align_a_5g1_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g1_part_defs[] = {
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x016037e7),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x0000006f),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g1_part_defs);
static const struct rtw89_reg5_def rtw8852b_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, 0x01f053f1),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070),
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(rtw8852b_tssi_align_a_5g2_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g2_part_defs[] = {
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01f053f1),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g2_part_defs);
static const struct rtw89_reg5_def rtw8852b_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, 0x01c047ee),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070),
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(rtw8852b_tssi_align_a_5g3_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_a_5g3_part_defs[] = {
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x01c047ee),
RTW89_DECL_RFK_WM(0x5634, 0x3fffffff, 0x00000070),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x3fffffff, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_a_5g3_part_defs);
static const struct rtw89_reg5_def rtw8852b_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, 0x01ff2bb5),
RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000078),
RTW89_DECL_RFK_WM(0x7638, 0x000fffff, 0x00000),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x018f2bb0),
RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000072),
RTW89_DECL_RFK_WM(0x7644, 0x000fffff, 0x00000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_2g_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_b_2g_part_defs[] = {
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x01ff2bb5),
RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000078),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x018f2bb0),
RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000072),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_2g_part_defs);
static const struct rtw89_reg5_def rtw8852b_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, 0x009003da),
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(rtw8852b_tssi_align_b_5g1_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g1_part_defs[] = {
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x009003da),
RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g1_part_defs);
static const struct rtw89_reg5_def rtw8852b_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, 0x013027e6),
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(rtw8852b_tssi_align_b_5g2_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g2_part_defs[] = {
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x013027e6),
RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g2_part_defs);
static const struct rtw89_reg5_def rtw8852b_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, 0x009003da),
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(rtw8852b_tssi_align_b_5g3_all_defs);
static const struct rtw89_reg5_def rtw8852b_tssi_align_b_5g3_part_defs[] = {
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x009003da),
RTW89_DECL_RFK_WM(0x7634, 0x3fffffff, 0x00000069),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7640, 0x3fffffff, 0x00000000),
};
RTW89_DECLARE_RFK_TBL(rtw8852b_tssi_align_b_5g3_part_defs);
static const struct rtw89_reg5_def rtw8852b_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(rtw8852b_tssi_slope_defs_a);
static const struct rtw89_reg5_def rtw8852b_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(rtw8852b_tssi_slope_defs_b);
@@ -0,0 +1,62 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __RTW89_8852B_RFK_TABLE_H__
#define __RTW89_8852B_RFK_TABLE_H__
#include "phy.h"
extern const struct rtw89_rfk_tbl rtw8852b_afe_init_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_check_addc_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_check_addc_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_en_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_en_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_dis_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_check_dadc_dis_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dack_s0_1_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dack_s0_2_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dack_s0_3_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dack_s1_1_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dack_s1_2_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dack_s1_3_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dpk_afe_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dpk_afe_restore_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_dpk_kip_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_a_defs_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_a_defs_5g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_b_defs_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_sys_b_defs_5g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_he_tb_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_init_txpwr_he_tb_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_dck_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_dck_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_dac_gain_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_dac_gain_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_a_defs_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_a_defs_5g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_b_defs_2g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_b_defs_5g_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_2g_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_2g_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g1_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g1_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g2_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g2_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g3_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_a_5g3_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_2g_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_2g_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g1_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g1_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g2_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g2_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g3_all_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_align_b_5g3_part_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852b_tssi_slope_defs_b_tbl;
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __RTW89_8852B_TABLE_H__
#define __RTW89_8852B_TABLE_H__
#include "core.h"
extern const struct rtw89_phy_table rtw89_8852b_phy_bb_table;
extern const struct rtw89_phy_table rtw89_8852b_phy_bb_gain_table;
extern const struct rtw89_phy_table rtw89_8852b_phy_radioa_table;
extern const struct rtw89_phy_table rtw89_8852b_phy_radiob_table;
extern const struct rtw89_phy_table rtw89_8852b_phy_nctl_table;
extern const struct rtw89_txpwr_track_cfg rtw89_8852b_trk_cfg;
extern const struct rtw89_rfe_parms rtw89_8852b_dflt_parms;
#endif
@@ -0,0 +1,107 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2020-2022 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/pci.h>
#include "pci.h"
#include "reg.h"
#include "rtw8852b.h"
static const struct rtw89_pci_info rtw8852b_pci_info = {
.gen_def = &rtw89_pci_gen_ax,
.isr_def = &rtw89_pci_isr_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,
.group_bd_addr = false,
.rpp_fmt_size = sizeof(struct rtw89_pci_rpp_fmt),
.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,
.parse_rpp = rtw89_pci_parse_rpp,
.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 = NULL,
};
static const struct rtw89_driver_info rtw89_8852be_info = {
.chip = &rtw8852b_chip_info,
.variant = NULL,
.quirks = NULL,
.dev_id_quirks = 0,
.bus = {
.pci = &rtw8852b_pci_info,
},
};
static const struct pci_device_id rtw89_8852be_id_table[] = {
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb852),
.driver_data = (kernel_ulong_t)&rtw89_8852be_info,
},
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb85b),
.driver_data = (kernel_ulong_t)&rtw89_8852be_info,
},
{},
};
MODULE_DEVICE_TABLE(pci, rtw89_8852be_id_table);
static struct pci_driver rtw89_8852be_driver = {
.name = "rtw89_8852be",
.id_table = rtw89_8852be_id_table,
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops,
.err_handler = &rtw89_pci_err_handler,
};
module_pci_driver(rtw89_8852be_driver);
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852BE driver");
MODULE_LICENSE("Dual BSD/GPL");
@@ -0,0 +1,959 @@
// 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 \
RTW89_GEN_MODULE_FWNAME(RTW8852BT_FW_BASENAME, RTW8852BT_FW_FORMAT_MAX)
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_pmac_regs rtw8852bt_pmac_regs = {
.cck_txon = {R_CNT_CCKTXON, B_CNT_CCKTXON},
.cck_txen = {R_CNT_CCKTXEN, B_CNT_CCKTXEN},
.cck_cca = {R_CNT_CCK_CCA_P0, B_CNT_CCK_CCA_P0},
.cck_sfd_gg = {R_SFD_GG_CNT, B_SFD_GG_CNT},
.cck_sig_gg = {R_SIG_GG_CNT, B_SIG_GG_CNT},
.cck_spoofing = {R_SPOOF_CNT, B_SPOOF_CNT},
.cck_brk = {},
.brk = {R_CNT_BRK, B_CNT_BRK},
.brk_option = {},
.search_fail = {R_CNT_SEARCH_FAIL, B_CNT_SEARCH_FAIL},
.lsig_brk_s_th = {R_CNT_LSIG_BRK_S_TH, B_CNT_LSIG_BRK_S_TH},
.lsig_brk_l_th = {R_CNT_LSIG_BRK_L_TH, B_CNT_LSIG_BRK_L_TH},
.rxl_err_parity = {R_CNT_RXL_ERR_PARITY, B_CNT_RXL_ERR_PARITY},
.rxl_err_rate = {R_CNT_RXL_ERR_RATE, B_CNT_RXL_ERR_RATE},
.ofdm_cca = {R_CNT_OFDM_CCA, B_CNT_OFDM_CCA},
.cca_spoofing = {R_CNT_CCA_SPOOFING, B_CNT_CCA_SPOOFING},
.ampdu_miss = {R_CNT_AMPDU_MISS, B_CNT_AMPDU_MISS},
.r1b_rx_rpt_rst = {R_R1B_RX_RPT_RST, B_R1B_RX_RPT_RST},
.r1b_rr_sel = {R_R1B_RR_SEL, B_R1B_RR_SEL},
.enable_all_cnt = {R_ENABLE_ALL_CNT, B_ENABLE_ALL_CNT},
.rst_all_cnt = {R_RST_ALL_CNT, B_RST_ALL_CNT},
.cck_crc32 = R_CNT_CCK_CRC32_P0,
.cck_crc32_ok_mask = B_CNT_CCK_CRC32OK_P0,
.cck_crc32_fail_mask = B_CNT_CCK_CRC32FAIL_P0,
.ofdm_txon = R_CNT_OFDMTXON,
.ofdm_txon_mask = B_CNT_OFDMTXON,
.ofdm_txen_mask = B_CNT_OFDMTXEN,
.l_crc = R_CNT_L_CRC,
.l_crc_ok_mask = B_CNT_L_CRC_OK,
.l_crc_err_mask = B_CNT_L_CRC_ERR,
.ht_crc = R_CNT_HT_CRC,
.ht_crc_ok_mask = B_CNT_HT_CRC_OK,
.ht_crc_err_mask = B_CNT_HT_CRC_ERR,
.vht_crc = R_CNT_VHT_CRC,
.vht_crc_ok_mask = B_CNT_VHT_CRC_OK,
.vht_crc_err_mask = B_CNT_VHT_CRC_ERR,
.he_crc = R_CNT_HE_CRC,
.he_crc_ok_mask = B_CNT_HE_CRC_OK,
.he_crc_err_mask = B_CNT_HE_CRC_ERR,
.eht_crc = 0,
.eht_crc_ok_mask = 0,
.eht_crc_err_mask = 0,
.ampdu_crc = R_CNT_AMPDU_RX_CRC32,
.ampdu_crc_ok_mask = B_CNT_AMPDU_RX_CRC32_OK,
.ampdu_crc_err_mask = B_CNT_AMPDU_RX_CRC32_ERR,
};
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)
{
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
rtwdev->is_tssi_mode[RF_PATH_A] = false;
rtwdev->is_tssi_mode[RF_PATH_B] = false;
memset(rfk_mcc, 0, sizeof(*rfk_mcc));
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;
rtw8852bt_mcc_get_ch_info(rtwdev, 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);
rtw89_fw_h2c_rf_ntfy_mcc(rtwdev);
}
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,
.data_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,
.chan_to_rf18_val = NULL,
.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,
.calc_rx_gain_normal = 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,
.get_ch_dma = {rtw89_core_get_ch_dma,
NULL,
NULL,},
.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_punctured_cmac_tbl = NULL,
.h2c_default_dmac_tbl = NULL,
.h2c_update_beacon = rtw89_fw_h2c_update_beacon,
.h2c_ba_cam = rtw89_fw_h2c_ba_cam,
.h2c_wow_cam_update = rtw89_fw_h2c_wow_cam_update,
.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,
};
static const struct rtw89_chanctx_listener rtw8852bt_chanctx_listener = {
.callbacks[RTW89_CHANCTX_CALLBACK_RFK] = rtw8852bt_rfk_chanctx_cb,
};
#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_def = {
.fw_basename = RTW8852BT_FW_BASENAME,
.fw_format_max = RTW8852BT_FW_FORMAT_MAX,
.fw_b_aid = 0,
},
.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,
.max_vht_mpdu_cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454,
.max_eht_mpdu_cap = 0,
.max_tx_agg_num = 128,
.max_rx_agg_num = 64,
.dis_2g_40m_ul_ofdma = true,
.rsvd_ple_ofst = 0x6f800,
.qta_def = {
.hfc_param_ini = {rtw8852bt_hfc_param_ini_pcie, NULL, NULL, NULL},
.dle_mem = {rtw8852bt_dle_mem_pcie, NULL, NULL, NULL},
},
.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,
.chanctx_listener = &rtw8852bt_chanctx_listener,
.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 = 2,
.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,
.support_noise = false,
.support_fw_cmd_ofld = false,
.ul_tb_waveform_ctrl = true,
.ul_tb_pwr_diff = false,
.rx_freq_from_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,
.addrcam_ver = 0,
.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,
.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,
.rf_para_ulink_v9 = NULL,
.rf_para_dlink_v9 = NULL,
.rf_para_ulink_num_v9 = 0,
.rf_para_dlink_num_v9 = 0,
.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},
.btc_sb = {{{R_AX_SCOREBOARD, R_AX_SCOREBOARD},}},
.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,
.pmac_regs = &rtw8852bt_pmac_regs,
#ifdef CONFIG_PM
.wowlan_stub = &rtw_wowlan_stub_8852bt,
#endif
.xtal_info = NULL,
.default_quirks = 0,
};
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");
@@ -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
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,34 @@
/* 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);
void rtw8852bt_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
void rtw8852bt_rfk_chanctx_cb(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_state state);
#endif
@@ -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);
@@ -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
@@ -0,0 +1,109 @@
// 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,
.isr_def = &rtw89_pci_isr_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,
.group_bd_addr = false,
.rpp_fmt_size = sizeof(struct rtw89_pci_rpp_fmt),
.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,
.parse_rpp = rtw89_pci_parse_rpp,
.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,
.dev_id_quirks = 0,
.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,
.err_handler = &rtw89_pci_err_handler,
};
module_pci_driver(rtw89_8852bte_driver);
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852BE-VT driver");
MODULE_LICENSE("Dual BSD/GPL");
@@ -0,0 +1,85 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2025 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/usb.h>
#include "rtw8852b.h"
#include "reg.h"
#include "usb.h"
static const struct rtw89_usb_info rtw8852b_usb_info = {
.usb_host_request_2 = R_AX_USB_HOST_REQUEST_2,
.usb_wlan0_1 = R_AX_USB_WLAN0_1,
.hci_func_en = R_AX_HCI_FUNC_EN,
.usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0,
.usb_endpoint_0 = R_AX_USB_ENDPOINT_0,
.usb_endpoint_2 = R_AX_USB_ENDPOINT_2,
.rx_agg_alignment = 8,
.bulkout_id = {
[RTW89_DMA_ACH0] = 3,
[RTW89_DMA_ACH1] = 4,
[RTW89_DMA_ACH2] = 5,
[RTW89_DMA_ACH3] = 6,
[RTW89_DMA_B0MG] = 0,
[RTW89_DMA_B0HI] = 1,
[RTW89_DMA_H2C] = 2,
},
};
static const struct rtw89_driver_info rtw89_8852bu_info = {
.chip = &rtw8852b_chip_info,
.variant = NULL,
.quirks = NULL,
.dev_id_quirks = 0,
.bus = {
.usb = &rtw8852b_usb_info,
}
};
static const struct usb_device_id rtw_8852bu_id_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb832, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb83a, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb852, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb85a, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xa85b, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0586, 0x3428, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1a62, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1cb6, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0x6931, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0xf0c8, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3327, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x3574, 0x6121, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0100, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0108, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x6822, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
{},
};
MODULE_DEVICE_TABLE(usb, rtw_8852bu_id_table);
static struct usb_driver rtw_8852bu_driver = {
.name = KBUILD_MODNAME,
.id_table = rtw_8852bu_id_table,
.probe = rtw89_usb_probe,
.disconnect = rtw89_usb_disconnect,
};
module_usb_driver(rtw_8852bu_driver);
MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852BU driver");
MODULE_LICENSE("Dual BSD/GPL");
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,107 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2022 Realtek Corporation
*/
#ifndef __RTW89_8852C_H__
#define __RTW89_8852C_H__
#include "core.h"
#define RF_PATH_NUM_8852C 2
#define BB_PATH_NUM_8852C 2
struct rtw8852c_u_efuse {
u8 rsvd[0x88];
u8 mac_addr[ETH_ALEN];
u8 rsvd1[8];
u8 sn[RTW89_EFUSE_SN_LEN];
u8 rsvd2[29];
u8 uuid[RTW89_EFUSE_UUID_LEN];
} __packed;
struct rtw8852c_e_efuse {
u8 mac_addr[ETH_ALEN];
};
struct rtw8852c_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 rtw8852c_efuse {
u8 rsvd[0x210];
struct rtw8852c_tssi_offset path_a_tssi;
u8 rsvd1[10];
struct rtw8852c_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 bw40_1s_tssi_6g_a[TSSI_MCS_6G_CH_GROUP_NUM];
u8 rsvd14[10];
u8 bw40_1s_tssi_6g_b[TSSI_MCS_6G_CH_GROUP_NUM];
u8 rsvd15[94];
u8 rx_gain_6g_l0;
u8 rsvd16;
u8 rx_gain_6g_l1;
u8 rsvd17;
u8 rx_gain_6g_m0;
u8 rsvd18;
u8 rx_gain_6g_m1;
u8 rsvd19;
u8 rx_gain_6g_h0;
u8 rsvd20;
u8 rx_gain_6g_h1;
u8 rsvd21;
u8 rx_gain_6g_uh0;
u8 rsvd22;
u8 rx_gain_6g_uh1;
u8 rsvd23;
u8 channel_plan_6g;
u8 rsvd24[71];
union {
struct rtw8852c_u_efuse u;
struct rtw8852c_e_efuse e;
};
} __packed;
extern const struct rtw89_chip_info rtw8852c_chip_info;
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,37 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2022 Realtek Corporation
*/
#ifndef __RTW89_8852C_RFK_H__
#define __RTW89_8852C_RFK_H__
#include "core.h"
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, 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_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,
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,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
void rtw8852c_lck_init(struct rtw89_dev *rtwdev);
void rtw8852c_lck_track(struct rtw89_dev *rtwdev);
void rtw8852c_rfk_chanctx_cb(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_state state);
#endif
@@ -0,0 +1,781 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2019-2022 Realtek Corporation
*/
#include "rtw8852c_rfk_table.h"
static const struct rtw89_reg5_def rtw8852c_dack_reload_defs[] = {
RTW89_DECL_RFK_WM(0xc004, BIT(17), 0x1),
RTW89_DECL_RFK_WM(0xc024, BIT(17), 0x1),
RTW89_DECL_RFK_WM(0xc104, BIT(17), 0x1),
RTW89_DECL_RFK_WM(0xc124, BIT(17), 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_dack_reload_defs);
static const struct rtw89_reg5_def rtw8852c_dack_reset_defs_a[] = {
RTW89_DECL_RFK_WM(0xc000, BIT(17), 0x0),
RTW89_DECL_RFK_WM(0xc000, BIT(17), 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_dack_reset_defs_a);
static const struct rtw89_reg5_def rtw8852c_dack_reset_defs_b[] = {
RTW89_DECL_RFK_WM(0xc100, BIT(17), 0x0),
RTW89_DECL_RFK_WM(0xc100, BIT(17), 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_dack_reset_defs_b);
static const struct rtw89_reg5_def rtw8852c_dack_defs_s0[] = {
RTW89_DECL_RFK_WM(0x12b8, BIT(30), 0x1),
RTW89_DECL_RFK_WM(0x030c, BIT(28), 0x1),
RTW89_DECL_RFK_WM(0x032c, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0xc004, 0xfff00000, 0x30),
RTW89_DECL_RFK_WM(0xc024, 0xfff00000, 0x30),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_dack_defs_s0);
static const struct rtw89_reg5_def rtw8852c_dack_defs_s1[] = {
RTW89_DECL_RFK_WM(0x32b8, BIT(30), 0x1),
RTW89_DECL_RFK_WM(0x030c, BIT(28), 0x1),
RTW89_DECL_RFK_WM(0x032c, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0xc104, 0xfff00000, 0x30),
RTW89_DECL_RFK_WM(0xc124, 0xfff00000, 0x30),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_dack_defs_s1);
static const struct rtw89_reg5_def rtw8852c_drck_defs[] = {
RTW89_DECL_RFK_WM(0xc0c4, BIT(6), 0x0),
RTW89_DECL_RFK_WM(0xc094, BIT(9), 0x1),
RTW89_DECL_RFK_DELAY(1),
RTW89_DECL_RFK_WM(0xc094, BIT(9), 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_drck_defs);
static const struct rtw89_reg5_def rtw8852c_iqk_rxk_cfg_defs[] = {
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0f),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x03),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_iqk_rxk_cfg_defs);
static const struct rtw89_reg5_def rtw8852c_iqk_afebb_restore_defs_a[] = {
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x0),
RTW89_DECL_RFK_WM(0x5670, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x12a0, 0x000ff000, 0x00),
RTW89_DECL_RFK_WM(0x20fc, 0x00010000, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x01000000, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_A, 0x10005, 0x00001, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_iqk_afebb_restore_defs_a);
static const struct rtw89_reg5_def rtw8852c_iqk_afebb_restore_defs_b[] = {
RTW89_DECL_RFK_WM(0x32b8, 0x40000000, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x00020000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x00200000, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x02000000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x20000000, 0x0),
RTW89_DECL_RFK_WM(0x7670, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x32a0, 0x000ff000, 0x00),
RTW89_DECL_RFK_WM(0x20fc, 0x00020000, 0x0),
RTW89_DECL_RFK_WM(0x20fc, 0x02000000, 0x0),
RTW89_DECL_RFK_WRF(RF_PATH_B, 0x10005, 0x00001, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_iqk_afebb_restore_defs_b);
static const struct rtw89_reg5_def rtw8852c_read_rxsram_pre_defs[] = {
RTW89_DECL_RFK_WM(0x80e8, BIT(7), 0x1),
RTW89_DECL_RFK_WM(0x8074, BIT(31), 0x1),
RTW89_DECL_RFK_WM(0x80d4, MASKDWORD, 0x00020000),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_read_rxsram_pre_defs);
static const struct rtw89_reg5_def rtw8852c_read_rxsram_post_defs[] = {
RTW89_DECL_RFK_WM(0x80e8, BIT(7), 0x0),
RTW89_DECL_RFK_WM(0x8074, BIT(31), 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_read_rxsram_post_defs);
static const struct rtw89_reg5_def rtw8852c_dpk_mdpd_order0_defs[] = {
RTW89_DECL_RFK_WM(0x80a0, BIT(1) | BIT(0), 0x0),
RTW89_DECL_RFK_WM(0x809c, BIT(10) | BIT(9), 0x2),
RTW89_DECL_RFK_WM(0x80a0, 0x00001F00, 0x4),
RTW89_DECL_RFK_WM(0x8070, 0x70000000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_mdpd_order0_defs);
static const struct rtw89_reg5_def rtw8852c_dpk_mdpd_order1_defs[] = {
RTW89_DECL_RFK_WM(0x80a0, BIT(1) | BIT(0), 0x1),
RTW89_DECL_RFK_WM(0x809c, BIT(10) | BIT(9), 0x1),
RTW89_DECL_RFK_WM(0x80a0, 0x00001F00, 0x0),
RTW89_DECL_RFK_WM(0x8070, 0x70000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_mdpd_order1_defs);
static const struct rtw89_reg5_def rtw8852c_dpk_mdpd_order2_defs[] = {
RTW89_DECL_RFK_WM(0x80a0, BIT(1) | BIT(0), 0x2),
RTW89_DECL_RFK_WM(0x809c, BIT(10) | BIT(9), 0x0),
RTW89_DECL_RFK_WM(0x80a0, 0x00001F00, 0x0),
RTW89_DECL_RFK_WM(0x8070, 0x70000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_mdpd_order2_defs);
static const struct rtw89_reg5_def rtw8852c_dpk_mdpd_order3_defs[] = {
RTW89_DECL_RFK_WM(0x80a0, BIT(1) | BIT(0), 0x3),
RTW89_DECL_RFK_WM(0x809c, BIT(10) | BIT(9), 0x3),
RTW89_DECL_RFK_WM(0x80a0, 0x00001F00, 0x4),
RTW89_DECL_RFK_WM(0x8070, 0x70000000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_mdpd_order3_defs);
static const struct rtw89_reg5_def rtw8852c_dpk_kip_pwr_clk_on_defs[] = {
RTW89_DECL_RFK_WM(0x8008, MASKDWORD, 0x00000080),
RTW89_DECL_RFK_WM(0x8088, MASKDWORD, 0x807f030a),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_kip_pwr_clk_on_defs);
static const struct rtw89_reg5_def rtw8852c_dpk_kip_pwr_clk_off_defs[] = {
RTW89_DECL_RFK_WM(0x8008, MASKDWORD, 0x00000000),
RTW89_DECL_RFK_WM(0x8088, MASKDWORD, 0x80000000),
RTW89_DECL_RFK_WM(0x80f4, BIT(18), 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_dpk_kip_pwr_clk_off_defs);
static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs[] = {
RTW89_DECL_RFK_WM(0x12bc, 0x000ffff0, 0xb5b5),
RTW89_DECL_RFK_WM(0x32bc, 0x000ffff0, 0xb5b5),
RTW89_DECL_RFK_WM(0x0300, 0xff000000, 0x16),
RTW89_DECL_RFK_WM(0x0304, 0x0000ffff, 0x1313),
RTW89_DECL_RFK_WM(0x0308, 0xff000000, 0x13),
RTW89_DECL_RFK_WM(0x0314, 0xffff0000, 0x2041),
RTW89_DECL_RFK_WM(0x0318, 0xffffffff, 0x00410041),
RTW89_DECL_RFK_WM(0x0324, 0xffff0000, 0x0041),
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(rtw8852c_tssi_sys_defs);
static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs_2g_a[] = {
RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x33),
RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x33),
RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_sys_defs_2g_a);
static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs_2g_b[] = {
RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x33),
RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x33),
RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_sys_defs_2g_b);
static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs_5g_a[] = {
RTW89_DECL_RFK_WM(0x120c, 0x000000ff, 0x44),
RTW89_DECL_RFK_WM(0x12c0, 0x0ff00000, 0x44),
RTW89_DECL_RFK_WM(0x58f8, 0x40000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_sys_defs_5g_a);
static const struct rtw89_reg5_def rtw8852c_tssi_sys_defs_5g_b[] = {
RTW89_DECL_RFK_WM(0x320c, 0x000000ff, 0x44),
RTW89_DECL_RFK_WM(0x32c0, 0x0ff00000, 0x44),
RTW89_DECL_RFK_WM(0x78f8, 0x40000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_sys_defs_5g_b);
static const struct rtw89_reg5_def rtw8852c_tssi_txpwr_ctrl_bb_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, 0x026d000),
RTW89_DECL_RFK_WM(0x5814, 0xf8000000, 0x00),
RTW89_DECL_RFK_WM(0x5818, 0xffffffff, 0x002c18e8),
RTW89_DECL_RFK_WM(0x581c, 0x3fffffff, 0x3dc80280),
RTW89_DECL_RFK_WM(0x5820, 0xffffffff, 0x00000080),
RTW89_DECL_RFK_WM(0x58e8, 0x0000003f, 0x03),
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(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_DECL_RFK_WM(0x58f8, 0x000fffff, 0x000),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txpwr_ctrl_bb_defs_a);
static const struct rtw89_reg5_def rtw8852c_tssi_txpwr_ctrl_bb_defs_b[] = {
RTW89_DECL_RFK_WM(0x766c, 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, 0x026d000),
RTW89_DECL_RFK_WM(0x7814, 0xf8000000, 0x00),
RTW89_DECL_RFK_WM(0x7818, 0xffffffff, 0x002c18e8),
RTW89_DECL_RFK_WM(0x781c, 0x3fffffff, 0x3dc80280),
RTW89_DECL_RFK_WM(0x7820, 0xffffffff, 0x00000080),
RTW89_DECL_RFK_WM(0x78e8, 0x0000003f, 0x03),
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(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_DECL_RFK_WM(0x78f8, 0x000fffff, 0x000),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txpwr_ctrl_bb_defs_b);
static const struct rtw89_reg5_def rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_a[] = {
RTW89_DECL_RFK_WM(0x58a0, 0xffffffff, 0x000000fe),
RTW89_DECL_RFK_WM(0x58e4, 0x0000007f, 0x1f),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_a);
static const struct rtw89_reg5_def rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_b[] = {
RTW89_DECL_RFK_WM(0x78a0, 0xffffffff, 0x000000fe),
RTW89_DECL_RFK_WM(0x78e4, 0x0000007f, 0x1f),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_b);
static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_a[] = {
RTW89_DECL_RFK_WM(0x58c4, 0x3ffc0000, 0x0),
RTW89_DECL_RFK_WM(0x58c8, 0x00000fff, 0x0),
RTW89_DECL_RFK_WM(0x58c8, 0x00fff000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_a);
static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_b[] = {
RTW89_DECL_RFK_WM(0x78c4, 0x3ffc0000, 0x0),
RTW89_DECL_RFK_WM(0x78c8, 0x00000fff, 0x0),
RTW89_DECL_RFK_WM(0x78c8, 0x00fff000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_b);
static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_2g_a[] = {
RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000),
RTW89_DECL_RFK_WM(0x5814, 0x003ff000, 0x1af),
RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_2g_a);
static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_2g_b[] = {
RTW89_DECL_RFK_WM(0x780c, 0x0fff0000, 0x000),
RTW89_DECL_RFK_WM(0x7814, 0x003ff000, 0x1af),
RTW89_DECL_RFK_WM(0x7814, 0x18000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_2g_b);
static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_5g_a[] = {
RTW89_DECL_RFK_WM(0x580c, 0x0fff0000, 0x000),
RTW89_DECL_RFK_WM(0x5814, 0x00001000, 0x1),
RTW89_DECL_RFK_WM(0x5814, 0x0003c000, 0xb),
RTW89_DECL_RFK_WM(0x5814, 0x00002000, 0x1),
RTW89_DECL_RFK_WM(0x5814, 0x003c0000, 0x6),
RTW89_DECL_RFK_WM(0x5814, 0x18000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_5g_a);
static const struct rtw89_reg5_def rtw8852c_tssi_dck_defs_5g_b[] = {
RTW89_DECL_RFK_WM(0x780c, 0x0fff0000, 0x000),
RTW89_DECL_RFK_WM(0x7814, 0x00001000, 0x1),
RTW89_DECL_RFK_WM(0x7814, 0x0003c000, 0xb),
RTW89_DECL_RFK_WM(0x7814, 0x00002000, 0x1),
RTW89_DECL_RFK_WM(0x7814, 0x003c0000, 0x6),
RTW89_DECL_RFK_WM(0x7814, 0x18000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_dck_defs_5g_b);
static const struct rtw89_reg5_def rtw8852c_tssi_set_bbgain_split_a[] = {
RTW89_DECL_RFK_WM(0x5818, 0x08000000, 0x1),
RTW89_DECL_RFK_WM(0x58d4, 0xf0000000, 0x7),
RTW89_DECL_RFK_WM(0x58f0, 0x000c0000, 0x1),
RTW89_DECL_RFK_WM(0x58f0, 0xfff00000, 0x400),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_bbgain_split_a);
static const struct rtw89_reg5_def rtw8852c_tssi_set_bbgain_split_b[] = {
RTW89_DECL_RFK_WM(0x7818, 0x08000000, 0x1),
RTW89_DECL_RFK_WM(0x78d4, 0xf0000000, 0x7),
RTW89_DECL_RFK_WM(0x78f0, 0x000c0000, 0x1),
RTW89_DECL_RFK_WM(0x78f0, 0xfff00000, 0x400),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_bbgain_split_b);
static const struct rtw89_reg5_def rtw8852c_tssi_slope_cal_org_defs_2g_a[] = {
RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x5610, 0x07ffffff, 0x0201020),
RTW89_DECL_RFK_WM(0x5614, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x5618, 0x07ffffff, 0x0801008),
RTW89_DECL_RFK_WM(0x561c, 0x000001ff, 0x008),
RTW89_DECL_RFK_WM(0x561c, 0xffff0000, 0x0808),
RTW89_DECL_RFK_WM(0x5620, 0xffffffff, 0x08080808),
RTW89_DECL_RFK_WM(0x5624, 0xffffffff, 0x0808081e),
RTW89_DECL_RFK_WM(0x5628, 0xffffffff, 0x08080808),
RTW89_DECL_RFK_WM(0x562c, 0x0000ffff, 0x081d),
RTW89_DECL_RFK_WM(0x581c, 0x00100000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_cal_org_defs_2g_a);
static const struct rtw89_reg5_def rtw8852c_tssi_slope_cal_org_defs_2g_b[] = {
RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x7610, 0x07ffffff, 0x0204020),
RTW89_DECL_RFK_WM(0x7614, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x7618, 0x07ffffff, 0x0801008),
RTW89_DECL_RFK_WM(0x761c, 0x000001ff, 0x020),
RTW89_DECL_RFK_WM(0x761c, 0xffff0000, 0x0808),
RTW89_DECL_RFK_WM(0x7620, 0xffffffff, 0x08080808),
RTW89_DECL_RFK_WM(0x7624, 0xffffffff, 0x08081e21),
RTW89_DECL_RFK_WM(0x7628, 0xffffffff, 0x08080808),
RTW89_DECL_RFK_WM(0x762c, 0x0000ffff, 0x1d23),
RTW89_DECL_RFK_WM(0x781c, 0x00100000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_cal_org_defs_2g_b);
static const struct rtw89_reg5_def rtw8852c_tssi_slope_cal_org_defs_5g_a[] = {
RTW89_DECL_RFK_WM(0x5608, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x560c, 0x07ffffff, 0x0201008),
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, 0x08080808),
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, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_cal_org_defs_5g_a);
static const struct rtw89_reg5_def rtw8852c_tssi_slope_cal_org_defs_5g_b[] = {
RTW89_DECL_RFK_WM(0x7608, 0x07ffffff, 0x0201008),
RTW89_DECL_RFK_WM(0x760c, 0x07ffffff, 0x0201008),
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, 0x08080808),
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, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_cal_org_defs_5g_b);
static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_2g_a[] = {
RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000),
RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x2d2721),
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x3b8),
RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x3d2),
RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x042),
RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0x06b),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x5640, 0x000ffc00, 0x3bc),
RTW89_DECL_RFK_WM(0x5640, 0x3ff00000, 0x3d6),
RTW89_DECL_RFK_WM(0x5644, 0x000003ff, 0x03e),
RTW89_DECL_RFK_WM(0x5644, 0x000ffc00, 0x06b),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_2g_a);
static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_2g_b[] = {
RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x000000),
RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x2d2721),
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7634, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x7634, 0x000ffc00, 0x3c0),
RTW89_DECL_RFK_WM(0x7634, 0x3ff00000, 0x3da),
RTW89_DECL_RFK_WM(0x7638, 0x000003ff, 0x002),
RTW89_DECL_RFK_WM(0x7638, 0x000ffc00, 0x071),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7640, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x7640, 0x000ffc00, 0x3c8),
RTW89_DECL_RFK_WM(0x7640, 0x3ff00000, 0x3e2),
RTW89_DECL_RFK_WM(0x7644, 0x000003ff, 0x00c),
RTW89_DECL_RFK_WM(0x7644, 0x000ffc00, 0x071),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_2g_b);
static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_5g_a[] = {
RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000),
RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x312600),
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x000),
RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x3e9),
RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x039),
RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0x07d),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x5640, 0x000ffc00, 0x000),
RTW89_DECL_RFK_WM(0x5640, 0x3ff00000, 0x3e9),
RTW89_DECL_RFK_WM(0x5644, 0x000003ff, 0x039),
RTW89_DECL_RFK_WM(0x5644, 0x000ffc00, 0x07d),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_5g_a);
static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_5g_b[] = {
RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x000000),
RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x312600),
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7634, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x7634, 0x000ffc00, 0x000),
RTW89_DECL_RFK_WM(0x7634, 0x3ff00000, 0x3e9),
RTW89_DECL_RFK_WM(0x7638, 0x000003ff, 0x039),
RTW89_DECL_RFK_WM(0x7638, 0x000ffc00, 0x07d),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7640, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x7640, 0x000ffc00, 0x000),
RTW89_DECL_RFK_WM(0x7640, 0x3ff00000, 0x3e9),
RTW89_DECL_RFK_WM(0x7644, 0x000003ff, 0x039),
RTW89_DECL_RFK_WM(0x7644, 0x000ffc00, 0x07d),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_5g_b);
static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_6g_a[] = {
RTW89_DECL_RFK_WM(0x5604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x5600, 0x3fffffff, 0x000000),
RTW89_DECL_RFK_WM(0x5604, 0x003fffff, 0x312600),
RTW89_DECL_RFK_WM(0x5630, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5634, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x5634, 0x000ffc00, 0x000),
RTW89_DECL_RFK_WM(0x5634, 0x3ff00000, 0x3e9),
RTW89_DECL_RFK_WM(0x5638, 0x000003ff, 0x039),
RTW89_DECL_RFK_WM(0x5638, 0x000ffc00, 0x080),
RTW89_DECL_RFK_WM(0x563c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x5640, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x5640, 0x000ffc00, 0x000),
RTW89_DECL_RFK_WM(0x5640, 0x3ff00000, 0x3e9),
RTW89_DECL_RFK_WM(0x5644, 0x000003ff, 0x039),
RTW89_DECL_RFK_WM(0x5644, 0x000ffc00, 0x080),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_6g_a);
static const struct rtw89_reg5_def rtw8852c_tssi_set_aligk_default_defs_6g_b[] = {
RTW89_DECL_RFK_WM(0x7604, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x7600, 0x3fffffff, 0x000000),
RTW89_DECL_RFK_WM(0x7604, 0x003fffff, 0x312600),
RTW89_DECL_RFK_WM(0x7630, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7634, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x7634, 0x000ffc00, 0x000),
RTW89_DECL_RFK_WM(0x7634, 0x3ff00000, 0x3e9),
RTW89_DECL_RFK_WM(0x7638, 0x000003ff, 0x039),
RTW89_DECL_RFK_WM(0x7638, 0x000ffc00, 0x080),
RTW89_DECL_RFK_WM(0x763c, 0x3fffffff, 0x00000000),
RTW89_DECL_RFK_WM(0x7640, 0x000003ff, 0x000),
RTW89_DECL_RFK_WM(0x7640, 0x000ffc00, 0x000),
RTW89_DECL_RFK_WM(0x7640, 0x3ff00000, 0x3e9),
RTW89_DECL_RFK_WM(0x7644, 0x000003ff, 0x039),
RTW89_DECL_RFK_WM(0x7644, 0x000ffc00, 0x080),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_set_aligk_default_defs_6g_b);
static const struct rtw89_reg5_def rtw8852c_tssi_slope_defs_a[] = {
RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x0),
RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x1),
RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1),
RTW89_DECL_RFK_WM(0x58e8, 0x0000003f, 0x0f),
RTW89_DECL_RFK_WM(0x581c, 0x000003ff, 0x280),
RTW89_DECL_RFK_WM(0x581c, 0x000ffc00, 0x200),
RTW89_DECL_RFK_WM(0x58b8, 0x007f0000, 0x00),
RTW89_DECL_RFK_WM(0x58b8, 0x7f000000, 0x00),
RTW89_DECL_RFK_WM(0x58b4, 0x7f000000, 0x0a),
RTW89_DECL_RFK_WM(0x58b8, 0x0000007f, 0x28),
RTW89_DECL_RFK_WM(0x58b8, 0x00007f00, 0x76),
RTW89_DECL_RFK_WM(0x5810, 0x20000000, 0x0),
RTW89_DECL_RFK_WM(0x5814, 0x20000000, 0x1),
RTW89_DECL_RFK_WM(0x580c, 0x10000000, 0x1),
RTW89_DECL_RFK_WM(0x580c, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x5834, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x5834, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5838, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5838, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x5854, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x5854, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5858, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5858, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x5824, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x5824, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5828, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5828, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x582c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x582c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5830, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5830, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x583c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x583c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5840, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5840, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x5844, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x5844, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5848, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5848, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x584c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x584c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5850, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5850, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x585c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x585c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x5860, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x5860, 0x003ff000, 0x000),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_defs_a);
static const struct rtw89_reg5_def rtw8852c_tssi_slope_defs_b[] = {
RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x0),
RTW89_DECL_RFK_WM(0x7814, 0x00000800, 0x1),
RTW89_DECL_RFK_WM(0x781c, 0x20000000, 0x1),
RTW89_DECL_RFK_WM(0x78e8, 0x0000003f, 0x0f),
RTW89_DECL_RFK_WM(0x781c, 0x000003ff, 0x280),
RTW89_DECL_RFK_WM(0x781c, 0x000ffc00, 0x200),
RTW89_DECL_RFK_WM(0x78b8, 0x007f0000, 0x00),
RTW89_DECL_RFK_WM(0x78b8, 0x7f000000, 0x00),
RTW89_DECL_RFK_WM(0x78b4, 0x7f000000, 0x0a),
RTW89_DECL_RFK_WM(0x78b8, 0x0000007f, 0x28),
RTW89_DECL_RFK_WM(0x78b8, 0x00007f00, 0x76),
RTW89_DECL_RFK_WM(0x7810, 0x20000000, 0x0),
RTW89_DECL_RFK_WM(0x7814, 0x20000000, 0x1),
RTW89_DECL_RFK_WM(0x780c, 0x10000000, 0x1),
RTW89_DECL_RFK_WM(0x780c, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x7834, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x7834, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x7838, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x7838, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x7854, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x7854, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x7858, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x7858, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x7824, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x7824, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x7828, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x7828, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x782c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x782c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x7830, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x7830, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x783c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x783c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x7840, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x7840, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x7844, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x7844, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x7848, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x7848, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x784c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x784c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x7850, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x7850, 0x003ff000, 0x000),
RTW89_DECL_RFK_WM(0x785c, 0x0003ffff, 0x115f2),
RTW89_DECL_RFK_WM(0x785c, 0x3ffc0000, 0x000),
RTW89_DECL_RFK_WM(0x7860, 0x00000fff, 0x121),
RTW89_DECL_RFK_WM(0x7860, 0x003ff000, 0x000),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_slope_defs_b);
static const struct rtw89_reg5_def rtw8852c_tssi_run_slope_defs_a[] = {
RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_run_slope_defs_a);
static const struct rtw89_reg5_def rtw8852c_tssi_run_slope_defs_b[] = {
RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_run_slope_defs_b);
static const struct rtw89_reg5_def rtw8852c_tssi_track_defs_a[] = {
RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x0),
RTW89_DECL_RFK_WM(0x5814, 0x00000800, 0x0),
RTW89_DECL_RFK_WM(0x581c, 0x20000000, 0x1),
RTW89_DECL_RFK_WM(0x5864, 0x000003ff, 0x1ff),
RTW89_DECL_RFK_WM(0x5864, 0x000ffc00, 0x200),
RTW89_DECL_RFK_WM(0x5820, 0x00000fff, 0x080),
RTW89_DECL_RFK_WM(0x5814, 0x01000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_track_defs_a);
static const struct rtw89_reg5_def rtw8852c_tssi_track_defs_b[] = {
RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x0),
RTW89_DECL_RFK_WM(0x7814, 0x00000800, 0x0),
RTW89_DECL_RFK_WM(0x781c, 0x20000000, 0x1),
RTW89_DECL_RFK_WM(0x7864, 0x000003ff, 0x1ff),
RTW89_DECL_RFK_WM(0x7864, 0x000ffc00, 0x200),
RTW89_DECL_RFK_WM(0x7820, 0x00000fff, 0x080),
RTW89_DECL_RFK_WM(0x7814, 0x01000000, 0x0),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_track_defs_b);
static const struct rtw89_reg5_def rtw8852c_tssi_txagc_ofst_mv_avg_defs_a[] = {
RTW89_DECL_RFK_WM(0x58e4, 0x00003800, 0x1),
RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x0),
RTW89_DECL_RFK_WM(0x58e4, 0x00008000, 0x1),
RTW89_DECL_RFK_WM(0x58e4, 0x000f0000, 0x0),
RTW89_DECL_RFK_WM(0x58e8, 0x0000003f, 0x03),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txagc_ofst_mv_avg_defs_a);
static const struct rtw89_reg5_def rtw8852c_tssi_txagc_ofst_mv_avg_defs_b[] = {
RTW89_DECL_RFK_WM(0x78e4, 0x00003800, 0x1),
RTW89_DECL_RFK_WM(0x78e4, 0x00004000, 0x0),
RTW89_DECL_RFK_WM(0x78e4, 0x00008000, 0x1),
RTW89_DECL_RFK_WM(0x78e4, 0x000f0000, 0x0),
RTW89_DECL_RFK_WM(0x78e8, 0x0000003f, 0x03),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_txagc_ofst_mv_avg_defs_b);
static const struct rtw89_reg5_def rtw8852c_tssi_enable_defs_a[] = {
RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x0),
RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x1),
RTW89_DECL_RFK_WRF(0x0, 0x10055, 0x00080, 0x1),
RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_enable_defs_a);
static const struct rtw89_reg5_def rtw8852c_tssi_enable_defs_b[] = {
RTW89_DECL_RFK_WM(0x78e4, 0x00004000, 0x0),
RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x0),
RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x1),
RTW89_DECL_RFK_WRF(0x1, 0x10055, 0x00080, 0x1),
RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_enable_defs_b);
static const struct rtw89_reg5_def rtw8852c_tssi_disable_defs_a[] = {
RTW89_DECL_RFK_WM(0x5820, 0x80000000, 0x00000000),
RTW89_DECL_RFK_WM(0x5818, 0x10000000, 0x00000000),
RTW89_DECL_RFK_WM(0x58e4, 0x00004000, 0x00000001),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_disable_defs_a);
static const struct rtw89_reg5_def rtw8852c_tssi_disable_defs_b[] = {
RTW89_DECL_RFK_WM(0x7820, 0x80000000, 0x00000000),
RTW89_DECL_RFK_WM(0x7818, 0x10000000, 0x00000000),
RTW89_DECL_RFK_WM(0x78e4, 0x00004000, 0x00000001),
};
RTW89_DECLARE_RFK_TBL(rtw8852c_tssi_disable_defs_b);
@@ -0,0 +1,67 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2022 Realtek Corporation
*/
#ifndef __RTW89_8852C_RFK_TABLE_H__
#define __RTW89_8852C_RFK_TABLE_H__
#include "phy.h"
extern const struct rtw89_rfk_tbl rtw8852c_dack_reload_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_dack_reset_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_dack_reset_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_dack_defs_s0_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_dack_defs_s1_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_drck_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_iqk_rxk_cfg_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_iqk_afebb_restore_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_iqk_afebb_restore_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_read_rxsram_pre_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_read_rxsram_post_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_dpk_mdpd_order0_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_dpk_mdpd_order1_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_dpk_mdpd_order2_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_dpk_mdpd_order3_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_dpk_kip_pwr_clk_on_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_dpk_kip_pwr_clk_off_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_2g_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_2g_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_5g_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_sys_defs_5g_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_txpwr_ctrl_bb_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_txpwr_ctrl_bb_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_2g_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_2g_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_5g_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_dck_defs_5g_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_bbgain_split_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_bbgain_split_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_cal_org_defs_2g_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_cal_org_defs_2g_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_cal_org_defs_5g_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_cal_org_defs_5g_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_2g_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_2g_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_5g_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_5g_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_6g_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_set_aligk_default_defs_6g_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_slope_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_run_slope_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_run_slope_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_track_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_track_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_txagc_ofst_mv_avg_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_txagc_ofst_mv_avg_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_enable_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_enable_defs_b_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_disable_defs_a_tbl;
extern const struct rtw89_rfk_tbl rtw8852c_tssi_disable_defs_b_tbl;
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2022 Realtek Corporation
*/
#ifndef __RTW89_8852C_TABLE_H__
#define __RTW89_8852C_TABLE_H__
#include "core.h"
extern const struct rtw89_phy_table rtw89_8852c_phy_bb_table;
extern const struct rtw89_phy_table rtw89_8852c_phy_bb_gain_table;
extern const struct rtw89_phy_table rtw89_8852c_phy_radioa_table;
extern const struct rtw89_phy_table rtw89_8852c_phy_radiob_table;
extern const struct rtw89_phy_table rtw89_8852c_phy_nctl_table;
extern const struct rtw89_phy_tssi_dbw_table rtw89_8852c_tssi_dbw_table;
extern const struct rtw89_txpwr_track_cfg rtw89_8852c_trk_cfg;
extern const struct rtw89_rfe_parms rtw89_8852c_dflt_parms;
#endif
@@ -0,0 +1,132 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2020-2022 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/pci.h>
#include "pci.h"
#include "reg.h"
#include "rtw8852c.h"
static const struct rtw89_pci_bd_idx_addr rtw8852c_bd_idx_addr_low_power = {
.tx_bd_addrs = {R_AX_DRV_FW_HSK_0, R_AX_DRV_FW_HSK_1, R_AX_DRV_FW_HSK_2,
R_AX_DRV_FW_HSK_3, 0, 0,
0, 0, R_AX_DRV_FW_HSK_4,
0, 0, 0,
R_AX_DRV_FW_HSK_5},
.rx_bd_addrs = {R_AX_DRV_FW_HSK_6, R_AX_DRV_FW_HSK_7},
};
static const struct rtw89_pci_info rtw8852c_pci_info = {
.gen_def = &rtw89_pci_gen_ax,
.isr_def = &rtw89_pci_isr_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_V1_256B,
.rx_burst = MAC_AX_RX_BURST_V1_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_ENABLE,
.io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_6MS,
.rx_ring_eq_is_full = false,
.check_rx_tag = false,
.no_rxbd_fs = false,
.group_bd_addr = false,
.rpp_fmt_size = sizeof(struct rtw89_pci_rpp_fmt),
.init_cfg_reg = R_AX_HAXI_INIT_CFG1,
.txhci_en_bit = B_AX_TXHCI_EN_V1,
.rxhci_en_bit = B_AX_RXHCI_EN_V1,
.rxbd_mode_bit = B_AX_RXBD_MODE_V1,
.exp_ctrl_reg = R_AX_HAXI_EXP_CTRL,
.max_tag_num_mask = B_AX_MAX_TAG_NUM_V1_MASK,
.rxbd_rwptr_clr_reg = R_AX_RXBD_RWPTR_CLR_V1,
.txbd_rwptr_clr2_reg = R_AX_TXBD_RWPTR_CLR2_V1,
.dma_io_stop = {R_AX_HAXI_INIT_CFG1, B_AX_STOP_AXI_MST},
.dma_stop1 = {R_AX_HAXI_DMA_STOP1, B_AX_TX_STOP1_MASK},
.dma_stop2 = {R_AX_HAXI_DMA_STOP2, B_AX_TX_STOP2_ALL},
.dma_busy1 = {R_AX_HAXI_DMA_BUSY1, DMA_BUSY1_CHECK},
.dma_busy2_reg = R_AX_HAXI_DMA_BUSY2,
.dma_busy3_reg = R_AX_HAXI_DMA_BUSY3,
.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,
.bd_ram_table = &rtw89_bd_ram_table_dual,
.ltr_set = rtw89_pci_ltr_set_v1,
.fill_txaddr_info = rtw89_pci_fill_txaddr_info_v1,
.parse_rpp = rtw89_pci_parse_rpp,
.config_intr_mask = rtw89_pci_config_intr_mask_v1,
.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,
.dev_id_quirks = 0,
.bus = {
.pci = &rtw8852c_pci_info,
},
};
static const struct pci_device_id rtw89_8852ce_id_table[] = {
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xc852),
.driver_data = (kernel_ulong_t)&rtw89_8852ce_info,
},
{},
};
MODULE_DEVICE_TABLE(pci, rtw89_8852ce_id_table);
static struct pci_driver rtw89_8852ce_driver = {
.name = "rtw89_8852ce",
.id_table = rtw89_8852ce_id_table,
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops,
.err_handler = &rtw89_pci_err_handler,
};
module_pci_driver(rtw89_8852ce_driver);
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852CE driver");
MODULE_LICENSE("Dual BSD/GPL");
@@ -0,0 +1,91 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2025 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/usb.h>
#include "rtw8852c.h"
#include "reg.h"
#include "usb.h"
static const struct rtw89_usb_info rtw8852c_usb_info = {
.usb_host_request_2 = R_AX_USB_HOST_REQUEST_2_V1,
.usb_wlan0_1 = R_AX_USB_WLAN0_1_V1,
.hci_func_en = R_AX_HCI_FUNC_EN_V1,
.usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0_V1,
.usb_endpoint_0 = R_AX_USB_ENDPOINT_0_V1,
.usb_endpoint_2 = R_AX_USB_ENDPOINT_2_V1,
.rx_agg_alignment = 8,
.bulkout_id = {
[RTW89_DMA_ACH0] = 3,
[RTW89_DMA_ACH2] = 5,
[RTW89_DMA_ACH4] = 4,
[RTW89_DMA_ACH6] = 6,
[RTW89_DMA_B0MG] = 0,
[RTW89_DMA_B0HI] = 0,
[RTW89_DMA_B1MG] = 1,
[RTW89_DMA_B1HI] = 1,
[RTW89_DMA_H2C] = 2,
},
};
static const struct rtw89_driver_info rtw89_8852cu_info = {
.chip = &rtw8852c_chip_info,
.variant = NULL,
.quirks = NULL,
.dev_id_quirks = 0,
.bus = {
.usb = &rtw8852c_usb_info,
},
};
static const struct rtw89_driver_info rtw89_8852cu_valve_info = {
.chip = &rtw8852c_chip_info,
.variant = NULL,
.quirks = NULL,
.dev_id_quirks = BIT(RTW89_QUIRK_HW_INFO_SYSFS),
.bus = {
.usb = &rtw8852c_usb_info,
},
};
static const struct usb_device_id rtw_8852cu_id_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03a6, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4024, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xc832, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xc85a, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xc85d, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0x991d, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x28de, 0x2432, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852cu_valve_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x8206, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x35b2, 0x0502, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0101, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0102, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x37ad, 0x0103, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
{},
};
MODULE_DEVICE_TABLE(usb, rtw_8852cu_id_table);
static struct usb_driver rtw_8852cu_driver = {
.name = KBUILD_MODNAME,
.id_table = rtw_8852cu_id_table,
.probe = rtw89_usb_probe,
.disconnect = rtw89_usb_disconnect,
};
module_usb_driver(rtw_8852cu_driver);
MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852CU driver");
MODULE_LICENSE("Dual BSD/GPL");
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,74 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2023 Realtek Corporation
*/
#ifndef __RTW89_8922A_H__
#define __RTW89_8922A_H__
#include "core.h"
#define RF_PATH_NUM_8922A 2
#define BB_PATH_NUM_8922A 2
struct rtw8922a_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];
u8 bw_diff_5g[10];
} __packed;
struct rtw8922a_rx_gain {
u8 _2g_ofdm;
u8 _2g_cck;
u8 _5g_low;
u8 _5g_mid;
u8 _5g_high;
} __packed;
struct rtw8922a_rx_gain_6g {
u8 _6g_l0;
u8 _6g_l1;
u8 _6g_m0;
u8 _6g_m1;
u8 _6g_h0;
u8 _6g_h1;
u8 _6g_uh0;
u8 _6g_uh1;
} __packed;
struct rtw8922a_efuse {
u8 country_code[2];
u8 rsvd[0xe];
struct rtw8922a_tssi_offset path_a_tssi;
struct rtw8922a_tssi_offset path_b_tssi;
u8 rsvd1[0x54];
u8 channel_plan;
u8 xtal_k;
u8 rsvd2[0x7];
u8 board_info;
u8 rsvd3[0x8];
u8 rfe_type;
u8 rsvd4[0x5];
u8 path_a_therm;
u8 path_b_therm;
u8 rsvd5[0x2];
struct rtw8922a_rx_gain rx_gain_a;
struct rtw8922a_rx_gain rx_gain_b;
u8 rsvd6[0x22];
u8 bw40_1s_tssi_6g_a[TSSI_MCS_6G_CH_GROUP_NUM];
u8 rsvd7[0xa];
u8 bw40_1s_tssi_6g_b[TSSI_MCS_6G_CH_GROUP_NUM];
u8 rsvd8[0xa];
u8 bw40_1s_tssi_6g_c[TSSI_MCS_6G_CH_GROUP_NUM];
u8 rsvd9[0xa];
u8 bw40_1s_tssi_6g_d[TSSI_MCS_6G_CH_GROUP_NUM];
u8 rsvd10[0xa];
struct rtw8922a_rx_gain_6g rx_gain_6g_a;
struct rtw8922a_rx_gain_6g rx_gain_6g_b;
} __packed;
extern const struct rtw89_chip_info rtw8922a_chip_info;
extern const struct rtw89_chip_variant rtw8922ae_vs_variant;
#endif
@@ -0,0 +1,381 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2023 Realtek Corporation
*/
#include "chan.h"
#include "debug.h"
#include "mac.h"
#include "phy.h"
#include "reg.h"
#include "rtw8922a.h"
#include "rtw8922a_rfk.h"
static void rtw8922a_tssi_cont_en(struct rtw89_dev *rtwdev, bool en,
enum rtw89_rf_path path)
{
static const u32 tssi_trk_man[2] = {R_TSSI_PWR_P0, R_TSSI_PWR_P1};
if (en)
rtw89_phy_write32_mask(rtwdev, tssi_trk_man[path], B_TSSI_CONT_EN, 0);
else
rtw89_phy_write32_mask(rtwdev, tssi_trk_man[path], B_TSSI_CONT_EN, 1);
}
void rtw8922a_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx)
{
if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) {
if (phy_idx == RTW89_PHY_0)
rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_A);
else
rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_B);
} else {
rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_A);
rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_B);
}
}
static
void rtw8922a_ctl_band_ch_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
const struct rtw89_chan *chan)
{
const u32 rf_addr[2] = {RR_CFGCH, RR_CFGCH_V1};
struct rtw89_hal *hal = &rtwdev->hal;
u32 rf_reg[RF_PATH_NUM_8922A][2];
u8 synpath;
u32 rf18;
u8 kpath;
u8 path;
u8 i;
rf_reg[RF_PATH_A][0] = rtw89_read_rf(rtwdev, RF_PATH_A, rf_addr[0], RFREG_MASK);
rf_reg[RF_PATH_A][1] = rtw89_read_rf(rtwdev, RF_PATH_A, rf_addr[1], RFREG_MASK);
rf_reg[RF_PATH_B][0] = rtw89_read_rf(rtwdev, RF_PATH_B, rf_addr[0], RFREG_MASK);
rf_reg[RF_PATH_B][1] = rtw89_read_rf(rtwdev, RF_PATH_B, rf_addr[1], RFREG_MASK);
kpath = rtw89_phy_get_kpath(rtwdev, phy);
synpath = rtw89_phy_get_syn_sel(rtwdev, phy);
rf18 = rtw89_read_rf(rtwdev, synpath, RR_CFGCH, RFREG_MASK);
if (rf18 == INV_RF_DATA) {
rtw89_warn(rtwdev, "[RFK] Invalid RF18 value\n");
return;
}
for (path = 0; path < RF_PATH_NUM_8922A; path++) {
if (!(kpath & BIT(path)))
continue;
for (i = 0; i < 2; i++) {
if (rf_reg[path][i] == INV_RF_DATA) {
rtw89_warn(rtwdev,
"[RFK] Invalid RF_0x18 for Path-%d\n", path);
return;
}
rf_reg[path][i] &= ~(RR_CFGCH_BAND1 | RR_CFGCH_BW_V2 |
RR_CFGCH_BAND0 | RR_CFGCH_CH);
rf_reg[path][i] |= rtw89_chip_chan_to_rf18_val(rtwdev, chan);
rtw89_write_rf(rtwdev, path, rf_addr[i],
RFREG_MASK, rf_reg[path][i]);
fsleep(100);
}
}
if (hal->cv != CHIP_CAV)
return;
if (chan->band_type == RTW89_BAND_2G) {
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x00003);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c990);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0xebe38);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000);
} else {
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x00003);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c190);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0xebe38);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000);
}
}
void rtw8922a_set_channel_rf(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
rtw8922a_ctl_band_ch_bw(rtwdev, phy_idx, chan);
}
enum _rf_syn_pow {
RF_SYN_ON_OFF,
RF_SYN_OFF_ON,
RF_SYN_ALLON,
RF_SYN_ALLOFF,
};
static void rtw8922a_set_syn01_cav(struct rtw89_dev *rtwdev, enum _rf_syn_pow syn)
{
if (syn == RF_SYN_ALLON) {
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x2);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x2);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3);
} else if (syn == RF_SYN_ON_OFF) {
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x2);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x0);
} else if (syn == RF_SYN_OFF_ON) {
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x2);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3);
} else if (syn == RF_SYN_ALLOFF) {
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x0);
}
}
static void rtw8922a_set_syn01_cbv(struct rtw89_dev *rtwdev, enum _rf_syn_pow syn)
{
if (syn == RF_SYN_ALLON) {
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0xf);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0xf);
} else if (syn == RF_SYN_ON_OFF) {
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0xf);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0x0);
} else if (syn == RF_SYN_OFF_ON) {
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0xf);
} else if (syn == RF_SYN_ALLOFF) {
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0x0);
}
}
static void rtw8922a_set_syn01(struct rtw89_dev *rtwdev, enum _rf_syn_pow syn)
{
struct rtw89_hal *hal = &rtwdev->hal;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "SYN config=%d\n", syn);
if (hal->cv == CHIP_CAV)
rtw8922a_set_syn01_cav(rtwdev, syn);
else
rtw8922a_set_syn01_cbv(rtwdev, syn);
}
static void rtw8922a_chlk_ktbl_sel(struct rtw89_dev *rtwdev, u8 kpath, u8 idx)
{
u32 tmp;
if (idx > 2) {
rtw89_warn(rtwdev, "[DBCC][ERROR]indx is out of limit!! index(%d)", idx);
return;
}
if (kpath & RF_A) {
rtw89_phy_write32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_EN, 0x1);
rtw89_phy_write32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_IQC_V1, idx);
rtw89_phy_write32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_MDPD_V1, idx);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RR_TXG_SEL, 0x4 | idx);
tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, BIT(0));
rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, tmp);
tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, BIT(1));
rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G5, tmp);
}
if (kpath & RF_B) {
rtw89_phy_write32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_EN, 0x1);
rtw89_phy_write32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_IQC_V1, idx);
rtw89_phy_write32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_MDPD_V1, idx);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RR_TXG_SEL, 0x4 | idx);
tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, BIT(0));
rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT_C1, B_CFIR_LUT_G3, tmp);
tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, BIT(1));
rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT_C1, B_CFIR_LUT_G5, tmp);
}
}
static u8 rtw8922a_chlk_reload_sel_tbl_v0(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan, u8 path)
{
struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {};
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
u8 tbl_sel;
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];
}
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].rf18[tbl_sel] = rtw89_chip_chan_to_rf18_val(rtwdev, chan);
rfk_mcc->data[path].table_idx = tbl_sel;
return tbl_sel;
}
static u8 rtw8922a_chlk_reload_sel_tbl_v1(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan, u8 path)
{
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {};
u8 tbl_sel;
for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) {
struct rtw89_rfk_chan_desc *p = &desc[tbl_sel];
p->ch = rfk_mcc->ch[tbl_sel];
p->has_band = true;
p->band = rfk_mcc->band[tbl_sel];
p->has_bw = true;
p->bw = rfk_mcc->bw[tbl_sel];
}
tbl_sel = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan);
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->rf18[tbl_sel] = rtw89_chip_chan_to_rf18_val(rtwdev, chan);
/* shared table array, but tbl_sel can be independent by path */
rfk_mcc[path].table_idx = tbl_sel;
return tbl_sel;
}
static u8 rtw8922a_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan, u8 path)
{
if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V1, &rtwdev->fw))
return rtw8922a_chlk_reload_sel_tbl_v1(rtwdev, chan, path);
else
return rtw8922a_chlk_reload_sel_tbl_v0(rtwdev, chan, path);
}
static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev)
{
struct rtw89_entity_conf conf;
u8 s0_tbl, s1_tbl;
rtw89_entity_get_conf(rtwdev, &conf);
s0_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, conf.chans[0], 0);
s1_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, conf.chans[1], 1);
rtw8922a_chlk_ktbl_sel(rtwdev, RF_A, s0_tbl);
rtw8922a_chlk_ktbl_sel(rtwdev, RF_B, s1_tbl);
}
static void rtw8922a_rfk_mlo_ctrl(struct rtw89_dev *rtwdev)
{
enum _rf_syn_pow syn_pow;
if (!rtwdev->dbcc_en)
goto set_rfk_reload;
switch (rtwdev->mlo_dbcc_mode) {
case MLO_0_PLUS_2_1RF:
syn_pow = RF_SYN_OFF_ON;
break;
case MLO_0_PLUS_2_2RF:
case MLO_1_PLUS_1_2RF:
case MLO_2_PLUS_0_1RF:
case MLO_2_PLUS_0_2RF:
case MLO_2_PLUS_2_2RF:
case MLO_DBCC_NOT_SUPPORT:
default:
syn_pow = RF_SYN_ON_OFF;
break;
case MLO_1_PLUS_1_1RF:
case DBCC_LEGACY:
syn_pow = RF_SYN_ALLON;
break;
}
rtw8922a_set_syn01(rtwdev, syn_pow);
set_rfk_reload:
rtw8922a_chlk_reload(rtwdev);
}
static void rtw8922a_rfk_pll_init(struct rtw89_dev *rtwdev)
{
int ret;
u8 tmp;
ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_PLL_1, &tmp);
if (ret)
return;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL_1, tmp | 0xf8, 0xFF);
if (ret)
return;
ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_APBT, &tmp);
if (ret)
return;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_APBT, tmp & ~0x60, 0xFF);
if (ret)
return;
ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_XTAL_PLL, &tmp);
if (ret)
return;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_PLL, tmp | 0x38, 0xFF);
if (ret)
return;
}
void rtw8922a_rfk_hw_init(struct rtw89_dev *rtwdev)
{
if (rtwdev->dbcc_en)
rtw8922a_rfk_mlo_ctrl(rtwdev);
rtw8922a_rfk_pll_init(rtwdev);
}
void rtw8922a_pre_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
bool mlo_1_1;
if (!rtwdev->dbcc_en)
return;
mlo_1_1 = rtw89_is_mlo_1_1(rtwdev);
if (mlo_1_1)
rtw8922a_set_syn01(rtwdev, RF_SYN_ALLON);
else if (phy_idx == RTW89_PHY_0)
rtw8922a_set_syn01(rtwdev, RF_SYN_ON_OFF);
else
rtw8922a_set_syn01(rtwdev, RF_SYN_OFF_ON);
fsleep(1000);
}
void rtw8922a_post_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
rtw8922a_rfk_mlo_ctrl(rtwdev);
}
@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2023 Realtek Corporation
*/
#ifndef __RTW89_8922A_RFK_H__
#define __RTW89_8922A_RFK_H__
#include "core.h"
void rtw8922a_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx);
void rtw8922a_set_channel_rf(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
void rtw8922a_rfk_hw_init(struct rtw89_dev *rtwdev);
void rtw8922a_pre_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
void rtw8922a_post_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
#endif
@@ -0,0 +1,121 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2023 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/pci.h>
#include "pci.h"
#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,
.isr_def = &rtw89_pci_isr_be,
.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_V1_256B,
.rx_burst = MAC_AX_RX_BURST_V1_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_ENABLE,
.io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_DEF,
.rx_ring_eq_is_full = true,
.check_rx_tag = true,
.no_rxbd_fs = true,
.group_bd_addr = false,
.rpp_fmt_size = sizeof(struct rtw89_pci_rpp_fmt),
.init_cfg_reg = R_BE_HAXI_INIT_CFG1,
.txhci_en_bit = B_BE_TXDMA_EN,
.rxhci_en_bit = B_BE_RXDMA_EN,
.rxbd_mode_bit = B_BE_RXQ_RXBD_MODE_MASK,
.exp_ctrl_reg = R_BE_HAXI_EXP_CTRL_V1,
.max_tag_num_mask = B_BE_MAX_TAG_NUM_MASK,
.rxbd_rwptr_clr_reg = R_BE_RXBD_RWPTR_CLR1_V1,
.txbd_rwptr_clr2_reg = R_BE_TXBD_RWPTR_CLR1,
.dma_io_stop = {R_BE_HAXI_INIT_CFG1, B_BE_STOP_AXI_MST},
.dma_stop1 = {R_BE_HAXI_DMA_STOP1, B_BE_TX_STOP1_MASK},
.dma_stop2 = {0},
.dma_busy1 = {R_BE_HAXI_DMA_BUSY1, DMA_BUSY1_CHECK_BE},
.dma_busy2_reg = 0,
.dma_busy3_reg = R_BE_HAXI_DMA_BUSY1,
.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,
.bd_ram_table = NULL,
.ltr_set = rtw89_pci_ltr_set_v2,
.fill_txaddr_info = rtw89_pci_fill_txaddr_info_v1,
.parse_rpp = rtw89_pci_parse_rpp,
.config_intr_mask = rtw89_pci_config_intr_mask_v2,
.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,
.dev_id_quirks = 0,
.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,
.dev_id_quirks = 0,
.bus = {
.pci = &rtw8922a_pci_info,
},
};
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);
static struct pci_driver rtw89_8922ae_driver = {
.name = "rtw89_8922ae",
.id_table = rtw89_8922ae_id_table,
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops_be,
.err_handler = &rtw89_pci_err_handler,
};
module_pci_driver(rtw89_8922ae_driver);
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11be wireless 8922AE/8922AE-VS driver");
MODULE_LICENSE("Dual BSD/GPL");
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2026 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/usb.h>
#include "rtw8922a.h"
#include "usb.h"
static const struct rtw89_usb_info rtw8922a_usb_info = {
.usb_host_request_2 = 0,
.usb_wlan0_1 = 0,
.hci_func_en = 0,
.usb3_mac_npi_config_intf_0 = 0,
.usb_endpoint_0 = 0,
.usb_endpoint_2 = 0,
.rx_agg_alignment = 16,
.bulkout_id = {
[RTW89_DMA_ACH0] = 3,
[RTW89_DMA_ACH2] = 5,
[RTW89_DMA_ACH4] = 4,
[RTW89_DMA_ACH6] = 6,
[RTW89_DMA_B0MG] = 0,
[RTW89_DMA_B0HI] = 0,
[RTW89_DMA_B1MG] = 1,
[RTW89_DMA_B1HI] = 1,
[RTW89_DMA_H2C] = 2,
},
};
static const struct rtw89_driver_info rtw89_8922au_info = {
.chip = &rtw8922a_chip_info,
.variant = NULL,
.quirks = NULL,
.dev_id_quirks = 0,
.bus = {
.usb = &rtw8922a_usb_info,
},
};
static const struct usb_device_id rtw_8922au_id_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03ef, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0502, 0x76d7, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4025, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4026, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1bcf, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1bd2, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0x8912, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0xda0e, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x332b, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x3625, 0x010a, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x37ad, 0x0100, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x37ad, 0x0101, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x3822, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x4822, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x5822, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&rtw89_8922au_info },
{},
};
MODULE_DEVICE_TABLE(usb, rtw_8922au_id_table);
static struct usb_driver rtw_8922au_driver = {
.name = KBUILD_MODNAME,
.id_table = rtw_8922au_id_table,
.probe = rtw89_usb_probe,
.disconnect = rtw89_usb_disconnect,
};
module_usb_driver(rtw_8922au_driver);
MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
MODULE_DESCRIPTION("Realtek 802.11be wireless 8922AU driver");
MODULE_LICENSE("Dual BSD/GPL");
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,83 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2026 Realtek Corporation
*/
#ifndef __RTW89_8922D_H__
#define __RTW89_8922D_H__
#include "core.h"
#define RF_PATH_NUM_8922D 2
#define BB_PATH_NUM_8922D 2
struct rtw8922d_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];
u8 bw_diff_5g[10];
} __packed;
struct rtw8922d_tssi_offset_6g {
u8 bw40_1s_tssi_6g[TSSI_MCS_6G_CH_GROUP_NUM];
u8 rsvd[0xa];
} __packed;
struct rtw8922d_rx_gain {
u8 _2g_ofdm;
u8 _2g_cck;
u8 _5g_low;
u8 _5g_mid;
u8 _5g_high;
} __packed;
struct rtw8922d_rx_gain_6g {
u8 _6g_l0;
u8 _6g_l1;
u8 _6g_m0;
u8 _6g_m1;
u8 _6g_h0;
u8 _6g_h1;
u8 _6g_uh0;
u8 _6g_uh1;
} __packed;
struct rtw8922d_efuse {
u8 country_code[2];
u8 rsvd[0xe];
struct rtw8922d_tssi_offset path_a_tssi;
struct rtw8922d_tssi_offset path_b_tssi;
u8 rsvd1[0x54];
u8 channel_plan;
u8 xtal_k;
u8 rsvd2[0x7];
u8 board_info;
u8 rsvd3[0x8];
u8 rfe_type;
u8 rsvd4[2];
u8 bt_setting_2;
u8 bt_setting_3;
u8 rsvd4_2;
u8 path_a_therm;
u8 path_b_therm;
u8 rsvd5[0x2];
struct rtw8922d_rx_gain rx_gain_a;
struct rtw8922d_rx_gain rx_gain_b;
u8 rsvd6[0x18];
struct rtw8922d_rx_gain rx_gain_a_2;
struct rtw8922d_rx_gain rx_gain_b_2;
struct rtw8922d_tssi_offset_6g path_a_tssi_6g;
struct rtw8922d_tssi_offset_6g path_b_tssi_6g;
struct rtw8922d_tssi_offset_6g path_c_tssi_6g;
struct rtw8922d_tssi_offset_6g path_d_tssi_6g;
struct rtw8922d_rx_gain_6g rx_gain_6g_a;
struct rtw8922d_rx_gain_6g rx_gain_6g_b;
u8 rsvd7[0x5a];
struct rtw8922d_rx_gain_6g rx_gain_6g_a_2;
struct rtw8922d_rx_gain_6g rx_gain_6g_b_2;
} __packed;
extern const struct rtw89_chip_info rtw8922d_chip_info;
extern const struct rtw89_chip_variant rtw8922de_vs_variant;
#endif
@@ -0,0 +1,402 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2026 Realtek Corporation
*/
#include "chan.h"
#include "debug.h"
#include "phy.h"
#include "reg.h"
#include "rtw8922d.h"
#include "rtw8922d_rfk.h"
static const struct rtw89_reg5_def rtw8922d_nctl_post_defs[] = {
RTW89_DECL_RFK_WM(0x20c7c, 0x00e00000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8922d_nctl_post_defs);
static void rtw8922d_tssi_cont_en(struct rtw89_dev *rtwdev, bool en,
enum rtw89_rf_path path, u8 phy_idx)
{
static const u32 tssi_trk_man[2] = {R_TSSI_EN_P0_BE4,
R_TSSI_EN_P0_BE4 + 0x100};
if (en)
rtw89_phy_write32_idx(rtwdev, tssi_trk_man[path],
B_TSSI_CONT_EN, 0, phy_idx);
else
rtw89_phy_write32_idx(rtwdev, tssi_trk_man[path],
B_TSSI_CONT_EN, 1, phy_idx);
}
void rtw8922d_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx)
{
if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) {
if (phy_idx == RTW89_PHY_0)
rtw8922d_tssi_cont_en(rtwdev, en, RF_PATH_A, phy_idx);
else
rtw8922d_tssi_cont_en(rtwdev, en, RF_PATH_B, phy_idx);
} else {
rtw8922d_tssi_cont_en(rtwdev, en, RF_PATH_A, phy_idx);
rtw8922d_tssi_cont_en(rtwdev, en, RF_PATH_B, phy_idx);
}
}
static
void rtw8922d_ctl_band_ch_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
const struct rtw89_chan *chan)
{
u8 synpath;
u32 rf18;
synpath = rtw89_phy_get_syn_sel(rtwdev, phy);
rf18 = rtw89_chip_chan_to_rf18_val(rtwdev, chan);
rtw89_write_rf(rtwdev, synpath, RR_RSV1, RFREG_MASK, 0x0);
rtw89_write_rf(rtwdev, synpath, RR_MOD, RFREG_MASK, 0x30000);
rtw89_write_rf(rtwdev, synpath, RR_CFGCH, RFREG_MASK, rf18);
fsleep(400);
rtw89_write_rf(rtwdev, synpath, RR_RSV1, RFREG_MASK, 0x1);
rtw89_write_rf(rtwdev, synpath, RR_CFGCH_V1, RFREG_MASK, rf18);
}
void rtw8922d_set_channel_rf(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
rtw8922d_ctl_band_ch_bw(rtwdev, phy_idx, chan);
}
enum _rf_syn_pow {
RF_SYN_ON_OFF,
RF_SYN_OFF_ON,
RF_SYN_ALLON,
RF_SYN_ALLOFF,
};
static void rtw8922d_set_syn01(struct rtw89_dev *rtwdev, enum _rf_syn_pow syn)
{
rtw89_debug(rtwdev, RTW89_DBG_RFK, "SYN config=%d\n", syn);
if (syn == RF_SYN_ALLON) {
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, BIT(1), 0x0);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, BIT(1), 0x0);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, MASKDWORD, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, MASKDWORD, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0xf);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0xf);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, MASKDWORD, 0x1);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, MASKDWORD, 0x1);
} else if (syn == RF_SYN_ON_OFF) {
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, BIT(1), 0x0);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, MASKDWORD, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0xf);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, MASKDWORD, 0x1);
} else if (syn == RF_SYN_OFF_ON) {
rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, BIT(1), 0x0);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, MASKDWORD, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0xf);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, MASKDWORD, 0x1);
} else if (syn == RF_SYN_ALLOFF) {
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0x0);
}
}
void rtw8922d_chlk_ktbl_ctl_mld(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool manual)
{
if (manual) {
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
u8 path = phy_idx; /* numerical equal for target */
u8 idx = rfk_mcc[path].table_idx;
rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_RST, 0x1);
rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_RST, 0x1);
rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_IDX0, idx);
rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_IDX1, idx);
rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_IDX0, idx);
rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_IDX1, idx);
rtw89_phy_write32_mask(rtwdev, R_KTBL1A_BE4, B_KTBL1_TBL0, idx & BIT(0));
rtw89_phy_write32_mask(rtwdev, R_KTBL1A_BE4, B_KTBL1_TBL1, (idx & BIT(1)) >> 1);
rtw89_phy_write32_mask(rtwdev, R_KTBL1B_BE4, B_KTBL1_TBL0, idx & BIT(0));
rtw89_phy_write32_mask(rtwdev, R_KTBL1B_BE4, B_KTBL1_TBL1, (idx & BIT(1)) >> 1);
return;
}
rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_RST, 0x0);
rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_RST, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RR_SW_SEL, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT_V1, RR_SW_SEL, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RR_SW_SEL, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT_V1, RR_SW_SEL, 0x0);
}
static void rtw8922d_chlk_ktbl_sel_mld(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx, u8 idx)
{
if (phy_idx == RTW89_PHY_0) {
rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_MLD_IDX0, idx);
rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_MLD_IDX0, idx);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RR_TBL_SEL_IDX0, idx);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT_V1, RR_TBL_SEL_IDX0, idx);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RR_TBL_SEL_IDX0, idx);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT_V1, RR_TBL_SEL_IDX0, idx);
} else if (phy_idx == RTW89_PHY_1) {
rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_MLD_IDX1, idx);
rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_MLD_IDX1, idx);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RR_TBL_SEL_IDX1, idx);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT_V1, RR_TBL_SEL_IDX1, idx);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RR_TBL_SEL_IDX1, idx);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT_V1, RR_TBL_SEL_IDX1, idx);
}
rtw8922d_chlk_ktbl_ctl_mld(rtwdev, phy_idx, false);
}
static void rtw8922d_chlk_ktbl_sel(struct rtw89_dev *rtwdev, u8 kpath, u8 idx)
{
if (idx > 2) {
rtw89_warn(rtwdev, "[DBCC][ERROR]indx is out of limit!! index(%d)", idx);
return;
}
if (kpath & RF_A) {
rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_RST, 0x1);
rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_IDX0, idx);
rtw89_phy_write32_mask(rtwdev, R_KTBL0A_BE4, B_KTBL0_IDX1, idx);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RR_TXG_SEL, 0x4 | idx);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT_V1, RR_TXG_SEL, 0x4 | idx);
rtw89_phy_write32_mask(rtwdev, R_KTBL1A_BE4, B_KTBL1_TBL0, idx & BIT(0));
rtw89_phy_write32_mask(rtwdev, R_KTBL1A_BE4, B_KTBL1_TBL1, (idx & BIT(1)) >> 1);
}
if (kpath & RF_B) {
rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_RST, 0x1);
rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_IDX0, idx);
rtw89_phy_write32_mask(rtwdev, R_KTBL0B_BE4, B_KTBL0_IDX1, idx);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RR_TXG_SEL, 0x4 | idx);
rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT_V1, RR_TXG_SEL, 0x4 | idx);
rtw89_phy_write32_mask(rtwdev, R_KTBL1B_BE4, B_KTBL1_TBL0, idx & BIT(0));
rtw89_phy_write32_mask(rtwdev, R_KTBL1B_BE4, B_KTBL1_TBL1, (idx & BIT(1)) >> 1);
}
}
static u8 rtw8922d_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan, u8 path)
{
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {};
u8 tbl_sel;
for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) {
struct rtw89_rfk_chan_desc *p = &desc[tbl_sel];
p->ch = rfk_mcc->ch[tbl_sel];
p->has_band = true;
p->band = rfk_mcc->band[tbl_sel];
p->has_bw = true;
p->bw = rfk_mcc->bw[tbl_sel];
}
tbl_sel = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan);
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->rf18[tbl_sel] = rtw89_chip_chan_to_rf18_val(rtwdev, chan);
/* shared table array, but tbl_sel can be independent by path */
rfk_mcc[path].table_idx = tbl_sel;
return tbl_sel;
}
static void rtw8922d_chlk_reload(struct rtw89_dev *rtwdev)
{
struct rtw89_entity_conf conf;
u8 s0_tbl, s1_tbl;
rtw89_entity_get_conf(rtwdev, &conf);
s0_tbl = rtw8922d_chlk_reload_sel_tbl(rtwdev, conf.chans[0], 0);
s1_tbl = rtw8922d_chlk_reload_sel_tbl(rtwdev, conf.chans[1], 1);
if (conf.is_mld)
goto mld;
rtw8922d_chlk_ktbl_sel(rtwdev, RF_A, s0_tbl);
rtw8922d_chlk_ktbl_sel(rtwdev, RF_B, s1_tbl);
return;
mld:
if (test_bit(RTW89_PHY_0, conf.hw_bitmap))
rtw8922d_chlk_ktbl_sel_mld(rtwdev, RTW89_PHY_0, s0_tbl);
if (test_bit(RTW89_PHY_1, conf.hw_bitmap))
rtw8922d_chlk_ktbl_sel_mld(rtwdev, RTW89_PHY_1, s1_tbl);
}
static enum _rf_syn_pow rtw8922d_get_syn_pow(struct rtw89_dev *rtwdev)
{
switch (rtwdev->mlo_dbcc_mode) {
case MLO_0_PLUS_2_1RF:
return RF_SYN_OFF_ON;
case MLO_0_PLUS_2_2RF:
case MLO_1_PLUS_1_2RF:
case MLO_2_PLUS_0_1RF:
case MLO_2_PLUS_0_2RF:
case MLO_2_PLUS_2_2RF:
case MLO_DBCC_NOT_SUPPORT:
default:
return RF_SYN_ON_OFF;
case MLO_1_PLUS_1_1RF:
case DBCC_LEGACY:
return RF_SYN_ALLON;
}
}
void rtw8922d_rfk_mlo_ctrl(struct rtw89_dev *rtwdev)
{
enum _rf_syn_pow syn_pow = rtw8922d_get_syn_pow(rtwdev);
if (!rtwdev->dbcc_en)
goto set_rfk_reload;
rtw8922d_set_syn01(rtwdev, syn_pow);
set_rfk_reload:
rtw8922d_chlk_reload(rtwdev);
}
static void rtw8922d_x4k_setting(struct rtw89_dev *rtwdev)
{
u32 val;
val = rtw89_read_rf(rtwdev, RF_PATH_A, 0xB9, 0xF000);
rtw89_write_rf(rtwdev, RF_PATH_A, 0xB9, 0xF000, val);
val = rtw89_read_rf(rtwdev, RF_PATH_B, 0xB9, 0xF000);
rtw89_write_rf(rtwdev, RF_PATH_B, 0xB9, 0xF000, val);
rtw89_write_rf(rtwdev, RF_PATH_A, 0xC2, BIT(19), 0x1);
rtw89_write_rf(rtwdev, RF_PATH_B, 0xC2, BIT(19), 0x1);
}
void rtw8922d_rfk_hw_init(struct rtw89_dev *rtwdev)
{
rtw8922d_x4k_setting(rtwdev);
}
void rtw8922d_pre_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
bool mlo_1_1;
if (!rtwdev->dbcc_en)
return;
mlo_1_1 = rtw89_is_mlo_1_1(rtwdev);
if (mlo_1_1)
rtw8922d_set_syn01(rtwdev, RF_SYN_ALLON);
else if (phy_idx == RTW89_PHY_0)
rtw8922d_set_syn01(rtwdev, RF_SYN_ON_OFF);
else
rtw8922d_set_syn01(rtwdev, RF_SYN_OFF_ON);
fsleep(1000);
}
void rtw8922d_post_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
rtw8922d_rfk_mlo_ctrl(rtwdev);
}
static u8 _get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
{
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);
fsleep(200);
return rtw89_read_rf(rtwdev, path, RR_TM, RR_TM_VAL_V1);
}
static void _lck_keep_thermal(struct rtw89_dev *rtwdev)
{
struct rtw89_lck_info *lck = &rtwdev->lck;
int path;
for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
lck->thermal[path] = _get_thermal(rtwdev, path);
rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
"[LCK] path=%d thermal=0x%x", path, lck->thermal[path]);
}
}
static void _lck(struct rtw89_dev *rtwdev)
{
enum _rf_syn_pow syn_pow = rtw8922d_get_syn_pow(rtwdev);
u8 path_mask = 0;
u32 tmp18, tmp5;
int path;
rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "[LCK] DO LCK\n");
if (syn_pow == RF_SYN_ALLON)
path_mask = BIT(RF_PATH_A) | BIT(RF_PATH_B);
else if (syn_pow == RF_SYN_ON_OFF)
path_mask = BIT(RF_PATH_A);
else if (syn_pow == RF_SYN_OFF_ON)
path_mask = BIT(RF_PATH_B);
else
return;
for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
if (!(path_mask & BIT(path)))
continue;
tmp18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, MASKDWORD);
tmp5 = rtw89_read_rf(rtwdev, path, RR_RSV1, MASKDWORD);
rtw89_write_rf(rtwdev, path, RR_MOD, MASKDWORD, 0x10000);
rtw89_write_rf(rtwdev, path, RR_RSV1, MASKDWORD, 0x0);
rtw89_write_rf(rtwdev, path, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1);
rtw89_write_rf(rtwdev, path, RR_CFGCH, MASKDWORD, tmp18);
rtw89_write_rf(rtwdev, path, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0);
fsleep(400);
rtw89_write_rf(rtwdev, path, RR_RSV1, MASKDWORD, tmp5);
}
_lck_keep_thermal(rtwdev);
}
#define RTW8922D_LCK_TH 16
void rtw8922d_lck_track(struct rtw89_dev *rtwdev)
{
struct rtw89_lck_info *lck = &rtwdev->lck;
u8 cur_thermal;
int delta;
int path;
for (path = 0; path < rtwdev->chip->rf_path_num; path++) {
cur_thermal = _get_thermal(rtwdev, path);
delta = abs((int)cur_thermal - lck->thermal[path]);
rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
"[LCK] path=%d current thermal=0x%x delta=0x%x\n",
path, cur_thermal, delta);
if (delta >= RTW8922D_LCK_TH) {
_lck(rtwdev);
return;
}
}
}
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2026 Realtek Corporation
*/
#ifndef __RTW89_8922D_RFK_H__
#define __RTW89_8922D_RFK_H__
#include "core.h"
extern const struct rtw89_rfk_tbl rtw8922d_nctl_post_defs_tbl;
void rtw8922d_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx);
void rtw8922d_set_channel_rf(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
void rtw8922d_rfk_hw_init(struct rtw89_dev *rtwdev);
void rtw8922d_rfk_mlo_ctrl(struct rtw89_dev *rtwdev);
void rtw8922d_pre_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
void rtw8922d_post_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
void rtw8922d_lck_track(struct rtw89_dev *rtwdev);
void rtw8922d_chlk_ktbl_ctl_mld(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool manual);
#endif
@@ -0,0 +1,121 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2026 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/pci.h>
#include "pci.h"
#include "reg.h"
#include "rtw8922d.h"
static const struct rtw89_pci_info rtw8922d_pci_info = {
.gen_def = &rtw89_pci_gen_be,
.isr_def = &rtw89_pci_isr_be_v1,
.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_V1_256B,
.rx_burst = MAC_AX_RX_BURST_V1_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_ENABLE,
.io_rcy_tmr = MAC_AX_IO_RCY_ANA_TMR_DEF,
.rx_ring_eq_is_full = true,
.check_rx_tag = true,
.no_rxbd_fs = true,
.group_bd_addr = true,
.rpp_fmt_size = sizeof(struct rtw89_pci_rpp_fmt_v1),
.init_cfg_reg = R_BE_HAXI_INIT_CFG1,
.txhci_en_bit = B_BE_TXDMA_EN,
.rxhci_en_bit = B_BE_RXDMA_EN,
.rxbd_mode_bit = B_BE_RXQ_RXBD_MODE_MASK,
.exp_ctrl_reg = R_BE_HAXI_EXP_CTRL_V1,
.max_tag_num_mask = B_BE_MAX_TAG_NUM_MASK,
.rxbd_rwptr_clr_reg = R_BE_RXBD_RWPTR_CLR1_V1,
.txbd_rwptr_clr2_reg = R_BE_TXBD_RWPTR_CLR1,
.dma_io_stop = {R_BE_HAXI_INIT_CFG1, B_BE_STOP_AXI_MST},
.dma_stop1 = {R_BE_HAXI_DMA_STOP1, B_BE_TX_STOP1_MASK_V1},
.dma_stop2 = {0},
.dma_busy1 = {R_BE_HAXI_DMA_BUSY1, DMA_BUSY1_CHECK_BE_V1},
.dma_busy2_reg = 0,
.dma_busy3_reg = R_BE_HAXI_DMA_BUSY1,
.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 = BIT(RTW89_TXCH_ACH1) | BIT(RTW89_TXCH_ACH3) |
BIT(RTW89_TXCH_ACH5) | BIT(RTW89_TXCH_ACH7) |
BIT(RTW89_TXCH_CH9) | BIT(RTW89_TXCH_CH11),
.bd_idx_addr_low_power = NULL,
.dma_addr_set = &rtw89_pci_ch_dma_addr_set_be_v1,
.bd_ram_table = NULL,
.ltr_set = rtw89_pci_ltr_set_v2,
.fill_txaddr_info = rtw89_pci_fill_txaddr_info_v1,
.parse_rpp = rtw89_pci_parse_rpp_v1,
.config_intr_mask = rtw89_pci_config_intr_mask_v3,
.enable_intr = rtw89_pci_enable_intr_v3,
.disable_intr = rtw89_pci_disable_intr_v3,
.recognize_intrs = rtw89_pci_recognize_intrs_v3,
.ssid_quirks = NULL,
};
static const struct rtw89_driver_info rtw89_8922de_vs_info = {
.chip = &rtw8922d_chip_info,
.variant = &rtw8922de_vs_variant,
.quirks = NULL,
.dev_id_quirks = 0,
.bus = {
.pci = &rtw8922d_pci_info,
},
};
static const struct rtw89_driver_info rtw89_8922de_info = {
.chip = &rtw8922d_chip_info,
.variant = NULL,
.quirks = NULL,
.dev_id_quirks = 0,
.bus = {
.pci = &rtw8922d_pci_info,
},
};
static const struct pci_device_id rtw89_8922de_id_table[] = {
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x892D),
.driver_data = (kernel_ulong_t)&rtw89_8922de_vs_info,
},
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x882D),
.driver_data = (kernel_ulong_t)&rtw89_8922de_vs_info,
},
{
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x895D),
.driver_data = (kernel_ulong_t)&rtw89_8922de_info,
},
{},
};
MODULE_DEVICE_TABLE(pci, rtw89_8922de_id_table);
static struct pci_driver rtw89_8922de_driver = {
.name = "rtw89_8922de",
.id_table = rtw89_8922de_id_table,
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops_be,
.err_handler = &rtw89_pci_err_handler,
};
module_pci_driver(rtw89_8922de_driver);
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11be wireless 8922DE/8922DE-VS driver");
MODULE_LICENSE("Dual BSD/GPL");
@@ -0,0 +1,911 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#include "acpi.h"
#include "debug.h"
#include "fw.h"
#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)
{
switch (center_freq) {
default:
rtw89_debug(rtwdev, RTW89_DBG_SAR,
"center freq: %u to SAR subband is unhandled\n",
center_freq);
fallthrough;
case 2412 ... 2484:
return RTW89_SAR_2GHZ_SUBBAND;
case 5180 ... 5320:
return RTW89_SAR_5GHZ_SUBBAND_1_2;
case 5500 ... 5720:
return RTW89_SAR_5GHZ_SUBBAND_2_E;
case 5745 ... 5885:
return RTW89_SAR_5GHZ_SUBBAND_3_4;
case 5955 ... 6155:
return RTW89_SAR_6GHZ_SUBBAND_5_L;
case 6175 ... 6415:
return RTW89_SAR_6GHZ_SUBBAND_5_H;
case 6435 ... 6515:
return RTW89_SAR_6GHZ_SUBBAND_6;
case 6535 ... 6695:
return RTW89_SAR_6GHZ_SUBBAND_7_L;
case 6715 ... 6855:
return RTW89_SAR_6GHZ_SUBBAND_7_H;
/* 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_6ghz_span.
*/
case 6895 ... 7115:
return RTW89_SAR_6GHZ_SUBBAND_8;
}
}
static int rtw89_query_sar_config_common(struct rtw89_dev *rtwdev,
const struct rtw89_sar_parm *sar_parm,
s32 *cfg)
{
struct rtw89_sar_cfg_common *rtwsar = &rtwdev->sar.cfg_common;
enum rtw89_sar_subband subband_l, subband_h;
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->sar_subband_low;
subband_h = span->sar_subband_high;
} else {
subband_l = rtw89_sar_get_subband(rtwdev, center_freq);
subband_h = subband_l;
}
rtw89_debug(rtwdev, RTW89_DBG_SAR,
"center_freq %u: SAR subband {%u, %u}\n",
center_freq, subband_l, subband_h);
if (!rtwsar->set[subband_l] && !rtwsar->set[subband_h])
return -ENODATA;
if (!rtwsar->set[subband_l])
*cfg = rtwsar->cfg[subband_h];
else if (!rtwsar->set[subband_h])
*cfg = rtwsar->cfg[subband_l];
else
*cfg = min(rtwsar->cfg[subband_l], rtwsar->cfg[subband_h]);
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] = {
.descr_sar_source = "RTW89_SAR_SOURCE_COMMON",
.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) \
do { \
typeof(_src) _s = (_src); \
typeof(_dev) _d = (_dev); \
BUILD_BUG_ON(!rtw89_sar_handlers[_s].descr_sar_source); \
BUILD_BUG_ON(!rtw89_sar_handlers[_s].query_sar_config); \
if (test_bit(RTW89_FLAG_PROBE_DONE, _d->flags)) \
lockdep_assert_wiphy(_d->hw->wiphy); \
_d->sar._cfg_name = *(_cfg_data); \
_d->sar.src = _s; \
} while (0)
static s8 rtw89_txpwr_sar_to_mac(struct rtw89_dev *rtwdev, u8 fct, s32 cfg)
{
const u8 fct_mac = rtwdev->chip->txpwr_factor_mac;
s32 cfg_mac;
cfg_mac = fct > fct_mac ?
cfg >> (fct - fct_mac) : cfg << (fct_mac - fct);
return (s8)clamp_t(s32, cfg_mac,
RTW89_SAR_TXPWR_MAC_MIN,
RTW89_SAR_TXPWR_MAC_MAX);
}
static s32 rtw89_txpwr_tas_to_sar(const struct rtw89_sar_handler *sar_hdl,
s32 cfg)
{
const u8 fct = sar_hdl->txpwr_factor_sar;
if (fct > RTW89_TAS_FACTOR)
return cfg << (fct - RTW89_TAS_FACTOR);
else
return cfg >> (RTW89_TAS_FACTOR - fct);
}
static s32 rtw89_txpwr_sar_to_tas(const struct rtw89_sar_handler *sar_hdl,
s32 cfg)
{
const u8 fct = sar_hdl->txpwr_factor_sar;
if (fct > RTW89_TAS_FACTOR)
return cfg >> (fct - RTW89_TAS_FACTOR);
else
return cfg << (RTW89_TAS_FACTOR - fct);
}
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;
s32 offset;
int ret;
s32 cfg;
u8 fct;
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, sar_parm, &cfg);
if (ret)
return RTW89_SAR_TXPWR_MAC_MAX;
if (rtw89_tas_is_active(rtwdev)) {
switch (tas->state) {
case RTW89_TAS_STATE_DPR_OFF:
offset = rtw89_txpwr_tas_to_sar(sar_hdl, RTW89_TAS_DPR_OFF_OFFSET);
cfg += offset;
break;
case RTW89_TAS_STATE_DPR_ON:
offset = rtw89_txpwr_tas_to_sar(sar_hdl, RTW89_TAS_DPR_ON_OFFSET);
cfg -= offset;
break;
case RTW89_TAS_STATE_STATIC_SAR:
default:
break;
}
}
fct = sar_hdl->txpwr_factor_sar;
return rtw89_txpwr_sar_to_mac(rtwdev, fct, cfg);
}
EXPORT_SYMBOL(rtw89_query_sar);
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_wiphy(rtwdev->hw->wiphy);
if (src == RTW89_SAR_SOURCE_NONE) {
p += scnprintf(p, end - p, "no SAR is applied\n");
goto out;
}
p += scnprintf(p, end - p, "source: %d (%s)\n", src,
sar_hdl->descr_sar_source);
ret = sar_hdl->query_sar_config(rtwdev, sar_parm, &cfg);
if (ret) {
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;
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;
}
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 (!rtw89_tas_is_active(rtwdev)) {
p += scnprintf(p, end - p, "no TAS is applied\n");
goto out;
}
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)
{
/* 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);
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 = 5885, },
{ .start_freq = 5955, .end_freq = 6155, },
{ .start_freq = 6175, .end_freq = 6415, },
{ .start_freq = 6435, .end_freq = 6515, },
{ .start_freq = 6535, .end_freq = 6695, },
{ .start_freq = 6715, .end_freq = 6875, },
{ .start_freq = 6875, .end_freq = 7115, },
};
static_assert(RTW89_SAR_SUBBAND_NR ==
ARRAY_SIZE(rtw89_common_sar_freq_ranges));
const struct cfg80211_sar_capa rtw89_sar_capa = {
.type = NL80211_SAR_TYPE_POWER,
.num_freq_ranges = ARRAY_SIZE(rtw89_common_sar_freq_ranges),
.freq_ranges = rtw89_common_sar_freq_ranges,
};
int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_sar_cfg_common sar_common = {0};
u8 fct;
u32 freq_start;
u32 freq_end;
s32 power;
u32 i, idx;
lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (sar->type != NL80211_SAR_TYPE_POWER)
return -EINVAL;
fct = rtw89_sar_handlers[RTW89_SAR_SOURCE_COMMON].txpwr_factor_sar;
for (i = 0; i < sar->num_sub_specs; i++) {
idx = sar->sub_specs[i].freq_range_index;
if (idx >= ARRAY_SIZE(rtw89_common_sar_freq_ranges))
return -EINVAL;
freq_start = rtw89_common_sar_freq_ranges[idx].start_freq;
freq_end = rtw89_common_sar_freq_ranges[idx].end_freq;
power = sar->sub_specs[i].power;
rtw89_debug(rtwdev, RTW89_DBG_SAR,
"On freq %u to %u, set SAR limit %d (unit: 1/%lu dBm)\n",
freq_start, freq_end, power, BIT(fct));
sar_common.set[idx] = true;
sar_common.cfg[idx] = power;
}
return rtw89_apply_sar_common(rtwdev, &sar_common);
}
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;
cfg = kzalloc_obj(*cfg);
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_sar_parm sar_parm = {};
int ret;
if (src == RTW89_SAR_SOURCE_NONE)
return false;
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;
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);
switch (regd) {
default:
rtw89_debug(rtwdev, RTW89_DBG_SAR,
"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;
}
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,
"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;
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;
return __rtw89_tas_state_update(rtwdev, state);
}
static void rtw89_tas_init(struct rtw89_dev *rtwdev)
{
bool skip_acpi_dsm = rtwdev->hci.type == RTW89_HCI_TYPE_USB;
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;
if (!chip->support_tas)
return;
if (skip_acpi_dsm)
return;
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_TAS_EN, &res);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_SAR,
"acpi: cannot get TAS: %d\n", ret);
return;
}
ptr = res.u.policy_tas;
switch (ptr->enable) {
case 0:
tas->enable = false;
break;
case 1:
tas->enable = true;
break;
default:
break;
}
if (!tas->enable) {
rtw89_debug(rtwdev, RTW89_DBG_SAR, "TAS not enable\n");
goto out;
}
tas->enabled_countries = ptr->enabled_countries;
out:
kfree(ptr);
}
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 (!rtw89_tas_is_active(rtwdev))
return;
if (!rtw89_tas_query_sar_config(rtwdev, &cfg))
return;
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 bool rtw89_tas_track(struct rtw89_dev *rtwdev)
{
struct rtw89_tas_info *tas = &rtwdev->tas;
struct rtw89_hal *hal = &rtwdev->hal;
s32 cfg;
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_tas_info *tas = &rtwdev->tas;
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 (!rtw89_tas_is_active(rtwdev))
return;
if (!rtw89_tas_query_sar_config(rtwdev, &cfg))
return;
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_tas_fw_timer_enable(struct rtw89_dev *rtwdev, bool enable)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_tas_info *tas = &rtwdev->tas;
if (!tas->enable)
return;
if (chip->chip_gen == RTW89_CHIP_AX)
return;
rtw89_fw_h2c_rf_tas_trigger(rtwdev, enable);
}
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;
rtw89_debug(rtwdev, RTW89_DBG_SAR,
"%s: failed to track indicator: %d; reset and disable\n",
__func__, ret);
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);
if (!changes)
return;
rtw89_core_set_chip_txpwr(rtwdev);
}
@@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __RTW89_SAR_H__
#define __RTW89_SAR_H__
#include "core.h"
#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,
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, 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_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_tas_fw_timer_enable(struct rtw89_dev *rtwdev, bool enable);
void rtw89_sar_init(struct rtw89_dev *rtwdev);
void rtw89_sar_track(struct rtw89_dev *rtwdev);
#endif
@@ -0,0 +1,858 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2019-2020 Realtek Corporation
*/
#include <linux/devcoredump.h>
#include "cam.h"
#include "chan.h"
#include "debug.h"
#include "fw.h"
#include "mac.h"
#include "ps.h"
#include "reg.h"
#include "ser.h"
#include "util.h"
#define SER_RECFG_TIMEOUT 1000
enum ser_evt {
SER_EV_NONE,
SER_EV_STATE_IN,
SER_EV_STATE_OUT,
SER_EV_L1_RESET_PREPARE, /* pre-M0 */
SER_EV_L1_RESET, /* M1 */
SER_EV_DO_RECOVERY, /* M3 */
SER_EV_MAC_RESET_DONE, /* M5 */
SER_EV_L2_RESET,
SER_EV_L2_RECFG_DONE,
SER_EV_L2_RECFG_TIMEOUT,
SER_EV_M1_TIMEOUT,
SER_EV_M3_TIMEOUT,
SER_EV_FW_M5_TIMEOUT,
SER_EV_L0_RESET,
SER_EV_MAXX
};
enum ser_state {
SER_IDLE_ST,
SER_L1_RESET_PRE_ST,
SER_RESET_TRX_ST,
SER_DO_HCI_ST,
SER_L2_RESET_ST,
SER_ST_MAX_ST
};
struct ser_msg {
struct list_head list;
u8 event;
};
struct state_ent {
u8 state;
char *name;
void (*st_func)(struct rtw89_ser *ser, u8 event);
};
struct event_ent {
u8 event;
char *name;
};
static char *ser_ev_name(struct rtw89_ser *ser, u8 event)
{
if (event < SER_EV_MAXX)
return ser->ev_tbl[event].name;
return "err_ev_name";
}
static char *ser_st_name(struct rtw89_ser *ser)
{
if (ser->state < SER_ST_MAX_ST)
return ser->st_tbl[ser->state].name;
return "err_st_name";
}
#define RTW89_DEF_SER_CD_TYPE(_name, _type, _size) \
struct ser_cd_ ## _name { \
u32 type; \
u32 type_size; \
u64 padding; \
u8 data[_size]; \
} __packed; \
static void ser_cd_ ## _name ## _init(struct ser_cd_ ## _name *p) \
{ \
p->type = _type; \
p->type_size = sizeof(p->data); \
p->padding = 0x0123456789abcdef; \
}
enum rtw89_ser_cd_type {
RTW89_SER_CD_FW_RSVD_PLE = 0,
RTW89_SER_CD_FW_BACKTRACE = 1,
};
RTW89_DEF_SER_CD_TYPE(fw_rsvd_ple,
RTW89_SER_CD_FW_RSVD_PLE,
RTW89_FW_RSVD_PLE_SIZE);
RTW89_DEF_SER_CD_TYPE(fw_backtrace,
RTW89_SER_CD_FW_BACKTRACE,
RTW89_FW_BACKTRACE_MAX_SIZE);
struct rtw89_ser_cd_buffer {
struct ser_cd_fw_rsvd_ple fwple;
struct ser_cd_fw_backtrace fwbt;
} __packed;
static struct rtw89_ser_cd_buffer *rtw89_ser_cd_prep(struct rtw89_dev *rtwdev)
{
struct rtw89_ser_cd_buffer *buf;
buf = vzalloc(sizeof(*buf));
if (!buf)
return NULL;
ser_cd_fw_rsvd_ple_init(&buf->fwple);
ser_cd_fw_backtrace_init(&buf->fwbt);
return buf;
}
static void rtw89_ser_cd_send(struct rtw89_dev *rtwdev,
struct rtw89_ser_cd_buffer *buf)
{
rtw89_debug(rtwdev, RTW89_DBG_SER, "SER sends core dump\n");
/* After calling dev_coredump, buf's lifetime is supposed to be
* handled by the device coredump framework. Note that a new dump
* will be discarded if a previous one hasn't been released by
* framework yet.
*/
dev_coredumpv(rtwdev->dev, buf, sizeof(*buf), GFP_KERNEL);
}
static void rtw89_ser_cd_free(struct rtw89_dev *rtwdev,
struct rtw89_ser_cd_buffer *buf, bool free_self)
{
if (!free_self)
return;
rtw89_debug(rtwdev, RTW89_DBG_SER, "SER frees core dump by self\n");
/* When some problems happen during filling data of core dump,
* we won't send it to device coredump framework. Instead, we
* free buf by ourselves.
*/
vfree(buf);
}
static void ser_state_run(struct rtw89_ser *ser, u8 evt)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s receive %s\n",
ser_st_name(ser), ser_ev_name(ser, evt));
wiphy_lock(rtwdev->hw->wiphy);
rtw89_leave_lps(rtwdev);
wiphy_unlock(rtwdev->hw->wiphy);
ser->st_tbl[ser->state].st_func(ser, evt);
}
static void ser_state_goto(struct rtw89_ser *ser, u8 new_state)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
if (ser->state == new_state || new_state >= SER_ST_MAX_ST)
return;
ser_state_run(ser, SER_EV_STATE_OUT);
rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s goto -> %s\n",
ser_st_name(ser), ser->st_tbl[new_state].name);
ser->state = new_state;
ser_state_run(ser, SER_EV_STATE_IN);
}
static struct ser_msg *__rtw89_ser_dequeue_msg(struct rtw89_ser *ser)
{
struct ser_msg *msg;
spin_lock_irq(&ser->msg_q_lock);
msg = list_first_entry_or_null(&ser->msg_q, struct ser_msg, list);
if (msg)
list_del(&msg->list);
spin_unlock_irq(&ser->msg_q_lock);
return msg;
}
static void rtw89_ser_hdl_work(struct work_struct *work)
{
struct ser_msg *msg;
struct rtw89_ser *ser = container_of(work, struct rtw89_ser,
ser_hdl_work);
while ((msg = __rtw89_ser_dequeue_msg(ser))) {
ser_state_run(ser, msg->event);
kfree(msg);
}
}
static int ser_send_msg(struct rtw89_ser *ser, u8 event)
{
struct ser_msg *msg = NULL;
if (test_bit(RTW89_SER_DRV_STOP_RUN, ser->flags))
return -EIO;
msg = kmalloc_obj(*msg, GFP_ATOMIC);
if (!msg)
return -ENOMEM;
msg->event = event;
spin_lock_irq(&ser->msg_q_lock);
list_add(&msg->list, &ser->msg_q);
spin_unlock_irq(&ser->msg_q_lock);
schedule_work(&ser->ser_hdl_work);
return 0;
}
static void rtw89_ser_alarm_work(struct work_struct *work)
{
struct rtw89_ser *ser = container_of(work, struct rtw89_ser,
ser_alarm_work.work);
ser_send_msg(ser, ser->alarm_event);
ser->alarm_event = SER_EV_NONE;
}
static void ser_set_alarm(struct rtw89_ser *ser, u32 ms, u8 event)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
if (test_bit(RTW89_SER_DRV_STOP_RUN, ser->flags))
return;
ser->alarm_event = event;
ieee80211_queue_delayed_work(rtwdev->hw, &ser->ser_alarm_work,
msecs_to_jiffies(ms));
}
static void ser_del_alarm(struct rtw89_ser *ser)
{
cancel_delayed_work(&ser->ser_alarm_work);
ser->alarm_event = SER_EV_NONE;
}
/* driver function */
static void drv_stop_tx(struct rtw89_ser *ser)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
ieee80211_stop_queues(rtwdev->hw);
set_bit(RTW89_SER_DRV_STOP_TX, ser->flags);
}
static void drv_stop_rx(struct rtw89_ser *ser)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
clear_bit(RTW89_FLAG_RUNNING, rtwdev->flags);
set_bit(RTW89_SER_DRV_STOP_RX, ser->flags);
}
static void drv_trx_reset(struct rtw89_ser *ser)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
rtw89_hci_reset(rtwdev);
}
static void drv_resume_tx(struct rtw89_ser *ser)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
if (!test_bit(RTW89_SER_DRV_STOP_TX, ser->flags))
return;
ieee80211_wake_queues(rtwdev->hw);
clear_bit(RTW89_SER_DRV_STOP_TX, ser->flags);
}
static void drv_resume_rx(struct rtw89_ser *ser)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
if (!test_bit(RTW89_SER_DRV_STOP_RX, ser->flags))
return;
set_bit(RTW89_FLAG_RUNNING, rtwdev->flags);
clear_bit(RTW89_SER_DRV_STOP_RX, ser->flags);
}
static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
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 *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_vif_link *rtwvif_link;
struct rtw89_sta_link *rtwsta_link;
unsigned int link_id;
if (rtwvif != target_rtwvif)
return;
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_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);
}
static void ser_reset_mac_binding(struct rtw89_dev *rtwdev)
{
struct rtw89_vif *rtwvif;
rtw89_cam_reset_keys(rtwdev);
rtw89_for_each_rtwvif(rtwdev, rtwvif)
ser_deinit_cam(rtwdev, rtwvif);
rtw89_core_release_all_bits_map(rtwdev->mac_id_map, RTW89_MAX_MAC_ID_NUM);
rtw89_for_each_rtwvif(rtwdev, rtwvif)
ser_reset_vif(rtwdev, rtwvif);
rtwdev->total_sta_assoc = 0;
refcount_set(&rtwdev->refcount_ap_info, 0);
}
/* hal function */
static int hal_enable_dma(struct rtw89_ser *ser)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
int ret;
if (!test_bit(RTW89_SER_HAL_STOP_DMA, ser->flags))
return 0;
if (!rtwdev->hci.ops->mac_lv1_rcvy)
return -EIO;
ret = rtwdev->hci.ops->mac_lv1_rcvy(rtwdev, RTW89_LV1_RCVY_STEP_2);
if (!ret)
clear_bit(RTW89_SER_HAL_STOP_DMA, ser->flags);
else
rtw89_debug(rtwdev, RTW89_DBG_SER,
"lv1 rcvy fail to start dma: %d\n", ret);
return ret;
}
static int hal_stop_dma(struct rtw89_ser *ser)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
int ret;
if (!rtwdev->hci.ops->mac_lv1_rcvy)
return -EIO;
ret = rtwdev->hci.ops->mac_lv1_rcvy(rtwdev, RTW89_LV1_RCVY_STEP_1);
if (!ret)
set_bit(RTW89_SER_HAL_STOP_DMA, ser->flags);
else
rtw89_debug(rtwdev, RTW89_DBG_SER,
"lv1 rcvy fail to stop dma: %d\n", ret);
return ret;
}
static void hal_send_post_m0_event(struct rtw89_ser *ser)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_RESET_START_DMAC);
}
static void hal_send_m2_event(struct rtw89_ser *ser)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_DISABLE_EN);
}
static void hal_send_m4_event(struct rtw89_ser *ser)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_RCVY_EN);
}
static void hal_enable_err_imr(struct rtw89_ser *ser)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
mac->err_imr_ctrl(rtwdev, true);
}
/* state handler */
static void ser_idle_st_hdl(struct rtw89_ser *ser, u8 evt)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
switch (evt) {
case SER_EV_STATE_IN:
rtw89_hci_recovery_complete(rtwdev);
clear_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags);
clear_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags);
break;
case SER_EV_L1_RESET_PREPARE:
ser_state_goto(ser, SER_L1_RESET_PRE_ST);
break;
case SER_EV_L1_RESET:
ser_state_goto(ser, SER_RESET_TRX_ST);
break;
case SER_EV_L2_RESET:
ser_state_goto(ser, SER_L2_RESET_ST);
break;
case SER_EV_STATE_OUT:
set_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags);
rtw89_hci_recovery_start(rtwdev);
break;
default:
break;
}
}
static void ser_l1_reset_pre_st_hdl(struct rtw89_ser *ser, u8 evt)
{
switch (evt) {
case SER_EV_STATE_IN:
ser->prehandle_l1 = true;
hal_send_post_m0_event(ser);
ser_set_alarm(ser, 1000, SER_EV_M1_TIMEOUT);
break;
case SER_EV_L1_RESET:
ser_state_goto(ser, SER_RESET_TRX_ST);
break;
case SER_EV_M1_TIMEOUT:
ser_state_goto(ser, SER_L2_RESET_ST);
break;
case SER_EV_STATE_OUT:
ser_del_alarm(ser);
break;
default:
break;
}
}
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:
wiphy_lock(wiphy);
ser->sw_cnt.l1++;
wiphy_delayed_work_cancel(wiphy, &rtwdev->track_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->track_ps_work);
wiphy_unlock(wiphy);
drv_stop_tx(ser);
if (hal_stop_dma(ser)) {
ser_state_goto(ser, SER_L2_RESET_ST);
break;
}
drv_stop_rx(ser);
wiphy_lock(wiphy);
drv_trx_reset(ser);
wiphy_unlock(wiphy);
/* wait m3 */
hal_send_m2_event(ser);
/* set alarm to prevent FW response timeout */
ser_set_alarm(ser, 1000, SER_EV_M3_TIMEOUT);
break;
case SER_EV_DO_RECOVERY:
ser_state_goto(ser, SER_DO_HCI_ST);
break;
case SER_EV_M3_TIMEOUT:
ser_state_goto(ser, SER_L2_RESET_ST);
break;
case SER_EV_STATE_OUT:
ser_del_alarm(ser);
hal_enable_dma(ser);
drv_resume_rx(ser);
drv_resume_tx(ser);
wiphy_delayed_work_queue(wiphy, &rtwdev->track_work,
RTW89_TRACK_WORK_PERIOD);
wiphy_delayed_work_queue(wiphy, &rtwdev->track_ps_work,
RTW89_TRACK_PS_WORK_PERIOD);
break;
default:
break;
}
}
static void ser_do_hci_st_hdl(struct rtw89_ser *ser, u8 evt)
{
switch (evt) {
case SER_EV_STATE_IN:
/* wait m5 */
hal_send_m4_event(ser);
/* prevent FW response timeout */
ser_set_alarm(ser, 1000, SER_EV_FW_M5_TIMEOUT);
break;
case SER_EV_FW_M5_TIMEOUT:
ser_state_goto(ser, SER_L2_RESET_ST);
break;
case SER_EV_MAC_RESET_DONE:
hal_enable_err_imr(ser);
ser_state_goto(ser, SER_IDLE_ST);
break;
case SER_EV_STATE_OUT:
ser_del_alarm(ser);
break;
default:
break;
}
}
static void ser_mac_mem_dump(struct rtw89_dev *rtwdev, u8 *buf,
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 mem_page_size = mac->mem_page_size;
u32 *ptr = (u32 *)buf;
u32 base_addr, start_page, residue;
u32 cnt = 0;
u32 i;
start_page = start_addr / mem_page_size;
residue = start_addr % mem_page_size;
base_addr = rtw89_mac_mem_base_addrs(rtwdev, sel);
base_addr += start_page * mem_page_size;
while (cnt < len) {
rtw89_write32(rtwdev, filter_model_addr, base_addr);
for (i = indir_access_addr + residue;
i < indir_access_addr + mem_page_size;
i += 4, ptr++) {
*ptr = rtw89_read32(rtwdev, i);
cnt += 4;
if (cnt >= len)
break;
}
residue = 0;
base_addr += mem_page_size;
}
}
static void rtw89_ser_fw_rsvd_ple_dump(struct rtw89_dev *rtwdev, u8 *buf)
{
u32 start_addr = rtwdev->chip->rsvd_ple_ofst;
rtw89_debug(rtwdev, RTW89_DBG_SER,
"dump mem for fw rsvd payload engine (start addr: 0x%x)\n",
start_addr);
ser_mac_mem_dump(rtwdev, buf, RTW89_MAC_MEM_SHARED_BUF, start_addr,
RTW89_FW_RSVD_PLE_SIZE);
}
struct __fw_backtrace_entry {
u32 wcpu_addr;
u32 size;
u32 key;
} __packed;
struct __fw_backtrace_info {
u32 ra;
u32 sp;
} __packed;
static_assert(RTW89_FW_BACKTRACE_INFO_SIZE ==
sizeof(struct __fw_backtrace_info));
static u32 convert_addr_from_wcpu(u32 wcpu_addr)
{
if (wcpu_addr < 0x30000000)
return wcpu_addr;
return wcpu_addr & GENMASK(28, 0);
}
static int rtw89_ser_fw_backtrace_dump(struct rtw89_dev *rtwdev, u8 *buf,
const struct __fw_backtrace_entry *ent)
{
struct __fw_backtrace_info *ptr = (struct __fw_backtrace_info *)buf;
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 fwbt_addr = convert_addr_from_wcpu(ent->wcpu_addr);
u32 fwbt_size = ent->size;
u32 fwbt_key = ent->key;
u32 i;
if (fwbt_addr == 0) {
rtw89_warn(rtwdev, "FW backtrace invalid address: 0x%x\n",
fwbt_addr);
return -EINVAL;
}
if (fwbt_key != RTW89_FW_BACKTRACE_KEY) {
rtw89_warn(rtwdev, "FW backtrace invalid key: 0x%x\n",
fwbt_key);
return -EINVAL;
}
if (fwbt_size == 0 || !RTW89_VALID_FW_BACKTRACE_SIZE(fwbt_size) ||
fwbt_size > RTW89_FW_BACKTRACE_MAX_SIZE) {
rtw89_warn(rtwdev, "FW backtrace invalid size: 0x%x\n",
fwbt_size);
return -EINVAL;
}
rtw89_debug(rtwdev, RTW89_DBG_SER, "dump fw backtrace start\n");
rtw89_write32(rtwdev, filter_model_addr, fwbt_addr);
for (i = indir_access_addr;
i < indir_access_addr + fwbt_size;
i += RTW89_FW_BACKTRACE_INFO_SIZE, ptr++) {
*ptr = (struct __fw_backtrace_info){
.ra = rtw89_read32(rtwdev, i),
.sp = rtw89_read32(rtwdev, i + 4),
};
rtw89_debug(rtwdev, RTW89_DBG_SER,
"next sp: 0x%x, next ra: 0x%x\n",
ptr->sp, ptr->ra);
}
rtw89_debug(rtwdev, RTW89_DBG_SER, "dump fw backtrace end\n");
return 0;
}
static void ser_l2_reset_st_pre_hdl(struct rtw89_ser *ser)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
struct rtw89_ser_cd_buffer *buf;
struct __fw_backtrace_entry fwbt_ent;
int ret = 0;
buf = rtw89_ser_cd_prep(rtwdev);
if (!buf) {
ret = -ENOMEM;
goto bottom;
}
rtw89_ser_fw_rsvd_ple_dump(rtwdev, buf->fwple.data);
fwbt_ent = *(struct __fw_backtrace_entry *)buf->fwple.data;
ret = rtw89_ser_fw_backtrace_dump(rtwdev, buf->fwbt.data, &fwbt_ent);
if (ret)
goto bottom;
rtw89_ser_cd_send(rtwdev, buf);
bottom:
rtw89_ser_cd_free(rtwdev, buf, !!ret);
ser_reset_mac_binding(rtwdev);
rtw89_core_stop(rtwdev);
rtw89_entity_init(rtwdev);
rtw89_fw_release_general_pkt_list(rtwdev, false);
INIT_LIST_HEAD(&rtwdev->rtwvifs_list);
}
static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
switch (evt) {
case SER_EV_STATE_IN:
wiphy_lock(rtwdev->hw->wiphy);
ser->sw_cnt.l2++;
ser_l2_reset_st_pre_hdl(ser);
wiphy_unlock(rtwdev->hw->wiphy);
ieee80211_restart_hw(rtwdev->hw);
ser_set_alarm(ser, SER_RECFG_TIMEOUT, SER_EV_L2_RECFG_TIMEOUT);
break;
case SER_EV_L2_RECFG_TIMEOUT:
rtw89_info(rtwdev, "Err: ser L2 re-config timeout\n");
fallthrough;
case SER_EV_L2_RECFG_DONE:
ser_state_goto(ser, SER_IDLE_ST);
break;
case SER_EV_STATE_OUT:
ser_del_alarm(ser);
break;
default:
break;
}
}
static const struct event_ent ser_ev_tbl[] = {
{SER_EV_NONE, "SER_EV_NONE"},
{SER_EV_STATE_IN, "SER_EV_STATE_IN"},
{SER_EV_STATE_OUT, "SER_EV_STATE_OUT"},
{SER_EV_L1_RESET_PREPARE, "SER_EV_L1_RESET_PREPARE pre-m0"},
{SER_EV_L1_RESET, "SER_EV_L1_RESET m1"},
{SER_EV_DO_RECOVERY, "SER_EV_DO_RECOVERY m3"},
{SER_EV_MAC_RESET_DONE, "SER_EV_MAC_RESET_DONE m5"},
{SER_EV_L2_RESET, "SER_EV_L2_RESET"},
{SER_EV_L2_RECFG_DONE, "SER_EV_L2_RECFG_DONE"},
{SER_EV_L2_RECFG_TIMEOUT, "SER_EV_L2_RECFG_TIMEOUT"},
{SER_EV_M1_TIMEOUT, "SER_EV_M1_TIMEOUT"},
{SER_EV_M3_TIMEOUT, "SER_EV_M3_TIMEOUT"},
{SER_EV_FW_M5_TIMEOUT, "SER_EV_FW_M5_TIMEOUT"},
{SER_EV_L0_RESET, "SER_EV_L0_RESET"},
{SER_EV_MAXX, "SER_EV_MAX"}
};
static const struct state_ent ser_st_tbl[] = {
{SER_IDLE_ST, "SER_IDLE_ST", ser_idle_st_hdl},
{SER_L1_RESET_PRE_ST, "SER_L1_RESET_PRE_ST", ser_l1_reset_pre_st_hdl},
{SER_RESET_TRX_ST, "SER_RESET_TRX_ST", ser_reset_trx_st_hdl},
{SER_DO_HCI_ST, "SER_DO_HCI_ST", ser_do_hci_st_hdl},
{SER_L2_RESET_ST, "SER_L2_RESET_ST", ser_l2_reset_st_hdl}
};
int rtw89_ser_init(struct rtw89_dev *rtwdev)
{
struct rtw89_ser *ser = &rtwdev->ser;
memset(ser, 0, sizeof(*ser));
INIT_LIST_HEAD(&ser->msg_q);
ser->state = SER_IDLE_ST;
ser->st_tbl = ser_st_tbl;
ser->ev_tbl = ser_ev_tbl;
bitmap_zero(ser->flags, RTW89_NUM_OF_SER_FLAGS);
spin_lock_init(&ser->msg_q_lock);
INIT_WORK(&ser->ser_hdl_work, rtw89_ser_hdl_work);
INIT_DELAYED_WORK(&ser->ser_alarm_work, rtw89_ser_alarm_work);
return 0;
}
int rtw89_ser_deinit(struct rtw89_dev *rtwdev)
{
struct rtw89_ser *ser = (struct rtw89_ser *)&rtwdev->ser;
set_bit(RTW89_SER_DRV_STOP_RUN, ser->flags);
cancel_delayed_work_sync(&ser->ser_alarm_work);
cancel_work_sync(&ser->ser_hdl_work);
clear_bit(RTW89_SER_DRV_STOP_RUN, ser->flags);
return 0;
}
void rtw89_ser_recfg_done(struct rtw89_dev *rtwdev)
{
ser_send_msg(&rtwdev->ser, SER_EV_L2_RECFG_DONE);
}
int rtw89_ser_notify(struct rtw89_dev *rtwdev, u32 err)
{
u8 event = SER_EV_NONE;
rtw89_info(rtwdev, "SER catches error: 0x%x\n", err);
switch (err) {
case MAC_AX_ERR_L1_PREERR_DMAC: /* pre-M0 */
event = SER_EV_L1_RESET_PREPARE;
break;
case MAC_AX_ERR_L1_ERR_DMAC:
case MAC_AX_ERR_L0_PROMOTE_TO_L1:
event = SER_EV_L1_RESET; /* M1 */
break;
case MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE:
event = SER_EV_DO_RECOVERY; /* M3 */
break;
case MAC_AX_ERR_L1_RESET_RECOVERY_DONE:
event = SER_EV_MAC_RESET_DONE; /* M5 */
break;
case MAC_AX_ERR_L0_ERR_CMAC0:
case MAC_AX_ERR_L0_ERR_CMAC1:
case MAC_AX_ERR_L0_RESET_DONE:
event = SER_EV_L0_RESET;
break;
default:
if (err == MAC_AX_ERR_L1_PROMOTE_TO_L2 ||
(err >= MAC_AX_ERR_L2_ERR_AH_DMA &&
err <= MAC_AX_GET_ERR_MAX))
event = SER_EV_L2_RESET;
break;
}
if (event == SER_EV_NONE) {
rtw89_warn(rtwdev, "SER cannot recognize error: 0x%x\n", err);
return -EINVAL;
}
ser_send_msg(&rtwdev->ser, event);
return 0;
}
EXPORT_SYMBOL(rtw89_ser_notify);
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
* Copyright(c) 2019-2020 Realtek Corporation
*/
#ifndef __SER_H__
#define __SER_H__
#include "core.h"
int rtw89_ser_init(struct rtw89_dev *rtwdev);
int rtw89_ser_deinit(struct rtw89_dev *rtwdev);
int rtw89_ser_notify(struct rtw89_dev *rtwdev, u32 err);
void rtw89_ser_recfg_done(struct rtw89_dev *rtwdev);
#endif /* __SER_H__*/
@@ -0,0 +1,892 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2020 Realtek Corporation
*/
#ifndef __RTW89_TXRX_H__
#define __RTW89_TXRX_H__
#include "debug.h"
#define DATA_RATE_MODE_CTRL_MASK GENMASK(8, 7)
#define DATA_RATE_MODE_CTRL_MASK_V1 GENMASK(10, 8)
#define DATA_RATE_NOT_HT_IDX_MASK GENMASK(3, 0)
#define DATA_RATE_MODE_NON_HT 0x0
#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)
#define DATA_RATE_MCS_MASK_V1 GENMASK(4, 0)
#define DATA_RATE_MODE_VHT 0x2
#define DATA_RATE_MODE_HE 0x3
#define DATA_RATE_MODE_EHT 0x4
static inline u8 rtw89_get_data_rate_mode(struct rtw89_dev *rtwdev, u16 hw_rate)
{
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
return u16_get_bits(hw_rate, DATA_RATE_MODE_CTRL_MASK_V1);
return u16_get_bits(hw_rate, DATA_RATE_MODE_CTRL_MASK);
}
static inline u8 rtw89_get_data_not_ht_idx(struct rtw89_dev *rtwdev, u16 hw_rate)
{
return u16_get_bits(hw_rate, DATA_RATE_NOT_HT_IDX_MASK);
}
static inline u8 rtw89_get_data_ht_mcs(struct rtw89_dev *rtwdev, u16 hw_rate)
{
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
return u16_get_bits(hw_rate, DATA_RATE_HT_IDX_MASK_V1);
return u16_get_bits(hw_rate, DATA_RATE_HT_IDX_MASK);
}
static inline u8 rtw89_get_data_mcs(struct rtw89_dev *rtwdev, u16 hw_rate)
{
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
return u16_get_bits(hw_rate, DATA_RATE_MCS_MASK_V1);
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)
return u16_get_bits(hw_rate, DATA_RATE_NSS_MASK_V1);
return u16_get_bits(hw_rate, DATA_RATE_VHT_HE_NSS_MASK);
}
/* TX WD BODY DWORD 0 */
#define RTW89_TXWD_BODY0_WP_OFFSET GENMASK(31, 24)
#define RTW89_TXWD_BODY0_WP_OFFSET_V1 GENMASK(28, 24)
#define RTW89_TXWD_BODY0_MORE_DATA BIT(23)
#define RTW89_TXWD_BODY0_WD_INFO_EN BIT(22)
#define RTW89_TXWD_BODY0_FW_DL BIT(20)
#define RTW89_TXWD_BODY0_CHANNEL_DMA GENMASK(19, 16)
#define RTW89_TXWD_BODY0_HDR_LLC_LEN GENMASK(15, 11)
#define RTW89_TXWD_BODY0_STF_MODE BIT(10)
#define RTW89_TXWD_BODY0_WD_PAGE BIT(7)
#define RTW89_TXWD_BODY0_HW_AMSDU BIT(5)
#define RTW89_TXWD_BODY0_HW_SSN_SEL GENMASK(3, 2)
#define RTW89_TXWD_BODY0_HW_SSN_MODE GENMASK(1, 0)
/* TX WD BODY DWORD 1 */
#define RTW89_TXWD_BODY1_ADDR_INFO_NUM GENMASK(31, 26)
#define RTW89_TXWD_BODY1_PAYLOAD_ID GENMASK(31, 16)
#define RTW89_TXWD_BODY1_SEC_KEYID GENMASK(5, 4)
#define RTW89_TXWD_BODY1_SEC_TYPE GENMASK(3, 0)
/* TX WD BODY DWORD 2 */
#define RTW89_TXWD_BODY2_MACID GENMASK(30, 24)
#define RTW89_TXWD_BODY2_TID_INDICATE BIT(23)
#define RTW89_TXWD_BODY2_QSEL GENMASK(22, 17)
#define RTW89_TXWD_BODY2_TXPKT_SIZE GENMASK(13, 0)
/* TX WD BODY DWORD 3 */
#define RTW89_TXWD_BODY3_BK BIT(13)
#define RTW89_TXWD_BODY3_AGG_EN BIT(12)
#define RTW89_TXWD_BODY3_SW_SEQ GENMASK(11, 0)
/* TX WD BODY DWORD 4 */
#define RTW89_TXWD_BODY4_SEC_IV_L1 GENMASK(31, 24)
#define RTW89_TXWD_BODY4_SEC_IV_L0 GENMASK(23, 16)
/* TX WD BODY DWORD 5 */
#define RTW89_TXWD_BODY5_SEC_IV_H5 GENMASK(31, 24)
#define RTW89_TXWD_BODY5_SEC_IV_H4 GENMASK(23, 16)
#define RTW89_TXWD_BODY5_SEC_IV_H3 GENMASK(15, 8)
#define RTW89_TXWD_BODY5_SEC_IV_H2 GENMASK(7, 0)
/* TX WD BODY DWORD 6 (V1) */
/* TX WD BODY DWORD 7 (V1) */
#define RTW89_TXWD_BODY7_USE_RATE_V1 BIT(31)
#define RTW89_TXWD_BODY7_DATA_BW GENMASK(29, 28)
#define RTW89_TXWD_BODY7_GI_LTF GENMASK(27, 25)
#define RTW89_TXWD_BODY7_DATA_RATE GENMASK(24, 16)
/* TX WD INFO DWORD 0 */
#define RTW89_TXWD_INFO0_USE_RATE BIT(30)
#define RTW89_TXWD_INFO0_DATA_BW GENMASK(29, 28)
#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)
/* TX WD INFO DWORD 1 */
#define RTW89_TXWD_INFO1_DATA_TXCNT_LMT_SEL BIT(31)
#define RTW89_TXWD_INFO1_DATA_TXCNT_LMT GENMASK(30, 25)
#define RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE GENMASK(24, 16)
#define RTW89_TXWD_INFO1_A_CTRL_BSR BIT(14)
#define RTW89_TXWD_INFO1_MAX_AGGNUM GENMASK(7, 0)
/* TX WD INFO DWORD 2 */
#define RTW89_TXWD_INFO2_AMPDU_DENSITY GENMASK(20, 18)
#define RTW89_TXWD_INFO2_SEC_TYPE GENMASK(12, 9)
#define RTW89_TXWD_INFO2_SEC_HW_ENC BIT(8)
#define RTW89_TXWD_INFO2_FORCE_KEY_EN BIT(8)
#define RTW89_TXWD_INFO2_SEC_CAM_IDX GENMASK(7, 0)
/* TX WD INFO DWORD 3 */
#define RTW89_TXWD_INFO3_SPE_RPT BIT(10)
/* TX WD INFO DWORD 4 */
#define RTW89_TXWD_INFO4_HW_RTS_EN BIT(31)
#define RTW89_TXWD_INFO4_RTS_EN BIT(27)
#define RTW89_TXWD_INFO4_SW_DEFINE GENMASK(3, 0)
/* TX WD INFO DWORD 5 */
/* TX WD BODY DWORD 0 */
#define BE_TXD_BODY0_EN_HWSEQ_MODE GENMASK(1, 0)
#define BE_TXD_BODY0_HW_SSN_SEL GENMASK(4, 2)
#define BE_TXD_BODY0_HWAMSDU BIT(5)
#define BE_TXD_BODY0_HW_SEC_IV BIT(6)
#define BE_TXD_BODY0_WD_PAGE BIT(7)
#define BE_TXD_BODY0_CHK_EN BIT(8)
#define BE_TXD_BODY0_WP_INT BIT(9)
#define BE_TXD_BODY0_STF_MODE BIT(10)
#define BE_TXD_BODY0_HDR_LLC_LEN GENMASK(15, 11)
#define BE_TXD_BODY0_CH_DMA GENMASK(19, 16)
#define BE_TXD_BODY0_SMH_EN BIT(20)
#define BE_TXD_BODY0_PKT_OFFSET BIT(21)
#define BE_TXD_BODY0_WDINFO_EN BIT(22)
#define BE_TXD_BODY0_MOREDATA BIT(23)
#define BE_TXD_BODY0_WP_OFFSET_V1 GENMASK(27, 24)
#define BE_TXD_BODY0_AZ_FTM_SEC_V1 BIT(28)
#define BE_TXD_BODY0_WD_SOURCE GENMASK(30, 29)
#define BE_TXD_BODY0_HCI_SEQNUM_MODE BIT(31)
/* TX WD BODY DWORD 1 */
#define BE_TXD_BODY1_DMA_TXAGG_NUM GENMASK(6, 0)
#define BE_TXD_BODY1_REUSE_NUM GENMASK(11, 7)
#define BE_TXD_BODY1_SEC_TYPE GENMASK(15, 12)
#define BE_TXD_BODY1_SEC_KEYID GENMASK(17, 16)
#define BE_TXD_BODY1_SW_SEC_IV BIT(18)
#define BE_TXD_BODY1_REUSE_SIZE GENMASK(23, 20)
#define BE_TXD_BODY1_REUSE_START_OFFSET GENMASK(25, 24)
#define BE_TXD_BODY1_ADDR_INFO_NUM GENMASK(31, 26)
/* TX WD BODY DWORD 2 */
#define BE_TXD_BODY2_TXPKTSIZE GENMASK(13, 0)
#define BE_TXD_BODY2_AGG_EN BIT(14)
#define BE_TXD_BODY2_BK BIT(15)
#define BE_TXD_BODY2_MACID_EXTEND BIT(16)
#define BE_TXD_BODY2_QSEL GENMASK(22, 17)
#define BE_TXD_BODY2_TID_IND BIT(23)
#define BE_TXD_BODY2_MACID GENMASK(31, 24)
#define BE_TXD_BODY2_QSEL_V1 GENMASK(20, 15)
#define BE_TXD_BODY2_TID_IND_V1 BIT(21)
#define BE_TXD_BODY2_MACID_V1 GENMASK(31, 22)
/* TX WD BODY DWORD 3 */
#define BE_TXD_BODY3_WIFI_SEQ GENMASK(11, 0)
#define BE_TXD_BODY3_MLO_FLAG BIT(12)
#define BE_TXD_BODY3_IS_MLD_SW_EN BIT(13)
#define BE_TXD_BODY3_TRY_RATE BIT(14)
#define BE_TXD_BODY3_BK_V1 BIT(14)
#define BE_TXD_BODY3_RELINK_FLAG_V1 BIT(15)
#define BE_TXD_BODY3_BAND0_SU_TC_V1 GENMASK(21, 16)
#define BE_TXD_BODY3_TOTAL_TC GENMASK(27, 22)
#define BE_TXD_BODY3_RU_RTY BIT(28)
#define BE_TXD_BODY3_MU_PRI_RTY BIT(29)
#define BE_TXD_BODY3_MU_2ND_RTY BIT(30)
#define BE_TXD_BODY3_BAND1_SU_RTY_V1 BIT(31)
#define BE_TXD_BODY3_DRIVER_QUEUE_TIME GENMASK(31, 16)
/* TX WD BODY DWORD 4 */
#define BE_TXD_BODY4_TXDESC_CHECKSUM GENMASK(15, 0)
#define BE_TXD_BODY4_SEC_IV_L0 GENMASK(23, 16)
#define BE_TXD_BODY4_SEC_IV_L1 GENMASK(31, 24)
/* TX WD BODY DWORD 5 */
#define BE_TXD_BODY5_SEC_IV_H2 GENMASK(7, 0)
#define BE_TXD_BODY5_SEC_IV_H3 GENMASK(15, 8)
#define BE_TXD_BODY5_SEC_IV_H4 GENMASK(23, 16)
#define BE_TXD_BODY5_SEC_IV_H5 GENMASK(31, 24)
/* TX WD BODY DWORD 6 */
#define BE_TXD_BODY6_MU_TC GENMASK(4, 0)
#define BE_TXD_BODY6_RU_TC GENMASK(9, 5)
#define BE_TXD_BODY6_PS160 BIT(10)
#define BE_TXD_BODY6_BMC BIT(11)
#define BE_TXD_BODY6_NO_ACK BIT(12)
#define BE_TXD_BODY6_UPD_WLAN_HDR BIT(13)
#define BE_TXD_BODY6_A4_HDR BIT(14)
#define BE_TXD_BODY6_EOSP_BIT BIT(15)
#define BE_TXD_BODY6_S_IDX GENMASK(23, 16)
#define BE_TXD_BODY6_RU_POS GENMASK(31, 24)
#define BE_TXD_BODY6_MU_TC_V1 GENMASK(3, 0)
#define BE_TXD_BODY6_RU_TC_V1 GENMASK(8, 5)
#define BE_TXD_BODY6_RELINK_EN BIT(9)
#define BE_TXD_BODY6_RELINK_LAST BIT(10)
/* TX WD BODY DWORD 7 */
#define BE_TXD_BODY7_RTS_TC GENMASK(5, 0)
#define BE_TXD_BODY7_MSDU_NUM GENMASK(9, 6)
#define BE_TXD_BODY7_DATA_ER BIT(10)
#define BE_TXD_BODY7_DATA_BW_ER BIT(11)
#define BE_TXD_BODY7_DATA_DCM BIT(12)
#define BE_TXD_BODY7_GI_LTF GENMASK(15, 13)
#define BE_TXD_BODY7_DATARATE GENMASK(27, 16)
#define BE_TXD_BODY7_DATA_BW GENMASK(30, 28)
#define BE_TXD_BODY7_USERATE_SEL BIT(31)
/* TX WD INFO DWORD 0 */
#define BE_TXD_INFO0_MBSSID GENMASK(3, 0)
#define BE_TXD_INFO0_MULTIPORT_ID GENMASK(6, 4)
#define BE_TXD_INFO0_DISRTSFB BIT(9)
#define BE_TXD_INFO0_DISDATAFB BIT(10)
#define BE_TXD_INFO0_DATA_LDPC BIT(11)
#define BE_TXD_INFO0_DATA_STBC BIT(12)
#define BE_TXD_INFO0_DATA_TXCNT_LMT GENMASK(21, 16)
#define BE_TXD_INFO0_DATA_TXCNT_LMT_SEL BIT(22)
#define BE_TXD_INFO0_RESP_PHYSTS_CSI_EN_V1 BIT(23)
#define BE_TXD_INFO0_RLS_TO_CPUIO BIT(30)
#define BE_TXD_INFO0_ACK_CH_INFO BIT(31)
/* TX WD INFO DWORD 1 */
#define BE_TXD_INFO1_MAX_AGG_NUM GENMASK(7, 0)
#define BE_TXD_INFO1_BCN_SRCH_SEQ GENMASK(9, 8)
#define BE_TXD_INFO1_NAVUSEHDR BIT(10)
#define BE_TXD_INFO1_A_CTRL_BQR BIT(12)
#define BE_TXD_INFO1_A_CTRL_BSR BIT(14)
#define BE_TXD_INFO1_A_CTRL_CAS BIT(15)
#define BE_TXD_INFO1_DATA_RTY_LOWEST_RATE GENMASK(27, 16)
#define BE_TXD_INFO1_SW_DEFINE GENMASK(31, 28)
/* TX WD INFO DWORD 2 */
#define BE_TXD_INFO2_SEC_CAM_IDX GENMASK(7, 0)
#define BE_TXD_INFO2_FORCE_KEY_EN BIT(8)
#define BE_TXD_INFO2_SEC_CAM_IDX_V1 GENMASK(9, 0)
#define BE_TXD_INFO2_FORCE_KEY_EN_V1 BIT(10)
#define BE_TXD_INFO2_LIFETIME_SEL GENMASK(15, 13)
#define BE_TXD_INFO2_FORCE_TXOP BIT(17)
#define BE_TXD_INFO2_AMPDU_DENSITY GENMASK(20, 18)
#define BE_TXD_INFO2_LSIG_TXOP_EN BIT(21)
#define BE_TXD_INFO2_OBW_CTS2SELF_DUP_TYPE GENMASK(29, 26)
#define BE_TXD_INFO2_SPE_RPT_V1 BIT(30)
#define BE_TXD_INFO2_SIFS_TX_V1 BIT(31)
/* TX WD INFO DWORD 3 */
#define BE_TXD_INFO3_SPE_PKT GENMASK(3, 0)
#define BE_TXD_INFO3_SPE_PKT_TYPE GENMASK(7, 4)
#define BE_TXD_INFO3_CQI_SND BIT(8)
#define BE_TXD_INFO3_RTT_EN BIT(9)
#define BE_TXD_INFO3_HT_DATA_SND_V1 BIT(10)
#define BE_TXD_INFO3_BT_NULL BIT(11)
#define BE_TXD_INFO3_DISABLE_TXBF BIT(11)
#define BE_TXD_INFO3_TRI_FRAME BIT(12)
#define BE_TXD_INFO3_NULL_0 BIT(13)
#define BE_TXD_INFO3_NULL_1 BIT(14)
#define BE_TXD_INFO3_RAW BIT(15)
#define BE_TXD_INFO3_GROUP_BIT_IE_OFFSET GENMASK(23, 16)
#define BE_TXD_INFO3_SIGNALING_TA_PKT_EN BIT(25)
#define BE_TXD_INFO3_BCNPKT_TSF_CTRL BIT(26)
#define BE_TXD_INFO3_SIGNALING_TA_PKT_SC GENMASK(30, 27)
#define BE_TXD_INFO3_FORCE_BSS_CLR BIT(31)
/* TX WD INFO DWORD 4 */
#define BE_TXD_INFO4_PUNCTURE_PATTERN GENMASK(15, 0)
#define BE_TXD_INFO4_PUNC_MODE GENMASK(17, 16)
#define BE_TXD_INFO4_SW_TX_OK_0 BIT(18)
#define BE_TXD_INFO4_SW_TX_OK_1 BIT(19)
#define BE_TXD_INFO4_SW_EHT_NLTF_SWITCH BIT(20)
#define BE_TXD_INFO4_SW_EHT_NLTF GENMASK(22, 21)
#define BE_TXD_INFO4_SW_TX_PWR_DBM GENMASK(26, 23)
#define BE_TXD_INFO4_RTS_EN BIT(27)
#define BE_TXD_INFO4_CTS2SELF BIT(28)
#define BE_TXD_INFO4_CCA_RTS GENMASK(30, 29)
#define BE_TXD_INFO4_HW_RTS_EN BIT(31)
/* TX WD INFO DWORD 5 */
#define BE_TXD_INFO5_SR_RATE_V1 GENMASK(4, 0)
#define BE_TXD_INFO5_SR_EN_V1 BIT(5)
#define BE_TXD_INFO5_NDPA_DURATION GENMASK(31, 16)
/* TX WD INFO DWORD 6 */
#define BE_TXD_INFO6_UL_APEP_LEN GENMASK(11, 0)
#define BE_TXD_INFO6_UL_GI_LTF GENMASK(14, 12)
#define BE_TXD_INFO6_UL_DOPPLER BIT(15)
#define BE_TXD_INFO6_UL_STBC BIT(16)
#define BE_TXD_INFO6_UL_MU_MIMO_EN BIT(17)
#define BE_TXD_INFO6_UL_LENGTH_REF GENMASK(21, 18)
#define BE_TXD_INFO6_UL_RF_GAIN_IDX GENMASK(31, 22)
/* TX WD INFO DWORD 7 */
#define BE_TXD_INFO7_UL_FIXED_GAIN_EN BIT(0)
#define BE_TXD_INFO7_UL_PRI_EXP_RSSI_DBM GENMASK(7, 1)
#define BE_TXD_INFO7_ELNA_IDX BIT(8)
#define BE_TXD_INFO7_UL_APEP_UNIT GENMASK(10, 9)
#define BE_TXD_INFO7_UL_TRI_PAD GENMASK(13, 11)
#define BE_TXD_INFO7_UL_T_PE GENMASK(15, 14)
#define BE_TXD_INFO7_UL_EHT_USR_PRES BIT(16)
#define BE_TXD_INFO7_UL_HELTF_SYMBOL_NUM GENMASK(19, 17)
#define BE_TXD_INFO7_ULBW GENMASK(21, 20)
#define BE_TXD_INFO7_ULBW_EXT GENMASK(23, 22)
#define BE_TXD_INFO7_UL_TRI_PAD_TSF BIT(24)
#define BE_TXD_INFO7_USE_WD_UL GENMASK(25, 24)
#define BE_TXD_INFO7_EXTEND_MODE_SEL GENMASK(31, 28)
/* RX WD dword0 */
#define AX_RXD_RPKT_LEN_MASK GENMASK(13, 0)
#define AX_RXD_SHIFT_MASK GENMASK(15, 14)
#define AX_RXD_WL_HD_IV_LEN_MASK GENMASK(21, 16)
#define AX_RXD_BB_SEL BIT(22)
#define AX_RXD_MAC_INFO_VLD BIT(23)
#define AX_RXD_RPKT_TYPE_MASK GENMASK(27, 24)
#define AX_RXD_DRV_INFO_SIZE_MASK GENMASK(30, 28)
#define AX_RXD_LONG_RXD BIT(31)
/* RX WD dword1 */
#define AX_RXD_PPDU_TYPE_MASK GENMASK(3, 0)
#define AX_RXD_PPDU_CNT_MASK GENMASK(6, 4)
#define AX_RXD_SR_EN BIT(7)
#define AX_RXD_USER_ID_MASK GENMASK(15, 8)
#define AX_RXD_USER_ID_v1_MASK GENMASK(13, 8)
#define AX_RXD_RX_DATARATE_MASK GENMASK(24, 16)
#define AX_RXD_RX_GI_LTF_MASK GENMASK(27, 25)
#define AX_RXD_NON_SRG_PPDU BIT(28)
#define AX_RXD_INTER_PPDU BIT(29)
#define AX_RXD_NON_SRG_PPDU_v1 BIT(14)
#define AX_RXD_INTER_PPDU_v1 BIT(15)
#define AX_RXD_BW_MASK GENMASK(31, 30)
#define AX_RXD_BW_v1_MASK GENMASK(31, 29)
/* RX WD dword2 */
#define AX_RXD_FREERUN_CNT_MASK GENMASK(31, 0)
/* RX WD dword3 */
#define AX_RXD_A1_MATCH BIT(0)
#define AX_RXD_SW_DEC BIT(1)
#define AX_RXD_HW_DEC BIT(2)
#define AX_RXD_AMPDU BIT(3)
#define AX_RXD_AMPDU_END_PKT BIT(4)
#define AX_RXD_AMSDU BIT(5)
#define AX_RXD_AMSDU_CUT BIT(6)
#define AX_RXD_LAST_MSDU BIT(7)
#define AX_RXD_BYPASS BIT(8)
#define AX_RXD_CRC32_ERR BIT(9)
#define AX_RXD_ICV_ERR BIT(10)
#define AX_RXD_MAGIC_WAKE BIT(11)
#define AX_RXD_UNICAST_WAKE BIT(12)
#define AX_RXD_PATTERN_WAKE BIT(13)
#define AX_RXD_GET_CH_INFO_MASK GENMASK(15, 14)
#define AX_RXD_PATTERN_IDX_MASK GENMASK(20, 16)
#define AX_RXD_TARGET_IDC_MASK GENMASK(23, 21)
#define AX_RXD_CHKSUM_OFFLOAD_EN BIT(24)
#define AX_RXD_WITH_LLC BIT(25)
#define AX_RXD_RX_STATISTICS BIT(26)
/* RX WD dword4 */
#define AX_RXD_TYPE_MASK GENMASK(1, 0)
#define AX_RXD_MC BIT(2)
#define AX_RXD_BC BIT(3)
#define AX_RXD_MD BIT(4)
#define AX_RXD_MF BIT(5)
#define AX_RXD_PWR BIT(6)
#define AX_RXD_QOS BIT(7)
#define AX_RXD_TID_MASK GENMASK(11, 8)
#define AX_RXD_EOSP BIT(12)
#define AX_RXD_HTC BIT(13)
#define AX_RXD_QNULL BIT(14)
#define AX_RXD_SEQ_MASK GENMASK(27, 16)
#define AX_RXD_FRAG_MASK GENMASK(31, 28)
/* RX WD dword5 */
#define AX_RXD_SEC_CAM_IDX_MASK GENMASK(7, 0)
#define AX_RXD_ADDR_CAM_MASK GENMASK(15, 8)
#define AX_RXD_MAC_ID_MASK GENMASK(23, 16)
#define AX_RXD_RX_PL_ID_MASK GENMASK(27, 24)
#define AX_RXD_ADDR_CAM_VLD BIT(28)
#define AX_RXD_ADDR_FWD_EN BIT(29)
#define AX_RXD_RX_PL_MATCH BIT(30)
/* RX WD dword6 */
#define AX_RXD_MAC_ADDR_MASK GENMASK(31, 0)
/* RX WD dword7 */
#define AX_RXD_MAC_ADDR_H_MASK GENMASK(15, 0)
#define AX_RXD_SMART_ANT BIT(16)
#define AX_RXD_SEC_TYPE_MASK GENMASK(20, 17)
#define AX_RXD_HDR_CNV BIT(21)
#define AX_RXD_HDR_OFFSET_MASK GENMASK(26, 22)
#define AX_RXD_BIP_KEYID BIT(27)
#define AX_RXD_BIP_ENC BIT(28)
struct rtw89_rxinfo_user {
__le32 w0;
};
#define RTW89_RXINFO_USER_MAC_ID_VALID BIT(0)
#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_BCN BIT(4)
#define RTW89_RXINFO_USER_MACID GENMASK(15, 8)
#define RTW89_RXINFO_USER_MACID_V1 GENMASK(31, 20)
struct rtw89_rxinfo {
__le32 w0;
__le32 w1;
struct rtw89_rxinfo_user user[];
} __packed;
#define RTW89_RXINFO_W0_USR_NUM GENMASK(3, 0)
#define RTW89_RXINFO_W0_USR_NUM_V1 GENMASK(4, 0)
#define RTW89_RXINFO_W0_FW_DEFINE GENMASK(15, 8)
#define RTW89_RXINFO_W0_PLCP_LEN_V1 GENMASK(23, 16)
#define RTW89_RXINFO_W0_LSIG_LEN GENMASK(27, 16)
#define RTW89_RXINFO_W0_INVALID_V1 BIT(27)
#define RTW89_RXINFO_W0_IS_TO_SELF BIT(28)
#define RTW89_RXINFO_W0_RX_CNT_VLD BIT(29)
#define RTW89_RXINFO_W0_LONG_RXD GENMASK(31, 30)
#define RTW89_RXINFO_W1_SERVICE GENMASK(15, 0)
#define RTW89_RXINFO_W1_PLCP_LEN GENMASK(23, 16)
struct rtw89_phy_sts_hdr {
__le32 w0;
__le32 w1;
} __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)
#define RTW89_PHY_STS_HDR_W1_RSSI_A GENMASK(7, 0)
#define RTW89_PHY_STS_HDR_W1_RSSI_B GENMASK(15, 8)
#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;
};
#define RTW89_PHY_STS_IEHDR_TYPE GENMASK(4, 0)
#define RTW89_PHY_STS_IEHDR_LEN GENMASK(11, 5)
/* BE RXD dword0 */
#define BE_RXD_RPKT_LEN_MASK GENMASK(13, 0)
#define BE_RXD_SHIFT_MASK GENMASK(15, 14)
#define BE_RXD_DRV_INFO_SZ_MASK GENMASK(19, 18)
#define BE_RXD_HDR_CNV_SZ_MASK GENMASK(21, 20)
#define BE_RXD_PHY_RPT_SZ_MASK GENMASK(23, 22)
#define BE_RXD_RPKT_TYPE_MASK GENMASK(29, 24)
#define BE_RXD_BB_SEL BIT(30)
#define BE_RXD_LONG_RXD BIT(31)
/* BE RXD dword1 */
#define BE_RXD_PKT_ID_MASK GENMASK(11, 0)
#define BE_RXD_FWD_TARGET_MASK GENMASK(23, 16)
#define BE_RXD_BCN_FW_INFO_MASK GENMASK(25, 24)
#define BE_RXD_FW_RLS BIT(26)
/* BE RXD dword2 */
#define BE_RXD_MAC_ID_MASK GENMASK(7, 0)
#define BE_RXD_MAC_ID_V1 GENMASK(9, 0)
#define BE_RXD_TYPE_MASK GENMASK(11, 10)
#define BE_RXD_LAST_MSDU BIT(12)
#define BE_RXD_AMSDU_CUT BIT(13)
#define BE_RXD_ADDR_CAM_VLD BIT(14)
#define BE_RXD_REORDER BIT(15)
#define BE_RXD_SEQ_MASK GENMASK(27, 16)
#define BE_RXD_TID_MASK GENMASK(31, 28)
/* BE RXD dword3 */
#define BE_RXD_SEC_TYPE_MASK GENMASK(3, 0)
#define BE_RXD_BIP_KEYID BIT(4)
#define BE_RXD_BIP_ENC BIT(5)
#define BE_RXD_CRC32_ERR BIT(6)
#define BE_RXD_ICV_ERR BIT(7)
#define BE_RXD_HW_DEC BIT(8)
#define BE_RXD_SW_DEC BIT(9)
#define BE_RXD_A1_MATCH BIT(10)
#define BE_RXD_AMPDU BIT(11)
#define BE_RXD_AMPDU_EOF BIT(12)
#define BE_RXD_AMSDU BIT(13)
#define BE_RXD_MC BIT(14)
#define BE_RXD_BC BIT(15)
#define BE_RXD_MD BIT(16)
#define BE_RXD_MF BIT(17)
#define BE_RXD_PWR BIT(18)
#define BE_RXD_QOS BIT(19)
#define BE_RXD_EOSP BIT(20)
#define BE_RXD_HTC BIT(21)
#define BE_RXD_QNULL BIT(22)
#define BE_RXD_A4_FRAME BIT(23)
#define BE_RXD_FRAG_MASK GENMASK(27, 24)
#define BE_RXD_GET_CH_INFO_V2 GENMASK(31, 29)
#define BE_RXD_GET_CH_INFO_V1_MASK GENMASK(31, 30)
/* BE RXD dword4 */
#define BE_RXD_PPDU_TYPE_MASK GENMASK(7, 0)
#define BE_RXD_PPDU_CNT_MASK GENMASK(10, 8)
#define BE_RXD_BW_MASK GENMASK(14, 12)
#define BE_RXD_RX_GI_LTF_MASK GENMASK(18, 16)
#define BE_RXD_RX_REORDER_FIELD_EN BIT(19)
#define BE_RXD_RX_DATARATE_MASK GENMASK(31, 20)
/* BE RXD dword5 */
#define BE_RXD_FREERUN_CNT_MASK GENMASK(31, 0)
/* BE RXD dword6 */
#define BE_RXD_ADDR_CAM_MASK GENMASK(7, 0)
#define BE_RXD_ADDR_CAM_V1 GENMASK(9, 0)
#define BE_RXD_RX_STATISTICS_V1 BIT(11)
#define BE_RXD_SMART_ANT_V1 BIT(12)
#define BE_RXD_SR_EN BIT(13)
#define BE_RXD_NON_SRG_PPDU BIT(14)
#define BE_RXD_INTER_PPDU BIT(15)
#define BE_RXD_USER_ID_MASK GENMASK(21, 16)
#define BE_RXD_SEC_CAM_IDX_V1 GENMASK(31, 22)
#define BE_RXD_RX_STATISTICS BIT(22)
#define BE_RXD_SMART_ANT BIT(23)
#define BE_RXD_SEC_CAM_IDX_MASK GENMASK(31, 24)
/* BE RXD dword7 */
#define BE_RXD_PATTERN_IDX_MASK GENMASK(4, 0)
#define BE_RXD_MAGIC_WAKE BIT(5)
#define BE_RXD_UNICAST_WAKE BIT(6)
#define BE_RXD_PATTERN_WAKE BIT(7)
#define BE_RXD_RX_PL_MATCH BIT(8)
#define BE_RXD_RX_PL_ID_MASK GENMASK(15, 12)
#define BE_RXD_HDR_CNV BIT(16)
#define BE_RXD_NAT25_HIT BIT(17)
#define BE_RXD_IS_DA BIT(18)
#define BE_RXD_CHKSUM_OFFLOAD_EN BIT(19)
#define BE_RXD_RXSC_ENTRY_MASK GENMASK(22, 20)
#define BE_RXD_RXSC_HIT BIT(23)
#define BE_RXD_WITH_LLC BIT(24)
#define BE_RXD_RX_AGG_FIELD_EN BIT(25)
/* BE RXD dword8 */
#define BE_RXD_MAC_ADDR_MASK GENMASK(31, 0)
/* BE RXD dword9 */
#define BE_RXD_MAC_ADDR_H_MASK GENMASK(15, 0)
#define BE_RXD_HDR_OFFSET_MASK GENMASK(20, 16)
#define BE_RXD_WL_HD_IV_LEN_MASK GENMASK(26, 21)
/* 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)
#define RTW89_PHY_STS_IE00_W3_RX_PATH_EN GENMASK(31, 28)
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_SU BIT(27)
#define RTW89_PHY_STS_IE01_W2_LDPC BIT(28)
#define RTW89_PHY_STS_IE01_W2_STBC BIT(30)
#define RTW89_PHY_STS_IE01_W3_BF BIT(8)
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)
union rtw89_phy_sts_ie09 {
struct {
__le64 qw0;
} gen0;
struct {
__le64 qw0;
__le64 qw1;
} gen2;
} __packed;
#define RTW89_PHY_STS_IE09_L_SIG_MASK GENMASK(21, 5) /* Legacy/VHT/HE L-SIG */
#define RTW89_PHY_STS_IE09_L_SIG_MASK_GEN2 GENMASK(31, 15) /* Legacy/VHT/HE L-SIG for GEN2 */
#define RTW89_PHY_STS_IE09_L_SIG_RATE GENMASK(3, 0)
#define RTW89_PHY_STS_IE09_L_SIG_RSVD BIT(4)
#define RTW89_PHY_STS_IE09_L_SIG_LENGTH GENMASK(16, 5)
#define RTW89_PHY_STS_IE09_VHT_SIG_A1_MASK GENMASK_ULL(45, 22) /* VHT SIG-A1 */
#define RTW89_PHY_STS_IE09_VHT_SIG_A1_MASK_GEN2 GENMASK_ULL(55, 32) /* VHT SIG-A1 for GEN2 */
#define RTW89_PHY_STS_IE09_VHT_SIG_A1_BW GENMASK(1, 0)
#define RTW89_PHY_STS_IE09_VHT_SIG_A1_RSVD1 BIT(2)
#define RTW89_PHY_STS_IE09_VHT_SIG_A1_STBC BIT(3)
#define RTW89_PHY_STS_IE09_VHT_SIG_A1_GRP_ID GENMASK(9, 4)
#define RTW89_PHY_STS_IE09_VHT_SIG_A1_SU_NSTS GENMASK(12, 10)
#define RTW89_PHY_STS_IE09_VHT_SIG_A1_SU_PAID GENMASK(21, 13)
#define RTW89_PHY_STS_IE09_VHT_SIG_A1_MU_NSTS0 GENMASK(12, 10)
#define RTW89_PHY_STS_IE09_VHT_SIG_A1_MU_NSTS1 GENMASK(15, 13)
#define RTW89_PHY_STS_IE09_VHT_SIG_A1_MU_NSTS2 GENMASK(18, 16)
#define RTW89_PHY_STS_IE09_VHT_SIG_A1_MU_NSTS3 GENMASK(21, 19)
#define RTW89_PHY_STS_IE09_VHT_SIG_A1_TXOP_NOPS BIT(22)
#define RTW89_PHY_STS_IE09_VHT_SIG_A1_RSVD2 BIT(23)
#define RTW89_PHY_STS_IE09_VHT_SIG_A2_MASK GENMASK_ULL(55, 46) /* VHT SIG-A2 */
#define RTW89_PHY_STS_IE09_VHT_SIG_A2_MASK_GEN2_L0 GENMASK_ULL(63, 56) /* VHT SIG-A2 for GEN2 */
#define RTW89_PHY_STS_IE09_VHT_SIG_A2_MASK_GEN2_H8 GENMASK_ULL(1, 0) /* VHT SIG-A2 for GEN2 */
#define RTW89_PHY_STS_IE09_VHT_SIG_A2_SGI BIT(0)
#define RTW89_PHY_STS_IE09_VHT_SIG_A2_SGI_DISA BIT(1)
#define RTW89_PHY_STS_IE09_VHT_SIG_A2_SUMU_CODE0 BIT(2)
#define RTW89_PHY_STS_IE09_VHT_SIG_A2_LDPC BIT(3)
#define RTW89_PHY_STS_IE09_VHT_SIG_A2_SUMU_CODE3 GENMASK(7, 4)
#define RTW89_PHY_STS_IE09_VHT_SIG_A2_BF BIT(8)
#define RTW89_PHY_STS_IE09_VHT_SIG_A2_RSVD3 BIT(9)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_MASK GENMASK_ULL(47, 22) /* HE SU SIG-A1 */
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_MASK_GEN2 GENMASK_ULL(57, 32) /* HE SU SIG-A1 for GEN2 */
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_FORMAT BIT(0)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_BEAM_CHANGE BIT(1)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_ULDL BIT(2)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_MCS GENMASK(6, 3)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_DCM BIT(7)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_BSS_COLOR GENMASK(13, 8)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_RSVD1 BIT(14)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_SR GENMASK(18, 15)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_BW GENMASK(20, 19)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_GILTF GENMASK(22, 21)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A1_NSTS GENMASK(25, 23)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_MASK GENMASK_ULL(63, 48) /* HE SU SIG-A2 */
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_MASK_GEN2_L0 GENMASK_ULL(63, 58) /* HE SU SIG-A2 for GEN2 */
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_MASK_GEN2_H6 GENMASK_ULL(9, 0) /* HE SU SIG-A2 for GEN2 */
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_TXOP GENMASK(6, 0)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_CODING BIT(7)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_LDPC_XSYMSEG BIT(8)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_STBC BIT(9)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_BEAMFORMED BIT(10)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_PREFEC GENMASK(12, 11)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_PE BIT(13)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_RSVD2 BIT(14)
#define RTW89_PHY_STS_IE09_HE_SU_SIG_A2_DOPPLER BIT(15)
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_MASK GENMASK_ULL(47, 22) /* HE TB SIG-A1 */
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_MASK_GEN2 GENMASK_ULL(57, 32) /* HE TB SIG-A1 for GEN2 */
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_FORMAT BIT(0)
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_BSS_COLOR GENMASK(6, 1)
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_SB1 GENMASK(10, 7)
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_SB2 GENMASK(14, 11)
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_SB3 GENMASK(18, 15)
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_SB4 GENMASK(22, 19)
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_RSVD1 BIT(23)
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A1_BW GENMASK(25, 24)
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A2_MASK GENMASK_ULL(63, 48) /* HE TB SIG-A2 */
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A2_MASK_GEN2_L0 GENMASK_ULL(63, 58) /* HE TB SIG-A2 for GEN2 */
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A2_MASK_GEN2_H6 GENMASK_ULL(9, 0) /* HE TB SIG-A2 for GEN2 */
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A2_TXOP GENMASK(6, 0)
#define RTW89_PHY_STS_IE09_HE_TB_SIG_A2_RSVD1 GENMASK(15, 7)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_MASK GENMASK_ULL(47, 22) /* HE MU SIG-A1 */
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_MASK_GEN2 GENMASK_ULL(57, 32) /* HE MU SIG-A1 for GEN2 */
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_ULDL BIT(0)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SIGB_MCS GENMASK(3, 1)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SIGB_DCM BIT(4)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_BSS_COLOR GENMASK(10, 5)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SR GENMASK(14, 11)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_BW GENMASK(17, 15)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SIGB_SYM_USR GENMASK(21, 18)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_SIGB_COM BIT(22)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_GI_LTF GENMASK(24, 23)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A1_DOPPLER BIT(25)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_MASK GENMASK_ULL(63, 48) /* HE MU SIG-A2 */
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_MASK_GEN2_L0 GENMASK_ULL(63, 58) /* HE MU SIG-A2 for GEN2 */
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_MASK_GEN2_H6 GENMASK_ULL(9, 0) /* HE MU SIG-A2 for GEN2 */
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_TXOP GENMASK(6, 0)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_RSVD BIT(7)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_LTF_MID GENMASK(10, 8)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_MID BIT(10)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_LPDC_XSYMSEG BIT(11)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_STBC BIT(12)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_FEC GENMASK(14, 13)
#define RTW89_PHY_STS_IE09_HE_MU_SIG_A2_PE BIT(15)
struct rtw89_phy_sts_ie10 {
__le64 qw0;
u8 sigb[];
} __packed;
enum rtw89_tx_channel {
RTW89_TXCH_ACH0 = 0,
RTW89_TXCH_ACH1 = 1,
RTW89_TXCH_ACH2 = 2,
RTW89_TXCH_ACH3 = 3,
RTW89_TXCH_ACH4 = 4,
RTW89_TXCH_ACH5 = 5,
RTW89_TXCH_ACH6 = 6,
RTW89_TXCH_ACH7 = 7,
RTW89_TXCH_CH8 = 8, /* MGMT Band 0 */
RTW89_TXCH_CH9 = 9, /* HI Band 0 */
RTW89_TXCH_CH10 = 10, /* MGMT Band 1 */
RTW89_TXCH_CH11 = 11, /* HI Band 1 */
RTW89_TXCH_CH12 = 12, /* FW CMD */
/* keep last */
RTW89_TXCH_NUM,
RTW89_TXCH_MAX = RTW89_TXCH_NUM - 1
};
enum rtw89_rx_channel {
RTW89_RXCH_RXQ = 0,
RTW89_RXCH_RPQ = 1,
/* keep last */
RTW89_RXCH_NUM,
RTW89_RXCH_MAX = RTW89_RXCH_NUM - 1
};
enum rtw89_tx_qsel {
RTW89_TX_QSEL_BE_0 = 0x00,
RTW89_TX_QSEL_BK_0 = 0x01,
RTW89_TX_QSEL_VI_0 = 0x02,
RTW89_TX_QSEL_VO_0 = 0x03,
RTW89_TX_QSEL_BE_1 = 0x04,
RTW89_TX_QSEL_BK_1 = 0x05,
RTW89_TX_QSEL_VI_1 = 0x06,
RTW89_TX_QSEL_VO_1 = 0x07,
RTW89_TX_QSEL_BE_2 = 0x08,
RTW89_TX_QSEL_BK_2 = 0x09,
RTW89_TX_QSEL_VI_2 = 0x0a,
RTW89_TX_QSEL_VO_2 = 0x0b,
RTW89_TX_QSEL_BE_3 = 0x0c,
RTW89_TX_QSEL_BK_3 = 0x0d,
RTW89_TX_QSEL_VI_3 = 0x0e,
RTW89_TX_QSEL_VO_3 = 0x0f,
RTW89_TX_QSEL_B0_BCN = 0x10,
RTW89_TX_QSEL_B0_HI = 0x11,
RTW89_TX_QSEL_B0_MGMT = 0x12,
RTW89_TX_QSEL_B0_NOPS = 0x13,
RTW89_TX_QSEL_B0_MGMT_FAST = 0x14,
/* reserved */
/* reserved */
/* reserved */
RTW89_TX_QSEL_B1_BCN = 0x18,
RTW89_TX_QSEL_B1_HI = 0x19,
RTW89_TX_QSEL_B1_MGMT = 0x1a,
RTW89_TX_QSEL_B1_NOPS = 0x1b,
RTW89_TX_QSEL_B1_MGMT_FAST = 0x1c,
/* reserved */
/* reserved */
/* reserved */
};
static inline u8 rtw89_core_get_qsel(struct rtw89_dev *rtwdev, u8 tid)
{
switch (tid) {
default:
rtw89_warn(rtwdev, "Should use tag 1d: %d\n", tid);
fallthrough;
case 0:
case 3:
return RTW89_TX_QSEL_BE_0;
case 1:
case 2:
return RTW89_TX_QSEL_BK_0;
case 4:
case 5:
return RTW89_TX_QSEL_VI_0;
case 6:
case 7:
return RTW89_TX_QSEL_VO_0;
}
}
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_tid_indicate(struct rtw89_dev *rtwdev, u8 tid)
{
switch (tid) {
case 3:
case 2:
case 5:
case 7:
return 1;
default:
rtw89_warn(rtwdev, "Should use tag 1d: %d\n", tid);
fallthrough;
case 0:
case 1:
case 4:
case 6:
return 0;
}
}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,101 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2025 Realtek Corporation
*/
#ifndef __RTW89_USB_H__
#define __RTW89_USB_H__
#include "txrx.h"
#define RTW89_USB_VENQT 0x05
#define RTW89_USB_VENQT_READ 0xc0
#define RTW89_USB_VENQT_WRITE 0x40
#define RTW89_USB_RECVBUF_SZ 20480
#define RTW89_USB_RXCB_NUM 8
#define RTW89_USB_RX_SKB_NUM 16
#define RTW89_USB_MAX_RXQ_LEN 512
#define RTW89_USB_MOD512_PADDING 4
#define RTW89_MAX_ENDPOINT_NUM 9
#define RTW89_MAX_BULKIN_NUM 2
#define RTW89_MAX_BULKOUT_NUM 7
#define R_AX_RXAGG_0_V1 0x6000
#define B_AX_RXAGG_0_EN BIT(31)
#define B_AX_RXAGG_0_NUM_TH GENMASK(23, 16)
#define B_AX_RXAGG_0_TIME_32US_TH GENMASK(15, 8)
#define B_AX_RXAGG_0_BUF_SZ_1K GENMASK(7, 0)
#define R_AX_RXAGG_1_V1 0x6004
#define R_BE_RXAGG_0_V1 0x6000
#define B_BE_RXAGG_0_EN BIT(31)
#define B_BE_RXAGG_0_NUM_TH GENMASK(23, 16)
#define B_BE_RXAGG_0_TIME_32US_TH GENMASK(15, 8)
#define B_BE_RXAGG_0_BUF_SZ_1K GENMASK(7, 0)
#define R_BE_RXAGG_1_V1 0x6004
#define R_AX_RXAGG_0 0x8900
#define B_AX_RXAGG_0_BUF_SZ_4K GENMASK(7, 0)
#define RTW89_USB_MAX_TX_URBS_PER_CH 128
struct rtw89_usb_info {
u32 usb_host_request_2;
u32 usb_wlan0_1;
u32 hci_func_en;
u32 usb3_mac_npi_config_intf_0;
u32 usb_endpoint_0;
u32 usb_endpoint_2;
u8 rx_agg_alignment;
u8 bulkout_id[RTW89_DMA_CH_NUM];
};
struct rtw89_usb_rx_ctrl_block {
struct rtw89_dev *rtwdev;
struct urb *rx_urb;
struct sk_buff *rx_skb;
};
struct rtw89_usb_tx_ctrl_block {
struct rtw89_dev *rtwdev;
u8 txch;
struct sk_buff_head tx_ack_queue;
};
struct rtw89_usb {
struct rtw89_dev *rtwdev;
struct usb_device *udev;
const struct rtw89_usb_info *info;
__le32 *vendor_req_buf;
atomic_t continual_io_error;
u8 in_pipe[RTW89_MAX_BULKIN_NUM];
u8 out_pipe[RTW89_MAX_BULKOUT_NUM];
struct workqueue_struct *rxwq;
struct rtw89_usb_rx_ctrl_block rx_cb[RTW89_USB_RXCB_NUM];
struct sk_buff_head rx_queue;
struct sk_buff_head rx_free_queue;
struct work_struct rx_work;
struct work_struct rx_urb_work;
struct usb_anchor tx_submitted;
struct sk_buff_head tx_queue[RTW89_TXCH_NUM];
atomic_t tx_inflight[RTW89_TXCH_NUM];
};
static inline struct rtw89_usb *rtw89_usb_priv(struct rtw89_dev *rtwdev)
{
return (struct rtw89_usb *)rtwdev->priv;
}
int rtw89_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id);
void rtw89_usb_disconnect(struct usb_interface *intf);
#endif

Some files were not shown because too many files have changed in this diff Show More