Merge tag 'rtw-next-2025-07-18' of https://github.com/pkshih/rtw

Ping-Ke Shih says:
==================
rtw-next patches for v6.17

Some minor fixes and refinements. Major changes are listed:

rtw89:

 - STA+P2P concurrency feature gets implemented.

 - add USB architecture and support RTL8851BU and RTL8852BU.
==================

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg
2025-07-18 13:57:33 +02:00
65 changed files with 3497 additions and 685 deletions

View File

@@ -6618,7 +6618,7 @@ static int rtl8xxxu_submit_rx_urb(struct rtl8xxxu_priv *priv,
skb_size = fops->rx_agg_buf_size;
skb_size += (rx_desc_sz + sizeof(struct rtl8723au_phy_stats));
} else {
skb_size = IEEE80211_MAX_FRAME_LEN;
skb_size = IEEE80211_MAX_FRAME_LEN + rx_desc_sz;
}
skb = __netdev_alloc_skb(NULL, skb_size, GFP_KERNEL);

View File

@@ -1487,22 +1487,9 @@ _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
rtlefuse->
eeprom_chnlarea_txpwr_ht40_1s[rf_path][index];
if ((rtlefuse->
eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] -
rtlefuse->
eprom_chnl_txpwr_ht40_2sdf[rf_path][index])
> 0) {
rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
rtlefuse->
eeprom_chnlarea_txpwr_ht40_1s[rf_path]
[index] -
rtlefuse->
eprom_chnl_txpwr_ht40_2sdf[rf_path]
[index];
} else {
rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0;
}
rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
max(rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] -
rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path][index], 0);
}
for (i = 0; i < 14; i++) {

View File

@@ -163,20 +163,9 @@ _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
rtlefuse->
eeprom_chnlarea_txpwr_ht40_1s[rf_path][index];
if ((rtlefuse->
eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] -
rtlefuse->
eprom_chnl_txpwr_ht40_2sdf[rf_path][index])
> 0) {
rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
rtlefuse->
eeprom_chnlarea_txpwr_ht40_1s[rf_path]
[index] - rtlefuse->
eprom_chnl_txpwr_ht40_2sdf[rf_path]
[index];
} else {
rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0;
}
rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
max(rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] -
rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path][index], 0);
}
for (i = 0; i < 14; i++) {
RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,

View File

@@ -223,10 +223,7 @@ static void rtl92ee_dm_dig(struct ieee80211_hw *hw)
if (mac->link_state >= MAC80211_LINKED) {
if (bfirstconnect) {
if (dm_dig->rssi_val_min <= dig_maxofmin)
current_igi = dm_dig->rssi_val_min;
else
current_igi = dig_maxofmin;
current_igi = min(dm_dig->rssi_val_min, dig_maxofmin);
dm_dig->large_fa_hit = 0;
} else {

View File

@@ -1449,18 +1449,9 @@ _rtl8723e_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
[rf_path][index];
if ((rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
[rf_path][index] -
rtlefuse->eprom_chnl_txpwr_ht40_2sdf
[rf_path][index]) > 0) {
rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
[rf_path][index] -
rtlefuse->eprom_chnl_txpwr_ht40_2sdf
[rf_path][index];
} else {
rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0;
}
rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
max(rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] -
rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path][index], 0);
}
for (i = 0; i < 14; i++) {

View File

@@ -468,10 +468,7 @@ static void rtl8723be_dm_dig(struct ieee80211_hw *hw)
if (mac->link_state >= MAC80211_LINKED) {
if (bfirstconnect) {
if (dm_digtable->rssi_val_min <= dig_maxofmin)
current_igi = dm_digtable->rssi_val_min;
else
current_igi = dig_maxofmin;
current_igi = min(dm_digtable->rssi_val_min, dig_maxofmin);
dm_digtable->large_fa_hit = 0;
} else {

View File

@@ -756,10 +756,7 @@ static void rtl8821ae_dm_dig(struct ieee80211_hw *hw)
rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
"DIG AfterLink\n");
if (first_connect) {
if (dm_digtable->rssi_val_min <= dig_max_of_min)
current_igi = dm_digtable->rssi_val_min;
else
current_igi = dig_max_of_min;
current_igi = min(dm_digtable->rssi_val_min, dig_max_of_min);
rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
"First Connect\n");
} else {

View File

@@ -1501,28 +1501,28 @@ static u8 rtw_coex_algorithm(struct rtw_dev *rtwdev)
algorithm = COEX_ALGO_HFP;
break;
case BPM_HID:
case BPM_HFP + BPM_HID:
case BPM_HFP | BPM_HID:
algorithm = COEX_ALGO_HID;
break;
case BPM_HFP + BPM_A2DP:
case BPM_HID + BPM_A2DP:
case BPM_HFP + BPM_HID + BPM_A2DP:
case BPM_HFP | BPM_A2DP:
case BPM_HID | BPM_A2DP:
case BPM_HFP | BPM_HID | BPM_A2DP:
algorithm = COEX_ALGO_A2DP_HID;
break;
case BPM_HFP + BPM_PAN:
case BPM_HID + BPM_PAN:
case BPM_HFP + BPM_HID + BPM_PAN:
case BPM_HFP | BPM_PAN:
case BPM_HID | BPM_PAN:
case BPM_HFP | BPM_HID | BPM_PAN:
algorithm = COEX_ALGO_PAN_HID;
break;
case BPM_HFP + BPM_A2DP + BPM_PAN:
case BPM_HID + BPM_A2DP + BPM_PAN:
case BPM_HFP + BPM_HID + BPM_A2DP + BPM_PAN:
case BPM_HFP | BPM_A2DP | BPM_PAN:
case BPM_HID | BPM_A2DP | BPM_PAN:
case BPM_HFP | BPM_HID | BPM_A2DP | BPM_PAN:
algorithm = COEX_ALGO_A2DP_PAN_HID;
break;
case BPM_PAN:
algorithm = COEX_ALGO_PAN;
break;
case BPM_A2DP + BPM_PAN:
case BPM_A2DP | BPM_PAN:
algorithm = COEX_ALGO_A2DP_PAN;
break;
case BPM_A2DP:

View File

@@ -1409,3 +1409,13 @@ int rtw_mac_init(struct rtw_dev *rtwdev)
return 0;
}
int rtw_mac_postinit(struct rtw_dev *rtwdev)
{
const struct rtw_chip_info *chip = rtwdev->chip;
if (!chip->ops->mac_postinit)
return 0;
return chip->ops->mac_postinit(rtwdev);
}

View File

@@ -38,6 +38,7 @@ void rtw_write_firmware_page(struct rtw_dev *rtwdev, u32 page,
const u8 *data, u32 size);
int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw);
int rtw_mac_init(struct rtw_dev *rtwdev);
int rtw_mac_postinit(struct rtw_dev *rtwdev);
void rtw_mac_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop);
int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev);
int rtw_ddma_to_fw_fifo(struct rtw_dev *rtwdev, u32 ocp_src, u32 size);

View File

@@ -349,7 +349,7 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
int i;
if (vif->type == NL80211_IFTYPE_STATION) {
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
si->mac_id = rtwvif->mac_id;
} else {
si->mac_id = rtw_acquire_macid(rtwdev);
@@ -386,7 +386,7 @@ void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
cancel_work_sync(&si->rc_work);
if (vif->type != NL80211_IFTYPE_STATION)
if (vif->type != NL80211_IFTYPE_STATION || sta->tdls)
rtw_release_macid(rtwdev, si->mac_id);
if (fw_exist)
rtw_fw_media_status_report(rtwdev, si->mac_id, false);
@@ -1412,6 +1412,12 @@ int rtw_power_on(struct rtw_dev *rtwdev)
chip->ops->phy_set_param(rtwdev);
ret = rtw_mac_postinit(rtwdev);
if (ret) {
rtw_err(rtwdev, "failed to configure mac in postinit\n");
goto err_off;
}
ret = rtw_hci_start(rtwdev);
if (ret) {
rtw_err(rtwdev, "failed to start hci\n");

View File

@@ -858,6 +858,7 @@ struct rtw_chip_ops {
int (*power_on)(struct rtw_dev *rtwdev);
void (*power_off)(struct rtw_dev *rtwdev);
int (*mac_init)(struct rtw_dev *rtwdev);
int (*mac_postinit)(struct rtw_dev *rtwdev);
int (*dump_fw_crash)(struct rtw_dev *rtwdev);
void (*shutdown)(struct rtw_dev *rtwdev);
int (*read_efuse)(struct rtw_dev *rtwdev, u8 *map);

View File

@@ -1832,6 +1832,7 @@ static const struct rtw_chip_ops rtw8703b_ops = {
.power_on = rtw_power_on,
.power_off = rtw_power_off,
.mac_init = rtw8723x_mac_init,
.mac_postinit = rtw8723x_mac_postinit,
.dump_fw_crash = NULL,
.shutdown = NULL,
.read_efuse = rtw8703b_read_efuse,

View File

@@ -1397,6 +1397,7 @@ static const struct rtw_chip_ops rtw8723d_ops = {
.query_phy_status = query_phy_status,
.set_channel = rtw8723d_set_channel,
.mac_init = rtw8723x_mac_init,
.mac_postinit = rtw8723x_mac_postinit,
.shutdown = rtw8723d_shutdown,
.read_rf = rtw_phy_read_rf_sipi,
.write_rf = rtw_phy_write_rf_reg_sipi,

View File

@@ -353,7 +353,6 @@ static int __rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
static int __rtw8723x_mac_init(struct rtw_dev *rtwdev)
{
rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN);
rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG);
rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);
@@ -370,6 +369,13 @@ static int __rtw8723x_mac_init(struct rtw_dev *rtwdev)
return 0;
}
static int __rtw8723x_mac_postinit(struct rtw_dev *rtwdev)
{
rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN);
return 0;
}
static void __rtw8723x_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
{
u8 ldo_pwr;
@@ -760,6 +766,7 @@ const struct rtw8723x_common rtw8723x_common = {
.lck = __rtw8723x_lck,
.read_efuse = __rtw8723x_read_efuse,
.mac_init = __rtw8723x_mac_init,
.mac_postinit = __rtw8723x_mac_postinit,
.cfg_ldo25 = __rtw8723x_cfg_ldo25,
.set_tx_power_index = __rtw8723x_set_tx_power_index,
.efuse_grant = __rtw8723x_efuse_grant,

View File

@@ -137,6 +137,7 @@ struct rtw8723x_common {
void (*lck)(struct rtw_dev *rtwdev);
int (*read_efuse)(struct rtw_dev *rtwdev, u8 *log_map);
int (*mac_init)(struct rtw_dev *rtwdev);
int (*mac_postinit)(struct rtw_dev *rtwdev);
void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable);
void (*set_tx_power_index)(struct rtw_dev *rtwdev);
void (*efuse_grant)(struct rtw_dev *rtwdev, bool on);
@@ -383,6 +384,11 @@ static inline int rtw8723x_mac_init(struct rtw_dev *rtwdev)
return rtw8723x_common.mac_init(rtwdev);
}
static inline int rtw8723x_mac_postinit(struct rtw_dev *rtwdev)
{
return rtw8723x_common.mac_postinit(rtwdev);
}
static inline void rtw8723x_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
{
rtw8723x_common.cfg_ldo25(rtwdev, enable);

View File

@@ -919,6 +919,7 @@ static const struct rtw_chip_ops rtw8812a_ops = {
.query_phy_status = rtw8812a_query_phy_status,
.set_channel = rtw88xxa_set_channel,
.mac_init = NULL,
.mac_postinit = NULL,
.read_rf = rtw88xxa_phy_read_rf,
.write_rf = rtw_phy_write_rf_reg_sipi,
.set_antenna = NULL,

View File

@@ -2055,6 +2055,7 @@ static const struct rtw_chip_ops rtw8814a_ops = {
.query_phy_status = rtw8814a_query_phy_status,
.set_channel = rtw8814a_set_channel,
.mac_init = rtw8814a_mac_init,
.mac_postinit = NULL,
.read_rf = rtw_phy_read_rf,
.write_rf = rtw_phy_write_rf_reg_sipi,
.set_tx_power_index = rtw8814a_set_tx_power_index,

View File

@@ -865,6 +865,7 @@ static const struct rtw_chip_ops rtw8821a_ops = {
.query_phy_status = rtw8821a_query_phy_status,
.set_channel = rtw88xxa_set_channel,
.mac_init = NULL,
.mac_postinit = NULL,
.read_rf = rtw88xxa_phy_read_rf,
.write_rf = rtw_phy_write_rf_reg_sipi,
.set_antenna = NULL,

View File

@@ -1663,6 +1663,7 @@ static const struct rtw_chip_ops rtw8821c_ops = {
.query_phy_status = query_phy_status,
.set_channel = rtw8821c_set_channel,
.mac_init = rtw8821c_mac_init,
.mac_postinit = NULL,
.read_rf = rtw_phy_read_rf,
.write_rf = rtw_phy_write_rf_reg_sipi,
.set_antenna = NULL,

View File

@@ -2154,6 +2154,7 @@ static const struct rtw_chip_ops rtw8822b_ops = {
.query_phy_status = query_phy_status,
.set_channel = rtw8822b_set_channel,
.mac_init = rtw8822b_mac_init,
.mac_postinit = NULL,
.read_rf = rtw_phy_read_rf,
.write_rf = rtw_phy_write_rf_reg_sipi,
.set_tx_power_index = rtw8822b_set_tx_power_index,

View File

@@ -4964,6 +4964,7 @@ static const struct rtw_chip_ops rtw8822c_ops = {
.query_phy_status = query_phy_status,
.set_channel = rtw8822c_set_channel,
.mac_init = rtw8822c_mac_init,
.mac_postinit = NULL,
.dump_fw_crash = rtw8822c_dump_fw_crash,
.read_rf = rtw_phy_read_rf,
.write_rf = rtw_phy_write_rf_reg_mix,

View File

@@ -17,6 +17,9 @@ config RTW89_CORE
config RTW89_PCI
tristate
config RTW89_USB
tristate
config RTW89_8851B
tristate
@@ -49,6 +52,17 @@ config RTW89_8851BE
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
@@ -72,6 +86,18 @@ config RTW89_8852BE
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

View File

@@ -31,6 +31,9 @@ rtw89_8851b-objs := rtw8851b.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 \
@@ -52,6 +55,9 @@ rtw89_8852b-objs := rtw8852b.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 \
@@ -81,3 +87,6 @@ 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

View File

@@ -236,6 +236,50 @@ int rtw89_acpi_dsm_get_policy_6ghz_sp(struct rtw89_dev *rtwdev,
return 0;
}
static bool chk_acpi_policy_6ghz_vlp_sig(const struct rtw89_acpi_policy_6ghz_vlp *p)
{
return p->signature[0] == 0x52 &&
p->signature[1] == 0x54 &&
p->signature[2] == 0x4B &&
p->signature[3] == 0x0B;
}
static
int rtw89_acpi_dsm_get_policy_6ghz_vlp(struct rtw89_dev *rtwdev,
union acpi_object *obj,
struct rtw89_acpi_policy_6ghz_vlp **policy)
{
const struct rtw89_acpi_policy_6ghz_vlp *ptr;
u32 buf_len;
if (obj->type != ACPI_TYPE_BUFFER) {
rtw89_debug(rtwdev, RTW89_DBG_ACPI,
"acpi: expect buffer but type: %d\n", obj->type);
return -EINVAL;
}
buf_len = obj->buffer.length;
if (buf_len < sizeof(*ptr)) {
rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n",
__func__, buf_len);
return -EINVAL;
}
ptr = (typeof(ptr))obj->buffer.pointer;
if (!chk_acpi_policy_6ghz_vlp_sig(ptr)) {
rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__);
return -EINVAL;
}
*policy = kmemdup(ptr, sizeof(*ptr), GFP_KERNEL);
if (!*policy)
return -ENOMEM;
rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_6ghz_vlp: ", *policy,
sizeof(*ptr));
return 0;
}
static bool chk_acpi_policy_tas_sig(const struct rtw89_acpi_policy_tas *p)
{
return p->signature[0] == 0x52 &&
@@ -279,6 +323,51 @@ static int rtw89_acpi_dsm_get_policy_tas(struct rtw89_dev *rtwdev,
return 0;
}
static
bool chk_acpi_policy_reg_rules_sig(const struct rtw89_acpi_policy_reg_rules *p)
{
return p->signature[0] == 0x52 &&
p->signature[1] == 0x54 &&
p->signature[2] == 0x4B &&
p->signature[3] == 0x0A;
}
static
int rtw89_acpi_dsm_get_policy_reg_rules(struct rtw89_dev *rtwdev,
union acpi_object *obj,
struct rtw89_acpi_policy_reg_rules **policy)
{
const struct rtw89_acpi_policy_reg_rules *ptr;
u32 buf_len;
if (obj->type != ACPI_TYPE_BUFFER) {
rtw89_debug(rtwdev, RTW89_DBG_ACPI,
"acpi: expect buffer but type: %d\n", obj->type);
return -EINVAL;
}
buf_len = obj->buffer.length;
if (buf_len < sizeof(*ptr)) {
rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n",
__func__, buf_len);
return -EINVAL;
}
ptr = (typeof(ptr))obj->buffer.pointer;
if (!chk_acpi_policy_reg_rules_sig(ptr)) {
rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__);
return -EINVAL;
}
*policy = kmemdup(ptr, sizeof(*ptr), GFP_KERNEL);
if (!*policy)
return -ENOMEM;
rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_reg_rules: ", *policy,
sizeof(*ptr));
return 0;
}
int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
enum rtw89_acpi_dsm_func func,
struct rtw89_acpi_dsm_result *res)
@@ -300,8 +389,14 @@ int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
else if (func == RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP)
ret = rtw89_acpi_dsm_get_policy_6ghz_sp(rtwdev, obj,
&res->u.policy_6ghz_sp);
else if (func == RTW89_ACPI_DSM_FUNC_6GHZ_VLP_SUP)
ret = rtw89_acpi_dsm_get_policy_6ghz_vlp(rtwdev, obj,
&res->u.policy_6ghz_vlp);
else if (func == RTW89_ACPI_DSM_FUNC_TAS_EN)
ret = rtw89_acpi_dsm_get_policy_tas(rtwdev, obj, &res->u.policy_tas);
else if (func == RTW89_ACPI_DSM_FUNC_REG_RULES_EN)
ret = rtw89_acpi_dsm_get_policy_reg_rules(rtwdev, obj,
&res->u.policy_reg_rules);
else
ret = rtw89_acpi_dsm_get_value(rtwdev, obj, &res->u.value);

View File

@@ -19,11 +19,13 @@ enum rtw89_acpi_dsm_func {
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_FCC = BIT(0),
RTW89_ACPI_CONF_UNII4_IC = BIT(1),
RTW89_ACPI_CONF_UNII4_US = BIT(0),
RTW89_ACPI_CONF_UNII4_CA = BIT(1),
};
enum rtw89_acpi_policy_mode {
@@ -56,6 +58,7 @@ struct rtw89_acpi_policy_6ghz {
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 {
@@ -66,6 +69,19 @@ struct rtw89_acpi_policy_6ghz_sp {
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;
@@ -74,13 +90,26 @@ struct rtw89_acpi_policy_tas {
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;
};

View File

@@ -7,6 +7,7 @@
#include "debug.h"
#include "fw.h"
#include "mac.h"
#include "phy.h"
#include "ps.h"
#include "sar.h"
#include "util.h"
@@ -128,6 +129,48 @@ void rtw89_chan_create(struct rtw89_chan *chan, u8 center_chan, u8 primary_chan,
bandwidth);
}
static void _rtw89_chan_update_punctured(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
const struct cfg80211_chan_def *chandef)
{
struct ieee80211_bss_conf *bss_conf;
if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION &&
rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT)
return;
rcu_read_lock();
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
if (!bss_conf->eht_support) {
rcu_read_unlock();
return;
}
rcu_read_unlock();
rtw89_chip_h2c_punctured_cmac_tbl(rtwdev, rtwvif_link, chandef->punctured);
}
static void rtw89_chan_update_punctured(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx idx,
const struct cfg80211_chan_def *chandef)
{
struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
unsigned int link_id;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
if (!rtwvif_link->chanctx_assigned ||
rtwvif_link->chanctx_idx != idx)
continue;
_rtw89_chan_update_punctured(rtwdev, rtwvif_link, chandef);
}
}
}
bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx idx,
const struct rtw89_chan *new)
@@ -999,6 +1042,11 @@ static void rtw89_mcc_assign_pattern(struct rtw89_dev *rtwdev,
*pattern = *new;
memset(&pattern->courtesy, 0, sizeof(pattern->courtesy));
if (RTW89_MCC_REQ_COURTESY(pattern, aux) && aux->is_gc)
aux->ignore_bcn = true;
else
aux->ignore_bcn = false;
if (RTW89_MCC_REQ_COURTESY(pattern, aux) && rtw89_mcc_can_courtesy(ref, aux)) {
crtz = &pattern->courtesy.ref;
ref->crtz = crtz;
@@ -1013,6 +1061,11 @@ static void rtw89_mcc_assign_pattern(struct rtw89_dev *rtwdev,
ref->crtz = NULL;
}
if (RTW89_MCC_REQ_COURTESY(pattern, ref) && ref->is_gc)
ref->ignore_bcn = true;
else
ref->ignore_bcn = false;
if (RTW89_MCC_REQ_COURTESY(pattern, ref) && rtw89_mcc_can_courtesy(aux, ref)) {
crtz = &pattern->courtesy.aux;
aux->crtz = crtz;
@@ -1115,7 +1168,7 @@ static int __rtw89_mcc_calc_pattern_strict(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *ref = &mcc->role_ref;
struct rtw89_mcc_role *aux = &mcc->role_aux;
struct rtw89_mcc_config *config = &mcc->config;
u16 min_tob = RTW89_MCC_EARLY_RX_BCN_TIME;
u16 min_tob = RTW89_MCC_EARLY_RX_BCN_TIME + RTW89_MCC_SWITCH_CH_TIME;
u16 min_toa = RTW89_MCC_MIN_RX_BCN_TIME;
u16 bcn_ofst = config->beacon_offset;
s16 upper_toa_ref, lower_toa_ref;
@@ -1271,11 +1324,11 @@ static int __rtw89_mcc_calc_pattern_anchor(struct rtw89_dev *rtwdev,
u16 bcn_ofst = config->beacon_offset;
bool small_bcn_ofst;
if (bcn_ofst < RTW89_MCC_MIN_RX_BCN_TIME)
if (bcn_ofst < RTW89_MCC_MIN_RX_BCN_WITH_SWITCH_CH_TIME)
small_bcn_ofst = true;
else if (bcn_ofst < aux->duration - aux->limit.max_toa)
small_bcn_ofst = true;
else if (mcc_intvl - bcn_ofst < RTW89_MCC_MIN_RX_BCN_TIME)
else if (mcc_intvl - bcn_ofst < RTW89_MCC_MIN_RX_BCN_WITH_SWITCH_CH_TIME)
small_bcn_ofst = false;
else
return -EPERM;
@@ -2170,6 +2223,7 @@ static void rtw89_mcc_handle_beacon_noa(struct rtw89_dev *rtwdev, bool enable)
rtw89_p2p_noa_renew(rtwvif_go);
if (enable) {
duration += RTW89_MCC_SWITCH_CH_TIME;
noa_desc.start_time = cpu_to_le32(start_time);
noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(interval));
noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(duration));
@@ -2253,15 +2307,6 @@ static int rtw89_mcc_start(struct rtw89_dev *rtwdev)
else
mcc->mode = RTW89_MCC_MODE_GC_STA;
if (rtw89_mcc_ignore_bcn(rtwdev, ref)) {
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, false);
} else if (rtw89_mcc_ignore_bcn(rtwdev, aux)) {
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, false);
} else {
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, true);
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, true);
}
rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC sel mode: %d\n", mcc->mode);
mcc->group = RTW89_MCC_DFLT_GROUP;
@@ -2270,6 +2315,15 @@ static int rtw89_mcc_start(struct rtw89_dev *rtwdev)
if (ret)
return ret;
if (rtw89_mcc_ignore_bcn(rtwdev, ref) || aux->ignore_bcn) {
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, false);
} else if (rtw89_mcc_ignore_bcn(rtwdev, aux) || ref->ignore_bcn) {
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, false);
} else {
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, true);
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, true);
}
if (rtw89_concurrent_via_mrc(rtwdev))
ret = __mrc_fw_start(rtwdev, false);
else
@@ -2281,6 +2335,7 @@ static int rtw89_mcc_start(struct rtw89_dev *rtwdev)
rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_START);
rtw89_mcc_start_beacon_noa(rtwdev);
rtw89_phy_dig_suspend(rtwdev);
rtw89_mcc_prepare(rtwdev, true);
return 0;
@@ -2333,9 +2388,11 @@ static void rtw89_mcc_stop(struct rtw89_dev *rtwdev,
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
struct rtw89_mcc_role *ref = &mcc->role_ref;
struct rtw89_mcc_role *aux = &mcc->role_aux;
struct rtw89_mcc_stop_sel sel = {
.hint.target = pause ? pause->trigger : NULL,
};
bool rsn_scan;
int ret;
if (!pause) {
@@ -2343,6 +2400,12 @@ static void rtw89_mcc_stop(struct rtw89_dev *rtwdev,
bitmap_zero(hal->changes, NUM_OF_RTW89_CHANCTX_CHANGES);
}
rsn_scan = pause && pause->rsn == RTW89_CHANCTX_PAUSE_REASON_HW_SCAN;
if (rsn_scan && ref->is_go)
sel.hint.target = ref->rtwvif_link;
else if (rsn_scan && aux->is_go)
sel.hint.target = aux->rtwvif_link;
/* by default, stop at ref */
rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_stop_sel_iterator, &sel);
if (!sel.filled)
@@ -2371,6 +2434,8 @@ static void rtw89_mcc_stop(struct rtw89_dev *rtwdev,
rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_STOP);
rtw89_mcc_stop_beacon_noa(rtwdev);
rtw89_fw_h2c_mcc_dig(rtwdev, RTW89_CHANCTX_0, 0, 0, false);
rtw89_phy_dig_resume(rtwdev, true);
rtw89_mcc_prepare(rtwdev, false);
}
@@ -2378,7 +2443,11 @@ static void rtw89_mcc_stop(struct rtw89_dev *rtwdev,
static int rtw89_mcc_update(struct rtw89_dev *rtwdev)
{
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
bool old_ref_ignore_bcn = mcc->role_ref.ignore_bcn;
bool old_aux_ignore_bcn = mcc->role_aux.ignore_bcn;
struct rtw89_mcc_config *config = &mcc->config;
struct rtw89_mcc_role *ref = &mcc->role_ref;
struct rtw89_mcc_role *aux = &mcc->role_aux;
struct rtw89_mcc_config old_cfg = *config;
bool courtesy_changed;
bool sync_changed;
@@ -2393,6 +2462,11 @@ static int rtw89_mcc_update(struct rtw89_dev *rtwdev)
if (ret)
return ret;
if (old_ref_ignore_bcn != ref->ignore_bcn)
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, !ref->ignore_bcn);
else if (old_aux_ignore_bcn != aux->ignore_bcn)
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, !aux->ignore_bcn);
if (memcmp(&old_cfg.pattern.courtesy, &config->pattern.courtesy,
sizeof(old_cfg.pattern.courtesy)) == 0)
courtesy_changed = false;
@@ -2428,10 +2502,105 @@ static int rtw89_mcc_update(struct rtw89_dev *rtwdev)
return 0;
}
static int rtw89_mcc_search_gc_iterator(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *mcc_role,
unsigned int ordered_idx,
void *data)
{
struct rtw89_mcc_role **role = data;
if (mcc_role->is_gc)
*role = mcc_role;
return 0;
}
static struct rtw89_mcc_role *rtw89_mcc_get_gc_role(struct rtw89_dev *rtwdev)
{
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
struct rtw89_mcc_role *role = NULL;
if (mcc->mode != RTW89_MCC_MODE_GC_STA)
return NULL;
rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_search_gc_iterator, &role);
return role;
}
void rtw89_mcc_gc_detect_beacon_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_vif_link *rtwvif_link = container_of(work, struct rtw89_vif_link,
mcc_gc_detect_beacon_work.work);
struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
enum rtw89_entity_mode mode;
struct rtw89_dev *rtwdev;
lockdep_assert_wiphy(wiphy);
rtwdev = rtwvif_link->rtwvif->rtwdev;
mode = rtw89_get_entity_mode(rtwdev);
if (mode != RTW89_ENTITY_MODE_MCC)
return;
if (READ_ONCE(rtwvif_link->sync_bcn_tsf) > rtwvif_link->last_sync_bcn_tsf)
rtwvif_link->detect_bcn_count = 0;
else
rtwvif_link->detect_bcn_count++;
if (rtwvif_link->detect_bcn_count < RTW89_MCC_DETECT_BCN_MAX_TRIES)
rtw89_chanctx_proceed(rtwdev, NULL);
else
ieee80211_connection_loss(vif);
}
bool rtw89_mcc_detect_go_bcn(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev);
struct rtw89_chanctx_pause_parm pause_parm = {
.rsn = RTW89_CHANCTX_PAUSE_REASON_GC_BCN_LOSS,
.trigger = rtwvif_link,
};
struct ieee80211_bss_conf *bss_conf;
struct rtw89_mcc_role *role;
u16 bcn_int;
if (mode != RTW89_ENTITY_MODE_MCC)
return false;
role = rtw89_mcc_get_gc_role(rtwdev);
if (!role)
return false;
if (role->rtwvif_link != rtwvif_link)
return false;
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"MCC GC beacon loss, pause MCC to detect GO beacon\n");
rcu_read_lock();
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
bcn_int = bss_conf->beacon_int;
rcu_read_unlock();
rtw89_chanctx_pause(rtwdev, &pause_parm);
rtwvif_link->last_sync_bcn_tsf = READ_ONCE(rtwvif_link->sync_bcn_tsf);
wiphy_delayed_work_queue(rtwdev->hw->wiphy,
&rtwvif_link->mcc_gc_detect_beacon_work,
usecs_to_jiffies(ieee80211_tu_to_usec(bcn_int)));
return true;
}
static void rtw89_mcc_detect_connection(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *role)
{
struct ieee80211_vif *vif;
bool start_detect;
int ret;
ret = rtw89_core_send_nullfunc(rtwdev, role->rtwvif_link, true, false,
@@ -2445,7 +2614,12 @@ static void rtw89_mcc_detect_connection(struct rtw89_dev *rtwdev,
return;
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"MCC <macid %d> can not detect AP\n", role->rtwvif_link->mac_id);
"MCC <macid %d> can not detect AP/GO\n", role->rtwvif_link->mac_id);
start_detect = rtw89_mcc_detect_go_bcn(rtwdev, role->rtwvif_link);
if (start_detect)
return;
vif = rtwvif_link_to_vif(role->rtwvif_link);
ieee80211_connection_loss(vif);
}
@@ -2461,9 +2635,9 @@ static void rtw89_mcc_track(struct rtw89_dev *rtwdev)
u16 bcn_ofst;
u16 diff;
if (rtw89_mcc_ignore_bcn(rtwdev, ref))
if (rtw89_mcc_ignore_bcn(rtwdev, ref) || aux->ignore_bcn)
rtw89_mcc_detect_connection(rtwdev, aux);
else if (rtw89_mcc_ignore_bcn(rtwdev, aux))
else if (rtw89_mcc_ignore_bcn(rtwdev, aux) || ref->ignore_bcn)
rtw89_mcc_detect_connection(rtwdev, ref);
if (mcc->mode != RTW89_MCC_MODE_GC_STA)
@@ -2622,6 +2796,30 @@ static void rtw89_mcc_update_limit(struct rtw89_dev *rtwdev)
rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_upd_lmt_iterator, NULL);
}
static int rtw89_mcc_get_links_iterator(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *mcc_role,
unsigned int ordered_idx,
void *data)
{
struct rtw89_mcc_links_info *info = data;
info->links[ordered_idx] = mcc_role->rtwvif_link;
return 0;
}
void rtw89_mcc_get_links(struct rtw89_dev *rtwdev, struct rtw89_mcc_links_info *info)
{
enum rtw89_entity_mode mode;
memset(info, 0, sizeof(*info));
mode = rtw89_get_entity_mode(rtwdev);
if (unlikely(mode != RTW89_ENTITY_MODE_MCC))
return;
rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_get_links_iterator, info);
}
void rtw89_chanctx_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
@@ -2690,6 +2888,7 @@ void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
return;
case RTW89_ENTITY_MODE_MCC_PREPARE:
delay = ieee80211_tu_to_usec(RTW89_CHANCTX_TIME_MCC_PREPARE);
rtw89_phy_dig_suspend(rtwdev);
break;
case RTW89_ENTITY_MODE_MCC:
delay = ieee80211_tu_to_usec(RTW89_CHANCTX_TIME_MCC);
@@ -3088,6 +3287,9 @@ void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
rtw89_set_channel(rtwdev);
}
if (changed & IEEE80211_CHANCTX_CHANGE_PUNCTURING)
rtw89_chan_update_punctured(rtwdev, idx, &ctx->def);
}
int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
@@ -3231,5 +3433,7 @@ int rtw89_chanctx_ops_reassign_vif(struct rtw89_dev *rtwdev,
return ret;
}
_rtw89_chan_update_punctured(rtwdev, rtwvif_link, &new_ctx->def);
return 0;
}

View File

@@ -18,16 +18,22 @@
#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)
@@ -90,6 +96,7 @@ struct rtw89_mr_chanctx_info {
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 {
@@ -178,7 +185,15 @@ const struct rtw89_chan *__rtw89_mgnt_chan_get(struct rtw89_dev *rtwdev,
#define rtw89_mgnt_chan_get(rtwdev, link_index) \
__rtw89_mgnt_chan_get(rtwdev, __func__, link_index)
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);

View File

@@ -319,15 +319,25 @@ static const struct ieee80211_supported_band rtw89_sband_6ghz = {
.n_bitrates = ARRAY_SIZE(rtw89_bitrates) - 4,
};
static void __rtw89_traffic_stats_accu(struct rtw89_traffic_stats *stats,
struct sk_buff *skb, bool tx)
{
if (tx) {
stats->tx_cnt++;
stats->tx_unicast += skb->len;
} else {
stats->rx_cnt++;
stats->rx_unicast += skb->len;
}
}
static void rtw89_traffic_stats_accu(struct rtw89_dev *rtwdev,
struct rtw89_traffic_stats *stats,
struct sk_buff *skb, bool tx)
struct rtw89_vif *rtwvif,
struct sk_buff *skb,
bool accu_dev, bool tx)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
if (tx && ieee80211_is_assoc_req(hdr->frame_control))
rtw89_wow_parse_akm(rtwdev, skb);
if (!ieee80211_is_data(hdr->frame_control))
return;
@@ -335,12 +345,12 @@ static void rtw89_traffic_stats_accu(struct rtw89_dev *rtwdev,
is_multicast_ether_addr(hdr->addr1))
return;
if (tx) {
stats->tx_cnt++;
stats->tx_unicast += skb->len;
} else {
stats->rx_cnt++;
stats->rx_unicast += skb->len;
if (accu_dev)
__rtw89_traffic_stats_accu(&rtwdev->stats, skb, tx);
if (rtwvif) {
__rtw89_traffic_stats_accu(&rtwvif->stats, skb, tx);
__rtw89_traffic_stats_accu(&rtwvif->stats_ps, skb, tx);
}
}
@@ -984,13 +994,25 @@ rtw89_core_tx_wake(struct rtw89_dev *rtwdev,
if (!RTW89_CHK_FW_FEATURE(TX_WAKE, &rtwdev->fw))
return;
if (!test_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags))
return;
switch (chip->chip_id) {
case RTL8852BT:
if (test_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags))
goto notify;
break;
case RTL8852C:
if (test_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags))
goto notify;
break;
default:
if (test_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags) &&
tx_req->tx_type == RTW89_CORE_TX_TYPE_MGMT)
goto notify;
break;
}
if (chip->chip_id != RTL8852C &&
tx_req->tx_type != RTW89_CORE_TX_TYPE_MGMT)
return;
return;
notify:
rtw89_mac_notify_wake(rtwdev);
}
@@ -1150,8 +1172,8 @@ static int rtw89_core_tx_write_link(struct rtw89_dev *rtwdev,
tx_req.rtwsta_link = rtwsta_link;
tx_req.desc_info.sw_mld = sw_mld;
rtw89_traffic_stats_accu(rtwdev, &rtwdev->stats, skb, true);
rtw89_traffic_stats_accu(rtwdev, &rtwvif->stats, skb, true);
rtw89_traffic_stats_accu(rtwdev, rtwvif, skb, true, true);
rtw89_wow_parse_akm(rtwdev, skb);
rtw89_core_tx_update_desc_info(rtwdev, &tx_req);
rtw89_core_tx_wake(rtwdev, &tx_req);
@@ -2267,7 +2289,7 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac,
if (desc_info->data_rate < RTW89_HW_RATE_NR)
pkt_stat->rx_rate_cnt[desc_info->data_rate]++;
rtw89_traffic_stats_accu(rtwdev, &rtwvif->stats, skb, false);
rtw89_traffic_stats_accu(rtwdev, rtwvif, skb, false, false);
out:
rcu_read_unlock();
@@ -2280,7 +2302,7 @@ static void rtw89_core_rx_stats(struct rtw89_dev *rtwdev,
{
struct rtw89_vif_rx_stats_iter_data iter_data;
rtw89_traffic_stats_accu(rtwdev, &rtwdev->stats, skb, false);
rtw89_traffic_stats_accu(rtwdev, NULL, skb, true, false);
iter_data.rtwdev = rtwdev;
iter_data.phy_ppdu = phy_ppdu;
@@ -2884,6 +2906,9 @@ static enum rtw89_ps_mode rtw89_update_ps_mode(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE)
return RTW89_PS_MODE_NONE;
if (rtw89_disable_ps_mode || !chip->ps_mode_supported ||
RTW89_CHK_FW_FEATURE(NO_DEEP_PS, &rtwdev->fw))
return RTW89_PS_MODE_NONE;
@@ -3567,9 +3592,22 @@ void rtw89_roc_work(struct wiphy *wiphy, struct wiphy_work *work)
}
static enum rtw89_tfc_lv rtw89_get_traffic_level(struct rtw89_dev *rtwdev,
u32 throughput, u64 cnt)
u32 throughput, u64 cnt,
enum rtw89_tfc_interval interval)
{
if (cnt < 100)
u64 cnt_level;
switch (interval) {
default:
case RTW89_TFC_INTERVAL_100MS:
cnt_level = 5;
break;
case RTW89_TFC_INTERVAL_2SEC:
cnt_level = 100;
break;
}
if (cnt < cnt_level)
return RTW89_TFC_IDLE;
if (throughput > 50)
return RTW89_TFC_HIGH;
@@ -3581,13 +3619,14 @@ static enum rtw89_tfc_lv rtw89_get_traffic_level(struct rtw89_dev *rtwdev,
}
static bool rtw89_traffic_stats_calc(struct rtw89_dev *rtwdev,
struct rtw89_traffic_stats *stats)
struct rtw89_traffic_stats *stats,
enum rtw89_tfc_interval interval)
{
enum rtw89_tfc_lv tx_tfc_lv = stats->tx_tfc_lv;
enum rtw89_tfc_lv rx_tfc_lv = stats->rx_tfc_lv;
stats->tx_throughput_raw = (u32)(stats->tx_unicast >> RTW89_TP_SHIFT);
stats->rx_throughput_raw = (u32)(stats->rx_unicast >> RTW89_TP_SHIFT);
stats->tx_throughput_raw = rtw89_bytes_to_mbps(stats->tx_unicast, interval);
stats->rx_throughput_raw = rtw89_bytes_to_mbps(stats->rx_unicast, interval);
ewma_tp_add(&stats->tx_ewma_tp, stats->tx_throughput_raw);
ewma_tp_add(&stats->rx_ewma_tp, stats->rx_throughput_raw);
@@ -3595,9 +3634,9 @@ static bool rtw89_traffic_stats_calc(struct rtw89_dev *rtwdev,
stats->tx_throughput = ewma_tp_read(&stats->tx_ewma_tp);
stats->rx_throughput = ewma_tp_read(&stats->rx_ewma_tp);
stats->tx_tfc_lv = rtw89_get_traffic_level(rtwdev, stats->tx_throughput,
stats->tx_cnt);
stats->tx_cnt, interval);
stats->rx_tfc_lv = rtw89_get_traffic_level(rtwdev, stats->rx_throughput,
stats->rx_cnt);
stats->rx_cnt, interval);
stats->tx_avg_len = stats->tx_cnt ?
DIV_ROUND_DOWN_ULL(stats->tx_unicast, stats->tx_cnt) : 0;
stats->rx_avg_len = stats->rx_cnt ?
@@ -3623,10 +3662,12 @@ static bool rtw89_traffic_stats_track(struct rtw89_dev *rtwdev)
unsigned int link_id;
bool tfc_changed;
tfc_changed = rtw89_traffic_stats_calc(rtwdev, &rtwdev->stats);
tfc_changed = rtw89_traffic_stats_calc(rtwdev, &rtwdev->stats,
RTW89_TFC_INTERVAL_2SEC);
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
rtw89_traffic_stats_calc(rtwdev, &rtwvif->stats);
rtw89_traffic_stats_calc(rtwdev, &rtwvif->stats,
RTW89_TFC_INTERVAL_2SEC);
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
rtw89_fw_h2c_tp_offload(rtwdev, rtwvif_link);
@@ -3646,8 +3687,8 @@ static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev)
if (rtwvif->offchan)
continue;
if (rtwvif->stats.tx_tfc_lv != RTW89_TFC_IDLE ||
rtwvif->stats.rx_tfc_lv != RTW89_TFC_IDLE)
if (rtwvif->stats_ps.tx_tfc_lv >= RTW89_TFC_MID ||
rtwvif->stats_ps.rx_tfc_lv >= RTW89_TFC_MID)
continue;
vif = rtwvif_to_vif(rtwvif);
@@ -3786,6 +3827,34 @@ static void rtw89_core_mlo_track(struct rtw89_dev *rtwdev)
}
}
static void rtw89_track_ps_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
track_ps_work.work);
struct rtw89_vif *rtwvif;
lockdep_assert_wiphy(wiphy);
if (test_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags))
return;
if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
return;
wiphy_delayed_work_queue(wiphy, &rtwdev->track_ps_work,
RTW89_TRACK_PS_WORK_PERIOD);
rtw89_for_each_rtwvif(rtwdev, rtwvif)
rtw89_traffic_stats_calc(rtwdev, &rtwvif->stats_ps,
RTW89_TFC_INTERVAL_100MS);
if (rtwdev->scanning)
return;
if (rtwdev->lps_enabled && !rtwdev->btc.lps)
rtw89_enter_lps_track(rtwdev);
}
static void rtw89_track_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
@@ -4025,6 +4094,7 @@ int rtw89_core_sta_link_add(struct rtw89_dev *rtwdev,
&rtwsta_link->tx_retry);
rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false, 60);
}
rtw89_phy_dig_suspend(rtwdev);
} else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta_link->mac_id, false);
if (ret) {
@@ -4213,6 +4283,7 @@ int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev,
if (vif->p2p)
rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false,
rtwsta_link->tx_retry);
rtw89_phy_dig_resume(rtwdev, false);
}
rtw89_assoc_link_set(rtwsta_link);
@@ -4872,6 +4943,8 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->track_work,
RTW89_TRACK_WORK_PERIOD);
wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->track_ps_work,
RTW89_TRACK_PS_WORK_PERIOD);
set_bit(RTW89_FLAG_RUNNING, rtwdev->flags);
@@ -4906,6 +4979,7 @@ void rtw89_core_stop(struct rtw89_dev *rtwdev)
wiphy_work_cancel(wiphy, &btc->icmp_notify_work);
cancel_delayed_work_sync(&rtwdev->txq_reinvoke_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->track_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->track_ps_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->chanctx_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_act1_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_bt_devinfo_work);
@@ -5133,6 +5207,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work);
INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work);
wiphy_delayed_work_init(&rtwdev->track_work, rtw89_track_work);
wiphy_delayed_work_init(&rtwdev->track_ps_work, rtw89_track_ps_work);
wiphy_delayed_work_init(&rtwdev->chanctx_work, rtw89_chanctx_work);
wiphy_delayed_work_init(&rtwdev->coex_act1_work, rtw89_coex_act1_work);
wiphy_delayed_work_init(&rtwdev->coex_bt_devinfo_work, rtw89_coex_bt_devinfo_work);
@@ -5588,6 +5663,9 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
int ret;
int tx_headroom = IEEE80211_HT_CTL_LEN;
if (rtwdev->hci.type == RTW89_HCI_TYPE_USB)
tx_headroom += chip->txwd_body_size + chip->txwd_info_size;
hw->vif_data_size = struct_size_t(struct rtw89_vif, links_inst, n);
hw->sta_data_size = struct_size_t(struct rtw89_sta, links_inst, n);
hw->txq_data_size = sizeof(struct rtw89_txq);

View File

@@ -40,6 +40,7 @@ extern const struct ieee80211_ops rtw89_ops;
#define BYPASS_CR_DATA 0xbabecafe
#define RTW89_TRACK_WORK_PERIOD round_jiffies_relative(HZ * 2)
#define RTW89_TRACK_PS_WORK_PERIOD msecs_to_jiffies(100)
#define RTW89_FORBID_BA_TIMER round_jiffies_relative(HZ * 4)
#define CFO_TRACK_MAX_USER 64
#define MAX_RSSI 110
@@ -130,6 +131,17 @@ enum rtw89_hci_type {
RTW89_HCI_TYPE_PCIE,
RTW89_HCI_TYPE_USB,
RTW89_HCI_TYPE_SDIO,
RTW89_HCI_TYPE_NUM,
};
enum rtw89_hci_dle_type {
RTW89_HCI_DLE_TYPE_PCIE,
RTW89_HCI_DLE_TYPE_USB2,
RTW89_HCI_DLE_TYPE_USB3,
RTW89_HCI_DLE_TYPE_SDIO,
RTW89_HCI_DLE_TYPE_NUM,
};
enum rtw89_core_chip_id {
@@ -1381,6 +1393,11 @@ struct rtw89_btc_wl_smap {
u32 emlsr: 1;
};
enum rtw89_tfc_interval {
RTW89_TFC_INTERVAL_100MS,
RTW89_TFC_INTERVAL_2SEC,
};
enum rtw89_tfc_lv {
RTW89_TFC_IDLE,
RTW89_TFC_ULTRA_LOW,
@@ -1389,7 +1406,6 @@ enum rtw89_tfc_lv {
RTW89_TFC_HIGH,
};
#define RTW89_TP_SHIFT 18 /* bytes/2s --> Mbps */
DECLARE_EWMA(tp, 10, 2);
struct rtw89_traffic_stats {
@@ -3480,6 +3496,7 @@ struct rtw89_efuse {
u8 addr[ETH_ALEN];
u8 rfe_type;
char country_code[2];
u8 adc_td;
};
struct rtw89_phy_rate_pattern {
@@ -3580,6 +3597,7 @@ struct rtw89_vif_link {
u8 hit_rule;
u8 last_noa_nr;
u64 sync_bcn_tsf;
u64 last_sync_bcn_tsf;
bool rand_tsf_done;
bool trigger;
bool lsig_txop;
@@ -3603,6 +3621,8 @@ struct rtw89_vif_link {
struct list_head general_pkt_list;
struct rtw89_p2p_noa_setter p2p_noa;
struct rtw89_ps_noa_once_handler noa_once;
struct wiphy_delayed_work mcc_gc_detect_beacon_work;
u8 detect_bcn_count;
};
enum rtw89_lv1_rcvy_step {
@@ -3659,6 +3679,7 @@ struct rtw89_hci_ops {
struct rtw89_hci_info {
const struct rtw89_hci_ops *ops;
enum rtw89_hci_type type;
enum rtw89_hci_dle_type dle_type;
u32 rpwm_addr;
u32 cpwm_addr;
bool paused;
@@ -3758,6 +3779,9 @@ struct rtw89_chip_ops {
struct rtw89_sta_link *rtwsta_link);
int (*h2c_txtime_cmac_tbl)(struct rtw89_dev *rtwdev,
struct rtw89_sta_link *rtwsta_link);
int (*h2c_punctured_cmac_tbl)(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
u16 punctured);
int (*h2c_default_dmac_tbl)(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
@@ -3842,7 +3866,7 @@ struct rtw89_scan_option {
u16 slow_pd;
u16 norm_cy;
u8 opch_end;
u16 delay;
u16 delay; /* in unit of ms */
u64 prohib_chan;
enum rtw89_phy_idx band;
enum rtw89_scan_be_operation operation;
@@ -4357,8 +4381,8 @@ struct rtw89_chip_info {
u16 max_amsdu_limit;
bool dis_2g_40m_ul_ofdma;
u32 rsvd_ple_ofst;
const struct rtw89_hfc_param_ini *hfc_param_ini;
const struct rtw89_dle_mem *dle_mem;
const struct rtw89_hfc_param_ini *hfc_param_ini[RTW89_HCI_TYPE_NUM];
const struct rtw89_dle_mem *dle_mem[RTW89_HCI_DLE_TYPE_NUM];
u8 wde_qempty_acq_grpnum;
u8 wde_qempty_mgq_grpsel;
u32 rf_base_addr[2];
@@ -4562,11 +4586,21 @@ enum rtw89_fw_type {
RTW89_FW_LOGFMT = 255,
};
#define RTW89_FW_FEATURE_GROUP(_grp, _features...) \
RTW89_FW_FEATURE_##_grp##_MIN, \
__RTW89_FW_FEATURE_##_grp##_S = RTW89_FW_FEATURE_##_grp##_MIN - 1, \
_features \
__RTW89_FW_FEATURE_##_grp##_E, \
RTW89_FW_FEATURE_##_grp##_MAX = __RTW89_FW_FEATURE_##_grp##_E - 1
enum rtw89_fw_feature {
RTW89_FW_FEATURE_OLD_HT_RA_FORMAT,
RTW89_FW_FEATURE_SCAN_OFFLOAD,
RTW89_FW_FEATURE_TX_WAKE,
RTW89_FW_FEATURE_CRASH_TRIGGER,
RTW89_FW_FEATURE_GROUP(CRASH_TRIGGER,
RTW89_FW_FEATURE_CRASH_TRIGGER_TYPE_0,
RTW89_FW_FEATURE_CRASH_TRIGGER_TYPE_1,
),
RTW89_FW_FEATURE_NO_PACKET_DROP,
RTW89_FW_FEATURE_NO_DEEP_PS,
RTW89_FW_FEATURE_NO_LPS_PG,
@@ -4587,6 +4621,7 @@ enum rtw89_fw_feature {
RTW89_FW_FEATURE_BEACON_LOSS_COUNT_V1,
RTW89_FW_FEATURE_SCAN_OFFLOAD_EXTRA_OP,
RTW89_FW_FEATURE_RFK_NTFY_MCC_V0,
RTW89_FW_FEATURE_LPS_DACK_BY_C2H_REG,
};
struct rtw89_fw_suit {
@@ -4684,6 +4719,10 @@ struct rtw89_fw_info {
#define RTW89_CHK_FW_FEATURE(_feat, _fw) \
(!!((_fw)->feature_map & BIT(RTW89_FW_FEATURE_ ## _feat)))
#define RTW89_CHK_FW_FEATURE_GROUP(_grp, _fw) \
(!!((_fw)->feature_map & GENMASK(RTW89_FW_FEATURE_ ## _grp ## _MAX, \
RTW89_FW_FEATURE_ ## _grp ## _MIN)))
#define RTW89_SET_FW_FEATURE(_fw_feature, _fw) \
((_fw)->feature_map |= BIT(_fw_feature))
@@ -4982,6 +5021,7 @@ enum rtw89_flags {
RTW89_FLAG_FORBIDDEN_TRACK_WORK,
RTW89_FLAG_CHANGING_INTERFACE,
RTW89_FLAG_HW_RFKILL_STATE,
RTW89_FLAG_UNPLUGGED,
NUM_OF_RTW89_FLAGS,
};
@@ -5146,7 +5186,7 @@ struct rtw89_dpk_bkup_para {
enum rtw89_band band;
enum rtw89_bandwidth bw;
u8 ch;
bool path_ok;
u8 path_ok;
u8 mdpd_en;
u8 txagc_dpk;
u8 ther_dpk;
@@ -5224,8 +5264,10 @@ struct rtw89_dig_info {
s8 tia_gain_a[TIA_GAIN_NUM];
s8 tia_gain_g[TIA_GAIN_NUM];
s8 *tia_gain;
u32 bak_dig;
bool is_linked_pre;
bool bypass_dig;
bool pause_dig;
};
enum rtw89_multi_cfo_mode {
@@ -5367,6 +5409,7 @@ struct rtw89_regulatory_info {
DECLARE_BITMAP(block_unii4, RTW89_REGD_MAX_COUNTRY_NUM);
DECLARE_BITMAP(block_6ghz, RTW89_REGD_MAX_COUNTRY_NUM);
DECLARE_BITMAP(block_6ghz_sp, RTW89_REGD_MAX_COUNTRY_NUM);
DECLARE_BITMAP(block_6ghz_vlp, RTW89_REGD_MAX_COUNTRY_NUM);
};
enum rtw89_ifs_clm_application {
@@ -5517,7 +5560,9 @@ struct rtw89_early_h2c {
struct rtw89_hw_scan_extra_op {
bool set;
u8 macid;
u8 port;
struct rtw89_chan chan;
struct rtw89_vif_link *rtwvif_link;
};
struct rtw89_hw_scan_info {
@@ -5528,6 +5573,8 @@ struct rtw89_hw_scan_info {
struct rtw89_hw_scan_extra_op extra_op;
bool connected;
bool abort;
u16 delay; /* in unit of ms */
u8 seq: 2;
};
enum rtw89_phy_bb_gain_band {
@@ -5753,6 +5800,7 @@ struct rtw89_mcc_role {
bool is_2ghz;
bool is_go;
bool is_gc;
bool ignore_bcn;
};
struct rtw89_mcc_bt_role {
@@ -5929,6 +5977,7 @@ struct rtw89_dev {
} bbs[RTW89_PHY_NUM];
struct wiphy_delayed_work track_work;
struct wiphy_delayed_work track_ps_work;
struct wiphy_delayed_work chanctx_work;
struct wiphy_delayed_work coex_act1_work;
struct wiphy_delayed_work coex_bt_devinfo_work;
@@ -5979,6 +6028,7 @@ struct rtw89_vif {
__be32 ip_addr;
struct rtw89_traffic_stats stats;
struct rtw89_traffic_stats stats_ps;
u32 tdls_peer;
struct ieee80211_scan_ies *scan_ies;
@@ -7291,6 +7341,17 @@ static inline bool rtw89_is_rtl885xb(struct rtw89_dev *rtwdev)
return false;
}
static inline u32 rtw89_bytes_to_mbps(u64 bytes, enum rtw89_tfc_interval interval)
{
switch (interval) {
default:
case RTW89_TFC_INTERVAL_2SEC:
return bytes >> 18; /* bytes/2s --> Mbps */;
case RTW89_TFC_INTERVAL_100MS:
return (bytes * 10) >> 17; /* bytes/100ms --> Mbps */
}
}
int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel);
int rtw89_h2c_tx(struct rtw89_dev *rtwdev,

View File

@@ -3596,7 +3596,7 @@ rtw89_debug_priv_fw_crash_set(struct rtw89_dev *rtwdev,
switch (crash_type) {
case RTW89_DBG_SIM_CPU_EXCEPTION:
if (!RTW89_CHK_FW_FEATURE(CRASH_TRIGGER, &rtwdev->fw))
if (!RTW89_CHK_FW_FEATURE_GROUP(CRASH_TRIGGER, &rtwdev->fw))
return -EOPNOTSUPP;
sim = rtw89_fw_h2c_trigger_cpu_exception;
break;

View File

@@ -814,33 +814,39 @@ struct __fw_feat_cfg {
static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, TX_WAKE),
__CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8851B, ge, 0, 29, 41, 0, CRASH_TRIGGER),
__CFG_FW_FEAT(RTL8851B, ge, 0, 29, 41, 0, CRASH_TRIGGER_TYPE_0),
__CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT),
__CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE),
__CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER),
__CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER_TYPE_0),
__CFG_FW_FEAT(RTL8852A, lt, 0, 13, 37, 0, NO_WOW_CPU_IO_RX),
__CFG_FW_FEAT(RTL8852A, lt, 0, 13, 38, 0, NO_PACKET_DROP),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER_TYPE_0),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 7, BEACON_FILTER),
__CFG_FW_FEAT(RTL8852B, lt, 0, 29, 30, 0, NO_WOW_CPU_IO_RX),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 127, 0, LPS_DACK_BY_C2H_REG),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, CRASH_TRIGGER_TYPE_1),
__CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, SCAN_OFFLOAD_EXTRA_OP),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, NO_LPS_PG),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, TX_WAKE),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 90, 0, CRASH_TRIGGER),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 90, 0, CRASH_TRIGGER_TYPE_0),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 91, 0, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 110, 0, BEACON_FILTER),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, SCAN_OFFLOAD_EXTRA_OP),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, LPS_DACK_BY_C2H_REG),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, CRASH_TRIGGER_TYPE_1),
__CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS),
__CFG_FW_FEAT(RTL8852C, ge, 0, 0, 0, 0, RFK_NTFY_MCC_V0),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER_TYPE_0),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 56, 10, BEACON_FILTER),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 80, 0, WOW_REASON_V1),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 128, 0, BEACON_LOSS_COUNT_V1),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER_TYPE_0),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 11, 0, MACID_PAUSE_SLEEP),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 21, 0, SCAN_OFFLOAD_BE_V0),
@@ -856,6 +862,8 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 51, 0, NO_PHYCAP_P1),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 64, 0, NO_POWER_DIFFERENCE),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 71, 0, BEACON_LOSS_COUNT_V1),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 76, 0, LPS_DACK_BY_C2H_REG),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 79, 0, CRASH_TRIGGER_TYPE_1),
};
static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw,
@@ -2824,8 +2832,14 @@ int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
struct rtw89_lps_parm *lps_param)
{
struct sk_buff *skb;
bool done_ack;
int ret;
if (RTW89_CHK_FW_FEATURE(LPS_DACK_BY_C2H_REG, &rtwdev->fw))
done_ack = false;
else
done_ack = !lps_param->psmode;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LPS_PARM_LEN);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
@@ -2847,7 +2861,7 @@ int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
H2C_CL_MAC_PS,
H2C_FUNC_MAC_LPS_PARM, 0, !lps_param->psmode,
H2C_FUNC_MAC_LPS_PARM, 0, done_ack,
H2C_LPS_PARM_LEN);
ret = rtw89_h2c_tx(rtwdev, skb, false);
@@ -3731,6 +3745,49 @@ int rtw89_fw_h2c_txtime_cmac_tbl_g7(struct rtw89_dev *rtwdev,
}
EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl_g7);
int rtw89_fw_h2c_punctured_cmac_tbl_g7(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
u16 punctured)
{
struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
int ret;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for punctured cmac g7\n");
return -ENOMEM;
}
skb_put(skb, len);
h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
h2c->c0 = le32_encode_bits(rtwvif_link->mac_id, CCTLINFO_G7_C0_MACID) |
le32_encode_bits(1, CCTLINFO_G7_C0_OP);
h2c->w4 = le32_encode_bits(~punctured, CCTLINFO_G7_W4_ACT_SUBCH_CBW);
h2c->m4 = cpu_to_le32(CCTLINFO_G7_W4_ACT_SUBCH_CBW);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1,
len);
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
rtw89_err(rtwdev, "failed to send h2c\n");
goto fail;
}
return 0;
fail:
dev_kfree_skb_any(skb);
return ret;
}
EXPORT_SYMBOL(rtw89_fw_h2c_punctured_cmac_tbl_g7);
int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
struct rtw89_sta_link *rtwsta_link)
{
@@ -5583,7 +5640,6 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
return 0;
}
#define RTW89_SCAN_DELAY_TSF_UNIT 1000000
int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
struct rtw89_scan_option *option,
struct rtw89_vif_link *rtwvif_link,
@@ -5615,7 +5671,7 @@ int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
scan_mode = RTW89_SCAN_IMMEDIATE;
} else {
scan_mode = RTW89_SCAN_DELAY;
tsf += (u64)option->delay * RTW89_SCAN_DELAY_TSF_UNIT;
tsf += (u64)option->delay * 1000;
}
}
@@ -5701,26 +5757,47 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
{
struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op;
struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
struct cfg80211_scan_request *req = rtwvif->scan_req;
struct rtw89_h2c_scanofld_be_macc_role *macc_role;
struct rtw89_hw_scan_extra_op scan_op[2] = {};
struct rtw89_chan *op = &scan_info->op_chan;
struct rtw89_h2c_scanofld_be_opch *opch;
struct rtw89_pktofld_info *pkt_info;
struct rtw89_h2c_scanofld_be *h2c;
struct ieee80211_vif *vif;
struct sk_buff *skb;
u8 macc_role_size = sizeof(*macc_role) * option->num_macc_role;
u8 opch_size = sizeof(*opch) * option->num_opch;
enum rtw89_scan_be_opmode opmode;
u8 probe_id[NUM_NL80211_BANDS];
u8 scan_offload_ver = U8_MAX;
u8 cfg_len = sizeof(*h2c);
unsigned int cond;
u8 ap_idx = U8_MAX;
u8 ver = U8_MAX;
u8 policy_val;
void *ptr;
u8 txbcn;
int ret;
u32 len;
u8 i;
scan_op[0].macid = rtwvif_link->mac_id;
scan_op[0].port = rtwvif_link->port;
scan_op[0].chan = *op;
vif = rtwvif_to_vif(rtwvif_link->rtwvif);
if (vif->type == NL80211_IFTYPE_AP)
ap_idx = 0;
if (ext->set) {
scan_op[1] = *ext;
vif = rtwvif_to_vif(ext->rtwvif_link->rtwvif);
if (vif->type == NL80211_IFTYPE_AP)
ap_idx = 1;
}
rtw89_scan_get_6g_disabled_chan(rtwdev, option);
if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw)) {
@@ -5781,7 +5858,7 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
RTW89_H2C_SCANOFLD_BE_W4_PROBE_5G) |
le32_encode_bits(probe_id[NL80211_BAND_6GHZ],
RTW89_H2C_SCANOFLD_BE_W4_PROBE_6G) |
le32_encode_bits(option->delay, RTW89_H2C_SCANOFLD_BE_W4_DELAY_START);
le32_encode_bits(option->delay / 1000, RTW89_H2C_SCANOFLD_BE_W4_DELAY_START);
h2c->w5 = le32_encode_bits(option->mlo_mode, RTW89_H2C_SCANOFLD_BE_W5_MLO_MODE);
@@ -5823,29 +5900,35 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
}
for (i = 0; i < option->num_opch; i++) {
bool is_ap_idx = i == ap_idx;
opmode = is_ap_idx ? RTW89_SCAN_OPMODE_TBTT : RTW89_SCAN_OPMODE_INTV;
policy_val = is_ap_idx ? 2 : RTW89_OFF_CHAN_TIME / 10;
txbcn = is_ap_idx ? 1 : 0;
opch = ptr;
opch->w0 = le32_encode_bits(rtwvif_link->mac_id,
opch->w0 = le32_encode_bits(scan_op[i].macid,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_MACID) |
le32_encode_bits(option->band,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_BAND) |
le32_encode_bits(rtwvif_link->port,
le32_encode_bits(scan_op[i].port,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_PORT) |
le32_encode_bits(RTW89_SCAN_OPMODE_INTV,
le32_encode_bits(opmode,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY) |
le32_encode_bits(true,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_TXNULL) |
le32_encode_bits(RTW89_OFF_CHAN_TIME / 10,
le32_encode_bits(policy_val,
RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY_VAL);
opch->w1 = le32_encode_bits(op->band_type,
opch->w1 = le32_encode_bits(scan_op[i].chan.band_type,
RTW89_H2C_SCANOFLD_BE_OPCH_W1_CH_BAND) |
le32_encode_bits(op->band_width,
le32_encode_bits(scan_op[i].chan.band_width,
RTW89_H2C_SCANOFLD_BE_OPCH_W1_BW) |
le32_encode_bits(0x3,
RTW89_H2C_SCANOFLD_BE_OPCH_W1_NOTIFY) |
le32_encode_bits(op->primary_channel,
le32_encode_bits(scan_op[i].chan.primary_channel,
RTW89_H2C_SCANOFLD_BE_OPCH_W1_PRI_CH) |
le32_encode_bits(op->channel,
le32_encode_bits(scan_op[i].chan.channel,
RTW89_H2C_SCANOFLD_BE_OPCH_W1_CENTRAL_CH);
opch->w2 = le32_encode_bits(0,
@@ -5853,7 +5936,9 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
le32_encode_bits(0,
RTW89_H2C_SCANOFLD_BE_OPCH_W2_SW_DEF) |
le32_encode_bits(rtw89_is_mlo_1_1(rtwdev) ? 1 : 2,
RTW89_H2C_SCANOFLD_BE_OPCH_W2_SS);
RTW89_H2C_SCANOFLD_BE_OPCH_W2_SS) |
le32_encode_bits(txbcn,
RTW89_H2C_SCANOFLD_BE_OPCH_W2_TXBCN);
opch->w3 = le32_encode_bits(RTW89_SCANOFLD_PKT_NONE,
RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT0) |
@@ -5985,6 +6070,59 @@ int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
}
EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc);
int rtw89_fw_h2c_mcc_dig(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx chanctx_idx,
u8 mcc_role_idx, u8 pd_val, bool en)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
struct rtw89_h2c_mcc_dig *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
int ret;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c mcc_dig\n");
return -ENOMEM;
}
skb_put(skb, len);
h2c = (struct rtw89_h2c_mcc_dig *)skb->data;
h2c->w0 = le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_REG_CNT) |
le32_encode_bits(en, RTW89_H2C_MCC_DIG_W0_DM_EN) |
le32_encode_bits(mcc_role_idx, RTW89_H2C_MCC_DIG_W0_IDX) |
le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_SET) |
le32_encode_bits(1, RTW89_H2C_MCC_DIG_W0_PHY0_EN) |
le32_encode_bits(chan->channel, RTW89_H2C_MCC_DIG_W0_CENTER_CH) |
le32_encode_bits(chan->band_type, RTW89_H2C_MCC_DIG_W0_BAND_TYPE);
h2c->w1 = le32_encode_bits(dig_regs->seg0_pd_reg,
RTW89_H2C_MCC_DIG_W1_ADDR_LSB) |
le32_encode_bits(dig_regs->seg0_pd_reg >> 8,
RTW89_H2C_MCC_DIG_W1_ADDR_MSB) |
le32_encode_bits(dig_regs->pd_lower_bound_mask,
RTW89_H2C_MCC_DIG_W1_BMASK_LSB) |
le32_encode_bits(dig_regs->pd_lower_bound_mask >> 8,
RTW89_H2C_MCC_DIG_W1_BMASK_MSB);
h2c->w2 = le32_encode_bits(pd_val, RTW89_H2C_MCC_DIG_W2_VAL_LSB);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, H2C_CL_OUTSRC_DM,
H2C_FUNC_FW_MCC_DIG, 0, 0, len);
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
rtw89_err(rtwdev, "failed to send h2c\n");
goto fail;
}
return 0;
fail:
dev_kfree_skb_any(skb);
return ret;
}
int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
@@ -6015,7 +6153,7 @@ int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
path = rtw89_phy_get_syn_sel(rtwdev, rtwvif_link->phy_idx);
val = rtw89_chip_chan_to_rf18_val(rtwdev, chan);
if (path >= chip->rf_path_num) {
if (path >= chip->rf_path_num || path >= NUM_OF_RTW89_FW_RFK_PATH) {
rtw89_err(rtwdev, "unsupported rf path (%d)\n", path);
ret = -ENOENT;
goto fail;
@@ -6621,6 +6759,34 @@ void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work)
}
}
void rtw89_fw_c2h_purge_obsoleted_scan_events(struct rtw89_dev *rtwdev)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
struct sk_buff *skb, *tmp;
int limit;
lockdep_assert_wiphy(rtwdev->hw->wiphy);
limit = skb_queue_len(&rtwdev->c2h_queue);
skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) {
struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb);
if (--limit < 0)
return;
if (!attr->is_scan_event || attr->scan_seq == scan_info->seq)
continue;
rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
"purge obsoleted scan event with seq=%d (cur=%d)\n",
attr->scan_seq, scan_info->seq);
skb_unlink(skb, &rtwdev->c2h_queue);
dev_kfree_skb_any(skb);
}
}
static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev,
struct rtw89_mac_h2c_info *info)
{
@@ -6660,13 +6826,18 @@ static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev,
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_fw_info *fw_info = &rtwdev->fw;
const u32 *c2h_reg = chip->c2h_regs;
u32 ret;
u32 ret, timeout;
u8 i, val;
info->id = RTW89_FWCMD_C2HREG_FUNC_NULL;
if (rtwdev->hci.type == RTW89_HCI_TYPE_USB)
timeout = RTW89_C2H_TIMEOUT_USB;
else
timeout = RTW89_C2H_TIMEOUT;
ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1,
RTW89_C2H_TIMEOUT, false, rtwdev,
timeout, false, rtwdev,
chip->c2h_ctrl_reg);
if (ret) {
rtw89_warn(rtwdev, "c2h reg timeout\n");
@@ -6773,6 +6944,7 @@ static void rtw89_hw_scan_cleanup(struct rtw89_dev *rtwdev,
scan_info->scanning_vif = NULL;
scan_info->abort = false;
scan_info->connected = false;
scan_info->delay = 0;
}
static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev,
@@ -7572,12 +7744,25 @@ static int rtw89_hw_scan_prehandle(struct rtw89_dev *rtwdev,
static void rtw89_hw_scan_update_link_beacon_noa(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
u16 tu)
u16 tu, bool scan)
{
struct ieee80211_p2p_noa_desc noa_desc = {};
struct ieee80211_bss_conf *bss_conf;
u16 beacon_int;
u64 tsf;
int ret;
rcu_read_lock();
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
beacon_int = bss_conf->beacon_int;
rcu_read_unlock();
tu += beacon_int * 3;
if (rtwdev->chip->chip_gen == RTW89_CHIP_AX)
rtwdev->scan_info.delay = ieee80211_tu_to_usec(beacon_int * 3) / 1000;
ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
if (ret) {
rtw89_warn(rtwdev, "%s: failed to get tsf\n", __func__);
@@ -7585,17 +7770,24 @@ static void rtw89_hw_scan_update_link_beacon_noa(struct rtw89_dev *rtwdev,
}
noa_desc.start_time = cpu_to_le32(tsf);
noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(tu));
noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(tu));
noa_desc.count = 1;
if (rtwdev->chip->chip_gen == RTW89_CHIP_AX) {
noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(tu));
noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(tu));
noa_desc.count = 1;
} else {
noa_desc.duration = cpu_to_le32(ieee80211_tu_to_usec(20000));
noa_desc.interval = cpu_to_le32(ieee80211_tu_to_usec(20000));
noa_desc.count = 255;
}
rtw89_p2p_noa_renew(rtwvif_link);
rtw89_p2p_noa_append(rtwvif_link, &noa_desc);
if (scan)
rtw89_p2p_noa_append(rtwvif_link, &noa_desc);
rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link);
}
static void rtw89_hw_scan_update_beacon_noa(struct rtw89_dev *rtwdev,
const struct cfg80211_scan_request *req)
static void rtw89_hw_scan_update_beacon_noa(struct rtw89_dev *rtwdev, bool scan)
{
const struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt;
const struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
@@ -7610,6 +7802,9 @@ static void rtw89_hw_scan_update_beacon_noa(struct rtw89_dev *rtwdev,
lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (!scan)
goto update;
list_for_each_safe(pos, tmp, &scan_info->chan_list) {
switch (chip->chip_gen) {
case RTW89_CHIP_AX:
@@ -7633,6 +7828,7 @@ static void rtw89_hw_scan_update_beacon_noa(struct rtw89_dev *rtwdev,
return;
}
update:
list_for_each_entry(rtwvif, &mgnt->active_list, mgnt_entry) {
unsigned int link_id;
@@ -7641,7 +7837,8 @@ static void rtw89_hw_scan_update_beacon_noa(struct rtw89_dev *rtwdev,
continue;
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
rtw89_hw_scan_update_link_beacon_noa(rtwdev, rtwvif_link, tu);
rtw89_hw_scan_update_link_beacon_noa(rtwdev, rtwvif_link,
tu, scan);
}
}
@@ -7676,7 +7873,9 @@ static void rtw89_hw_scan_set_extra_op_info(struct rtw89_dev *rtwdev,
*ext = (struct rtw89_hw_scan_extra_op){
.set = true,
.macid = tmp_link->mac_id,
.port = tmp_link->port,
.chan = *tmp_chan,
.rtwvif_link = tmp_link,
};
rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
@@ -7717,6 +7916,7 @@ int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
rtwdev->scan_info.connected = rtw89_is_any_vif_connected_or_connecting(rtwdev);
rtwdev->scan_info.scanning_vif = rtwvif_link;
rtwdev->scan_info.abort = false;
rtwdev->scan_info.delay = 0;
rtwvif->scan_ies = &scan_req->ies;
rtwvif->scan_req = req;
@@ -7745,9 +7945,10 @@ int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rx_fltr);
rtw89_chanctx_pause(rtwdev, &pause_parm);
rtw89_phy_dig_suspend(rtwdev);
if (mode == RTW89_ENTITY_MODE_MCC)
rtw89_hw_scan_update_beacon_noa(rtwdev, req);
rtw89_hw_scan_update_beacon_noa(rtwdev, true);
return 0;
}
@@ -7760,6 +7961,7 @@ struct rtw89_hw_scan_complete_cb_data {
static int rtw89_hw_scan_complete_cb(struct rtw89_dev *rtwdev, void *data)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev);
struct rtw89_hw_scan_complete_cb_data *cb_data = data;
struct rtw89_vif_link *rtwvif_link = cb_data->rtwvif_link;
struct cfg80211_scan_info info = {
@@ -7778,9 +7980,13 @@ static int rtw89_hw_scan_complete_cb(struct rtw89_dev *rtwdev, void *data)
ieee80211_wake_queues(rtwdev->hw);
rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, true);
rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true);
rtw89_phy_dig_resume(rtwdev, true);
rtw89_hw_scan_cleanup(rtwdev, rtwvif_link);
if (mode == RTW89_ENTITY_MODE_MCC)
rtw89_hw_scan_update_beacon_noa(rtwdev, false);
return 0;
}
@@ -7847,6 +8053,8 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev,
bool enable)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op;
struct rtw89_scan_option opt = {0};
bool connected;
int ret = 0;
@@ -7857,6 +8065,7 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev,
connected = rtwdev->scan_info.connected;
opt.enable = enable;
opt.target_ch_mode = connected;
opt.delay = rtwdev->scan_info.delay;
if (enable) {
ret = mac->add_chan_list(rtwdev, rtwvif_link);
if (ret)
@@ -7870,49 +8079,62 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev,
opt.num_macc_role = 0;
opt.mlo_mode = rtwdev->mlo_dbcc_mode;
opt.num_opch = connected ? 1 : 0;
if (connected && ext->set)
opt.num_opch++;
opt.opch_end = connected ? 0 : RTW89_CHAN_INVALID;
}
ret = mac->scan_offload(rtwdev, &opt, rtwvif_link, false);
ret = rtw89_mac_scan_offload(rtwdev, &opt, rtwvif_link, false);
out:
return ret;
}
#define H2C_FW_CPU_EXCEPTION_LEN 4
#define H2C_FW_CPU_EXCEPTION_TYPE_DEF 0x5566
#define H2C_FW_CPU_EXCEPTION_TYPE_0 0x5566
#define H2C_FW_CPU_EXCEPTION_TYPE_1 0x0
int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev)
{
struct rtw89_h2c_trig_cpu_except *h2c;
u32 cpu_exception_type_def;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
int ret;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_FW_CPU_EXCEPTION_LEN);
if (RTW89_CHK_FW_FEATURE(CRASH_TRIGGER_TYPE_1, &rtwdev->fw))
cpu_exception_type_def = H2C_FW_CPU_EXCEPTION_TYPE_1;
else if (RTW89_CHK_FW_FEATURE(CRASH_TRIGGER_TYPE_0, &rtwdev->fw))
cpu_exception_type_def = H2C_FW_CPU_EXCEPTION_TYPE_0;
else
return -EOPNOTSUPP;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev,
"failed to alloc skb for fw cpu exception\n");
return -ENOMEM;
}
skb_put(skb, H2C_FW_CPU_EXCEPTION_LEN);
RTW89_SET_FWCMD_CPU_EXCEPTION_TYPE(skb->data,
H2C_FW_CPU_EXCEPTION_TYPE_DEF);
skb_put(skb, len);
h2c = (struct rtw89_h2c_trig_cpu_except *)skb->data;
h2c->w0 = le32_encode_bits(cpu_exception_type_def,
RTW89_H2C_CPU_EXCEPTION_TYPE);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_TEST,
H2C_CL_FW_STATUS_TEST,
H2C_FUNC_CPU_EXCEPTION, 0, 0,
H2C_FW_CPU_EXCEPTION_LEN);
len);
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
rtw89_err(rtwdev, "failed to send h2c\n");
goto fail;
dev_kfree_skb_any(skb);
return ret;
}
return 0;
fail:
dev_kfree_skb_any(skb);
return ret;
}
#define H2C_PKT_DROP_LEN 24

View File

@@ -87,6 +87,9 @@ struct rtw89_c2hreg_phycap {
#define RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_6 GENMASK(7, 0)
#define RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_7 GENMASK(15, 8)
#define RTW89_C2HREG_PS_LEAVE_ACK_RET GENMASK(7, 0)
#define RTW89_C2HREG_PS_LEAVE_ACK_MACID GENMASK(31, 16)
struct rtw89_h2creg_hdr {
u32 w0;
};
@@ -112,6 +115,8 @@ struct rtw89_h2creg_sch_tx_en {
#define RTW89_C2HREG_HDR_LEN 2
#define RTW89_H2CREG_HDR_LEN 2
#define RTW89_C2H_TIMEOUT 1000000
#define RTW89_C2H_TIMEOUT_USB 4000
struct rtw89_mac_c2h_info {
u8 id;
u8 content_len;
@@ -154,6 +159,7 @@ enum rtw89_mac_c2h_type {
RTW89_FWCMD_C2HREG_FUNC_TX_PAUSE_RPT,
RTW89_FWCMD_C2HREG_FUNC_WOW_CPUIO_RX_ACK = 0xA,
RTW89_FWCMD_C2HREG_FUNC_PHY_CAP_PART1 = 0xC,
RTW89_FWCMD_C2HREG_FUNC_PS_LEAVE_ACK = 0xD,
RTW89_FWCMD_C2HREG_FUNC_NULL = 0xFF,
};
@@ -1829,10 +1835,11 @@ struct rtw89_h2c_lps_ml_cmn_info {
u8 dup_bcn_ofst[RTW89_PHY_NUM];
} __packed;
static inline void RTW89_SET_FWCMD_CPU_EXCEPTION_TYPE(void *cmd, u32 val)
{
le32p_replace_bits((__le32 *)cmd, val, GENMASK(31, 0));
}
struct rtw89_h2c_trig_cpu_except {
__le32 w0;
} __packed;
#define RTW89_H2C_CPU_EXCEPTION_TYPE GENMASK(31, 0)
static inline void RTW89_SET_FWCMD_PKT_DROP_SEL(void *cmd, u32 val)
{
@@ -2817,6 +2824,7 @@ struct rtw89_h2c_scanofld_be_opch {
#define RTW89_H2C_SCANOFLD_BE_OPCH_W2_PKTS_CTRL GENMASK(7, 0)
#define RTW89_H2C_SCANOFLD_BE_OPCH_W2_SW_DEF GENMASK(15, 8)
#define RTW89_H2C_SCANOFLD_BE_OPCH_W2_SS GENMASK(18, 16)
#define RTW89_H2C_SCANOFLD_BE_OPCH_W2_TXBCN BIT(19)
#define RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT0 GENMASK(7, 0)
#define RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT1 GENMASK(15, 8)
#define RTW89_H2C_SCANOFLD_BE_OPCH_W3_PKT2 GENMASK(23, 16)
@@ -3564,6 +3572,8 @@ struct rtw89_fw_c2h_attr {
u8 class;
u8 func;
u16 len;
u8 is_scan_event: 1;
u8 scan_seq: 2;
};
static inline struct rtw89_fw_c2h_attr *RTW89_SKB_C2H_CB(struct sk_buff *skb)
@@ -4341,6 +4351,7 @@ enum rtw89_mrc_h2c_func {
#define H2C_FUNC_OUTSRC_RA_MACIDCFG 0x0
#define H2C_CL_OUTSRC_DM 0x2
#define H2C_FUNC_FW_MCC_DIG 0x6
#define H2C_FUNC_FW_LPS_CH_INFO 0xb
#define H2C_FUNC_FW_LPS_ML_CMN_INFO 0xe
@@ -4378,6 +4389,27 @@ struct rtw89_fw_h2c_rf_get_mccch_v0 {
__le32 current_band_type;
} __packed;
struct rtw89_h2c_mcc_dig {
__le32 w0;
__le32 w1;
__le32 w2;
} __packed;
#define RTW89_H2C_MCC_DIG_W0_REG_CNT GENMASK(7, 0)
#define RTW89_H2C_MCC_DIG_W0_DM_EN BIT(8)
#define RTW89_H2C_MCC_DIG_W0_IDX GENMASK(10, 9)
#define RTW89_H2C_MCC_DIG_W0_SET BIT(11)
#define RTW89_H2C_MCC_DIG_W0_PHY0_EN BIT(12)
#define RTW89_H2C_MCC_DIG_W0_PHY1_EN BIT(13)
#define RTW89_H2C_MCC_DIG_W0_CENTER_CH GENMASK(23, 16)
#define RTW89_H2C_MCC_DIG_W0_BAND_TYPE GENMASK(31, 24)
#define RTW89_H2C_MCC_DIG_W1_ADDR_LSB GENMASK(7, 0)
#define RTW89_H2C_MCC_DIG_W1_ADDR_MSB GENMASK(15, 8)
#define RTW89_H2C_MCC_DIG_W1_BMASK_LSB GENMASK(23, 16)
#define RTW89_H2C_MCC_DIG_W1_BMASK_MSB GENMASK(31, 24)
#define RTW89_H2C_MCC_DIG_W2_VAL_LSB GENMASK(7, 0)
#define RTW89_H2C_MCC_DIG_W2_VAL_MSB GENMASK(15, 8)
#define NUM_OF_RTW89_FW_RFK_PATH 2
#define NUM_OF_RTW89_FW_RFK_TBL 3
@@ -4667,6 +4699,7 @@ struct rtw89_c2h_rf_tas_info {
#define RTW89_FW_BACKTRACE_KEY 0xBACEBACE
#define FWDL_WAIT_CNT 400000
#define FWDL_WAIT_CNT_USB 3200
int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type);
int rtw89_fw_recognize(struct rtw89_dev *rtwdev);
@@ -4708,6 +4741,9 @@ int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_txtime_cmac_tbl_g7(struct rtw89_dev *rtwdev,
struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_punctured_cmac_tbl_g7(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
u16 punctured);
int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
@@ -4724,6 +4760,7 @@ int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev,
struct rtw89_sta_link *rtwsta_link);
void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h);
void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_fw_c2h_purge_obsoleted_scan_events(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
@@ -4774,6 +4811,9 @@ int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx);
int rtw89_fw_h2c_mcc_dig(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx chanctx_idx,
u8 mcc_role_idx, u8 pd_val, bool en);
int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
const struct rtw89_chan *chan, enum rtw89_tssi_mode tssi_mode);
int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
@@ -5007,6 +5047,19 @@ int rtw89_chip_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
return chip->ops->h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
}
static inline
int rtw89_chip_h2c_punctured_cmac_tbl(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
u16 punctured)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (!chip->ops->h2c_punctured_cmac_tbl)
return 0;
return chip->ops->h2c_punctured_cmac_tbl(rtwdev, rtwvif_link, punctured);
}
static inline
int rtw89_chip_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
bool valid, struct ieee80211_ampdu_params *params)

View File

@@ -88,7 +88,7 @@ int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val)
ret = read_poll_timeout(rtw89_read8, lte_ctrl, (lte_ctrl & BIT(5)) != 0,
50, 50000, false, rtwdev, R_AX_LTE_CTRL + 3);
if (ret)
if (ret && !test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
rtw89_err(rtwdev, "[ERR]lte not ready(W)\n");
rtw89_write32(rtwdev, R_AX_LTE_WDATA, val);
@@ -104,7 +104,7 @@ int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val)
ret = read_poll_timeout(rtw89_read8, lte_ctrl, (lte_ctrl & BIT(5)) != 0,
50, 50000, false, rtwdev, R_AX_LTE_CTRL + 3);
if (ret)
if (ret && !test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
rtw89_err(rtwdev, "[ERR]lte not ready(W)\n");
rtw89_write32(rtwdev, R_AX_LTE_CTRL, 0x800F0000 | offset);
@@ -875,31 +875,30 @@ EXPORT_SYMBOL(rtw89_mac_set_err_status);
static int hfc_reset_param(struct rtw89_dev *rtwdev)
{
const struct rtw89_hfc_param_ini *param_ini, *param_inis;
struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
struct rtw89_hfc_param_ini param_ini = {NULL};
u8 qta_mode = rtwdev->mac.dle_info.qta_mode;
switch (rtwdev->hci.type) {
case RTW89_HCI_TYPE_PCIE:
param_ini = rtwdev->chip->hfc_param_ini[qta_mode];
param->en = 0;
break;
default:
param_inis = rtwdev->chip->hfc_param_ini[rtwdev->hci.type];
if (!param_inis)
return -EINVAL;
}
if (param_ini.pub_cfg)
param->pub_cfg = *param_ini.pub_cfg;
param_ini = &param_inis[qta_mode];
if (param_ini.prec_cfg)
param->prec_cfg = *param_ini.prec_cfg;
param->en = 0;
if (param_ini.ch_cfg)
param->ch_cfg = param_ini.ch_cfg;
if (param_ini->pub_cfg)
param->pub_cfg = *param_ini->pub_cfg;
if (param_ini->prec_cfg)
param->prec_cfg = *param_ini->prec_cfg;
if (param_ini->ch_cfg)
param->ch_cfg = param_ini->ch_cfg;
memset(&param->ch_info, 0, sizeof(param->ch_info));
memset(&param->pub_info, 0, sizeof(param->pub_info));
param->mode = param_ini.mode;
param->mode = param_ini->mode;
return 0;
}
@@ -1441,6 +1440,23 @@ void rtw89_mac_notify_wake(struct rtw89_dev *rtwdev)
rtw89_mac_send_rpwm(rtwdev, state, true);
}
static void rtw89_mac_power_switch_boot_mode(struct rtw89_dev *rtwdev)
{
u32 boot_mode;
if (rtwdev->hci.type != RTW89_HCI_TYPE_USB)
return;
boot_mode = rtw89_read32_mask(rtwdev, R_AX_GPIO_MUXCFG, B_AX_BOOT_MODE);
if (!boot_mode)
return;
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC);
rtw89_write32_clr(rtwdev, R_AX_SYS_STATUS1, B_AX_AUTO_WLPON);
rtw89_write32_clr(rtwdev, R_AX_GPIO_MUXCFG, B_AX_BOOT_MODE);
rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST);
}
static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
{
#define PWR_ACT 1
@@ -1451,6 +1467,8 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
int ret;
u8 val;
rtw89_mac_power_switch_boot_mode(rtwdev);
if (on) {
cfg_seq = chip->pwr_on_seq;
cfg_func = chip->ops->pwr_on_func;
@@ -1646,6 +1664,8 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
/* 8852C PCIE SCC */
.wde_size19 = {RTW89_WDE_PG_64, 3328, 0,},
.wde_size23 = {RTW89_WDE_PG_64, 1022, 2,},
/* 8852B USB2.0/USB3.0 SCC */
.wde_size25 = {RTW89_WDE_PG_64, 162, 94,},
/* PCIE */
.ple_size0 = {RTW89_PLE_PG_128, 1520, 16,},
.ple_size0_v1 = {RTW89_PLE_PG_128, 2688, 240, 212992,},
@@ -1661,6 +1681,10 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
.ple_size18 = {RTW89_PLE_PG_128, 2544, 16,},
/* 8852C PCIE SCC */
.ple_size19 = {RTW89_PLE_PG_128, 1904, 16,},
/* 8852B USB2.0 SCC */
.ple_size32 = {RTW89_PLE_PG_128, 620, 20,},
/* 8852B USB3.0 SCC */
.ple_size33 = {RTW89_PLE_PG_128, 632, 8,},
/* PCIE 64 */
.wde_qt0 = {3792, 196, 0, 107,},
.wde_qt0_v1 = {3302, 6, 0, 20,},
@@ -1675,6 +1699,8 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
/* 8852C PCIE SCC */
.wde_qt18 = {3228, 60, 0, 40,},
.wde_qt23 = {958, 48, 0, 16,},
/* 8852B USB2.0/USB3.0 SCC */
.wde_qt25 = {152, 2, 0, 8,},
.ple_qt0 = {320, 320, 32, 16, 13, 13, 292, 292, 64, 18, 1, 4, 0,},
.ple_qt1 = {320, 320, 32, 16, 1316, 1316, 1595, 1595, 1367, 1321, 1, 1307, 0,},
/* PCIE SCC */
@@ -1698,6 +1724,13 @@ const struct rtw89_mac_size_set rtw89_mac_size = {
/* PCIE 64 */
.ple_qt58 = {147, 0, 16, 20, 157, 13, 229, 0, 172, 14, 24, 0,},
.ple_qt59 = {147, 0, 32, 20, 1860, 13, 2025, 0, 1879, 14, 24, 0,},
/* USB2.0 52B SCC */
.ple_qt72 = {130, 0, 16, 48, 4, 13, 322, 0, 32, 14, 8, 0, 0,},
/* USB2.0 52B 92K */
.ple_qt73 = {130, 0, 32, 48, 37, 13, 355, 0, 65, 14, 24, 0, 0,},
/* USB3.0 52B 92K */
.ple_qt74 = {286, 0, 16, 48, 4, 13, 178, 0, 32, 14, 8, 0, 0,},
.ple_qt75 = {286, 0, 32, 48, 37, 13, 211, 0, 65, 14, 24, 0, 0,},
/* 8852A PCIE WOW */
.ple_qt_52a_wow = {264, 0, 32, 20, 64, 13, 1005, 0, 64, 128, 120,},
/* 8852B PCIE WOW */
@@ -1717,12 +1750,13 @@ static const struct rtw89_dle_mem *get_dle_mem_cfg(struct rtw89_dev *rtwdev,
enum rtw89_qta_mode mode)
{
struct rtw89_mac_info *mac = &rtwdev->mac;
const struct rtw89_dle_mem *cfg;
const struct rtw89_dle_mem *cfg, *cfgs;
cfg = &rtwdev->chip->dle_mem[mode];
if (!cfg)
cfgs = rtwdev->chip->dle_mem[rtwdev->hci.dle_type];
if (!cfgs)
return NULL;
cfg = &cfgs[mode];
if (cfg->mode != mode) {
rtw89_warn(rtwdev, "qta mode unmatch!\n");
return NULL;
@@ -5015,6 +5049,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
if (rtwvif_link && rtwvif->scan_req &&
!list_empty(&rtwdev->scan_info.chan_list)) {
rtwdev->scan_info.delay = 0;
ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, true);
if (ret) {
rtw89_hw_scan_abort(rtwdev, rtwvif_link);
@@ -5053,6 +5088,7 @@ rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_l
const struct rtw89_c2h_mac_bcnfltr_rpt *c2h =
(const struct rtw89_c2h_mac_bcnfltr_rpt *)skb->data;
u8 type, event, mac_id;
bool start_detect;
s8 sig;
type = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_TYPE);
@@ -5070,10 +5106,15 @@ rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_l
switch (type) {
case RTW89_BCN_FLTR_BEACON_LOSS:
if (!rtwdev->scanning && !rtwvif->offchan &&
!rtwvif_link->noa_once.in_duration)
!rtwvif_link->noa_once.in_duration) {
start_detect = rtw89_mcc_detect_go_bcn(rtwdev, rtwvif_link);
if (start_detect)
return;
ieee80211_connection_loss(vif);
else
} else {
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
}
return;
case RTW89_BCN_FLTR_NOTIFY:
nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
@@ -5124,6 +5165,7 @@ rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 le
{
/* N.B. This will run in interrupt context. */
struct rtw89_wait_info *fw_ofld_wait = &rtwdev->mac.fw_ofld_wait;
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
struct rtw89_wait_info *ps_wait = &rtwdev->mac.ps_wait;
const struct rtw89_c2h_done_ack *c2h =
(const struct rtw89_c2h_done_ack *)skb_c2h->data;
@@ -5166,9 +5208,11 @@ rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 le
h2c_return &= RTW89_C2H_SCAN_DONE_ACK_RETURN;
break;
case H2C_FUNC_SCANOFLD:
scan_info->seq++;
cond = RTW89_SCANOFLD_WAIT_COND_START;
break;
case H2C_FUNC_SCANOFLD_BE:
scan_info->seq++;
cond = RTW89_SCANOFLD_BE_WAIT_COND_START;
h2c_return &= RTW89_C2H_SCAN_DONE_ACK_RETURN;
break;
@@ -5665,10 +5709,15 @@ static void rtw89_mac_c2h_scanofld_rsp_atomic(struct rtw89_dev *rtwdev,
const struct rtw89_c2h_scanofld *c2h =
(const struct rtw89_c2h_scanofld *)skb->data;
struct rtw89_wait_info *fw_ofld_wait = &rtwdev->mac.fw_ofld_wait;
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb);
struct rtw89_completion_data data = {};
unsigned int cond;
u8 status, reason;
attr->is_scan_event = 1;
attr->scan_seq = scan_info->seq;
status = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_STATUS);
reason = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_RSN);
data.err = status != RTW89_SCAN_STATUS_SUCCESS;
@@ -5824,7 +5873,7 @@ int rtw89_mac_cfg_ppdu_status_ax(struct rtw89_dev *rtwdev, u8 mac_idx, bool enab
rtw89_write32(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN |
B_AX_APP_MAC_INFO_RPT |
B_AX_APP_RX_CNT_RPT | B_AX_APP_PLCP_HDR_RPT |
B_AX_APP_PLCP_HDR_RPT |
B_AX_PPDU_STAT_RPT_CRC32);
rtw89_write32_mask(rtwdev, R_AX_HW_RPT_FWD, B_AX_FWD_PPDU_STAT_MASK,
RTW89_PRPT_DEST_HOST);
@@ -5907,13 +5956,15 @@ int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex
ret = rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_2, &val32);
if (ret) {
rtw89_err(rtwdev, "Read R_AX_LTE_SW_CFG_2 fail!\n");
if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
rtw89_err(rtwdev, "Read R_AX_LTE_SW_CFG_2 fail!\n");
return ret;
}
val32 = val32 & B_AX_WL_RX_CTRL;
ret = rtw89_mac_write_lte(rtwdev, R_AX_LTE_SW_CFG_2, val32);
if (ret) {
rtw89_err(rtwdev, "Write R_AX_LTE_SW_CFG_2 fail!\n");
if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
rtw89_err(rtwdev, "Write R_AX_LTE_SW_CFG_2 fail!\n");
return ret;
}
@@ -6037,7 +6088,8 @@ int rtw89_mac_cfg_gnt(struct rtw89_dev *rtwdev,
ret = rtw89_mac_write_lte(rtwdev, R_AX_LTE_SW_CFG_1, val);
if (ret) {
rtw89_err(rtwdev, "Write LTE fail!\n");
if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
rtw89_err(rtwdev, "Write LTE fail!\n");
return ret;
}
@@ -6888,10 +6940,16 @@ int rtw89_fwdl_check_path_ready_ax(struct rtw89_dev *rtwdev,
bool h2c_or_fwdl)
{
u8 check = h2c_or_fwdl ? B_AX_H2C_PATH_RDY : B_AX_FWDL_PATH_RDY;
u32 timeout;
u8 val;
if (rtwdev->hci.type == RTW89_HCI_TYPE_USB)
timeout = FWDL_WAIT_CNT_USB;
else
timeout = FWDL_WAIT_CNT;
return read_poll_timeout_atomic(rtw89_read8, val, val & check,
1, FWDL_WAIT_CNT, false,
1, timeout, false,
rtwdev, R_AX_WCPU_FW_CTRL);
}

View File

@@ -6,6 +6,7 @@
#define __RTW89_MAC_H__
#include "core.h"
#include "fw.h"
#include "reg.h"
#define MAC_MEM_DUMP_PAGE_SIZE_AX 0x40000
@@ -924,6 +925,7 @@ struct rtw89_mac_size_set {
const struct rtw89_dle_size wde_size18;
const struct rtw89_dle_size wde_size19;
const struct rtw89_dle_size wde_size23;
const struct rtw89_dle_size wde_size25;
const struct rtw89_dle_size ple_size0;
const struct rtw89_dle_size ple_size0_v1;
const struct rtw89_dle_size ple_size3_v1;
@@ -933,6 +935,8 @@ struct rtw89_mac_size_set {
const struct rtw89_dle_size ple_size9;
const struct rtw89_dle_size ple_size18;
const struct rtw89_dle_size ple_size19;
const struct rtw89_dle_size ple_size32;
const struct rtw89_dle_size ple_size33;
const struct rtw89_wde_quota wde_qt0;
const struct rtw89_wde_quota wde_qt0_v1;
const struct rtw89_wde_quota wde_qt4;
@@ -941,6 +945,7 @@ struct rtw89_mac_size_set {
const struct rtw89_wde_quota wde_qt17;
const struct rtw89_wde_quota wde_qt18;
const struct rtw89_wde_quota wde_qt23;
const struct rtw89_wde_quota wde_qt25;
const struct rtw89_ple_quota ple_qt0;
const struct rtw89_ple_quota ple_qt1;
const struct rtw89_ple_quota ple_qt4;
@@ -955,6 +960,10 @@ struct rtw89_mac_size_set {
const struct rtw89_ple_quota ple_qt57;
const struct rtw89_ple_quota ple_qt58;
const struct rtw89_ple_quota ple_qt59;
const struct rtw89_ple_quota ple_qt72;
const struct rtw89_ple_quota ple_qt73;
const struct rtw89_ple_quota ple_qt74;
const struct rtw89_ple_quota ple_qt75;
const struct rtw89_ple_quota ple_qt_52a_wow;
const struct rtw89_ple_quota ple_qt_52b_wow;
const struct rtw89_ple_quota ple_qt_52bt_wow;
@@ -1575,4 +1584,28 @@ void rtw89_fwdl_secure_idmem_share_mode(struct rtw89_dev *rtwdev, u8 mode)
return mac->fwdl_secure_idmem_share_mode(rtwdev, mode);
}
static inline
int rtw89_mac_scan_offload(struct rtw89_dev *rtwdev,
struct rtw89_scan_option *option,
struct rtw89_vif_link *rtwvif_link,
bool wowlan)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
int ret;
ret = mac->scan_offload(rtwdev, option, rtwvif_link, wowlan);
if (option->enable) {
/*
* At this point, new scan request is acknowledged by firmware,
* so scan events of previous scan request become obsoleted.
* Purge the queued scan events to prevent interference to
* current new request.
*/
rtw89_fw_c2h_purge_obsoleted_scan_events(rtwdev);
}
return ret;
}
#endif

View File

@@ -113,6 +113,8 @@ static int __rtw89_ops_add_iface_link(struct rtw89_dev *rtwdev,
wiphy_work_init(&rtwvif_link->update_beacon_work, rtw89_core_update_beacon_work);
wiphy_delayed_work_init(&rtwvif_link->csa_beacon_work, rtw89_core_csa_beacon_work);
wiphy_delayed_work_init(&rtwvif_link->mcc_gc_detect_beacon_work,
rtw89_mcc_gc_detect_beacon_work);
INIT_LIST_HEAD(&rtwvif_link->general_pkt_list);
@@ -124,6 +126,7 @@ static int __rtw89_ops_add_iface_link(struct rtw89_dev *rtwdev,
rtwvif_link->chanctx_idx = RTW89_CHANCTX_0;
rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
rtwvif_link->rand_tsf_done = false;
rtwvif_link->detect_bcn_count = 0;
rcu_read_lock();
@@ -147,6 +150,8 @@ static void __rtw89_ops_remove_iface_link(struct rtw89_dev *rtwdev,
wiphy_work_cancel(rtwdev->hw->wiphy, &rtwvif_link->update_beacon_work);
wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwvif_link->csa_beacon_work);
wiphy_delayed_work_cancel(rtwdev->hw->wiphy,
&rtwvif_link->mcc_gc_detect_beacon_work);
rtw89_p2p_noa_once_deinit(rtwvif_link);
@@ -1772,6 +1777,7 @@ static int rtw89_ops_suspend(struct ieee80211_hw *hw,
set_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags);
wiphy_delayed_work_cancel(hw->wiphy, &rtwdev->track_work);
wiphy_delayed_work_cancel(hw->wiphy, &rtwdev->track_ps_work);
ret = rtw89_wow_suspend(rtwdev, wowlan);
if (ret) {
@@ -1797,6 +1803,8 @@ static int rtw89_ops_resume(struct ieee80211_hw *hw)
clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags);
wiphy_delayed_work_queue(hw->wiphy, &rtwdev->track_work,
RTW89_TRACK_WORK_PERIOD);
wiphy_delayed_work_queue(hw->wiphy, &rtwdev->track_ps_work,
RTW89_TRACK_PS_WORK_PERIOD);
return ret ? 1 : 0;
}

View File

@@ -2638,6 +2638,10 @@ static void rtw89_pci_set_dbg(struct rtw89_dev *rtwdev)
rtw89_write32_set(rtwdev, R_AX_PCIE_DBG_CTRL,
B_AX_ASFF_FULL_NO_STK | B_AX_EN_STUCK_DBG);
rtw89_write32_mask(rtwdev, R_AX_PCIE_EXP_CTRL,
B_AX_EN_STUCK_DBG | B_AX_ASFF_FULL_NO_STK,
B_AX_EN_STUCK_DBG);
if (rtwdev->chip->chip_id == RTL8852A)
rtw89_write32_set(rtwdev, R_AX_PCIE_EXP_CTRL,
B_AX_EN_CHKDSC_NO_RX_STUCK);
@@ -4486,6 +4490,7 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
rtwdev->pci_info = info->bus.pci;
rtwdev->hci.ops = &rtw89_pci_ops;
rtwdev->hci.type = RTW89_HCI_TYPE_PCIE;
rtwdev->hci.dle_type = RTW89_HCI_DLE_TYPE_PCIE;
rtwdev->hci.rpwm_addr = pci_info->rpwm_addr;
rtwdev->hci.cpwm_addr = pci_info->cpwm_addr;

View File

@@ -897,7 +897,8 @@ static u32 rtw89_phy_read_rf_a(struct rtw89_dev *rtwdev,
30, false, rtwdev, R_SWSI_V1,
B_SWSI_R_DATA_DONE_V1);
if (ret) {
rtw89_err(rtwdev, "read swsi busy\n");
if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
rtw89_err(rtwdev, "read swsi busy\n");
return INV_RF_DATA;
}
@@ -6315,18 +6316,13 @@ static void rtw89_phy_dig_config_igi(struct rtw89_dev *rtwdev,
}
}
static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev,
struct rtw89_bb_ctx *bb,
u8 rssi, bool enable)
static u8 rtw89_phy_dig_cal_under_region(struct rtw89_dev *rtwdev,
struct rtw89_bb_ctx *bb,
const struct rtw89_chan *chan)
{
const struct rtw89_chan *chan = rtw89_mgnt_chan_get(rtwdev, bb->phy_idx);
const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
enum rtw89_bandwidth cbw = chan->band_width;
struct rtw89_dig_info *dig = &bb->dig;
u8 final_rssi = 0, under_region = dig->pd_low_th_ofst;
u8 ofdm_cca_th;
s8 cck_cca_th;
u32 pd_val = 0;
u8 under_region = dig->pd_low_th_ofst;
if (rtwdev->chip->chip_gen == RTW89_CHIP_AX)
under_region += PD_TH_SB_FLTR_CMP_VAL;
@@ -6348,6 +6344,20 @@ static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev,
break;
}
return under_region;
}
static u32 __rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev,
struct rtw89_bb_ctx *bb,
u8 rssi, bool enable,
const struct rtw89_chan *chan)
{
struct rtw89_dig_info *dig = &bb->dig;
u8 ofdm_cca_th, under_region;
u8 final_rssi;
u32 pd_val;
under_region = rtw89_phy_dig_cal_under_region(rtwdev, bb, chan);
dig->dyn_pd_th_max = dig->igi_rssi;
final_rssi = min_t(u8, rssi, dig->igi_rssi);
@@ -6360,10 +6370,28 @@ static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev,
"igi=%d, ofdm_ccaTH=%d, backoff=%d, PD_low=%d\n",
final_rssi, ofdm_cca_th, under_region, pd_val);
} else {
pd_val = 0;
rtw89_debug(rtwdev, RTW89_DBG_DIG,
"Dynamic PD th disabled, Set PD_low_bd=0\n");
}
return pd_val;
}
static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev,
struct rtw89_bb_ctx *bb,
u8 rssi, bool enable)
{
const struct rtw89_chan *chan = rtw89_mgnt_chan_get(rtwdev, bb->phy_idx);
const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
struct rtw89_dig_info *dig = &bb->dig;
u8 final_rssi, under_region = dig->pd_low_th_ofst;
s8 cck_cca_th;
u32 pd_val;
pd_val = __rtw89_phy_dig_dyn_pd_th(rtwdev, bb, rssi, enable, chan);
dig->bak_dig = pd_val;
rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
dig_regs->pd_lower_bound_mask, pd_val, bb->phy_idx);
rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
@@ -6372,6 +6400,8 @@ static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev,
if (!rtwdev->hal.support_cckpd)
return;
final_rssi = min_t(u8, rssi, dig->igi_rssi);
under_region = rtw89_phy_dig_cal_under_region(rtwdev, bb, chan);
cck_cca_th = max_t(s8, final_rssi - under_region, CCKPD_TH_MIN_RSSI);
pd_val = (u32)(cck_cca_th - IGI_RSSI_MAX);
@@ -6399,32 +6429,12 @@ void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
#define IGI_RSSI_MIN 10
#define ABS_IGI_MIN 0xc
static void __rtw89_phy_dig(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
static
void rtw89_phy_cal_igi_fa_rssi(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
{
struct rtw89_dig_info *dig = &bb->dig;
bool is_linked = rtwdev->total_sta_assoc > 0;
u8 igi_min;
if (unlikely(dig->bypass_dig)) {
dig->bypass_dig = false;
return;
}
rtw89_debug(rtwdev, RTW89_DBG_DIG, "BB-%d dig track\n", bb->phy_idx);
rtw89_phy_dig_update_rssi_info(rtwdev, bb);
if (!dig->is_linked_pre && is_linked) {
rtw89_debug(rtwdev, RTW89_DBG_DIG, "First connected\n");
rtw89_phy_dig_update_para(rtwdev, bb);
dig->igi_fa_rssi = dig->igi_rssi;
} else if (dig->is_linked_pre && !is_linked) {
rtw89_debug(rtwdev, RTW89_DBG_DIG, "First disconnected\n");
rtw89_phy_dig_update_para(rtwdev, bb);
dig->igi_fa_rssi = dig->igi_rssi;
}
dig->is_linked_pre = is_linked;
rtw89_phy_dig_igi_offset_by_env(rtwdev, bb);
igi_min = max_t(int, dig->igi_rssi - IGI_RSSI_MIN, 0);
@@ -6438,6 +6448,173 @@ static void __rtw89_phy_dig(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
} else {
dig->igi_fa_rssi = dig->dyn_igi_max;
}
}
struct rtw89_phy_iter_mcc_dig {
struct rtw89_vif_link *rtwvif_link;
bool has_sta;
u8 rssi_min;
};
static void rtw89_phy_set_mcc_dig(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_bb_ctx *bb,
u8 rssi_min, u8 mcc_role_idx,
bool is_linked)
{
struct rtw89_dig_info *dig = &bb->dig;
const struct rtw89_chan *chan;
u8 pd_val;
if (is_linked) {
dig->igi_rssi = rssi_min >> 1;
dig->igi_fa_rssi = dig->igi_rssi;
} else {
rtw89_debug(rtwdev, RTW89_DBG_DIG, "RSSI update : NO Link\n");
dig->igi_rssi = rssi_nolink;
dig->igi_fa_rssi = dig->igi_rssi;
}
chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
rtw89_phy_cal_igi_fa_rssi(rtwdev, bb);
pd_val = __rtw89_phy_dig_dyn_pd_th(rtwdev, bb, dig->igi_fa_rssi,
is_linked, chan);
rtw89_fw_h2c_mcc_dig(rtwdev, rtwvif_link->chanctx_idx,
mcc_role_idx, pd_val, true);
rtw89_debug(rtwdev, RTW89_DBG_DIG,
"MCC chanctx_idx %d chan %d rssi %d pd_val %d",
rtwvif_link->chanctx_idx, chan->primary_channel,
dig->igi_rssi, pd_val);
}
static void rtw89_phy_set_mcc_dig_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_phy_iter_mcc_dig *mcc_dig = (struct rtw89_phy_iter_mcc_dig *)data;
unsigned int link_id = mcc_dig->rtwvif_link->link_id;
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_sta_link *rtwsta_link;
if (rtwsta->rtwvif != mcc_dig->rtwvif_link->rtwvif)
return;
rtwsta_link = rtwsta->links[link_id];
if (!rtwsta_link)
return;
mcc_dig->has_sta = true;
if (ewma_rssi_read(&rtwsta_link->avg_rssi) < mcc_dig->rssi_min)
mcc_dig->rssi_min = ewma_rssi_read(&rtwsta_link->avg_rssi);
}
static void rtw89_phy_dig_mcc(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
{
struct rtw89_phy_iter_mcc_dig mcc_dig;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_mcc_links_info info;
int i;
rtw89_mcc_get_links(rtwdev, &info);
for (i = 0; i < ARRAY_SIZE(info.links); i++) {
rtwvif_link = info.links[i];
if (!rtwvif_link)
continue;
memset(&mcc_dig, 0, sizeof(mcc_dig));
mcc_dig.rtwvif_link = rtwvif_link;
mcc_dig.has_sta = false;
mcc_dig.rssi_min = U8_MAX;
ieee80211_iterate_stations_atomic(rtwdev->hw,
rtw89_phy_set_mcc_dig_iter,
&mcc_dig);
rtw89_phy_set_mcc_dig(rtwdev, rtwvif_link, bb,
mcc_dig.rssi_min, i, mcc_dig.has_sta);
}
}
static void rtw89_phy_dig_ctrl(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb,
bool pause_dig, bool restore)
{
const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
struct rtw89_dig_info *dig = &bb->dig;
bool en_dig;
u32 pd_val;
if (dig->pause_dig == pause_dig)
return;
if (pause_dig) {
en_dig = false;
pd_val = 0;
} else {
en_dig = rtwdev->total_sta_assoc > 0;
pd_val = restore ? dig->bak_dig : 0;
}
rtw89_debug(rtwdev, RTW89_DBG_DIG, "%s <%s> PD_low=%d", __func__,
pause_dig ? "suspend" : "resume", pd_val);
rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
dig_regs->pd_lower_bound_mask, pd_val, bb->phy_idx);
rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
dig_regs->pd_spatial_reuse_en, en_dig, bb->phy_idx);
dig->pause_dig = pause_dig;
}
void rtw89_phy_dig_suspend(struct rtw89_dev *rtwdev)
{
struct rtw89_bb_ctx *bb;
rtw89_for_each_active_bb(rtwdev, bb)
rtw89_phy_dig_ctrl(rtwdev, bb, true, false);
}
void rtw89_phy_dig_resume(struct rtw89_dev *rtwdev, bool restore)
{
struct rtw89_bb_ctx *bb;
rtw89_for_each_active_bb(rtwdev, bb)
rtw89_phy_dig_ctrl(rtwdev, bb, false, restore);
}
static void __rtw89_phy_dig(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
{
struct rtw89_dig_info *dig = &bb->dig;
bool is_linked = rtwdev->total_sta_assoc > 0;
enum rtw89_entity_mode mode;
if (unlikely(dig->bypass_dig)) {
dig->bypass_dig = false;
return;
}
rtw89_debug(rtwdev, RTW89_DBG_DIG, "BB-%d dig track\n", bb->phy_idx);
rtw89_phy_dig_update_rssi_info(rtwdev, bb);
mode = rtw89_get_entity_mode(rtwdev);
if (mode == RTW89_ENTITY_MODE_MCC) {
rtw89_phy_dig_mcc(rtwdev, bb);
return;
}
if (unlikely(dig->pause_dig))
return;
if (!dig->is_linked_pre && is_linked) {
rtw89_debug(rtwdev, RTW89_DBG_DIG, "First connected\n");
rtw89_phy_dig_update_para(rtwdev, bb);
dig->igi_fa_rssi = dig->igi_rssi;
} else if (dig->is_linked_pre && !is_linked) {
rtw89_debug(rtwdev, RTW89_DBG_DIG, "First disconnected\n");
rtw89_phy_dig_update_para(rtwdev, bb);
dig->igi_fa_rssi = dig->igi_rssi;
}
dig->is_linked_pre = is_linked;
rtw89_phy_cal_igi_fa_rssi(rtwdev, bb);
rtw89_debug(rtwdev, RTW89_DBG_DIG,
"rssi=%03d, dyn_joint(max,min)=(%d,%d), final_rssi=%d\n",

View File

@@ -1010,6 +1010,8 @@ void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
u32 val);
void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb);
void rtw89_phy_dig(struct rtw89_dev *rtwdev);
void rtw89_phy_dig_suspend(struct rtw89_dev *rtwdev);
void rtw89_phy_dig_resume(struct rtw89_dev *rtwdev, bool restore);
void rtw89_phy_tx_path_div_track(struct rtw89_dev *rtwdev);
void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu);

View File

@@ -13,6 +13,31 @@
#include "reg.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 = {};
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)
return ret;
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");
return 0;
}
static int rtw89_fw_leave_lps_check(struct rtw89_dev *rtwdev, u8 macid)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
@@ -106,7 +131,8 @@ static void __rtw89_leave_lps(struct rtw89_dev *rtwdev,
};
rtw89_fw_h2c_lps_parm(rtwdev, &lps_param);
rtw89_fw_leave_lps_check(rtwdev, 0);
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);
}

View File

@@ -21,6 +21,7 @@
#define R_AX_SYS_PW_CTRL 0x0004
#define B_AX_SOP_ASWRM BIT(31)
#define B_AX_SOP_PWMM_DSWR BIT(29)
#define B_AX_SOP_EDSWR BIT(28)
#define B_AX_XTAL_OFF_A_DIE BIT(22)
#define B_AX_DIS_WLBT_PDNSUSEN_SOPC BIT(18)
#define B_AX_RDY_SYSPWR BIT(17)
@@ -182,6 +183,7 @@
#define R_AX_SYS_STATUS1 0x00F4
#define B_AX_SEL_0XC0_MASK GENMASK(17, 16)
#define B_AX_AUTO_WLPON BIT(10)
#define B_AX_PAD_HCI_SEL_V2_MASK GENMASK(5, 3)
#define MAC_AX_HCI_SEL_SDIO_UART 0
#define MAC_AX_HCI_SEL_MULTI_USB 1
@@ -380,6 +382,18 @@
#define B_AX_ACH1_BUSY BIT(9)
#define B_AX_ACH0_BUSY BIT(8)
#define R_AX_USB_ENDPOINT_0 0x1060
#define B_AX_EP_IDX GENMASK(3, 0)
#define R_AX_USB_ENDPOINT_2 0x1068
#define NUMP 0x1
#define R_AX_USB_HOST_REQUEST_2 0x1078
#define B_AX_R_USBIO_MODE BIT(4)
#define R_AX_USB3_MAC_NPI_CONFIG_INTF_0 0x1114
#define B_AX_SSPHY_LFPS_FILTER BIT(31)
#define R_AX_USB_WLAN0_1 0x1174
#define B_AX_USBRX_RST BIT(9)
#define B_AX_USBTX_RST BIT(8)
#define R_AX_PCIE_DBG_CTRL 0x11C0
#define B_AX_DBG_DUMMY_MASK GENMASK(23, 16)
#define B_AX_PCIE_DBG_SEL_MASK GENMASK(15, 13)
@@ -459,6 +473,17 @@
#define R_AX_WP_PAGE_CTRL2_V1 0x17A4
#define R_AX_WP_PAGE_INFO1_V1 0x17A8
#define R_AX_USB_ENDPOINT_0_V1 0x5060
#define B_AX_EP_IDX_V1 GENMASK(3, 0)
#define R_AX_USB_ENDPOINT_2_V1 0x5068
#define R_AX_USB_HOST_REQUEST_2_V1 0x5078
#define B_AX_R_USBIO_MODE_V1 BIT(4)
#define R_AX_USB3_MAC_NPI_CONFIG_INTF_0_V1 0x5114
#define B_AX_SSPHY_LFPS_FILTER_V1 BIT(31)
#define R_AX_USB_WLAN0_1_V1 0x5174
#define B_AX_USBRX_RST_V1 BIT(9)
#define B_AX_USBTX_RST_V1 BIT(8)
#define R_AX_H2CREG_DATA0_V1 0x7140
#define R_AX_H2CREG_DATA1_V1 0x7144
#define R_AX_H2CREG_DATA2_V1 0x7148
@@ -1025,6 +1050,12 @@
#define B_AX_DISPATCHER_INTN_SEL_MASK GENMASK(7, 4)
#define B_AX_DISPATCHER_CH_SEL_MASK GENMASK(3, 0)
#define R_AX_RXDMA_SETTING 0x8908
#define B_AX_BULK_SIZE GENMASK(1, 0)
#define USB11_BULKSIZE 0x2
#define USB2_BULKSIZE 0x1
#define USB3_BULKSIZE 0x0
#define R_AX_RX_FUNCTION_STOP 0x8920
#define B_AX_HDR_RX_STOP BIT(0)
@@ -8775,6 +8806,8 @@
#define B_P0_TSSI_RFC GENMASK(28, 27)
#define B_P0_TSSI_OFT_EN BIT(28)
#define B_P0_TSSI_OFT GENMASK(7, 0)
#define R_P0_TSSI_SLOPE_CAL 0x581c
#define B_P0_TSSI_SLOPE_CAL_EN BIT(20)
#define R_P0_TSSI_AVG 0x5820
#define B_P0_TSSI_EN BIT(31)
#define B_P0_TSSI_AVG GENMASK(15, 12)
@@ -9268,6 +9301,7 @@
#define B_WDADC_SEL GENMASK(5, 4)
#define R_ADCMOD 0xC0E8
#define B_ADCMOD_LP GENMASK(31, 16)
#define B_ADCMOD_AUTO_RST BIT(6)
#define R_DCIM 0xC0EC
#define B_DCIM_RC GENMASK(23, 16)
#define B_DCIM_FR GENMASK(14, 13)

View File

@@ -360,15 +360,13 @@ static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev,
struct wiphy *wiphy)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_regd_ctrl *regd_ctrl = &regulatory->ctrl;
const struct rtw89_chip_info *chip = rtwdev->chip;
struct ieee80211_supported_band *sband;
struct rtw89_acpi_dsm_result res = {};
bool enable_by_fcc;
bool enable_by_ic;
bool enable;
u8 index;
int ret;
u8 val;
int i;
sband = wiphy->bands[NL80211_BAND_5GHZ];
if (!sband)
@@ -385,35 +383,25 @@ static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev,
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"acpi: cannot eval unii 4: %d\n", ret);
enable_by_fcc = true;
enable_by_ic = false;
val = u8_encode_bits(1, RTW89_ACPI_CONF_UNII4_US);
goto bottom;
}
val = res.u.value;
enable_by_fcc = u8_get_bits(val, RTW89_ACPI_CONF_UNII4_FCC);
enable_by_ic = u8_get_bits(val, RTW89_ACPI_CONF_UNII4_IC);
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"acpi: eval if allow unii-4: 0x%x\n", val);
bottom:
for (i = 0; i < regd_ctrl->nr; i++) {
const struct rtw89_regd *regd = &regd_ctrl->map[i];
index = rtw89_regd_get_index_by_name(rtwdev, "US");
enable = u8_get_bits(val, RTW89_ACPI_CONF_UNII4_US);
if (enable && index != RTW89_REGD_MAX_COUNTRY_NUM)
clear_bit(index, regulatory->block_unii4);
switch (regd->txpwr_regd[RTW89_BAND_5G]) {
case RTW89_FCC:
if (enable_by_fcc)
clear_bit(i, regulatory->block_unii4);
break;
case RTW89_IC:
if (enable_by_ic)
clear_bit(i, regulatory->block_unii4);
break;
default:
break;
}
}
index = rtw89_regd_get_index_by_name(rtwdev, "CA");
enable = u8_get_bits(val, RTW89_ACPI_CONF_UNII4_CA);
if (enable && index != RTW89_REGD_MAX_COUNTRY_NUM)
clear_bit(index, regulatory->block_unii4);
}
static void __rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev, bool block,
@@ -490,12 +478,11 @@ static void rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev)
static void rtw89_regd_setup_policy_6ghz_sp(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_regd_ctrl *regd_ctrl = &regulatory->ctrl;
const struct rtw89_acpi_policy_6ghz_sp *ptr;
struct rtw89_acpi_dsm_result res = {};
bool enable_by_us;
bool enable;
u8 index;
int ret;
int i;
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP, &res);
if (ret) {
@@ -520,19 +507,69 @@ static void rtw89_regd_setup_policy_6ghz_sp(struct rtw89_dev *rtwdev)
bitmap_fill(regulatory->block_6ghz_sp, RTW89_REGD_MAX_COUNTRY_NUM);
enable_by_us = u8_get_bits(ptr->conf, RTW89_ACPI_CONF_6GHZ_SP_US);
index = rtw89_regd_get_index_by_name(rtwdev, "US");
enable = u8_get_bits(ptr->conf, RTW89_ACPI_CONF_6GHZ_SP_US);
if (enable && index != RTW89_REGD_MAX_COUNTRY_NUM)
clear_bit(index, regulatory->block_6ghz_sp);
for (i = 0; i < regd_ctrl->nr; i++) {
const struct rtw89_regd *tmp = &regd_ctrl->map[i];
if (enable_by_us && memcmp(tmp->alpha2, "US", 2) == 0)
clear_bit(i, regulatory->block_6ghz_sp);
}
index = rtw89_regd_get_index_by_name(rtwdev, "CA");
enable = u8_get_bits(ptr->conf, RTW89_ACPI_CONF_6GHZ_SP_CA);
if (enable && index != RTW89_REGD_MAX_COUNTRY_NUM)
clear_bit(index, regulatory->block_6ghz_sp);
out:
kfree(ptr);
}
static void rtw89_regd_setup_policy_6ghz_vlp(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_acpi_policy_6ghz_vlp *ptr = NULL;
struct rtw89_acpi_dsm_result res = {};
bool enable;
u8 index;
int ret;
u8 val;
/* By default, allow 6 GHz VLP on all countries except US and CA. */
val = ~(RTW89_ACPI_CONF_6GHZ_VLP_US | RTW89_ACPI_CONF_6GHZ_VLP_CA);
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6GHZ_VLP_SUP, &res);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"acpi: cannot eval policy 6ghz-vlp: %d\n", ret);
goto bottom;
}
ptr = res.u.policy_6ghz_vlp;
switch (ptr->override) {
default:
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"%s: unknown override case: %d\n", __func__,
ptr->override);
fallthrough;
case 0:
break;
case 1:
val = ptr->conf;
break;
}
bottom:
index = rtw89_regd_get_index_by_name(rtwdev, "US");
enable = u8_get_bits(val, RTW89_ACPI_CONF_6GHZ_VLP_US);
if (!enable && index != RTW89_REGD_MAX_COUNTRY_NUM)
set_bit(index, regulatory->block_6ghz_vlp);
index = rtw89_regd_get_index_by_name(rtwdev, "CA");
enable = u8_get_bits(val, RTW89_ACPI_CONF_6GHZ_VLP_CA);
if (!enable && index != RTW89_REGD_MAX_COUNTRY_NUM)
set_bit(index, regulatory->block_6ghz_vlp);
kfree(ptr);
}
static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
@@ -576,6 +613,7 @@ static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy)
if (regd_allow_6ghz) {
rtw89_regd_setup_policy_6ghz(rtwdev);
rtw89_regd_setup_policy_6ghz_sp(rtwdev);
rtw89_regd_setup_policy_6ghz_vlp(rtwdev);
return;
}
@@ -620,6 +658,30 @@ const char *rtw89_regd_get_string(enum rtw89_regulation_type regd)
return rtw89_regd_string[regd];
}
static void rtw89_regd_setup_reg_rules(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_acpi_policy_reg_rules *ptr;
struct rtw89_acpi_dsm_result res = {};
int ret;
regulatory->txpwr_uk_follow_etsi = true;
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_REG_RULES_EN, &res);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"acpi: cannot eval policy reg-rules: %d\n", ret);
return;
}
ptr = res.u.policy_reg_rules;
regulatory->txpwr_uk_follow_etsi =
!u8_get_bits(ptr->conf, RTW89_ACPI_CONF_REG_RULE_REGD_UK);
kfree(ptr);
}
int rtw89_regd_setup(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
@@ -636,7 +698,8 @@ int rtw89_regd_setup(struct rtw89_dev *rtwdev)
}
regulatory->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
regulatory->txpwr_uk_follow_etsi = true;
rtw89_regd_setup_reg_rules(rtwdev);
if (!wiphy)
return -EINVAL;
@@ -1046,7 +1109,16 @@ static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link, bool active,
unsigned int *changed)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_regd *regd = regulatory->regd;
bool blocked[NUM_OF_RTW89_REG_6GHZ_POWER] = {};
u8 index = rtw89_regd_get_index(rtwdev, regd);
struct ieee80211_bss_conf *bss_conf;
bool dflt = false;
if (index == RTW89_REGD_MAX_COUNTRY_NUM ||
test_bit(index, regulatory->block_6ghz_vlp))
blocked[RTW89_REG_6GHZ_POWER_VLP] = true;
rcu_read_lock();
@@ -1065,6 +1137,7 @@ static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev,
break;
default:
rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
dflt = true;
break;
}
} else {
@@ -1073,6 +1146,14 @@ static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev,
rcu_read_unlock();
if (!dflt && blocked[rtwvif_link->reg_6ghz_power]) {
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"%c%c 6 GHz power type-%u is blocked by policy\n",
regd->alpha2[0], regd->alpha2[1],
rtwvif_link->reg_6ghz_power);
return -EINVAL;
}
*changed += __rtw89_reg_6ghz_power_recalc(rtwdev);
return 0;
}

View File

@@ -51,6 +51,48 @@ static const struct rtw89_hfc_param_ini rtw8851b_hfc_param_ini_pcie[] = {
[RTW89_QTA_INVALID] = {NULL},
};
static const struct rtw89_hfc_ch_cfg rtw8851b_hfc_chcfg_usb[] = {
{18, 152, grp_0}, /* ACH 0 */
{18, 152, grp_0}, /* ACH 1 */
{18, 152, grp_0}, /* ACH 2 */
{18, 152, 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 */
{18, 152, grp_0}, /* B0MGQ */
{18, 152, grp_0}, /* B0HIQ */
{0, 0, grp_0}, /* B1MGQ */
{0, 0, grp_0}, /* B1HIQ */
{0, 0, 0} /* FWCMDQ */
};
static const struct rtw89_hfc_pub_cfg rtw8851b_hfc_pubcfg_usb = {
152, /* Group 0 */
0, /* Group 1 */
152, /* Public Max */
0 /* WP threshold */
};
static const struct rtw89_hfc_prec_cfg rtw8851b_hfc_preccfg_usb = {
9, /* CH 0-11 pre-cost */
32, /* H2C pre-cost */
64, /* WP CH 0-7 pre-cost */
24, /* WP CH 8-11 pre-cost */
1, /* CH 0-11 full condition */
1, /* H2C full condition */
1, /* WP CH 0-7 full condition */
1, /* WP CH 8-11 full condition */
};
static const struct rtw89_hfc_param_ini rtw8851b_hfc_param_ini_usb[] = {
[RTW89_QTA_SCC] = {rtw8851b_hfc_chcfg_usb, &rtw8851b_hfc_pubcfg_usb,
&rtw8851b_hfc_preccfg_usb, RTW89_HCIFC_STF},
[RTW89_QTA_DLFW] = {NULL, NULL,
&rtw8851b_hfc_preccfg_usb, RTW89_HCIFC_STF},
[RTW89_QTA_INVALID] = {NULL},
};
static const struct rtw89_dle_mem rtw8851b_dle_mem_pcie[] = {
[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size6,
&rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt6,
@@ -68,6 +110,32 @@ static const struct rtw89_dle_mem rtw8851b_dle_mem_pcie[] = {
NULL},
};
static const struct rtw89_dle_mem rtw8851b_dle_mem_usb2[] = {
[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size25,
&rtw89_mac_size.ple_size32, &rtw89_mac_size.wde_qt25,
&rtw89_mac_size.wde_qt25, &rtw89_mac_size.ple_qt72,
&rtw89_mac_size.ple_qt73},
[RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size9,
&rtw89_mac_size.ple_size8, &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 struct rtw89_dle_mem rtw8851b_dle_mem_usb3[] = {
[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size25,
&rtw89_mac_size.ple_size33, &rtw89_mac_size.wde_qt25,
&rtw89_mac_size.wde_qt25, &rtw89_mac_size.ple_qt74,
&rtw89_mac_size.ple_qt75},
[RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size9,
&rtw89_mac_size.ple_size8, &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 struct rtw89_reg3_def rtw8851b_btc_preagc_en_defs[] = {
{0x46D0, GENMASK(1, 0), 0x3},
{0x4AD4, GENMASK(31, 0), 0xf},
@@ -317,7 +385,8 @@ static int rtw8851b_pwr_on_func(struct rtw89_dev *rtwdev)
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);
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1);
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_WEI,
XTAL_SI_OFF_WEI);
@@ -362,8 +431,9 @@ static int rtw8851b_pwr_on_func(struct rtw89_dev *rtwdev)
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);
rtw89_write32_set(rtwdev, R_AX_GPIO0_16_EECS_EESK_LED1_PULL_LOW_EN,
B_AX_GPIO10_PULL_LOW_EN | B_AX_GPIO16_PULL_LOW_EN_V1);
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
rtw89_write32_set(rtwdev, R_AX_GPIO0_16_EECS_EESK_LED1_PULL_LOW_EN,
B_AX_GPIO10_PULL_LOW_EN | B_AX_GPIO16_PULL_LOW_EN_V1);
if (rtwdev->hal.cv == CHIP_CAV) {
ret = rtw89_read_efuse_ver(rtwdev, &val8);
@@ -447,7 +517,10 @@ static int rtw8851b_pwr_off_func(struct rtw89_dev *rtwdev)
if (ret)
return ret;
rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION);
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION);
else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB)
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_SOP_EDSWR);
if (rtwdev->hal.cv == CHIP_CAV) {
rtw8851b_patch_swr_pfm2pwm(rtwdev);
@@ -456,19 +529,18 @@ static int rtw8851b_pwr_off_func(struct rtw89_dev *rtwdev)
rtw89_write32_set(rtwdev, R_AX_SPSANA_ON_CTRL1, B_AX_FPWMDELAY);
}
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) {
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
} else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) {
val32 = rtw89_read32(rtwdev, R_AX_SYS_PW_CTRL);
val32 &= ~B_AX_AFSM_PCIE_SUS_EN;
val32 |= B_AX_AFSM_WLSUS_EN;
rtw89_write32(rtwdev, R_AX_SYS_PW_CTRL, val32);
}
return 0;
}
static void rtw8851b_efuse_parsing(struct rtw89_efuse *efuse,
struct rtw8851b_efuse *map)
{
ether_addr_copy(efuse->addr, map->e.mac_addr);
efuse->rfe_type = map->rfe_type;
efuse->xtal_cap = map->xtal_k;
}
static void rtw8851b_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
struct rtw8851b_efuse *map)
{
@@ -549,12 +621,18 @@ static int rtw8851b_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
switch (rtwdev->hci.type) {
case RTW89_HCI_TYPE_PCIE:
rtw8851b_efuse_parsing(efuse, map);
ether_addr_copy(efuse->addr, map->e.mac_addr);
break;
case RTW89_HCI_TYPE_USB:
ether_addr_copy(efuse->addr, map->u.mac_addr);
break;
default:
return -EOPNOTSUPP;
}
efuse->rfe_type = map->rfe_type;
efuse->xtal_cap = map->xtal_k;
rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type);
return 0;
@@ -712,12 +790,22 @@ static void rtw8851b_phycap_parsing_gain_comp(struct rtw89_dev *rtwdev, u8 *phyc
gain->comp_valid = valid;
}
static void rtw8851b_phycap_parsing_adc_td(struct rtw89_dev *rtwdev, u8 *phycap_map)
{
u32 phycap_addr = rtwdev->chip->phycap_addr;
struct rtw89_efuse *efuse = &rtwdev->efuse;
const u32 addr_adc_td = 0x5AF;
efuse->adc_td = phycap_map[addr_adc_td - phycap_addr] & GENMASK(4, 0);
}
static int rtw8851b_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map)
{
rtw8851b_phycap_parsing_tssi(rtwdev, phycap_map);
rtw8851b_phycap_parsing_thermal_trim(rtwdev, phycap_map);
rtw8851b_phycap_parsing_pa_bias_trim(rtwdev, phycap_map);
rtw8851b_phycap_parsing_gain_comp(rtwdev, phycap_map);
rtw8851b_phycap_parsing_adc_td(rtwdev, phycap_map);
return 0;
}
@@ -1083,39 +1171,72 @@ static void rtw8851b_ctrl_ch(struct rtw89_dev *rtwdev,
static void rtw8851b_bw_setting(struct rtw89_dev *rtwdev, u8 bw)
{
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_CTL, 0x8);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_EN, 0x2);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_BW0, 0x2);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_BW1, 0x4);
struct rtw89_efuse *efuse = &rtwdev->efuse;
u8 adc_bw_sel;
switch (efuse->adc_td) {
default:
case 0x19:
adc_bw_sel = 0x4;
break;
case 0x11:
adc_bw_sel = 0x5;
break;
case 0x9:
adc_bw_sel = 0x3;
break;
}
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_BW1, adc_bw_sel);
rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_MUL, 0xf);
rtw89_phy_write32_mask(rtwdev, R_ADCMOD, B_ADCMOD_LP, 0xa);
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ADJ, 0x92);
rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_RC, 0x3);
switch (bw) {
case RTW89_CHANNEL_WIDTH_5:
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_CTL, 0x8);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_EN, 0x2);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_BW0, 0x2);
rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x1);
rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x0);
rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ADJ, 0x92);
break;
case RTW89_CHANNEL_WIDTH_10:
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_CTL, 0x8);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_EN, 0x2);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_BW0, 0x2);
rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x1);
rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x1);
rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x0);
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ADJ, 0x92);
break;
case RTW89_CHANNEL_WIDTH_20:
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_CTL, 0x8);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_EN, 0x2);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_BW0, 0x2);
rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x2);
rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x2);
rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x0);
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ADJ, 0x92);
break;
case RTW89_CHANNEL_WIDTH_40:
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_CTL, 0x8);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_EN, 0x2);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_BW0, 0x2);
rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x2);
rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x2);
rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x0);
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ADJ, 0x92);
break;
case RTW89_CHANNEL_WIDTH_80:
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_CTL, 0x8);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_EN, 0x2);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0, B_P0_CFCH_BW0, 0x2);
rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x0);
rtw89_phy_write32_mask(rtwdev, R_WDADC, B_WDADC_SEL, 0x2);
rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK_DS, 0x0);
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ADJ, 0x92);
break;
default:
rtw89_warn(rtwdev, "Fail to set ADC\n");
@@ -2425,6 +2546,7 @@ static const struct rtw89_chip_ops rtw8851b_chip_ops = {
.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,
@@ -2467,8 +2589,13 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.max_amsdu_limit = 3500,
.dis_2g_40m_ul_ofdma = true,
.rsvd_ple_ofst = 0x2f800,
.hfc_param_ini = rtw8851b_hfc_param_ini_pcie,
.dle_mem = rtw8851b_dle_mem_pcie,
.hfc_param_ini = {rtw8851b_hfc_param_ini_pcie,
rtw8851b_hfc_param_ini_usb,
NULL},
.dle_mem = {rtw8851b_dle_mem_pcie,
rtw8851b_dle_mem_usb2,
rtw8851b_dle_mem_usb3,
NULL},
.wde_qempty_acq_grpnum = 4,
.wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000},

View File

@@ -12,14 +12,14 @@
#include "rtw8851b_rfk_table.h"
#include "rtw8851b_table.h"
#define DPK_VER_8851B 0x5
#define DPK_KIP_REG_NUM_8851B 7
#define DPK_VER_8851B 0x11
#define DPK_KIP_REG_NUM_8851B 8
#define DPK_RF_REG_NUM_8851B 4
#define DPK_KSET_NUM 4
#define RTW8851B_RXK_GROUP_NR 4
#define RTW8851B_RXK_GROUP_IDX_NR 2
#define RTW8851B_TXK_GROUP_NR 1
#define RTW8851B_IQK_VER 0x2a
#define RTW8851B_IQK_VER 0x14
#define RTW8851B_IQK_SS 1
#define RTW8851B_LOK_GRAM 10
#define RTW8851B_TSSI_PATH_NR 1
@@ -85,6 +85,24 @@ enum rf_mode {
RF_RXK2 = 0x7,
};
enum adc_ck {
ADC_NA = 0,
ADC_480M = 1,
ADC_960M = 2,
ADC_1920M = 3,
};
enum dac_ck {
DAC_40M = 0,
DAC_80M = 1,
DAC_120M = 2,
DAC_160M = 3,
DAC_240M = 4,
DAC_320M = 5,
DAC_480M = 6,
DAC_960M = 7,
};
static const u32 _tssi_de_cck_long[RF_PATH_NUM_8851B] = {0x5858};
static const u32 _tssi_de_cck_short[RF_PATH_NUM_8851B] = {0x5860};
static const u32 _tssi_de_mcs_20m[RF_PATH_NUM_8851B] = {0x5838};
@@ -116,7 +134,7 @@ static const u32 rtw8851b_backup_rf_regs[] = {
#define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8851b_backup_rf_regs)
static const u32 dpk_kip_reg[DPK_KIP_REG_NUM_8851B] = {
0x813c, 0x8124, 0xc0ec, 0xc0e8, 0xc0c4, 0xc0d4, 0xc0d8};
0x813c, 0x8124, 0xc0ec, 0xc0e8, 0xc0c4, 0xc0d4, 0xc0d8, 0x12a0};
static const u32 dpk_rf_reg[DPK_RF_REG_NUM_8851B] = {0xde, 0x8f, 0x5, 0x10005};
static void _set_ch(struct rtw89_dev *rtwdev, u32 val);
@@ -163,6 +181,51 @@ static void _rfk_drf_direct_cntrl(struct rtw89_dev *rtwdev,
rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0);
}
static void _txck_force(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
bool force, enum dac_ck ck)
{
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, 0x0);
if (!force)
return;
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_VAL, ck);
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, 0x1);
}
static void _rxck_force(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
bool force, enum adc_ck ck)
{
static const u32 ck960_8851b[] = {0x8, 0x2, 0x2, 0x4, 0xf, 0xa, 0x93};
static const u32 ck1920_8851b[] = {0x9, 0x0, 0x0, 0x3, 0xf, 0xa, 0x49};
const u32 *data;
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x0);
if (!force)
return;
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_VAL, ck);
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, 0x1);
switch (ck) {
case ADC_960M:
data = ck960_8851b;
break;
case ADC_1920M:
default:
data = ck1920_8851b;
break;
}
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_CTL, data[0]);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_EN, data[1]);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, data[2]);
rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, data[3]);
rtw89_phy_write32_mask(rtwdev, R_DRCK | (path << 8), B_DRCK_MUL, data[4]);
rtw89_phy_write32_mask(rtwdev, R_ADCMOD | (path << 8), B_ADCMOD_LP, data[5]);
rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 8), B_P0_RXCK_ADJ, data[6]);
}
static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
{
u32 rf_mode;
@@ -1044,10 +1107,43 @@ static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path)
rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1);
if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80)
if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80) {
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0101);
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_DPD_GDIS, 0x1);
_rxck_force(rtwdev, path, true, ADC_960M);
rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_rxclk_80_defs_tbl);
else
} else {
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0101);
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_DPD_GDIS, 0x1);
_rxck_force(rtwdev, path, true, ADC_960M);
rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_rxclk_others_defs_tbl);
}
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, (2)before RXK IQK\n", path);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[07:10] = 0x%x\n", path,
0xc0d4, rtw89_phy_read32_mask(rtwdev, 0xc0d4, GENMASK(10, 7)));
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[11:14] = 0x%x\n", path,
0xc0d4, rtw89_phy_read32_mask(rtwdev, 0xc0d4, GENMASK(14, 11)));
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[26:27] = 0x%x\n", path,
0xc0d4, rtw89_phy_read32_mask(rtwdev, 0xc0d4, GENMASK(27, 26)));
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[05:08] = 0x%x\n", path,
0xc0d8, rtw89_phy_read32_mask(rtwdev, 0xc0d8, GENMASK(8, 5)));
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[17:21] = 0x%x\n", path,
0xc0c4, rtw89_phy_read32_mask(rtwdev, 0xc0c4, GENMASK(21, 17)));
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[16:31] = 0x%x\n", path,
0xc0e8, rtw89_phy_read32_mask(rtwdev, 0xc0e8, GENMASK(31, 16)));
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[04:05] = 0x%x\n", path,
0xc0e4, rtw89_phy_read32_mask(rtwdev, 0xc0e4, GENMASK(5, 4)));
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[23:31] = 0x%x\n", path,
0x12a0, rtw89_phy_read32_mask(rtwdev, 0x12a0, GENMASK(31, 23)));
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[13:14] = 0x%x\n", path,
0xc0ec, rtw89_phy_read32_mask(rtwdev, 0xc0ec, GENMASK(14, 13)));
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x%x[16:23] = 0x%x\n", path,
0xc0ec, rtw89_phy_read32_mask(rtwdev, 0xc0ec, GENMASK(23, 16)));
}
static bool _txk_5g_group_sel(struct rtw89_dev *rtwdev,
@@ -1553,6 +1649,14 @@ static void _iqk_macbb_setting(struct rtw89_dev *rtwdev,
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__);
rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_macbb_defs_tbl);
_txck_force(rtwdev, path, true, DAC_960M);
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_DPD_GDIS, 0x1);
_rxck_force(rtwdev, path, true, ADC_1920M);
rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_macbb_bh_defs_tbl);
}
static void _iqk_init(struct rtw89_dev *rtwdev)
@@ -1794,7 +1898,21 @@ static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path pat
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(28 + path), 0x0);
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), MASKDWORD, 0xd801dffd);
rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_bb_afe_defs_tbl);
_txck_force(rtwdev, path, true, DAC_960M);
_rxck_force(rtwdev, path, true, ADC_1920M);
rtw89_phy_write32_mask(rtwdev, R_DCIM, B_DCIM_FR, 0x0);
rtw89_phy_write32_mask(rtwdev, R_ADCMOD, B_ADCMOD_AUTO_RST, 0x1);
rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1);
udelay(1);
rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f);
udelay(10);
rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13);
udelay(2);
rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0001);
udelay(2);
rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041);
udelay(10);
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(20 + path), 0x1);
rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(28 + path), 0x1);
@@ -1827,6 +1945,17 @@ static void _dpk_tssi_pause(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
is_pause ? "pause" : "resume");
}
static
void _dpk_tssi_slope_k_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
bool is_on)
{
rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_SLOPE_CAL + (path << 13),
B_P0_TSSI_SLOPE_CAL_EN, is_on);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI slpoe_k %s\n", path,
str_on_off(is_on));
}
static void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
@@ -1874,9 +2003,6 @@ static void _dpk_kip_control_rfc(struct rtw89_dev *rtwdev,
{
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13),
B_IQK_RFC_ON, ctrl_by_kip);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] RFC is controlled by %s\n",
ctrl_by_kip ? "KIP" : "BB");
}
static void _dpk_kip_preset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
@@ -2279,7 +2405,7 @@ static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order)
case 0: /* (5,3,1) */
rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, 0x0);
rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL_SEL, 0x2);
rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x4);
rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x3);
rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_DMAN, 0x1);
break;
case 1: /* (5,3,0) */
@@ -2315,8 +2441,6 @@ static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order)
static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path, u8 kidx)
{
rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_MA, 0x1);
if (rtw89_phy_read32_mask(rtwdev, R_IDL_MPA, B_IDL_MD500) == 0x1)
_dpk_set_mdpd_para(rtwdev, 0x2);
else if (rtw89_phy_read32_mask(rtwdev, R_IDL_MPA, B_IDL_MD530) == 0x1)
@@ -2419,9 +2543,6 @@ static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
u8 init_xdbm = 17;
bool is_fail;
if (dpk->bp[path][kidx].band != RTW89_BAND_2G)
init_xdbm = 15;
_dpk_kip_control_rfc(rtwdev, path, false);
_rfk_rf_direct_cntrl(rtwdev, path, false);
rtw89_write_rf(rtwdev, path, RR_BBDC, RFREG_MASK, 0x03ffd);
@@ -2485,6 +2606,7 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
"[DPK] ========= S%d[%d] DPK Start =========\n",
path, dpk->cur_idx[path]);
_dpk_tssi_slope_k_onoff(rtwdev, path, false);
_dpk_rxagc_onoff(rtwdev, path, false);
_rfk_drf_direct_cntrl(rtwdev, path, false);
_dpk_bb_afe_setting(rtwdev, path);
@@ -2502,7 +2624,7 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
_dpk_reload_rf(rtwdev, dpk_rf_reg, rf_bkup, path);
_dpk_bb_afe_restore(rtwdev, path);
_dpk_rxagc_onoff(rtwdev, path, true);
_dpk_tssi_slope_k_onoff(rtwdev, path, true);
if (rtwdev->is_tssi_mode[path])
_dpk_tssi_pause(rtwdev, path, false);
}

View File

@@ -63,16 +63,7 @@ static const struct rtw89_reg5_def rtw8851b_dack_manual_off_defs[] = {
RTW89_DECLARE_RFK_TBL(rtw8851b_dack_manual_off_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_rxclk_80_defs[] = {
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0101),
RTW89_DECL_RFK_WM(0x5670, 0x00002000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00080000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x2),
RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x1),
RTW89_DECL_RFK_WM(0xc0d4, 0x00000780, 0x8),
RTW89_DECL_RFK_WM(0xc0d4, 0x00007800, 0x2),
RTW89_DECL_RFK_WM(0xc0d4, 0x0c000000, 0x2),
RTW89_DECL_RFK_WM(0xc0d8, 0x000001e0, 0x5),
RTW89_DECL_RFK_WM(0xc0c4, 0x003e0000, 0xf),
RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x0),
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0f),
@@ -85,16 +76,7 @@ static const struct rtw89_reg5_def rtw8851b_iqk_rxclk_80_defs[] = {
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_rxclk_80_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_rxclk_others_defs[] = {
RTW89_DECL_RFK_WM(0x20fc, 0xffff0000, 0x0101),
RTW89_DECL_RFK_WM(0x5670, 0x00002000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00080000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x2),
RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x0),
RTW89_DECL_RFK_WM(0xc0d4, 0x00000780, 0x8),
RTW89_DECL_RFK_WM(0xc0d4, 0x00007800, 0x2),
RTW89_DECL_RFK_WM(0xc0d4, 0x0c000000, 0x2),
RTW89_DECL_RFK_WM(0xc0d8, 0x000001e0, 0x5),
RTW89_DECL_RFK_WM(0xc0c4, 0x003e0000, 0xf),
RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x2),
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x0f),
@@ -157,55 +139,38 @@ static const struct rtw89_reg5_def rtw8851b_iqk_macbb_defs[] = {
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(0x12a0, 0x00008000, 0x1),
RTW89_DECL_RFK_WM(0x5670, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00007000, 0x7),
RTW89_DECL_RFK_WM(0x5670, 0x00002000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00080000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x3),
RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x2),
RTW89_DECL_RFK_WM(0xc0d4, 0x00000780, 0x9),
RTW89_DECL_RFK_WM(0xc0d4, 0x00007800, 0x1),
RTW89_DECL_RFK_WM(0xc0d4, 0x0c000000, 0x0),
RTW89_DECL_RFK_WM(0xc0d8, 0x000001e0, 0x3),
RTW89_DECL_RFK_WM(0xc0c4, 0x003e0000, 0xa),
RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x0),
RTW89_DECL_RFK_WM(0xc0e8, 0x00000040, 0x1),
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x1f),
RTW89_DECL_RFK_WM(0x030c, 0xff000000, 0x13),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0001),
RTW89_DECL_RFK_WM(0x032c, 0xffff0000, 0x0041),
RTW89_DECL_RFK_WM(0x20fc, 0x00100000, 0x1),
RTW89_DECL_RFK_WM(0x20fc, 0x10000000, 0x1),
};
RTW89_DECLARE_RFK_TBL(rtw8851b_iqk_macbb_defs);
static const struct rtw89_reg5_def rtw8851b_iqk_bb_afe_defs[] = {
RTW89_DECL_RFK_WM(0x5670, 0x00004000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00008000, 0x1),
RTW89_DECL_RFK_WM(0x5670, 0x80000000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00007000, 0x7),
RTW89_DECL_RFK_WM(0x5670, 0x00002000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00080000, 0x1),
RTW89_DECL_RFK_WM(0x12a0, 0x00070000, 0x3),
static const struct rtw89_reg5_def rtw8851b_iqk_macbb_bh_defs[] = {
RTW89_DECL_RFK_WM(0x5670, 0x60000000, 0x2),
RTW89_DECL_RFK_WM(0xc0d4, 0x00000780, 0x9),
RTW89_DECL_RFK_WM(0xc0d4, 0x00007800, 0x1),
RTW89_DECL_RFK_WM(0xc0d4, 0x0c000000, 0x0),
RTW89_DECL_RFK_WM(0xc0d8, 0x000001e0, 0x3),
RTW89_DECL_RFK_WM(0xc0c4, 0x003e0000, 0xa),
RTW89_DECL_RFK_WM(0xc0ec, 0x00006000, 0x0),
RTW89_DECL_RFK_WM(0xc0e8, 0x00000040, 0x1),
RTW89_DECL_RFK_WM(0x12b8, 0x40000000, 0x1),
RTW89_DECL_RFK_WM(0x030c, MASKBYTE3, 0x1f),
RTW89_DECL_RFK_WM(0x030c, MASKBYTE3, 0x13),
RTW89_DECL_RFK_WM(0x032c, MASKHWORD, 0x0001),
RTW89_DECL_RFK_WM(0x032c, MASKHWORD, 0x0041),
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_bb_afe_defs);
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),

View File

@@ -17,8 +17,8 @@ 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_bb_afe_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;

View File

@@ -2320,9 +2320,9 @@ static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = {
{0x813c, 0x40000000},
{0x8140, 0x00000000},
{0x8144, 0x0b040b03},
{0x8148, 0x07020b04},
{0x814c, 0x07020b04},
{0x8150, 0xa0a00000},
{0x8148, 0x07020a04},
{0x814c, 0x07020a04},
{0x8150, 0xe4e40000},
{0x8158, 0xffffffff},
{0x815c, 0xffffffff},
{0x8160, 0xffffffff},
@@ -2577,14 +2577,14 @@ static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = {
{0x8534, 0x400042fe},
{0x8538, 0x50554200},
{0x853c, 0xb4183000},
{0x8540, 0xe537a50f},
{0x8540, 0xe535a50f},
{0x8544, 0xf12bf02b},
{0x8548, 0xf32bf22b},
{0x854c, 0xf62bf42b},
{0x8550, 0xf82bf72b},
{0x8554, 0xfa2bf92b},
{0x8558, 0xfd2bfc2b},
{0x855c, 0xe537fe2b},
{0x855c, 0xe535fe2b},
{0x8560, 0xf12af02a},
{0x8564, 0xf32af22a},
{0x8568, 0xf52af42a},
@@ -2653,7 +2653,7 @@ static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = {
{0x8664, 0x9700140f},
{0x8668, 0x00017430},
{0x866c, 0xe39ce35e},
{0x8670, 0xe52a0bbd},
{0x8670, 0xe5280bbd},
{0x8674, 0xe36a0001},
{0x8678, 0x0001e3c4},
{0x867c, 0x55005b30},
@@ -2664,93 +2664,93 @@ static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = {
{0x8690, 0x46100005},
{0x8694, 0x00010004},
{0x8698, 0x30f8e35e},
{0x869c, 0xe52a0023},
{0x869c, 0xe5280023},
{0x86a0, 0x54ed0002},
{0x86a4, 0x00230baa},
{0x86a8, 0x0002e52a},
{0x86a8, 0x0002e528},
{0x86ac, 0xe356e3e4},
{0x86b0, 0xe35e0001},
{0x86b4, 0x002230f3},
{0x86b8, 0x0002e52a},
{0x86b8, 0x0002e528},
{0x86bc, 0x0baa54ec},
{0x86c0, 0xe52a0022},
{0x86c0, 0xe5280022},
{0x86c4, 0xe3e40002},
{0x86c8, 0x0001e356},
{0x86cc, 0x0baae35e},
{0x86d0, 0xe3e430ec},
{0x86d4, 0x0001e356},
{0x86d8, 0x6d0f6c67},
{0x86dc, 0xe52ae39c},
{0x86dc, 0xe528e39c},
{0x86e0, 0xe39c6c8b},
{0x86e4, 0x0bace52a},
{0x86e4, 0x0bace528},
{0x86e8, 0x6d0f6cb3},
{0x86ec, 0xe52ae39c},
{0x86ec, 0xe528e39c},
{0x86f0, 0x6cdb0bad},
{0x86f4, 0xe39c6d0f},
{0x86f8, 0x6cf5e52a},
{0x86f8, 0x6cf5e528},
{0x86fc, 0xe39c6d0f},
{0x8700, 0x6c0be52a},
{0x8700, 0x6c0be528},
{0x8704, 0xe39c6d00},
{0x8708, 0x6c25e52a},
{0x870c, 0xe52ae39c},
{0x8708, 0x6c25e528},
{0x870c, 0xe528e39c},
{0x8710, 0x6c4df8c6},
{0x8714, 0xe52ae39c},
{0x8714, 0xe528e39c},
{0x8718, 0x6c75f9cf},
{0x871c, 0xe52ae39c},
{0x871c, 0xe528e39c},
{0x8720, 0xe39c6c99},
{0x8724, 0xfad6e52a},
{0x8724, 0xfad6e528},
{0x8728, 0x21e87410},
{0x872c, 0x6e670009},
{0x8730, 0xe3c46f0f},
{0x8734, 0x7410e52f},
{0x8734, 0x7410e52d},
{0x8738, 0x000b21e8},
{0x873c, 0xe3c46e8b},
{0x8740, 0x7410e52f},
{0x8740, 0x7410e52d},
{0x8744, 0x000d21e8},
{0x8748, 0x6f0f6eb3},
{0x874c, 0xe52fe3c4},
{0x874c, 0xe52de3c4},
{0x8750, 0xfe07ff08},
{0x8754, 0x21e87410},
{0x8758, 0x6ec7000e},
{0x875c, 0xe52fe3c4},
{0x875c, 0xe52de3c4},
{0x8760, 0x21e87410},
{0x8764, 0x6edb000f},
{0x8768, 0xe3c46f0f},
{0x876c, 0x7410e52f},
{0x876c, 0x7410e52d},
{0x8770, 0x001021e8},
{0x8774, 0xe3c46eef},
{0x8778, 0xff03e52f},
{0x877c, 0xe52ffe02},
{0x8778, 0xff03e52d},
{0x877c, 0xe52dfe02},
{0x8780, 0x21e87410},
{0x8784, 0x6e110013},
{0x8788, 0xe3c46f00},
{0x878c, 0xff03e52f},
{0x8790, 0xe52ffe02},
{0x878c, 0xff03e52d},
{0x8790, 0xe52dfe02},
{0x8794, 0x21e87410},
{0x8798, 0x6e250014},
{0x879c, 0xe52fe3c4},
{0x879c, 0xe52de3c4},
{0x87a0, 0xff08fc24},
{0x87a4, 0x7410fe07},
{0x87a8, 0x001521e8},
{0x87ac, 0xe3c46e39},
{0x87b0, 0x7410e52f},
{0x87b0, 0x7410e52d},
{0x87b4, 0x001621e8},
{0x87b8, 0xe3c46e4d},
{0x87bc, 0xfd27e52f},
{0x87bc, 0xfd27e52d},
{0x87c0, 0x21e87410},
{0x87c4, 0x6e750018},
{0x87c8, 0xe52fe3c4},
{0x87c8, 0xe52de3c4},
{0x87cc, 0x21e87410},
{0x87d0, 0x6e99001a},
{0x87d4, 0xe52fe3c4},
{0x87d4, 0xe52de3c4},
{0x87d8, 0xe36afe24},
{0x87dc, 0x63404380},
{0x87e0, 0x43006880},
{0x87e4, 0x31300bac},
{0x87e8, 0xe52f0022},
{0x87e8, 0xe52d0022},
{0x87ec, 0x54ec0002},
{0x87f0, 0x00220baa},
{0x87f4, 0x0002e52f},
{0x87f4, 0x0002e52d},
{0x87f8, 0xe362e3e4},
{0x87fc, 0xe36a0001},
{0x8800, 0x63404380},
@@ -2770,7 +2770,7 @@ static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = {
{0x8838, 0x55010004},
{0x883c, 0x66055b40},
{0x8840, 0x62000007},
{0x8844, 0xe40e6300},
{0x8844, 0xe40c6300},
{0x8848, 0x09000004},
{0x884c, 0x0b400a01},
{0x8850, 0x0e010d00},
@@ -2782,13 +2782,13 @@ static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = {
{0x8868, 0x00044d01},
{0x886c, 0x00074300},
{0x8870, 0x05a30562},
{0x8874, 0xe40e961f},
{0x8874, 0xe40c961f},
{0x8878, 0xe37e0004},
{0x887c, 0x06a20007},
{0x8880, 0xe40e07a3},
{0x8880, 0xe40c07a3},
{0x8884, 0xe37e0004},
{0x8888, 0x0002e3fe},
{0x888c, 0x4380e406},
{0x8888, 0x0002e3fc},
{0x888c, 0x4380e404},
{0x8890, 0x4d000007},
{0x8894, 0x43000004},
{0x8898, 0x000742fe},
@@ -2815,13 +2815,13 @@ static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = {
{0x88ec, 0x42000004},
{0x88f0, 0x00070001},
{0x88f4, 0x62006220},
{0x88f8, 0x0001e406},
{0x88f8, 0x0001e404},
{0x88fc, 0x63000007},
{0x8900, 0x09000004},
{0x8904, 0x0e010a00},
{0x8908, 0x00070032},
{0x890c, 0xe40e06a2},
{0x8910, 0x0002e41a},
{0x890c, 0xe40c06a2},
{0x8910, 0x0002e418},
{0x8914, 0x000742fe},
{0x8918, 0x00044d00},
{0x891c, 0x00014200},
@@ -2839,50 +2839,50 @@ static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = {
{0x894c, 0x00014300},
{0x8950, 0x6c060005},
{0x8954, 0xe2aae298},
{0x8958, 0xe42ae285},
{0x895c, 0xe432e2f3},
{0x8958, 0xe428e285},
{0x895c, 0xe430e2f3},
{0x8960, 0x0001e30c},
{0x8964, 0x0005e285},
{0x8968, 0xe2986c06},
{0x896c, 0xe42ae4a9},
{0x8970, 0xe432e2f3},
{0x896c, 0xe428e4a7},
{0x8970, 0xe430e2f3},
{0x8974, 0x0001e30c},
{0x8978, 0x6c000005},
{0x897c, 0xe2aae298},
{0x8980, 0xe445e285},
{0x8984, 0xe44de2f3},
{0x8980, 0xe443e285},
{0x8984, 0xe44be2f3},
{0x8988, 0x0001e30c},
{0x898c, 0x0005e285},
{0x8990, 0xe2986c00},
{0x8994, 0xe445e4a9},
{0x8998, 0xe44de2f3},
{0x8994, 0xe443e4a7},
{0x8998, 0xe44be2f3},
{0x899c, 0x0001e30c},
{0x89a0, 0x6c040005},
{0x89a4, 0xe2aae298},
{0x89a8, 0xe460e285},
{0x89ac, 0xe468e2f3},
{0x89a8, 0xe45ee285},
{0x89ac, 0xe466e2f3},
{0x89b0, 0x0001e30c},
{0x89b4, 0x0005e285},
{0x89b8, 0xe2986c04},
{0x89bc, 0xe460e4a9},
{0x89c0, 0xe468e2f3},
{0x89bc, 0xe45ee4a7},
{0x89c0, 0xe466e2f3},
{0x89c4, 0x0001e30c},
{0x89c8, 0x6c020005},
{0x89cc, 0xe2aae298},
{0x89d0, 0xe47be285},
{0x89d4, 0xe483e2f3},
{0x89d0, 0xe479e285},
{0x89d4, 0xe481e2f3},
{0x89d8, 0x0001e30c},
{0x89dc, 0x0005e285},
{0x89e0, 0xe2986c02},
{0x89e4, 0xe47be4a9},
{0x89e8, 0xe483e2f3},
{0x89e4, 0xe479e4a7},
{0x89e8, 0xe481e2f3},
{0x89ec, 0x0001e30c},
{0x89f0, 0x43800004},
{0x89f4, 0x610a6008},
{0x89f8, 0x63ce6200},
{0x89fc, 0x60800006},
{0x8a00, 0x00047f00},
{0x8a04, 0xe4e04300},
{0x8a04, 0xe4de4300},
{0x8a08, 0x00070001},
{0x8a0c, 0x4d015500},
{0x8a10, 0x74200004},
@@ -2895,22 +2895,22 @@ static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = {
{0x8a2c, 0x00014300},
{0x8a30, 0x74200004},
{0x8a34, 0x77000005},
{0x8a38, 0x73887e07},
{0x8a38, 0x73887e06},
{0x8a3c, 0x8f007380},
{0x8a40, 0x0004140f},
{0x8a44, 0x00057430},
{0x8a48, 0x00017300},
{0x8a4c, 0x0005e496},
{0x8a4c, 0x0005e494},
{0x8a50, 0x00017300},
{0x8a54, 0x43800004},
{0x8a58, 0x0006b103},
{0x8a5c, 0x91037cdb},
{0x8a60, 0x40db0007},
{0x8a64, 0x43000004},
{0x8a68, 0x0005e496},
{0x8a68, 0x0005e494},
{0x8a6c, 0x00067380},
{0x8a70, 0x60025d01},
{0x8a74, 0xe4ba6200},
{0x8a74, 0xe4b86200},
{0x8a78, 0x73000005},
{0x8a7c, 0x76080007},
{0x8a80, 0x00047578},
@@ -2943,8 +2943,8 @@ static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = {
{0x8aec, 0x7cdb0006},
{0x8af0, 0x00079103},
{0x8af4, 0x000440db},
{0x8af8, 0xe4964300},
{0x8afc, 0xe4ba7e03},
{0x8af8, 0xe4944300},
{0x8afc, 0xe4b87e03},
{0x8b00, 0x43800004},
{0x8b04, 0x0006b103},
{0x8b08, 0x91037c5b},
@@ -2976,14 +2976,14 @@ static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = {
{0x8b70, 0x43000004},
{0x8b74, 0x73000005},
{0x8b78, 0x76000007},
{0x8b7c, 0xe4c30001},
{0x8b7c, 0xe4c10001},
{0x8b80, 0x00040001},
{0x8b84, 0x60004380},
{0x8b88, 0x62016100},
{0x8b8c, 0x00066310},
{0x8b90, 0x00046000},
{0x8b94, 0x00014300},
{0x8b98, 0x0001e4e0},
{0x8b98, 0x0001e4de},
{0x8b9c, 0x4e004f02},
{0x8ba0, 0x52015302},
{0x8ba4, 0x140f0001},
@@ -3030,7 +3030,7 @@ static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = {
{0x8c48, 0xbf1ae3ac},
{0x8c4c, 0xe36e300b},
{0x8c50, 0xe390e377},
{0x8c54, 0x0001e523},
{0x8c54, 0x0001e521},
{0x8c58, 0x54c054bf},
{0x8c5c, 0x54c154a3},
{0x8c60, 0x4c1854a4},
@@ -3039,7 +3039,7 @@ static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = {
{0x8c6c, 0xbf051402},
{0x8c70, 0x54a354c1},
{0x8c74, 0xbf011402},
{0x8c78, 0x54dfe534},
{0x8c78, 0x54dfe532},
{0x8c7c, 0x54bf0001},
{0x8c80, 0x050a54e5},
{0x8c84, 0x000154df},
@@ -3060,186 +3060,185 @@ static const struct rtw89_reg2_def rtw89_8851b_phy_nctl_regs[] = {
{0x8cc0, 0x56005610},
{0x8cc4, 0x00018c00},
{0x8cc8, 0x57005704},
{0x8ccc, 0xa7038e00},
{0x8cd0, 0x33f0aff7},
{0x8cd4, 0xaf034019},
{0x8cd8, 0x33f0402b},
{0x8cdc, 0x33df402b},
{0x8ce0, 0x57005708},
{0x8ce4, 0x57818e00},
{0x8ce8, 0x8e005780},
{0x8cec, 0x00074380},
{0x8cf0, 0x5c005c01},
{0x8cf4, 0x00041403},
{0x8cf8, 0x00014300},
{0x8cfc, 0x0007427f},
{0x8d00, 0x62006280},
{0x8d04, 0x00049200},
{0x8d08, 0x00014200},
{0x8d0c, 0x0007427f},
{0x8d10, 0x63146394},
{0x8d14, 0x00049200},
{0x8d18, 0x00014200},
{0x8d1c, 0x42fe0004},
{0x8d20, 0x4d010007},
{0x8d24, 0x42000004},
{0x8d28, 0x140f7420},
{0x8d2c, 0x57005710},
{0x8d30, 0x0001141f},
{0x8d34, 0x42fe0004},
{0x8d38, 0x4d010007},
{0x8d3c, 0x42000004},
{0x8d40, 0x140f7420},
{0x8d44, 0x000742bf},
{0x8d48, 0x62006240},
{0x8d4c, 0x0004141f},
{0x8d50, 0x00014200},
{0x8d54, 0x5d060006},
{0x8d58, 0x61046003},
{0x8d5c, 0x00056201},
{0x8d60, 0x00017310},
{0x8d64, 0x43800004},
{0x8d68, 0x5e010007},
{0x8d6c, 0x140a5e00},
{0x8d70, 0x0006b103},
{0x8d74, 0x91037f07},
{0x8d78, 0x43070007},
{0x8d7c, 0x5c000006},
{0x8d80, 0x5e035d02},
{0x8d84, 0x43000004},
{0x8d88, 0x00060001},
{0x8d8c, 0x60005d04},
{0x8d90, 0x62016104},
{0x8d94, 0x73100005},
{0x8d98, 0x00040001},
{0x8d9c, 0x00074380},
{0x8da0, 0x5e005e01},
{0x8da4, 0xb103140a},
{0x8da8, 0x7fc60006},
{0x8dac, 0x00079103},
{0x8db0, 0x000643c6},
{0x8db4, 0x5d025c00},
{0x8db8, 0x00045e03},
{0x8dbc, 0x00014300},
{0x8dc0, 0x5d040006},
{0x8dc4, 0x61046000},
{0x8dc8, 0x00056201},
{0x8dcc, 0x00017310},
{0x8dd0, 0x43800004},
{0x8dd4, 0x5e010007},
{0x8dd8, 0x140a5e00},
{0x8ddc, 0x0006b103},
{0x8de0, 0x91037fc6},
{0x8de4, 0x43c60007},
{0x8de8, 0x5c000006},
{0x8dec, 0x5e035d02},
{0x8df0, 0x43000004},
{0x8df4, 0x00060001},
{0x8df8, 0x60025d00},
{0x8dfc, 0x62016100},
{0x8e00, 0x73000005},
{0x8e04, 0x00040001},
{0x8e08, 0x00074380},
{0x8e0c, 0x5e005e01},
{0x8e10, 0xb103140a},
{0x8e14, 0x7fc00006},
{0x8e18, 0x00079103},
{0x8e1c, 0x000643c0},
{0x8e20, 0x5d025c00},
{0x8e24, 0x00045e03},
{0x8e28, 0x00014300},
{0x8e2c, 0x7e020005},
{0x8e30, 0x42f70004},
{0x8e34, 0x6c080005},
{0x8e38, 0x42700004},
{0x8e3c, 0x73810005},
{0x8e40, 0x93007380},
{0x8e44, 0x42f70004},
{0x8e48, 0x6c000005},
{0x8e4c, 0x42000004},
{0x8e50, 0x00040001},
{0x8e54, 0x00074380},
{0x8e58, 0x73007304},
{0x8e5c, 0x72401405},
{0x8e60, 0x43000004},
{0x8e64, 0x74040006},
{0x8e68, 0x40010007},
{0x8e6c, 0xab004000},
{0x8e70, 0x0001140f},
{0x8e74, 0x140ae517},
{0x8e78, 0x140ae4c3},
{0x8e7c, 0x0001e51e},
{0x8e80, 0xe4c3e517},
{0x8e84, 0x00040001},
{0x8e88, 0x00047410},
{0x8e8c, 0x42f04380},
{0x8e90, 0x62080007},
{0x8e94, 0x24206301},
{0x8e98, 0x14c80000},
{0x8e9c, 0x00002428},
{0x8ea0, 0x1a4215f4},
{0x8ea4, 0x6300000b},
{0x8ea8, 0x42000004},
{0x8eac, 0x74304300},
{0x8eb0, 0x4380140f},
{0x8eb4, 0x73080007},
{0x8eb8, 0x00047300},
{0x8ebc, 0x00014300},
{0x8ec0, 0x4bf00007},
{0x8ec4, 0x490b4a8f},
{0x8ec8, 0x4a8e48f1},
{0x8ecc, 0x48a5490a},
{0x8ed0, 0x49094a8d},
{0x8ed4, 0x4a8c487d},
{0x8ed8, 0x48754908},
{0x8edc, 0x49074a8b},
{0x8ee0, 0x4a8a4889},
{0x8ee4, 0x48b74906},
{0x8ee8, 0x49054a89},
{0x8eec, 0x4a8848fc},
{0x8ef0, 0x48564905},
{0x8ef4, 0x49044a87},
{0x8ef8, 0x4a8648c1},
{0x8efc, 0x483d4904},
{0x8f00, 0x49034a85},
{0x8f04, 0x4a8448c7},
{0x8f08, 0x485e4903},
{0x8f0c, 0x49024a83},
{0x8f10, 0x4a8248ac},
{0x8f14, 0x48624902},
{0x8f18, 0x49024a81},
{0x8f1c, 0x4a804820},
{0x8f20, 0x48004900},
{0x8f24, 0x49014a90},
{0x8f28, 0x4a10481f},
{0x8f2c, 0x00060001},
{0x8f30, 0x5f005f80},
{0x8f34, 0x00059900},
{0x8f38, 0x00017300},
{0x8f3c, 0x63800006},
{0x8f40, 0x98006300},
{0x8f44, 0x549f0001},
{0x8f48, 0x5c015400},
{0x8f4c, 0x540054df},
{0x8f50, 0x00015c02},
{0x8f54, 0x07145c01},
{0x8f58, 0x5c025400},
{0x8f5c, 0x5c020001},
{0x8f60, 0x54000714},
{0x8f64, 0x00015c01},
{0x8f68, 0x4c184c98},
{0x8f6c, 0x00080001},
{0x8f70, 0x5c020004},
{0x8f74, 0x09017430},
{0x8f78, 0x0ba60c01},
{0x8f7c, 0x77800005},
{0x8f80, 0x52200007},
{0x8f84, 0x43800004},
{0x8f88, 0x610a6008},
{0x8f8c, 0x63c26200},
{0x8f90, 0x5c000007},
{0x8f94, 0x43000004},
{0x8f98, 0x00000001},
{0x8ccc, 0x33ee8e00},
{0x8cd0, 0xaf034019},
{0x8cd4, 0x33ee402b},
{0x8cd8, 0x33df402b},
{0x8cdc, 0x57005708},
{0x8ce0, 0x57818e00},
{0x8ce4, 0x8e005780},
{0x8ce8, 0x00074380},
{0x8cec, 0x5c005c01},
{0x8cf0, 0x00041403},
{0x8cf4, 0x00014300},
{0x8cf8, 0x0007427f},
{0x8cfc, 0x62006280},
{0x8d00, 0x00049200},
{0x8d04, 0x00014200},
{0x8d08, 0x0007427f},
{0x8d0c, 0x63146394},
{0x8d10, 0x00049200},
{0x8d14, 0x00014200},
{0x8d18, 0x42fe0004},
{0x8d1c, 0x4d010007},
{0x8d20, 0x42000004},
{0x8d24, 0x140f7420},
{0x8d28, 0x57005710},
{0x8d2c, 0x0001141f},
{0x8d30, 0x42fe0004},
{0x8d34, 0x4d010007},
{0x8d38, 0x42000004},
{0x8d3c, 0x140f7420},
{0x8d40, 0x000742bf},
{0x8d44, 0x62006240},
{0x8d48, 0x0004141f},
{0x8d4c, 0x00014200},
{0x8d50, 0x5d060006},
{0x8d54, 0x61046003},
{0x8d58, 0x00056200},
{0x8d5c, 0x00017310},
{0x8d60, 0x43800004},
{0x8d64, 0x5e010007},
{0x8d68, 0x140a5e00},
{0x8d6c, 0x0006b103},
{0x8d70, 0x91037f07},
{0x8d74, 0x43070007},
{0x8d78, 0x5c000006},
{0x8d7c, 0x5e035d02},
{0x8d80, 0x43000004},
{0x8d84, 0x00060001},
{0x8d88, 0x60005d04},
{0x8d8c, 0x62006104},
{0x8d90, 0x73100005},
{0x8d94, 0x00040001},
{0x8d98, 0x00074380},
{0x8d9c, 0x5e005e01},
{0x8da0, 0xb103140a},
{0x8da4, 0x7fc60006},
{0x8da8, 0x00079103},
{0x8dac, 0x000643c6},
{0x8db0, 0x5d025c00},
{0x8db4, 0x00045e03},
{0x8db8, 0x00014300},
{0x8dbc, 0x5d040006},
{0x8dc0, 0x61046000},
{0x8dc4, 0x00056200},
{0x8dc8, 0x00017310},
{0x8dcc, 0x43800004},
{0x8dd0, 0x5e010007},
{0x8dd4, 0x140a5e00},
{0x8dd8, 0x0006b103},
{0x8ddc, 0x91037fc6},
{0x8de0, 0x43c60007},
{0x8de4, 0x5c000006},
{0x8de8, 0x5e035d02},
{0x8dec, 0x43000004},
{0x8df0, 0x00060001},
{0x8df4, 0x60025d00},
{0x8df8, 0x62006100},
{0x8dfc, 0x73000005},
{0x8e00, 0x00040001},
{0x8e04, 0x00074380},
{0x8e08, 0x5e005e01},
{0x8e0c, 0xb103140a},
{0x8e10, 0x7fc00006},
{0x8e14, 0x00079103},
{0x8e18, 0x000643c0},
{0x8e1c, 0x5d025c00},
{0x8e20, 0x00045e03},
{0x8e24, 0x00014300},
{0x8e28, 0x7e020005},
{0x8e2c, 0x42f70004},
{0x8e30, 0x6c080005},
{0x8e34, 0x42700004},
{0x8e38, 0x73810005},
{0x8e3c, 0x93007380},
{0x8e40, 0x42f70004},
{0x8e44, 0x6c000005},
{0x8e48, 0x42000004},
{0x8e4c, 0x00040001},
{0x8e50, 0x00074380},
{0x8e54, 0x73007304},
{0x8e58, 0x72401405},
{0x8e5c, 0x43000004},
{0x8e60, 0x74040006},
{0x8e64, 0x40010007},
{0x8e68, 0xab004000},
{0x8e6c, 0x0001140f},
{0x8e70, 0x140ae515},
{0x8e74, 0x140ae4c1},
{0x8e78, 0x0001e51c},
{0x8e7c, 0xe4c1e515},
{0x8e80, 0x00040001},
{0x8e84, 0x00047410},
{0x8e88, 0x42f04380},
{0x8e8c, 0x62080007},
{0x8e90, 0x24206301},
{0x8e94, 0x14c80000},
{0x8e98, 0x00002428},
{0x8e9c, 0x1a4215f4},
{0x8ea0, 0x6300000b},
{0x8ea4, 0x42000004},
{0x8ea8, 0x74304300},
{0x8eac, 0x4380140f},
{0x8eb0, 0x73080007},
{0x8eb4, 0x00047300},
{0x8eb8, 0x00014300},
{0x8ebc, 0x4bf00007},
{0x8ec0, 0x490b4a8f},
{0x8ec4, 0x4a8e48f1},
{0x8ec8, 0x48a5490a},
{0x8ecc, 0x49094a8d},
{0x8ed0, 0x4a8c487d},
{0x8ed4, 0x48754908},
{0x8ed8, 0x49074a8b},
{0x8edc, 0x4a8a4889},
{0x8ee0, 0x48b74906},
{0x8ee4, 0x49054a89},
{0x8ee8, 0x4a8848fc},
{0x8eec, 0x48564905},
{0x8ef0, 0x49044a87},
{0x8ef4, 0x4a8648c1},
{0x8ef8, 0x483d4904},
{0x8efc, 0x49034a85},
{0x8f00, 0x4a8448c7},
{0x8f04, 0x485e4903},
{0x8f08, 0x49024a83},
{0x8f0c, 0x4a8248ac},
{0x8f10, 0x48624902},
{0x8f14, 0x49024a81},
{0x8f18, 0x4a804820},
{0x8f1c, 0x48004900},
{0x8f20, 0x49014a90},
{0x8f24, 0x4a10481f},
{0x8f28, 0x00060001},
{0x8f2c, 0x5f005f80},
{0x8f30, 0x00059900},
{0x8f34, 0x00017300},
{0x8f38, 0x63800006},
{0x8f3c, 0x98006300},
{0x8f40, 0x549f0001},
{0x8f44, 0x5c015400},
{0x8f48, 0x540054df},
{0x8f4c, 0x00015c02},
{0x8f50, 0x07145c01},
{0x8f54, 0x5c025400},
{0x8f58, 0x5c020001},
{0x8f5c, 0x54000714},
{0x8f60, 0x00015c01},
{0x8f64, 0x4c184c98},
{0x8f68, 0x00080001},
{0x8f6c, 0x5c020004},
{0x8f70, 0x09017430},
{0x8f74, 0x0ba60c01},
{0x8f78, 0x77800005},
{0x8f7c, 0x52200007},
{0x8f80, 0x43800004},
{0x8f84, 0x610a6008},
{0x8f88, 0x63c26200},
{0x8f8c, 0x5c000007},
{0x8f90, 0x43000004},
{0x8f94, 0x00000001},
{0x8080, 0x00000004},
{0x8080, 0x00000000},
{0x8088, 0x00000000},

View File

@@ -0,0 +1,39 @@
// 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 "usb.h"
static const struct rtw89_driver_info rtw89_8851bu_info = {
.chip = &rtw8851b_chip_info,
.variant = NULL,
.quirks = NULL,
};
static const struct usb_device_id rtw_8851bu_id_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb851, 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");

View File

@@ -2151,6 +2151,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
.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,
@@ -2184,8 +2185,8 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.max_amsdu_limit = 3500,
.dis_2g_40m_ul_ofdma = true,
.rsvd_ple_ofst = 0x6f800,
.hfc_param_ini = rtw8852a_hfc_param_ini_pcie,
.dle_mem = rtw8852a_dle_mem_pcie,
.hfc_param_ini = {rtw8852a_hfc_param_ini_pcie, NULL, NULL},
.dle_mem = {rtw8852a_dle_mem_pcie, NULL, NULL, NULL},
.wde_qempty_acq_grpnum = 16,
.wde_qempty_mgq_grpsel = 16,
.rf_base_addr = {0xc000, 0xd000},

View File

@@ -49,6 +49,48 @@ static const struct rtw89_hfc_param_ini rtw8852b_hfc_param_ini_pcie[] = {
[RTW89_QTA_INVALID] = {NULL},
};
static const struct rtw89_hfc_ch_cfg rtw8852b_hfc_chcfg_usb[] = {
{18, 152, grp_0}, /* ACH 0 */
{18, 152, grp_0}, /* ACH 1 */
{18, 152, grp_0}, /* ACH 2 */
{18, 152, 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 */
{18, 152, grp_0}, /* B0MGQ */
{18, 152, grp_0}, /* B0HIQ */
{0, 0, grp_0}, /* B1MGQ */
{0, 0, grp_0}, /* B1HIQ */
{0, 0, 0} /* FWCMDQ */
};
static const struct rtw89_hfc_pub_cfg rtw8852b_hfc_pubcfg_usb = {
152, /* Group 0 */
0, /* Group 1 */
152, /* Public Max */
0 /* WP threshold */
};
static const struct rtw89_hfc_prec_cfg rtw8852b_hfc_preccfg_usb = {
9, /* CH 0-11 pre-cost */
32, /* H2C pre-cost */
64, /* WP CH 0-7 pre-cost */
24, /* WP CH 8-11 pre-cost */
1, /* CH 0-11 full condition */
1, /* H2C full condition */
1, /* WP CH 0-7 full condition */
1, /* WP CH 8-11 full condition */
};
static const struct rtw89_hfc_param_ini rtw8852b_hfc_param_ini_usb[] = {
[RTW89_QTA_SCC] = {rtw8852b_hfc_chcfg_usb, &rtw8852b_hfc_pubcfg_usb,
&rtw8852b_hfc_preccfg_usb, RTW89_HCIFC_STF},
[RTW89_QTA_DLFW] = {NULL, NULL,
&rtw8852b_hfc_preccfg_usb, RTW89_HCIFC_STF},
[RTW89_QTA_INVALID] = {NULL},
};
static const struct rtw89_dle_mem rtw8852b_dle_mem_pcie[] = {
[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size7,
&rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt7,
@@ -66,6 +108,19 @@ static const struct rtw89_dle_mem rtw8852b_dle_mem_pcie[] = {
NULL},
};
static const struct rtw89_dle_mem rtw8852b_dle_mem_usb3[] = {
[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size25,
&rtw89_mac_size.ple_size33, &rtw89_mac_size.wde_qt25,
&rtw89_mac_size.wde_qt25, &rtw89_mac_size.ple_qt74,
&rtw89_mac_size.ple_qt75},
[RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size9,
&rtw89_mac_size.ple_size8, &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 rtw8852b_h2c_regs[RTW89_H2CREG_MAX] = {
R_AX_H2CREG_DATA0, R_AX_H2CREG_DATA1, R_AX_H2CREG_DATA2,
R_AX_H2CREG_DATA3
@@ -299,7 +354,8 @@ static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev)
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);
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
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);
@@ -361,7 +417,7 @@ static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev)
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);
if (rtwdev->hal.cv == CHIP_CBV) {
if (rtwdev->hal.cv == CHIP_CBV && rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) {
rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
rtw89_write16_mask(rtwdev, R_AX_HCI_LDO_CTRL, B_AX_R_AX_VADJ_MASK, 0xA);
rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
@@ -443,10 +499,22 @@ static int rtw8852b_pwr_off_func(struct rtw89_dev *rtwdev)
if (ret)
return ret;
rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION);
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION);
else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB)
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_SOP_EDSWR);
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);
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) {
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
} else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) {
val32 = rtw89_read32(rtwdev, R_AX_SYS_PW_CTRL);
val32 &= ~B_AX_AFSM_PCIE_SUS_EN;
val32 |= B_AX_AFSM_WLSUS_EN;
rtw89_write32(rtwdev, R_AX_SYS_PW_CTRL, val32);
}
return 0;
}
@@ -560,8 +628,11 @@ static void rtw8852b_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
static void rtw8852b_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));
rtw8852b_dpk_init(rtwdev);
rtw8852b_rck(rtwdev);
@@ -575,6 +646,7 @@ static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw8852b_mcc_get_ch_info(rtwdev, phy_idx);
rtw89_btc_ntfy_conn_rfk(rtwdev, true);
rtw8852b_rx_dck(rtwdev, phy_idx, chanctx_idx);
@@ -585,6 +657,7 @@ static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev,
rtw8852b_dpk(rtwdev, phy_idx, chanctx_idx);
rtw89_btc_ntfy_conn_rfk(rtwdev, false);
rtw89_fw_h2c_rf_ntfy_mcc(rtwdev);
}
static void rtw8852b_rfk_band_changed(struct rtw89_dev *rtwdev,
@@ -778,6 +851,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
.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,
@@ -793,6 +867,10 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
.btc_set_policy = rtw89_btc_set_policy_v1,
};
static const struct rtw89_chanctx_listener rtw8852b_chanctx_listener = {
.callbacks[RTW89_CHANCTX_CALLBACK_RFK] = rtw8852b_rfk_chanctx_cb,
};
#ifdef CONFIG_PM
static const struct wiphy_wowlan_support rtw_wowlan_stub_8852b = {
.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
@@ -820,8 +898,13 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.max_amsdu_limit = 5000,
.dis_2g_40m_ul_ofdma = true,
.rsvd_ple_ofst = 0x2f800,
.hfc_param_ini = rtw8852b_hfc_param_ini_pcie,
.dle_mem = rtw8852b_dle_mem_pcie,
.hfc_param_ini = {rtw8852b_hfc_param_ini_pcie,
rtw8852b_hfc_param_ini_usb,
NULL},
.dle_mem = {rtw8852b_dle_mem_pcie,
rtw8852b_dle_mem_usb3,
rtw8852b_dle_mem_usb3,
NULL},
.wde_qempty_acq_grpnum = 4,
.wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000, 0xf000},
@@ -836,6 +919,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.nctl_post_table = NULL,
.dflt_parms = &rtw89_8852b_dflt_parms,
.rfe_parms_conf = NULL,
.chanctx_listener = &rtw8852b_chanctx_listener,
.txpwr_factor_bb = 3,
.txpwr_factor_rf = 2,
.txpwr_factor_mac = 1,
@@ -844,7 +928,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.tssi_dbw_table = NULL,
.support_macid_num = RTW89_MAX_MAC_ID_NUM,
.support_link_num = 0,
.support_chanctx_num = 0,
.support_chanctx_num = 2,
.support_rnr = false,
.support_bands = BIT(NL80211_BAND_2GHZ) |
BIT(NL80211_BAND_5GHZ),

View File

@@ -172,14 +172,6 @@ static const struct rtw89_reg3_def rtw8852bx_btc_preagc_dis_defs[] = {
static DECLARE_PHY_REG3_TBL(rtw8852bx_btc_preagc_dis_defs);
static void rtw8852be_efuse_parsing(struct rtw89_efuse *efuse,
struct rtw8852bx_efuse *map)
{
ether_addr_copy(efuse->addr, map->e.mac_addr);
efuse->rfe_type = map->rfe_type;
efuse->xtal_cap = map->xtal_k;
}
static void rtw8852bx_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
struct rtw8852bx_efuse *map)
{
@@ -261,12 +253,18 @@ static int __rtw8852bx_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
switch (rtwdev->hci.type) {
case RTW89_HCI_TYPE_PCIE:
rtw8852be_efuse_parsing(efuse, map);
ether_addr_copy(efuse->addr, map->e.mac_addr);
break;
case RTW89_HCI_TYPE_USB:
ether_addr_copy(efuse->addr, map->u.mac_addr);
break;
default:
return -EOPNOTSUPP;
}
efuse->rfe_type = map->rfe_type;
efuse->xtal_cap = map->xtal_k;
rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type);
return 0;

View File

@@ -2,6 +2,7 @@
/* Copyright(c) 2019-2022 Realtek Corporation
*/
#include "chan.h"
#include "coex.h"
#include "debug.h"
#include "mac.h"
@@ -1145,19 +1146,19 @@ static void _lok_res_table(struct rtw89_dev *rtwdev, u8 path, u8 ibias)
static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path)
{
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u8 ch = rfk_mcc->table_idx;
bool is_fail1, is_fail2;
u32 vbuff_i;
u32 vbuff_q;
u32 core_i;
u32 core_q;
u32 tmp;
u8 ch;
tmp = rtw89_read_rf(rtwdev, path, RR_TXMO, RFREG_MASK);
core_i = FIELD_GET(RR_TXMO_COI, tmp);
core_q = FIELD_GET(RR_TXMO_COQ, tmp);
ch = (iqk_info->iqk_times / 2) % RTW89_IQK_CHS_NR;
if (core_i < 0x2 || core_i > 0x1d || core_q < 0x2 || core_q > 0x1d)
is_fail1 = true;
@@ -1386,26 +1387,11 @@ static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u
enum rtw89_chanctx_idx chanctx_idx)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u8 idx = rfk_mcc->table_idx;
u32 reg_rf18;
u32 reg_35c;
u8 idx;
u8 get_empty_table = false;
for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) {
if (iqk_info->iqk_mcc_ch[idx][path] == 0) {
get_empty_table = true;
break;
}
}
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (1)idx = %x\n", idx);
if (!get_empty_table) {
idx = iqk_info->iqk_table_idx[path] + 1;
if (idx > 1)
idx = 0;
}
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (2)idx = %x\n", idx);
reg_rf18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK);
reg_35c = rtw89_phy_read32_mask(rtwdev, R_CIRST, B_CIRST_SYN);
@@ -1506,11 +1492,10 @@ static void _iqk_afebb_restore(struct rtw89_dev *rtwdev,
static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path)
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u8 idx;
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
u8 idx = rfk_mcc->table_idx;
idx = iqk_info->iqk_table_idx[path];
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (3)idx = %x\n", idx);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] idx = %x\n", idx);
rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_IQC, idx);
rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3, idx);
@@ -4179,3 +4164,49 @@ void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev,
rtw8852b_ctrl_bw_ch(rtwdev, phy_idx, chan->channel, chan->band_type,
chan->band_width);
}
void rtw8852b_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
const struct rtw89_chan *chan = rtw89_mgnt_chan_get(rtwdev, 0);
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V0] = {};
u8 idx;
for (idx = 0; idx < ARRAY_SIZE(desc); idx++) {
struct rtw89_rfk_chan_desc *p = &desc[idx];
p->ch = rfk_mcc->ch[idx];
p->has_band = true;
p->band = rfk_mcc->band[idx];
}
idx = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan);
rfk_mcc->ch[idx] = chan->channel;
rfk_mcc->band[idx] = chan->band_type;
rfk_mcc->table_idx = idx;
}
void rtw8852b_rfk_chanctx_cb(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_state state)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
u8 path;
switch (state) {
case RTW89_CHANCTX_STATE_MCC_START:
dpk->is_dpk_enable = false;
for (path = 0; path < RTW8852B_DPK_RF_PATH; path++)
_dpk_onoff(rtwdev, path, false);
break;
case RTW89_CHANCTX_STATE_MCC_STOP:
dpk->is_dpk_enable = true;
for (path = 0; path < RTW8852B_DPK_RF_PATH; path++)
_dpk_onoff(rtwdev, path, false);
rtw8852b_dpk(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0);
break;
default:
break;
}
}

View File

@@ -27,5 +27,8 @@ void rtw8852b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
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

View File

@@ -533,8 +533,11 @@ static void rtw8852bt_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
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);
@@ -548,6 +551,7 @@ static void rtw8852bt_rfk_channel(struct rtw89_dev *rtwdev,
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);
@@ -558,6 +562,7 @@ static void rtw8852bt_rfk_channel(struct rtw89_dev *rtwdev,
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,
@@ -712,6 +717,7 @@ static const struct rtw89_chip_ops rtw8852bt_chip_ops = {
.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,
@@ -727,6 +733,10 @@ static const struct rtw89_chip_ops rtw8852bt_chip_ops = {
.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,
@@ -754,8 +764,8 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
.max_amsdu_limit = 5000,
.dis_2g_40m_ul_ofdma = true,
.rsvd_ple_ofst = 0x6f800,
.hfc_param_ini = rtw8852bt_hfc_param_ini_pcie,
.dle_mem = rtw8852bt_dle_mem_pcie,
.hfc_param_ini = {rtw8852bt_hfc_param_ini_pcie, 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},
@@ -769,6 +779,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
.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,
@@ -777,7 +788,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
.tssi_dbw_table = NULL,
.support_macid_num = RTW89_MAX_MAC_ID_NUM,
.support_link_num = 0,
.support_chanctx_num = 1,
.support_chanctx_num = 2,
.support_rnr = false,
.support_bands = BIT(NL80211_BAND_2GHZ) |
BIT(NL80211_BAND_5GHZ),

View File

@@ -2,6 +2,7 @@
/* Copyright(c) 2024 Realtek Corporation
*/
#include "chan.h"
#include "coex.h"
#include "debug.h"
#include "fw.h"
@@ -1529,26 +1530,11 @@ static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u
enum rtw89_chanctx_idx chanctx_idx)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u8 get_empty_table = false;
u8 idx = rfk_mcc->table_idx;
u32 reg_rf18;
u32 reg_35c;
u8 idx;
for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) {
if (iqk_info->iqk_mcc_ch[idx][path] == 0) {
get_empty_table = true;
break;
}
}
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (1)idx = %x\n", idx);
if (!get_empty_table) {
idx = iqk_info->iqk_table_idx[path] + 1;
if (idx > 1)
idx = 0;
}
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (2)idx = %x\n", idx);
reg_rf18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK);
reg_35c = rtw89_phy_read32_mask(rtwdev, R_CIRST, B_CIRST_SYN);
@@ -1640,7 +1626,8 @@ static void _iqk_afebb_restore(struct rtw89_dev *rtwdev,
static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path)
{
u8 idx = 0;
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
u8 idx = rfk_mcc->table_idx;
rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), 0x00000001, idx);
rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), 0x00000008, idx);
@@ -4252,3 +4239,49 @@ void rtw8852bt_set_channel_rf(struct rtw89_dev *rtwdev,
rtw8852bt_ctrl_bw_ch(rtwdev, phy_idx, chan->channel, chan->band_type,
chan->band_width);
}
void rtw8852bt_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
const struct rtw89_chan *chan = rtw89_mgnt_chan_get(rtwdev, 0);
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V0] = {};
u8 idx;
for (idx = 0; idx < ARRAY_SIZE(desc); idx++) {
struct rtw89_rfk_chan_desc *p = &desc[idx];
p->ch = rfk_mcc->ch[idx];
p->has_band = true;
p->band = rfk_mcc->band[idx];
}
idx = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan);
rfk_mcc->ch[idx] = chan->channel;
rfk_mcc->band[idx] = chan->band_type;
rfk_mcc->table_idx = idx;
}
void rtw8852bt_rfk_chanctx_cb(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_state state)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
u8 path;
switch (state) {
case RTW89_CHANCTX_STATE_MCC_START:
dpk->is_dpk_enable = false;
for (path = 0; path < RTW8852BT_SS; path++)
_dpk_onoff(rtwdev, path, false);
break;
case RTW89_CHANCTX_STATE_MCC_STOP:
dpk->is_dpk_enable = true;
for (path = 0; path < RTW8852BT_SS; path++)
_dpk_onoff(rtwdev, path, false);
rtw8852bt_dpk(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0);
break;
default:
break;
}
}

View File

@@ -27,5 +27,8 @@ void rtw8852bt_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
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

View File

@@ -0,0 +1,55 @@
// 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 "usb.h"
static const struct rtw89_driver_info rtw89_8852bu_info = {
.chip = &rtw8852b_chip_info,
.variant = NULL,
.quirks = NULL,
};
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(0x0db0, 0x6931, 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");

View File

@@ -2971,6 +2971,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
.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,
@@ -3004,8 +3005,8 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.max_amsdu_limit = 8000,
.dis_2g_40m_ul_ofdma = false,
.rsvd_ple_ofst = 0x6f800,
.hfc_param_ini = rtw8852c_hfc_param_ini_pcie,
.dle_mem = rtw8852c_dle_mem_pcie,
.hfc_param_ini = {rtw8852c_hfc_param_ini_pcie, NULL, NULL},
.dle_mem = {rtw8852c_dle_mem_pcie, NULL, NULL, NULL},
.wde_qempty_acq_grpnum = 16,
.wde_qempty_mgq_grpsel = 16,
.rf_base_addr = {0xe000, 0xf000},

View File

@@ -2826,6 +2826,7 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = {
.h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl_g7,
.h2c_ampdu_cmac_tbl = rtw89_fw_h2c_ampdu_cmac_tbl_g7,
.h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl_g7,
.h2c_punctured_cmac_tbl = rtw89_fw_h2c_punctured_cmac_tbl_g7,
.h2c_default_dmac_tbl = rtw89_fw_h2c_default_dmac_tbl_v2,
.h2c_update_beacon = rtw89_fw_h2c_update_beacon_be,
.h2c_ba_cam = rtw89_fw_h2c_ba_cam_v1,
@@ -2859,8 +2860,8 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.max_amsdu_limit = 8000,
.dis_2g_40m_ul_ofdma = false,
.rsvd_ple_ofst = 0x8f800,
.hfc_param_ini = rtw8922a_hfc_param_ini_pcie,
.dle_mem = rtw8922a_dle_mem_pcie,
.hfc_param_ini = {rtw8922a_hfc_param_ini_pcie, NULL, NULL},
.dle_mem = {rtw8922a_dle_mem_pcie, NULL, NULL, NULL},
.wde_qempty_acq_grpnum = 4,
.wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000, 0xf000},

View File

@@ -492,6 +492,7 @@ static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt)
case SER_EV_STATE_IN:
wiphy_lock(wiphy);
wiphy_delayed_work_cancel(wiphy, &rtwdev->track_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->track_ps_work);
wiphy_unlock(wiphy);
drv_stop_tx(ser);
@@ -525,6 +526,8 @@ static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt)
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:

View File

@@ -73,6 +73,7 @@ static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate)
#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)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
/* 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_BULKOUT_NUM 7
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;
__le32 *vendor_req_buf;
atomic_t continual_io_error;
u8 in_pipe;
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 sk_buff_head tx_queue[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

View File

@@ -12,7 +12,7 @@
#include "util.h"
#include "wow.h"
void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb)
void __rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb)
{
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
@@ -1412,6 +1412,8 @@ static void rtw89_fw_release_pno_pkt_list(struct rtw89_dev *rtwdev,
static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
static const u8 basic_rate_ie[] = {WLAN_EID_SUPP_RATES, 0x08,
0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c};
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config;
u8 num = nd_config->n_match_sets, i;
@@ -1423,10 +1425,11 @@ static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev,
skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr,
nd_config->match_sets[i].ssid.ssid,
nd_config->match_sets[i].ssid.ssid_len,
nd_config->ie_len);
nd_config->ie_len + sizeof(basic_rate_ie));
if (!skb)
return -ENOMEM;
skb_put_data(skb, basic_rate_ie, sizeof(basic_rate_ie));
skb_put_data(skb, nd_config->ie, nd_config->ie_len);
info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -1477,7 +1480,7 @@ static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable)
opt.enable = enable;
opt.repeat = RTW89_SCAN_NORMAL;
opt.norm_pd = max(interval, 1) * 10; /* in unit of 100ms */
opt.delay = max(rtw_wow->nd_config->delay, 1);
opt.delay = max(rtw_wow->nd_config->delay, 1) * 1000;
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
opt.operation = enable ? RTW89_SCAN_OP_START : RTW89_SCAN_OP_STOP;
@@ -1489,7 +1492,7 @@ static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable)
opt.opch_end = RTW89_CHAN_INVALID;
}
mac->scan_offload(rtwdev, &opt, rtwvif_link, true);
rtw89_mac_scan_offload(rtwdev, &opt, rtwvif_link, true);
return 0;
}

View File

@@ -116,9 +116,21 @@ static inline bool rtw_wow_has_mgd_features(struct rtw89_dev *rtwdev)
return !bitmap_empty(rtw_wow->flags, RTW89_WOW_FLAG_NUM);
}
void __rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb);
static inline
void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
if (likely(!ieee80211_is_assoc_req(hdr->frame_control)))
return;
__rtw89_wow_parse_akm(rtwdev, skb);
}
int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan);
int rtw89_wow_resume(struct rtw89_dev *rtwdev);
void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb);
#else
static inline
void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb)