mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 05:39:42 -04:00
Merge tag 'rtw-next-2025-03-13' of https://github.com/pkshih/rtw
Ping-Ke Shih says: ==================== rtw-next patches for v6.15 Some minor fixes and refinements of rtw89. The only major change is rtw88: * support RTL8814AE/RTL8814AU ==================== Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
@@ -54,6 +54,9 @@ config RTW88_8812A
|
||||
tristate
|
||||
select RTW88_88XXA
|
||||
|
||||
config RTW88_8814A
|
||||
tristate
|
||||
|
||||
config RTW88_8822BE
|
||||
tristate "Realtek 8822BE PCI wireless network adapter"
|
||||
depends on PCI
|
||||
@@ -222,6 +225,28 @@ config RTW88_8812AU
|
||||
|
||||
802.11ac USB wireless network adapter
|
||||
|
||||
config RTW88_8814AE
|
||||
tristate "Realtek 8814AE PCI wireless network adapter"
|
||||
depends on PCI
|
||||
select RTW88_CORE
|
||||
select RTW88_PCI
|
||||
select RTW88_8814A
|
||||
help
|
||||
Select this option will enable support for 8814AE chipset
|
||||
|
||||
802.11ac PCIe wireless network adapter
|
||||
|
||||
config RTW88_8814AU
|
||||
tristate "Realtek 8814AU USB wireless network adapter"
|
||||
depends on USB
|
||||
select RTW88_CORE
|
||||
select RTW88_USB
|
||||
select RTW88_8814A
|
||||
help
|
||||
Select this option will enable support for 8814AU chipset
|
||||
|
||||
802.11ac USB wireless network adapter
|
||||
|
||||
config RTW88_DEBUG
|
||||
bool "Realtek rtw88 debug support"
|
||||
depends on RTW88_CORE
|
||||
|
||||
@@ -94,6 +94,15 @@ rtw88_8821au-objs := rtw8821au.o
|
||||
obj-$(CONFIG_RTW88_8812AU) += rtw88_8812au.o
|
||||
rtw88_8812au-objs := rtw8812au.o
|
||||
|
||||
obj-$(CONFIG_RTW88_8814A) += rtw88_8814a.o
|
||||
rtw88_8814a-objs := rtw8814a.o rtw8814a_table.o
|
||||
|
||||
obj-$(CONFIG_RTW88_8814AE) += rtw88_8814ae.o
|
||||
rtw88_8814ae-objs := rtw8814ae.o
|
||||
|
||||
obj-$(CONFIG_RTW88_8814AU) += rtw88_8814au.o
|
||||
rtw88_8814au-objs := rtw8814au.o
|
||||
|
||||
obj-$(CONFIG_RTW88_PCI) += rtw88_pci.o
|
||||
rtw88_pci-objs := pci.o
|
||||
|
||||
|
||||
@@ -654,10 +654,10 @@ static void rtw_print_rate(struct seq_file *m, u8 rate)
|
||||
case DESC_RATE6M...DESC_RATE54M:
|
||||
rtw_print_ofdm_rate_txt(m, rate);
|
||||
break;
|
||||
case DESC_RATEMCS0...DESC_RATEMCS15:
|
||||
case DESC_RATEMCS0...DESC_RATEMCS31:
|
||||
rtw_print_ht_rate_txt(m, rate);
|
||||
break;
|
||||
case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9:
|
||||
case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT4SS_MCS9:
|
||||
rtw_print_vht_rate_txt(m, rate);
|
||||
break;
|
||||
default:
|
||||
@@ -692,9 +692,11 @@ static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v)
|
||||
{
|
||||
struct rtw_debugfs_priv *debugfs_priv = m->private;
|
||||
struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
|
||||
struct rtw_hal *hal = &rtwdev->hal;
|
||||
u8 path, rate, bw, ch, regd;
|
||||
struct rtw_power_params pwr_param = {0};
|
||||
struct rtw_hal *hal = &rtwdev->hal;
|
||||
u8 nss = rtwdev->efuse.hw_cap.nss;
|
||||
u8 path, rate, bw, ch, regd;
|
||||
u8 max_ht_rate, max_rate;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
bw = hal->current_band_width;
|
||||
@@ -707,19 +709,23 @@ static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v)
|
||||
seq_printf(m, "%-4s %-10s %-9s %-9s (%-4s %-4s %-4s) %-4s\n",
|
||||
"path", "rate", "pwr", "base", "byr", "lmt", "sar", "rem");
|
||||
|
||||
max_ht_rate = DESC_RATEMCS0 + nss * 8 - 1;
|
||||
|
||||
if (rtwdev->chip->vht_supported)
|
||||
max_rate = DESC_RATEVHT1SS_MCS0 + nss * 10 - 1;
|
||||
else
|
||||
max_rate = max_ht_rate;
|
||||
|
||||
mutex_lock(&hal->tx_power_mutex);
|
||||
for (path = RF_PATH_A; path <= RF_PATH_B; path++) {
|
||||
for (path = RF_PATH_A; path < hal->rf_path_num; path++) {
|
||||
/* there is no CCK rates used in 5G */
|
||||
if (hal->current_band_type == RTW_BAND_5G)
|
||||
rate = DESC_RATE6M;
|
||||
else
|
||||
rate = DESC_RATE1M;
|
||||
|
||||
/* now, not support vht 3ss and vht 4ss*/
|
||||
for (; rate <= DESC_RATEVHT2SS_MCS9; rate++) {
|
||||
/* now, not support ht 3ss and ht 4ss*/
|
||||
if (rate > DESC_RATEMCS15 &&
|
||||
rate < DESC_RATEVHT1SS_MCS0)
|
||||
for (; rate <= max_rate; rate++) {
|
||||
if (rate > max_ht_rate && rate <= DESC_RATEMCS31)
|
||||
continue;
|
||||
|
||||
rtw_get_tx_power_params(rtwdev, path, rate, bw,
|
||||
@@ -849,20 +855,28 @@ static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v)
|
||||
last_cnt->num_qry_pkt[rate_id + 9]);
|
||||
}
|
||||
|
||||
seq_printf(m, "[RSSI(dBm)] = {%d, %d}\n",
|
||||
seq_printf(m, "[RSSI(dBm)] = {%d, %d, %d, %d}\n",
|
||||
dm_info->rssi[RF_PATH_A] - 100,
|
||||
dm_info->rssi[RF_PATH_B] - 100);
|
||||
seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d}\n",
|
||||
dm_info->rssi[RF_PATH_B] - 100,
|
||||
dm_info->rssi[RF_PATH_C] - 100,
|
||||
dm_info->rssi[RF_PATH_D] - 100);
|
||||
seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d, -%d, -%d}\n",
|
||||
dm_info->rx_evm_dbm[RF_PATH_A],
|
||||
dm_info->rx_evm_dbm[RF_PATH_B]);
|
||||
seq_printf(m, "[Rx SNR] = {%d, %d}\n",
|
||||
dm_info->rx_evm_dbm[RF_PATH_B],
|
||||
dm_info->rx_evm_dbm[RF_PATH_C],
|
||||
dm_info->rx_evm_dbm[RF_PATH_D]);
|
||||
seq_printf(m, "[Rx SNR] = {%d, %d, %d, %d}\n",
|
||||
dm_info->rx_snr[RF_PATH_A],
|
||||
dm_info->rx_snr[RF_PATH_B]);
|
||||
seq_printf(m, "[CFO_tail(KHz)] = {%d, %d}\n",
|
||||
dm_info->rx_snr[RF_PATH_B],
|
||||
dm_info->rx_snr[RF_PATH_C],
|
||||
dm_info->rx_snr[RF_PATH_D]);
|
||||
seq_printf(m, "[CFO_tail(KHz)] = {%d, %d, %d, %d}\n",
|
||||
dm_info->cfo_tail[RF_PATH_A],
|
||||
dm_info->cfo_tail[RF_PATH_B]);
|
||||
dm_info->cfo_tail[RF_PATH_B],
|
||||
dm_info->cfo_tail[RF_PATH_C],
|
||||
dm_info->cfo_tail[RF_PATH_D]);
|
||||
|
||||
if (dm_info->curr_rx_rate >= DESC_RATE11M) {
|
||||
if (dm_info->curr_rx_rate >= DESC_RATE6M) {
|
||||
seq_puts(m, "[Rx Average Status]:\n");
|
||||
seq_printf(m, " * OFDM, EVM: {-%d}, SNR: {%d}\n",
|
||||
(u8)ewma_evm_read(&ewma_evm[RTW_EVM_OFDM]),
|
||||
@@ -875,6 +889,13 @@ static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v)
|
||||
(u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_B]),
|
||||
(u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_A]),
|
||||
(u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_B]));
|
||||
seq_printf(m, " * 3SS, EVM: {-%d, -%d, -%d}, SNR: {%d, %d, %d}\n",
|
||||
(u8)ewma_evm_read(&ewma_evm[RTW_EVM_3SS_A]),
|
||||
(u8)ewma_evm_read(&ewma_evm[RTW_EVM_3SS_B]),
|
||||
(u8)ewma_evm_read(&ewma_evm[RTW_EVM_3SS_C]),
|
||||
(u8)ewma_snr_read(&ewma_snr[RTW_SNR_3SS_A]),
|
||||
(u8)ewma_snr_read(&ewma_snr[RTW_SNR_3SS_B]),
|
||||
(u8)ewma_snr_read(&ewma_snr[RTW_SNR_3SS_C]));
|
||||
}
|
||||
|
||||
seq_puts(m, "[Rx Counter]:\n");
|
||||
|
||||
@@ -291,6 +291,7 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
|
||||
if (rtw_read8(rtwdev, REG_CR) == 0xea)
|
||||
cur_pwr = false;
|
||||
else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB &&
|
||||
chip->id != RTW_CHIP_TYPE_8814A &&
|
||||
(rtw_read8(rtwdev, REG_SYS_STATUS1 + 1) & BIT(0)))
|
||||
cur_pwr = false;
|
||||
else
|
||||
|
||||
@@ -1565,6 +1565,7 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev,
|
||||
{
|
||||
const struct rtw_chip_info *chip = rtwdev->chip;
|
||||
struct rtw_efuse *efuse = &rtwdev->efuse;
|
||||
int i;
|
||||
|
||||
ht_cap->ht_supported = true;
|
||||
ht_cap->cap = 0;
|
||||
@@ -1584,25 +1585,20 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev,
|
||||
ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
|
||||
ht_cap->ampdu_density = chip->ampdu_density;
|
||||
ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
|
||||
if (efuse->hw_cap.nss > 1) {
|
||||
ht_cap->mcs.rx_mask[0] = 0xFF;
|
||||
ht_cap->mcs.rx_mask[1] = 0xFF;
|
||||
ht_cap->mcs.rx_mask[4] = 0x01;
|
||||
ht_cap->mcs.rx_highest = cpu_to_le16(300);
|
||||
} else {
|
||||
ht_cap->mcs.rx_mask[0] = 0xFF;
|
||||
ht_cap->mcs.rx_mask[1] = 0x00;
|
||||
ht_cap->mcs.rx_mask[4] = 0x01;
|
||||
ht_cap->mcs.rx_highest = cpu_to_le16(150);
|
||||
}
|
||||
|
||||
for (i = 0; i < efuse->hw_cap.nss; i++)
|
||||
ht_cap->mcs.rx_mask[i] = 0xFF;
|
||||
ht_cap->mcs.rx_mask[4] = 0x01;
|
||||
ht_cap->mcs.rx_highest = cpu_to_le16(150 * efuse->hw_cap.nss);
|
||||
}
|
||||
|
||||
static void rtw_init_vht_cap(struct rtw_dev *rtwdev,
|
||||
struct ieee80211_sta_vht_cap *vht_cap)
|
||||
{
|
||||
struct rtw_efuse *efuse = &rtwdev->efuse;
|
||||
u16 mcs_map;
|
||||
u16 mcs_map = 0;
|
||||
__le16 highest;
|
||||
int i;
|
||||
|
||||
if (efuse->hw_cap.ptcl != EFUSE_HW_CAP_IGNORE &&
|
||||
efuse->hw_cap.ptcl != EFUSE_HW_CAP_PTCL_VHT)
|
||||
@@ -1625,21 +1621,15 @@ static void rtw_init_vht_cap(struct rtw_dev *rtwdev,
|
||||
if (rtw_chip_has_rx_ldpc(rtwdev))
|
||||
vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC;
|
||||
|
||||
mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
|
||||
IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
|
||||
IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
|
||||
IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
|
||||
IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
|
||||
IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
|
||||
IEEE80211_VHT_MCS_NOT_SUPPORTED << 14;
|
||||
if (efuse->hw_cap.nss > 1) {
|
||||
highest = cpu_to_le16(780);
|
||||
mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << 2;
|
||||
} else {
|
||||
highest = cpu_to_le16(390);
|
||||
mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << 2;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (i < efuse->hw_cap.nss)
|
||||
mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
|
||||
else
|
||||
mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
|
||||
}
|
||||
|
||||
highest = cpu_to_le16(390 * efuse->hw_cap.nss);
|
||||
|
||||
vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
|
||||
vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
|
||||
vht_cap->vht_mcs.rx_highest = highest;
|
||||
|
||||
@@ -386,6 +386,9 @@ enum rtw_evm {
|
||||
RTW_EVM_1SS,
|
||||
RTW_EVM_2SS_A,
|
||||
RTW_EVM_2SS_B,
|
||||
RTW_EVM_3SS_A,
|
||||
RTW_EVM_3SS_B,
|
||||
RTW_EVM_3SS_C,
|
||||
/* keep it last */
|
||||
RTW_EVM_NUM
|
||||
};
|
||||
@@ -403,6 +406,10 @@ enum rtw_snr {
|
||||
RTW_SNR_2SS_B,
|
||||
RTW_SNR_2SS_C,
|
||||
RTW_SNR_2SS_D,
|
||||
RTW_SNR_3SS_A,
|
||||
RTW_SNR_3SS_B,
|
||||
RTW_SNR_3SS_C,
|
||||
RTW_SNR_3SS_D,
|
||||
/* keep it last */
|
||||
RTW_SNR_NUM
|
||||
};
|
||||
@@ -828,7 +835,7 @@ struct rtw_vif {
|
||||
};
|
||||
|
||||
struct rtw_regulatory {
|
||||
char alpha2[2];
|
||||
char alpha2[2] __nonstring;
|
||||
u8 txpwr_regd_2g;
|
||||
u8 txpwr_regd_5g;
|
||||
};
|
||||
|
||||
@@ -2458,32 +2458,56 @@ void rtw_phy_config_swing_table(struct rtw_dev *rtwdev,
|
||||
swing_table->n[RF_PATH_A] = tbl->pwrtrk_2g_ccka_n;
|
||||
swing_table->p[RF_PATH_B] = tbl->pwrtrk_2g_cckb_p;
|
||||
swing_table->n[RF_PATH_B] = tbl->pwrtrk_2g_cckb_n;
|
||||
swing_table->p[RF_PATH_C] = tbl->pwrtrk_2g_cckc_p;
|
||||
swing_table->n[RF_PATH_C] = tbl->pwrtrk_2g_cckc_n;
|
||||
swing_table->p[RF_PATH_D] = tbl->pwrtrk_2g_cckd_p;
|
||||
swing_table->n[RF_PATH_D] = tbl->pwrtrk_2g_cckd_n;
|
||||
} else {
|
||||
swing_table->p[RF_PATH_A] = tbl->pwrtrk_2ga_p;
|
||||
swing_table->n[RF_PATH_A] = tbl->pwrtrk_2ga_n;
|
||||
swing_table->p[RF_PATH_B] = tbl->pwrtrk_2gb_p;
|
||||
swing_table->n[RF_PATH_B] = tbl->pwrtrk_2gb_n;
|
||||
swing_table->p[RF_PATH_C] = tbl->pwrtrk_2gc_p;
|
||||
swing_table->n[RF_PATH_C] = tbl->pwrtrk_2gc_n;
|
||||
swing_table->p[RF_PATH_D] = tbl->pwrtrk_2gd_p;
|
||||
swing_table->n[RF_PATH_D] = tbl->pwrtrk_2gd_n;
|
||||
}
|
||||
} else if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) {
|
||||
swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_1];
|
||||
swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_1];
|
||||
swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_1];
|
||||
swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_1];
|
||||
swing_table->p[RF_PATH_C] = tbl->pwrtrk_5gc_p[RTW_PWR_TRK_5G_1];
|
||||
swing_table->n[RF_PATH_C] = tbl->pwrtrk_5gc_n[RTW_PWR_TRK_5G_1];
|
||||
swing_table->p[RF_PATH_D] = tbl->pwrtrk_5gd_p[RTW_PWR_TRK_5G_1];
|
||||
swing_table->n[RF_PATH_D] = tbl->pwrtrk_5gd_n[RTW_PWR_TRK_5G_1];
|
||||
} else if (IS_CH_5G_BAND_3(channel)) {
|
||||
swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_2];
|
||||
swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_2];
|
||||
swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_2];
|
||||
swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_2];
|
||||
swing_table->p[RF_PATH_C] = tbl->pwrtrk_5gc_p[RTW_PWR_TRK_5G_2];
|
||||
swing_table->n[RF_PATH_C] = tbl->pwrtrk_5gc_n[RTW_PWR_TRK_5G_2];
|
||||
swing_table->p[RF_PATH_D] = tbl->pwrtrk_5gd_p[RTW_PWR_TRK_5G_2];
|
||||
swing_table->n[RF_PATH_D] = tbl->pwrtrk_5gd_n[RTW_PWR_TRK_5G_2];
|
||||
} else if (IS_CH_5G_BAND_4(channel)) {
|
||||
swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_3];
|
||||
swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_3];
|
||||
swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_3];
|
||||
swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_3];
|
||||
swing_table->p[RF_PATH_C] = tbl->pwrtrk_5gc_p[RTW_PWR_TRK_5G_3];
|
||||
swing_table->n[RF_PATH_C] = tbl->pwrtrk_5gc_n[RTW_PWR_TRK_5G_3];
|
||||
swing_table->p[RF_PATH_D] = tbl->pwrtrk_5gd_p[RTW_PWR_TRK_5G_3];
|
||||
swing_table->n[RF_PATH_D] = tbl->pwrtrk_5gd_n[RTW_PWR_TRK_5G_3];
|
||||
} else {
|
||||
swing_table->p[RF_PATH_A] = tbl->pwrtrk_2ga_p;
|
||||
swing_table->n[RF_PATH_A] = tbl->pwrtrk_2ga_n;
|
||||
swing_table->p[RF_PATH_B] = tbl->pwrtrk_2gb_p;
|
||||
swing_table->n[RF_PATH_B] = tbl->pwrtrk_2gb_n;
|
||||
swing_table->p[RF_PATH_C] = tbl->pwrtrk_2gc_p;
|
||||
swing_table->n[RF_PATH_C] = tbl->pwrtrk_2gc_n;
|
||||
swing_table->p[RF_PATH_D] = tbl->pwrtrk_2gd_p;
|
||||
swing_table->n[RF_PATH_D] = tbl->pwrtrk_2gd_n;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(rtw_phy_config_swing_table);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define REG_SYS_FUNC_EN 0x0002
|
||||
#define BIT_FEN_EN_25_1 BIT(13)
|
||||
#define BIT_FEN_ELDR BIT(12)
|
||||
#define BIT_FEN_PCIEA BIT(6)
|
||||
#define BIT_FEN_CPUEN BIT(2)
|
||||
#define BIT_FEN_USBA BIT(2)
|
||||
#define BIT_FEN_BB_GLB_RST BIT(1)
|
||||
@@ -39,6 +40,9 @@
|
||||
#define BIT_RF_RSTB BIT(1)
|
||||
#define BIT_RF_EN BIT(0)
|
||||
|
||||
#define REG_RF_CTRL1 0x0020
|
||||
#define REG_RF_CTRL2 0x0021
|
||||
|
||||
#define REG_AFE_CTRL1 0x0024
|
||||
#define BIT_MAC_CLK_SEL (BIT(20) | BIT(21))
|
||||
#define REG_EFUSE_CTRL 0x0030
|
||||
@@ -73,6 +77,8 @@
|
||||
#define BIT_BT_PTA_EN BIT(5)
|
||||
#define BIT_WLRFE_4_5_EN BIT(2)
|
||||
|
||||
#define REG_GPIO_PIN_CTRL 0x0044
|
||||
|
||||
#define REG_LED_CFG 0x004C
|
||||
#define BIT_LNAON_SEL_EN BIT(26)
|
||||
#define BIT_PAPE_SEL_EN BIT(25)
|
||||
@@ -110,6 +116,7 @@
|
||||
#define BIT_SDIO_PAD_E5 BIT(18)
|
||||
|
||||
#define REG_RF_B_CTRL 0x76
|
||||
#define REG_RF_CTRL3 0x0076
|
||||
|
||||
#define REG_AFE_CTRL_4 0x0078
|
||||
#define BIT_CK320M_AFE_EN BIT(4)
|
||||
@@ -603,15 +610,25 @@
|
||||
#define REG_CCA2ND 0x0838
|
||||
#define REG_L1PKTH 0x0848
|
||||
#define REG_CLKTRK 0x0860
|
||||
#define REG_CSI_MASK_SETTING1 0x0874
|
||||
#define REG_NBI_SETTING 0x087c
|
||||
#define BIT_NBI_ENABLE BIT(13)
|
||||
#define REG_CSI_FIX_MASK0 0x0880
|
||||
#define REG_CSI_FIX_MASK1 0x0884
|
||||
#define REG_CSI_FIX_MASK6 0x0898
|
||||
#define REG_CSI_FIX_MASK7 0x089c
|
||||
#define REG_ADCCLK 0x08AC
|
||||
#define REG_HSSI_READ 0x08B0
|
||||
#define REG_FPGA0_XCD_RF_PARA 0x08B4
|
||||
#define REG_RX_MCS_LIMIT 0x08BC
|
||||
#define REG_ADC160 0x08C4
|
||||
#define REG_DBGSEL 0x08fc
|
||||
#define REG_ANTSEL_SW 0x0900
|
||||
#define REG_DAC_RSTB 0x090c
|
||||
#define REG_PSD 0x0910
|
||||
#define BIT_PSD_INI GENMASK(23, 22)
|
||||
#define REG_SINGLE_TONE_CONT_TX 0x0914
|
||||
|
||||
#define REG_AGC_TABLE 0x0958
|
||||
#define REG_RFE_CTRL_E 0x0974
|
||||
#define REG_2ND_CCA_CTRL 0x0976
|
||||
#define REG_IQK_COM00 0x0978
|
||||
@@ -621,10 +638,18 @@
|
||||
|
||||
#define REG_FAS 0x09a4
|
||||
#define REG_RXSB 0x0a00
|
||||
#define BIT_RXSB_ANA_DIV BIT(15)
|
||||
#define REG_CCK_RX 0x0a04
|
||||
#define REG_CCK_PD_TH 0x0a0a
|
||||
|
||||
#define REG_CCK0_FAREPORT 0xa2c
|
||||
#define REG_PRECTRL 0x0a14
|
||||
#define BIT_DIS_CO_PATHSEL BIT(7)
|
||||
#define BIT_IQ_WGT GENMASK(9, 8)
|
||||
#define REG_CCA_MF 0x0a20
|
||||
#define BIT_MBC_WIN GENMASK(5, 4)
|
||||
#define REG_CCK0_TX_FILTER1 0x0a20
|
||||
#define REG_CCK0_TX_FILTER2 0x0a24
|
||||
#define REG_CCK0_DEBUG_PORT 0x0a28
|
||||
#define REG_CCK0_FAREPORT 0x0a2c
|
||||
#define BIT_CCK0_2RX BIT(18)
|
||||
#define BIT_CCK0_MRC BIT(22)
|
||||
#define REG_FA_CCK 0x0a5c
|
||||
@@ -643,10 +668,18 @@
|
||||
#define DIS_DPD_RATEVHT2SS_MCS1 BIT(9)
|
||||
#define DIS_DPD_RATEALL GENMASK(9, 0)
|
||||
|
||||
#define REG_CCA 0x0a70
|
||||
#define BIT_CCA_CO BIT(7)
|
||||
#define REG_ANTSEL 0x0a74
|
||||
#define BIT_ANT_BYCO BIT(8)
|
||||
#define REG_CCKTX 0x0a84
|
||||
#define BIT_CMB_CCA_2R BIT(28)
|
||||
|
||||
#define REG_CNTRST 0x0b58
|
||||
|
||||
#define REG_3WIRE_SWA 0x0c00
|
||||
#define REG_RX_IQC_AB_A 0x0c10
|
||||
#define REG_RX_IQC_CD_A 0x0c14
|
||||
#define REG_TXSCALE_A 0x0c1c
|
||||
#define BB_SWING_MASK GENMASK(31, 21)
|
||||
#define REG_TX_AGC_A_CCK_11_CCK_1 0xc20
|
||||
@@ -674,7 +707,7 @@
|
||||
#define REG_LSSI_WRITE_A 0x0c90
|
||||
#define REG_PREDISTA 0x0c90
|
||||
#define REG_TXAGCIDX 0x0c94
|
||||
|
||||
#define REG_TX_AGC_A 0x0c94
|
||||
#define REG_RFE_PINMUX_A 0x0cb0
|
||||
#define REG_RFE_INV_A 0x0cb4
|
||||
#define REG_RFE_CTRL8 0x0cb4
|
||||
@@ -683,6 +716,7 @@
|
||||
#define DPDT_CTRL_PIN 0x77
|
||||
#define RFE_INV_MASK 0x3ff00000
|
||||
#define REG_RFECTL_A 0x0cb8
|
||||
#define REG_RFE_INV0 0x0cbc
|
||||
#define REG_RFE_INV8 0x0cbd
|
||||
#define BIT_MASK_RFE_INV89 GENMASK(1, 0)
|
||||
#define REG_RFE_INV16 0x0cbe
|
||||
@@ -703,6 +737,7 @@
|
||||
|
||||
#define REG_3WIRE_SWB 0x0e00
|
||||
#define REG_RX_IQC_AB_B 0x0e10
|
||||
#define REG_RX_IQC_CD_B 0x0e14
|
||||
#define REG_TXSCALE_B 0x0e1c
|
||||
#define REG_TX_AGC_B_CCK_11_CCK_1 0xe20
|
||||
#define REG_TX_AGC_B_OFDM18_OFDM6 0xe24
|
||||
@@ -729,6 +764,7 @@
|
||||
#define REG_LSSI_WRITE_B 0x0e90
|
||||
#define REG_PREDISTB 0x0e90
|
||||
#define REG_INIDLYB 0x0e94
|
||||
#define REG_TX_AGC_B 0x0e94
|
||||
#define REG_RFE_PINMUX_B 0x0eb0
|
||||
#define REG_RFE_INV_B 0x0eb4
|
||||
#define REG_RFECTL_B 0x0eb8
|
||||
@@ -744,8 +780,11 @@
|
||||
#define REG_CRC_HT 0x0f10
|
||||
#define REG_CRC_OFDM 0x0f14
|
||||
#define REG_FA_OFDM 0x0f48
|
||||
#define REG_DBGRPT 0x0fa0
|
||||
#define REG_CCA_CCK 0x0fcc
|
||||
|
||||
#define REG_SYS_CFG3_8814A 0x1000
|
||||
|
||||
#define REG_ANAPARSW_MAC_0 0x1010
|
||||
#define BIT_CF_L_V2 GENMASK(29, 28)
|
||||
|
||||
@@ -863,9 +902,27 @@
|
||||
#define LTECOEX_WRITE_DATA REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1
|
||||
#define LTECOEX_READ_DATA REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1
|
||||
|
||||
#define REG_RX_IQC_AB_C 0x1810
|
||||
#define REG_RX_IQC_CD_C 0x1814
|
||||
#define REG_TXSCALE_C 0x181c
|
||||
#define REG_CK_MONHC 0x185c
|
||||
#define REG_AFE_PWR1_C 0x1860
|
||||
#define REG_IGN_GNT_BT1 0x1860
|
||||
#define REG_TX_AGC_C 0x1894
|
||||
#define REG_RFE_PINMUX_C 0x18b4
|
||||
|
||||
#define REG_RFESEL_CTRL 0x1990
|
||||
#define REG_AGC_TBL 0x1998
|
||||
|
||||
#define REG_RX_IQC_AB_D 0x1a10
|
||||
#define REG_RX_IQC_CD_D 0x1a14
|
||||
#define REG_TXSCALE_D 0x1a1c
|
||||
#define REG_CK_MONHD 0x1a5c
|
||||
#define REG_AFE_PWR1_D 0x1a60
|
||||
#define REG_TX_AGC_D 0x1a94
|
||||
#define REG_RFE_PINMUX_D 0x1ab4
|
||||
#define REG_RFE_INVSEL_D 0x1abc
|
||||
#define BIT_RFE_SELSW0_D GENMASK(27, 20)
|
||||
|
||||
#define REG_NOMASK_TXBT 0x1ca7
|
||||
#define REG_ANAPAR 0x1c30
|
||||
@@ -906,6 +963,7 @@
|
||||
#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8))
|
||||
#define RF18_CHANNEL_MASK (MASKBYTE0)
|
||||
#define RF18_RFSI_MASK (BIT(18) | BIT(17))
|
||||
#define RF_RCK1_V1 0x1c
|
||||
#define RF_RCK 0x1d
|
||||
#define RF_MODE_TABLE_ADDR 0x30
|
||||
#define RF_MODE_TABLE_DATA0 0x31
|
||||
|
||||
2257
drivers/net/wireless/realtek/rtw88/rtw8814a.c
Normal file
2257
drivers/net/wireless/realtek/rtw88/rtw8814a.c
Normal file
File diff suppressed because it is too large
Load Diff
62
drivers/net/wireless/realtek/rtw88/rtw8814a.h
Normal file
62
drivers/net/wireless/realtek/rtw88/rtw8814a.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2025 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW8814A_H__
|
||||
#define __RTW8814A_H__
|
||||
|
||||
struct rtw8814au_efuse {
|
||||
u8 vid[2]; /* 0xd0 */
|
||||
u8 pid[2]; /* 0xd2 */
|
||||
u8 res[4]; /* 0xd4 */
|
||||
u8 mac_addr[ETH_ALEN]; /* 0xd8 */
|
||||
} __packed;
|
||||
|
||||
struct rtw8814ae_efuse {
|
||||
u8 mac_addr[ETH_ALEN]; /* 0xd0 */
|
||||
u8 vid[2]; /* 0xd6 */
|
||||
u8 did[2]; /* 0xd8 */
|
||||
u8 svid[2]; /* 0xda */
|
||||
u8 smid[2]; /* 0xdc */
|
||||
} __packed;
|
||||
|
||||
struct rtw8814a_efuse {
|
||||
__le16 rtl_id;
|
||||
u8 res0[0x0c];
|
||||
u8 usb_mode; /* 0x0e */
|
||||
u8 res1;
|
||||
|
||||
/* power index for four RF paths */
|
||||
struct rtw_txpwr_idx txpwr_idx_table[4];
|
||||
|
||||
u8 channel_plan; /* 0xb8 */
|
||||
u8 xtal_k; /* 0xb9 */
|
||||
u8 thermal_meter; /* 0xba */
|
||||
u8 iqk_lck; /* 0xbb */
|
||||
u8 pa_type; /* 0xbc */
|
||||
u8 lna_type_2g[2]; /* 0xbd */
|
||||
u8 lna_type_5g[2]; /* 0xbf */
|
||||
u8 rf_board_option; /* 0xc1 */
|
||||
u8 res2;
|
||||
u8 rf_bt_setting; /* 0xc3 */
|
||||
u8 eeprom_version; /* 0xc4 */
|
||||
u8 eeprom_customer_id; /* 0xc5 */
|
||||
u8 tx_bb_swing_setting_2g; /* 0xc6 */
|
||||
u8 tx_bb_swing_setting_5g; /* 0xc7 */
|
||||
u8 res3;
|
||||
u8 trx_antenna_option; /* 0xc9 */
|
||||
u8 rfe_option; /* 0xca */
|
||||
u8 country_code[2]; /* 0xcb */
|
||||
u8 res4[3];
|
||||
union {
|
||||
struct rtw8814au_efuse u;
|
||||
struct rtw8814ae_efuse e;
|
||||
};
|
||||
u8 res5[0x122]; /* 0xde */
|
||||
} __packed;
|
||||
|
||||
static_assert(sizeof(struct rtw8814a_efuse) == 512);
|
||||
|
||||
extern const struct rtw_chip_info rtw8814a_hw_spec;
|
||||
|
||||
#endif
|
||||
23930
drivers/net/wireless/realtek/rtw88/rtw8814a_table.c
Normal file
23930
drivers/net/wireless/realtek/rtw88/rtw8814a_table.c
Normal file
File diff suppressed because it is too large
Load Diff
40
drivers/net/wireless/realtek/rtw88/rtw8814a_table.h
Normal file
40
drivers/net/wireless/realtek/rtw88/rtw8814a_table.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/* Copyright(c) 2025 Realtek Corporation
|
||||
*/
|
||||
|
||||
#ifndef __RTW8814A_TABLE_H__
|
||||
#define __RTW8814A_TABLE_H__
|
||||
|
||||
extern const struct rtw_table rtw8814a_mac_tbl;
|
||||
extern const struct rtw_table rtw8814a_agc_tbl;
|
||||
extern const struct rtw_table rtw8814a_bb_tbl;
|
||||
extern const struct rtw_table rtw8814a_bb_pg_tbl;
|
||||
extern const struct rtw_table rtw8814a_bb_pg_type0_tbl;
|
||||
extern const struct rtw_table rtw8814a_bb_pg_type2_tbl;
|
||||
extern const struct rtw_table rtw8814a_bb_pg_type3_tbl;
|
||||
extern const struct rtw_table rtw8814a_bb_pg_type4_tbl;
|
||||
extern const struct rtw_table rtw8814a_bb_pg_type5_tbl;
|
||||
extern const struct rtw_table rtw8814a_bb_pg_type7_tbl;
|
||||
extern const struct rtw_table rtw8814a_bb_pg_type8_tbl;
|
||||
extern const struct rtw_table rtw8814a_rf_a_tbl;
|
||||
extern const struct rtw_table rtw8814a_rf_b_tbl;
|
||||
extern const struct rtw_table rtw8814a_rf_c_tbl;
|
||||
extern const struct rtw_table rtw8814a_rf_d_tbl;
|
||||
extern const struct rtw_table rtw8814a_txpwr_lmt_tbl;
|
||||
extern const struct rtw_table rtw8814a_txpwr_lmt_type0_tbl;
|
||||
extern const struct rtw_table rtw8814a_txpwr_lmt_type1_tbl;
|
||||
extern const struct rtw_table rtw8814a_txpwr_lmt_type2_tbl;
|
||||
extern const struct rtw_table rtw8814a_txpwr_lmt_type3_tbl;
|
||||
extern const struct rtw_table rtw8814a_txpwr_lmt_type5_tbl;
|
||||
extern const struct rtw_table rtw8814a_txpwr_lmt_type7_tbl;
|
||||
extern const struct rtw_table rtw8814a_txpwr_lmt_type8_tbl;
|
||||
extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_tbl;
|
||||
extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type0_tbl;
|
||||
extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type2_tbl;
|
||||
extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type5_tbl;
|
||||
extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type7_tbl;
|
||||
extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type8_tbl;
|
||||
extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8814a[];
|
||||
extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8814a[];
|
||||
|
||||
#endif
|
||||
31
drivers/net/wireless/realtek/rtw88/rtw8814ae.c
Normal file
31
drivers/net/wireless/realtek/rtw88/rtw8814ae.c
Normal file
@@ -0,0 +1,31 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright(c) 2025 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include "pci.h"
|
||||
#include "rtw8814a.h"
|
||||
|
||||
static const struct pci_device_id rtw_8814ae_id_table[] = {
|
||||
{
|
||||
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8813),
|
||||
.driver_data = (kernel_ulong_t)&rtw8814a_hw_spec
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, rtw_8814ae_id_table);
|
||||
|
||||
static struct pci_driver rtw_8814ae_driver = {
|
||||
.name = "rtw_8814ae",
|
||||
.id_table = rtw_8814ae_id_table,
|
||||
.probe = rtw_pci_probe,
|
||||
.remove = rtw_pci_remove,
|
||||
.driver.pm = &rtw_pm_ops,
|
||||
.shutdown = rtw_pci_shutdown,
|
||||
};
|
||||
module_pci_driver(rtw_8814ae_driver);
|
||||
|
||||
MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
|
||||
MODULE_DESCRIPTION("Realtek 802.11ac wireless 8814ae driver");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
54
drivers/net/wireless/realtek/rtw88/rtw8814au.c
Normal file
54
drivers/net/wireless/realtek/rtw88/rtw8814au.c
Normal file
@@ -0,0 +1,54 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/* Copyright(c) 2025 Realtek Corporation
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/usb.h>
|
||||
#include "main.h"
|
||||
#include "rtw8814a.h"
|
||||
#include "usb.h"
|
||||
|
||||
static const struct usb_device_id rtw_8814au_id_table[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8813, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x400b, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x400d, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9054, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1817, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1852, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1853, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0026, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331a, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x809a, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x809b, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0106, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa834, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa833, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, rtw_8814au_id_table);
|
||||
|
||||
static struct usb_driver rtw_8814au_driver = {
|
||||
.name = "rtw_8814au",
|
||||
.id_table = rtw_8814au_id_table,
|
||||
.probe = rtw_usb_probe,
|
||||
.disconnect = rtw_usb_disconnect,
|
||||
};
|
||||
module_usb_driver(rtw_8814au_driver);
|
||||
|
||||
MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
|
||||
MODULE_DESCRIPTION("Realtek 802.11ac wireless 8814au driver");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
@@ -73,6 +73,10 @@ static const struct usb_device_id rtw_8822bu_id_table[] = {
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ELECOM WDB-867DU3S */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0107, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Mercusys MA30H */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x010a, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Mercusys MA30N */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3322, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* D-Link DWA-T185 rev. A1 */
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, rtw_8822bu_id_table);
|
||||
|
||||
@@ -73,6 +73,12 @@ static void rtw_rx_phy_stat(struct rtw_dev *rtwdev,
|
||||
rate_ss_evm = 2;
|
||||
evm_id = RTW_EVM_2SS_A;
|
||||
break;
|
||||
case DESC_RATEMCS16...DESC_RATEMCS23:
|
||||
case DESC_RATEVHT3SS_MCS0...DESC_RATEVHT3SS_MCS9:
|
||||
rate_ss = 3;
|
||||
rate_ss_evm = 3;
|
||||
evm_id = RTW_EVM_3SS_A;
|
||||
break;
|
||||
default:
|
||||
rtw_warn(rtwdev, "unknown pkt rate = %d\n", pkt_stat->rate);
|
||||
return;
|
||||
|
||||
@@ -101,7 +101,8 @@ void rtw_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss)
|
||||
*nss = 4;
|
||||
*mcs = rate - DESC_RATEVHT4SS_MCS0;
|
||||
} else if (rate >= DESC_RATEMCS0 &&
|
||||
rate <= DESC_RATEMCS15) {
|
||||
rate <= DESC_RATEMCS31) {
|
||||
*nss = 0;
|
||||
*mcs = rate - DESC_RATEMCS0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,6 +476,12 @@ int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
|
||||
case WLAN_CIPHER_SUITE_WEP104:
|
||||
hw_key_type = RTW89_SEC_KEY_TYPE_WEP104;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_TKIP:
|
||||
if (!chip->hw_tkip_crypto)
|
||||
return -EOPNOTSUPP;
|
||||
hw_key_type = RTW89_SEC_KEY_TYPE_TKIP;
|
||||
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_CCMP:
|
||||
hw_key_type = RTW89_SEC_KEY_TYPE_CCMP128;
|
||||
if (!chip->hw_mgmt_tx_encrypt)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "fw.h"
|
||||
#include "mac.h"
|
||||
#include "ps.h"
|
||||
#include "sar.h"
|
||||
#include "util.h"
|
||||
|
||||
static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev,
|
||||
@@ -2673,6 +2674,7 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_hal *hal = &rtwdev->hal;
|
||||
struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
|
||||
struct rtw89_entity_weight w = {};
|
||||
int ret;
|
||||
|
||||
rtwvif_link->chanctx_idx = cfg->idx;
|
||||
rtwvif_link->chanctx_assigned = true;
|
||||
@@ -2692,7 +2694,13 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
|
||||
rtw89_swap_chanctx(rtwdev, cfg->idx, RTW89_CHANCTX_0);
|
||||
|
||||
out:
|
||||
return rtw89_set_channel(rtwdev);
|
||||
ret = rtw89_set_channel(rtwdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
rtw89_tas_reset(rtwdev, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "ps.h"
|
||||
#include "reg.h"
|
||||
|
||||
#define RTW89_COEX_VERSION 0x07000313
|
||||
#define RTW89_COEX_VERSION 0x07000413
|
||||
#define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/
|
||||
#define BTC_E2G_LIMIT_DEF 80
|
||||
|
||||
@@ -132,6 +132,14 @@ static const u32 cxtbl[] = {
|
||||
|
||||
static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
|
||||
/* firmware version must be in decreasing order for each chip */
|
||||
{RTL8852BT, RTW89_FW_VER_CODE(0, 29, 122, 0),
|
||||
.fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7,
|
||||
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
|
||||
.fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
|
||||
.fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
|
||||
.fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800,
|
||||
.max_role_num = 6,
|
||||
},
|
||||
{RTL8852BT, RTW89_FW_VER_CODE(0, 29, 90, 0),
|
||||
.fcxbtcrpt = 7, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7,
|
||||
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
|
||||
@@ -1372,11 +1380,9 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
|
||||
} else if (ver->fcxbtcrpt == 8) {
|
||||
pfinfo = &pfwinfo->rpt_ctrl.finfo.v8;
|
||||
pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v8);
|
||||
break;
|
||||
} else if (ver->fcxbtcrpt == 7) {
|
||||
pfinfo = &pfwinfo->rpt_ctrl.finfo.v7;
|
||||
pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v7);
|
||||
break;
|
||||
} else {
|
||||
goto err;
|
||||
}
|
||||
@@ -1534,6 +1540,9 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
|
||||
} else if (ver->fcxbtafh == 2) {
|
||||
pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v2;
|
||||
pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v2);
|
||||
} else if (ver->fcxbtafh == 7) {
|
||||
pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v7;
|
||||
pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v7);
|
||||
} else {
|
||||
goto err;
|
||||
}
|
||||
@@ -8100,6 +8109,7 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
|
||||
return;
|
||||
|
||||
func = rtw89_btc_c2h_get_index_by_ver(rtwdev, func);
|
||||
pfwinfo->cnt_c2h++;
|
||||
|
||||
switch (func) {
|
||||
case BTF_EVNT_BUF_OVERFLOW:
|
||||
|
||||
@@ -2382,6 +2382,49 @@ static void rtw89_core_validate_rx_signal(struct ieee80211_rx_status *rx_status)
|
||||
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
|
||||
}
|
||||
|
||||
static void rtw89_core_update_rx_freq_from_ie(struct rtw89_dev *rtwdev,
|
||||
struct sk_buff *skb,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
size_t hdr_len, ielen;
|
||||
u8 *variable;
|
||||
int chan;
|
||||
|
||||
if (!rtwdev->chip->rx_freq_frome_ie)
|
||||
return;
|
||||
|
||||
if (!rtwdev->scanning)
|
||||
return;
|
||||
|
||||
if (ieee80211_is_beacon(mgmt->frame_control)) {
|
||||
variable = mgmt->u.beacon.variable;
|
||||
hdr_len = offsetof(struct ieee80211_mgmt,
|
||||
u.beacon.variable);
|
||||
} else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
|
||||
variable = mgmt->u.probe_resp.variable;
|
||||
hdr_len = offsetof(struct ieee80211_mgmt,
|
||||
u.probe_resp.variable);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (skb->len > hdr_len)
|
||||
ielen = skb->len - hdr_len;
|
||||
else
|
||||
return;
|
||||
|
||||
/* The parsing code for both 2GHz and 5GHz bands is the same in this
|
||||
* function.
|
||||
*/
|
||||
chan = cfg80211_get_ies_channel_number(variable, ielen, NL80211_BAND_2GHZ);
|
||||
if (chan == -1)
|
||||
return;
|
||||
|
||||
rx_status->band = chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G;
|
||||
rx_status->freq = ieee80211_channel_to_frequency(chan, rx_status->band);
|
||||
}
|
||||
|
||||
static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_rx_phy_ppdu *phy_ppdu,
|
||||
struct rtw89_rx_desc_info *desc_info,
|
||||
@@ -2399,6 +2442,7 @@ static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev,
|
||||
rtw89_core_update_rx_status_by_ppdu(rtwdev, rx_status, phy_ppdu);
|
||||
rtw89_core_update_radiotap(rtwdev, skb_ppdu, rx_status);
|
||||
rtw89_core_validate_rx_signal(rx_status);
|
||||
rtw89_core_update_rx_freq_from_ie(rtwdev, skb_ppdu, rx_status);
|
||||
|
||||
/* In low power mode, it does RX in thread context. */
|
||||
local_bh_disable();
|
||||
@@ -4557,8 +4601,6 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
|
||||
rtw89_mac_cfg_phy_rpt_bands(rtwdev, true);
|
||||
rtw89_mac_update_rts_threshold(rtwdev);
|
||||
|
||||
rtw89_tas_reset(rtwdev);
|
||||
|
||||
ret = rtw89_hci_start(rtwdev);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to start hci\n");
|
||||
@@ -4912,6 +4954,7 @@ void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwv
|
||||
rtw89_chip_rfk_scan(rtwdev, rtwvif_link, true);
|
||||
rtw89_hci_recalc_int_mit(rtwdev);
|
||||
rtw89_phy_config_edcca(rtwdev, bb, true);
|
||||
rtw89_tas_scan(rtwdev, true);
|
||||
|
||||
rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, mac_addr);
|
||||
}
|
||||
@@ -4938,6 +4981,7 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
|
||||
rtw89_btc_ntfy_scan_finish(rtwdev, rtwvif_link->phy_idx);
|
||||
bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx);
|
||||
rtw89_phy_config_edcca(rtwdev, bb, false);
|
||||
rtw89_tas_scan(rtwdev, false);
|
||||
|
||||
rtwdev->scanning = false;
|
||||
rtw89_for_each_active_bb(rtwdev, bb)
|
||||
|
||||
@@ -17,6 +17,7 @@ struct rtw89_dev;
|
||||
struct rtw89_pci_info;
|
||||
struct rtw89_mac_gen_def;
|
||||
struct rtw89_phy_gen_def;
|
||||
struct rtw89_fw_blacklist;
|
||||
struct rtw89_efuse_block_cfg;
|
||||
struct rtw89_h2c_rf_tssi;
|
||||
struct rtw89_fw_txpwr_track_cfg;
|
||||
@@ -3043,6 +3044,7 @@ struct rtw89_btc_rpt_cmn_info {
|
||||
union rtw89_btc_fbtc_btafh_info {
|
||||
struct rtw89_btc_fbtc_btafh v1;
|
||||
struct rtw89_btc_fbtc_btafh_v2 v2;
|
||||
struct rtw89_btc_fbtc_btafh_v7 v7;
|
||||
};
|
||||
|
||||
struct rtw89_btc_report_ctrl_state {
|
||||
@@ -3676,6 +3678,8 @@ struct rtw89_chip_ops {
|
||||
int (*h2c_ampdu_cmac_tbl)(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link);
|
||||
int (*h2c_txtime_cmac_tbl)(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_sta_link *rtwsta_link);
|
||||
int (*h2c_default_dmac_tbl)(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link);
|
||||
@@ -4237,6 +4241,7 @@ enum rtw89_chanctx_state {
|
||||
enum rtw89_chanctx_callbacks {
|
||||
RTW89_CHANCTX_CALLBACK_PLACEHOLDER,
|
||||
RTW89_CHANCTX_CALLBACK_RFK,
|
||||
RTW89_CHANCTX_CALLBACK_TAS,
|
||||
|
||||
NUM_OF_RTW89_CHANCTX_CALLBACKS,
|
||||
};
|
||||
@@ -4257,6 +4262,7 @@ struct rtw89_chip_info {
|
||||
bool try_ce_fw;
|
||||
u8 bbmcu_nr;
|
||||
u32 needed_fw_elms;
|
||||
const struct rtw89_fw_blacklist *fw_blacklist;
|
||||
u32 fifo_size;
|
||||
bool small_fifo_size;
|
||||
u32 dle_scc_rsvd_size;
|
||||
@@ -4277,10 +4283,13 @@ struct rtw89_chip_info {
|
||||
bool support_unii4;
|
||||
bool support_rnr;
|
||||
bool support_ant_gain;
|
||||
bool support_tas;
|
||||
bool ul_tb_waveform_ctrl;
|
||||
bool ul_tb_pwr_diff;
|
||||
bool rx_freq_frome_ie;
|
||||
bool hw_sec_hdr;
|
||||
bool hw_mgmt_tx_encrypt;
|
||||
bool hw_tkip_crypto;
|
||||
u8 rf_path_num;
|
||||
u8 tx_nss;
|
||||
u8 rx_nss;
|
||||
@@ -4484,6 +4493,7 @@ enum rtw89_fw_feature {
|
||||
RTW89_FW_FEATURE_CH_INFO_BE_V0,
|
||||
RTW89_FW_FEATURE_LPS_CH_INFO,
|
||||
RTW89_FW_FEATURE_NO_PHYCAP_P1,
|
||||
RTW89_FW_FEATURE_NO_POWER_DIFFERENCE,
|
||||
};
|
||||
|
||||
struct rtw89_fw_suit {
|
||||
@@ -4658,6 +4668,7 @@ enum rtw89_ant_gain_domain_type {
|
||||
struct rtw89_ant_gain_info {
|
||||
s8 offset[RTW89_ANT_GAIN_CHAIN_NUM][RTW89_ANT_GAIN_SUBBAND_NR];
|
||||
u32 regd_enabled;
|
||||
bool block_country;
|
||||
};
|
||||
|
||||
struct rtw89_6ghz_span {
|
||||
@@ -4673,18 +4684,29 @@ struct rtw89_6ghz_span {
|
||||
enum rtw89_tas_state {
|
||||
RTW89_TAS_STATE_DPR_OFF,
|
||||
RTW89_TAS_STATE_DPR_ON,
|
||||
RTW89_TAS_STATE_DPR_FORBID,
|
||||
RTW89_TAS_STATE_STATIC_SAR,
|
||||
};
|
||||
|
||||
#define RTW89_TAS_MAX_WINDOW 50
|
||||
#define RTW89_TAS_TX_RATIO_WINDOW 6
|
||||
#define RTW89_TAS_TXPWR_WINDOW 180
|
||||
struct rtw89_tas_info {
|
||||
s16 txpwr_history[RTW89_TAS_MAX_WINDOW];
|
||||
s32 total_txpwr;
|
||||
u8 cur_idx;
|
||||
s8 dpr_gap;
|
||||
s8 delta;
|
||||
u16 tx_ratio_history[RTW89_TAS_TX_RATIO_WINDOW];
|
||||
u64 txpwr_history[RTW89_TAS_TXPWR_WINDOW];
|
||||
u8 txpwr_head_idx;
|
||||
u8 txpwr_tail_idx;
|
||||
u8 tx_ratio_idx;
|
||||
u16 total_tx_ratio;
|
||||
u64 total_txpwr;
|
||||
u64 instant_txpwr;
|
||||
u32 window_size;
|
||||
s8 dpr_on_threshold;
|
||||
s8 dpr_off_threshold;
|
||||
enum rtw89_tas_state backup_state;
|
||||
enum rtw89_tas_state state;
|
||||
bool keep_history;
|
||||
bool block_regd;
|
||||
bool enable;
|
||||
bool pause;
|
||||
};
|
||||
|
||||
struct rtw89_chanctx_cfg {
|
||||
@@ -4742,6 +4764,7 @@ struct rtw89_edcca_bak {
|
||||
enum rtw89_dm_type {
|
||||
RTW89_DM_DYNAMIC_EDCCA,
|
||||
RTW89_DM_THERMAL_PROTECT,
|
||||
RTW89_DM_TAS,
|
||||
};
|
||||
|
||||
#define RTW89_THERMAL_PROT_LV_MAX 5
|
||||
@@ -5141,7 +5164,7 @@ struct rtw89_tssi_info {
|
||||
u32 alignment_backup_by_ch[RF_PATH_MAX][TSSI_MAX_CH_NUM][TSSI_ALIMK_VALUE_NUM];
|
||||
u32 alignment_value[RF_PATH_MAX][TSSI_ALIMK_MAX][TSSI_ALIMK_VALUE_NUM];
|
||||
bool alignment_done[RF_PATH_MAX][TSSI_ALIMK_MAX];
|
||||
u32 tssi_alimk_time;
|
||||
u64 tssi_alimk_time;
|
||||
};
|
||||
|
||||
struct rtw89_power_trim_info {
|
||||
|
||||
@@ -4154,6 +4154,7 @@ static const struct rtw89_disabled_dm_info {
|
||||
} rtw89_disabled_dm_infos[] = {
|
||||
DM_INFO(DYNAMIC_EDCCA),
|
||||
DM_INFO(THERMAL_PROTECT),
|
||||
DM_INFO(TAS),
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
|
||||
@@ -38,6 +38,16 @@ struct rtw89_arp_rsp {
|
||||
|
||||
static const u8 mss_signature[] = {0x4D, 0x53, 0x53, 0x4B, 0x50, 0x4F, 0x4F, 0x4C};
|
||||
|
||||
const struct rtw89_fw_blacklist rtw89_fw_blacklist_default = {
|
||||
.ver = 0x00,
|
||||
.list = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
},
|
||||
};
|
||||
EXPORT_SYMBOL(rtw89_fw_blacklist_default);
|
||||
|
||||
union rtw89_fw_element_arg {
|
||||
size_t offset;
|
||||
enum rtw89_rf_path rf_path;
|
||||
@@ -314,7 +324,7 @@ static int __parse_formatted_mssc(struct rtw89_dev *rtwdev,
|
||||
if (!sec->secure_boot)
|
||||
goto out;
|
||||
|
||||
sb_sel_ver = le32_to_cpu(section_content->sb_sel_ver.v);
|
||||
sb_sel_ver = get_unaligned_le32(§ion_content->sb_sel_ver.v);
|
||||
if (sb_sel_ver && sb_sel_ver != sec->sb_sel_mgn)
|
||||
goto ignore;
|
||||
|
||||
@@ -344,6 +354,46 @@ static int __parse_formatted_mssc(struct rtw89_dev *rtwdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __check_secure_blacklist(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_fw_bin_info *info,
|
||||
struct rtw89_fw_hdr_section_info *section_info,
|
||||
const void *content)
|
||||
{
|
||||
const struct rtw89_fw_blacklist *chip_blacklist = rtwdev->chip->fw_blacklist;
|
||||
const union rtw89_fw_section_mssc_content *section_content = content;
|
||||
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
|
||||
u8 byte_idx;
|
||||
u8 bit_mask;
|
||||
|
||||
if (!sec->secure_boot)
|
||||
return 0;
|
||||
|
||||
if (!info->secure_section_exist || section_info->ignore)
|
||||
return 0;
|
||||
|
||||
if (!chip_blacklist) {
|
||||
rtw89_warn(rtwdev, "chip no blacklist for secure firmware\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
byte_idx = section_content->blacklist.bit_in_chip_list >> 3;
|
||||
bit_mask = BIT(section_content->blacklist.bit_in_chip_list & 0x7);
|
||||
|
||||
if (section_content->blacklist.ver > chip_blacklist->ver) {
|
||||
rtw89_warn(rtwdev, "chip blacklist out of date (%u, %u)\n",
|
||||
section_content->blacklist.ver, chip_blacklist->ver);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (chip_blacklist->list[byte_idx] & bit_mask) {
|
||||
rtw89_warn(rtwdev, "firmware %u in chip blacklist\n",
|
||||
section_content->blacklist.ver);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __parse_security_section(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_fw_bin_info *info,
|
||||
struct rtw89_fw_hdr_section_info *section_info,
|
||||
@@ -364,8 +414,11 @@ static int __parse_security_section(struct rtw89_dev *rtwdev,
|
||||
*mssc_len += section_info->mssc * FWDL_SECURITY_CHKSUM_LEN;
|
||||
|
||||
if (sec->secure_boot) {
|
||||
if (sec->mss_idx >= section_info->mssc)
|
||||
if (sec->mss_idx >= section_info->mssc) {
|
||||
rtw89_err(rtwdev, "unexpected MSS %d >= %d\n",
|
||||
sec->mss_idx, section_info->mssc);
|
||||
return -EFAULT;
|
||||
}
|
||||
section_info->key_addr = content + section_info->len +
|
||||
sec->mss_idx * FWDL_SECURITY_SIGLEN;
|
||||
section_info->key_len = FWDL_SECURITY_SIGLEN;
|
||||
@@ -374,6 +427,9 @@ static int __parse_security_section(struct rtw89_dev *rtwdev,
|
||||
info->secure_section_exist = true;
|
||||
}
|
||||
|
||||
ret = __check_secure_blacklist(rtwdev, info, section_info, content);
|
||||
WARN_ONCE(ret, "Current firmware in blacklist. Please update firmware.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -489,6 +545,23 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev,
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
const struct rtw89_mfw_hdr *rtw89_mfw_get_hdr_ptr(struct rtw89_dev *rtwdev,
|
||||
const struct firmware *firmware)
|
||||
{
|
||||
const struct rtw89_mfw_hdr *mfw_hdr;
|
||||
|
||||
if (sizeof(*mfw_hdr) > firmware->size)
|
||||
return NULL;
|
||||
|
||||
mfw_hdr = (const struct rtw89_mfw_hdr *)firmware->data;
|
||||
|
||||
if (mfw_hdr->sig != RTW89_MFW_SIG)
|
||||
return NULL;
|
||||
|
||||
return mfw_hdr;
|
||||
}
|
||||
|
||||
static int rtw89_mfw_validate_hdr(struct rtw89_dev *rtwdev,
|
||||
const struct firmware *firmware,
|
||||
const struct rtw89_mfw_hdr *mfw_hdr)
|
||||
@@ -519,14 +592,15 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
|
||||
{
|
||||
struct rtw89_fw_info *fw_info = &rtwdev->fw;
|
||||
const struct firmware *firmware = fw_info->req.firmware;
|
||||
const struct rtw89_mfw_info *mfw_info = NULL, *tmp;
|
||||
const struct rtw89_mfw_hdr *mfw_hdr;
|
||||
const u8 *mfw = firmware->data;
|
||||
u32 mfw_len = firmware->size;
|
||||
const struct rtw89_mfw_hdr *mfw_hdr = (const struct rtw89_mfw_hdr *)mfw;
|
||||
const struct rtw89_mfw_info *mfw_info = NULL, *tmp;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (mfw_hdr->sig != RTW89_MFW_SIG) {
|
||||
mfw_hdr = rtw89_mfw_get_hdr_ptr(rtwdev, firmware);
|
||||
if (!mfw_hdr) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_FW, "use legacy firmware\n");
|
||||
/* legacy firmware support normal type only */
|
||||
if (type != RTW89_FW_NORMAL)
|
||||
@@ -582,13 +656,13 @@ static u32 rtw89_mfw_get_size(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_fw_info *fw_info = &rtwdev->fw;
|
||||
const struct firmware *firmware = fw_info->req.firmware;
|
||||
const struct rtw89_mfw_hdr *mfw_hdr =
|
||||
(const struct rtw89_mfw_hdr *)firmware->data;
|
||||
const struct rtw89_mfw_info *mfw_info;
|
||||
const struct rtw89_mfw_hdr *mfw_hdr;
|
||||
u32 size;
|
||||
int ret;
|
||||
|
||||
if (mfw_hdr->sig != RTW89_MFW_SIG) {
|
||||
mfw_hdr = rtw89_mfw_get_hdr_ptr(rtwdev, firmware);
|
||||
if (!mfw_hdr) {
|
||||
rtw89_warn(rtwdev, "not mfw format\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -775,6 +849,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
|
||||
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 47, 0, CH_INFO_BE_V0),
|
||||
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 49, 0, RFK_PRE_NOTIFY_V1),
|
||||
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 51, 0, NO_PHYCAP_P1),
|
||||
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 64, 0, NO_POWER_DIFFERENCE),
|
||||
};
|
||||
|
||||
static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw,
|
||||
@@ -1028,7 +1103,7 @@ int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev,
|
||||
bitmap = le32_to_cpu(elm->u.txpwr_trk.bitmap);
|
||||
|
||||
if ((bitmap & needed_bitmap) != needed_bitmap) {
|
||||
rtw89_warn(rtwdev, "needed txpwr trk bitmap %08x but %0x8x\n",
|
||||
rtw89_warn(rtwdev, "needed txpwr trk bitmap %08x but %08x\n",
|
||||
needed_bitmap, bitmap);
|
||||
return -ENOENT;
|
||||
}
|
||||
@@ -1460,7 +1535,6 @@ static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev,
|
||||
ret = rtw89_h2c_tx(rtwdev, skb, false);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to send h2c\n");
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -1547,7 +1621,6 @@ static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev,
|
||||
ret = rtw89_h2c_tx(rtwdev, skb, true);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to send h2c\n");
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -3435,9 +3508,10 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
|
||||
CCTLINFO_G7_W5_NOMINAL_PKT_PADDING3 |
|
||||
CCTLINFO_G7_W5_NOMINAL_PKT_PADDING4);
|
||||
|
||||
h2c->w6 = le32_encode_bits(vif->type == NL80211_IFTYPE_STATION ? 1 : 0,
|
||||
h2c->w6 = le32_encode_bits(vif->cfg.aid, CCTLINFO_G7_W6_AID12_PAID) |
|
||||
le32_encode_bits(vif->type == NL80211_IFTYPE_STATION ? 1 : 0,
|
||||
CCTLINFO_G7_W6_ULDL);
|
||||
h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_ULDL);
|
||||
h2c->m6 = cpu_to_le32(CCTLINFO_G7_W6_AID12_PAID | CCTLINFO_G7_W6_ULDL);
|
||||
|
||||
if (rtwsta_link) {
|
||||
h2c->w8 = le32_encode_bits(link_sta->he_cap.has_he,
|
||||
@@ -3573,6 +3647,61 @@ int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl);
|
||||
|
||||
int rtw89_fw_h2c_txtime_cmac_tbl_g7(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_sta_link *rtwsta_link)
|
||||
{
|
||||
struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
|
||||
u32 len = sizeof(*h2c);
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
|
||||
if (!skb) {
|
||||
rtw89_err(rtwdev, "failed to alloc skb for txtime_cmac_g7\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
skb_put(skb, len);
|
||||
h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
|
||||
|
||||
h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, CCTLINFO_G7_C0_MACID) |
|
||||
le32_encode_bits(1, CCTLINFO_G7_C0_OP);
|
||||
|
||||
if (rtwsta_link->cctl_tx_time) {
|
||||
h2c->w3 |= le32_encode_bits(1, CCTLINFO_G7_W3_AMPDU_TIME_SEL);
|
||||
h2c->m3 |= cpu_to_le32(CCTLINFO_G7_W3_AMPDU_TIME_SEL);
|
||||
|
||||
h2c->w2 |= le32_encode_bits(rtwsta_link->ampdu_max_time,
|
||||
CCTLINFO_G7_W2_AMPDU_MAX_TIME);
|
||||
h2c->m2 |= cpu_to_le32(CCTLINFO_G7_W2_AMPDU_MAX_TIME);
|
||||
}
|
||||
if (rtwsta_link->cctl_tx_retry_limit) {
|
||||
h2c->w2 |= le32_encode_bits(1, CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL) |
|
||||
le32_encode_bits(rtwsta_link->data_tx_cnt_lmt,
|
||||
CCTLINFO_G7_W2_DATA_TX_CNT_LMT);
|
||||
h2c->m2 |= cpu_to_le32(CCTLINFO_G7_W2_DATA_TXCNT_LMT_SEL |
|
||||
CCTLINFO_G7_W2_DATA_TX_CNT_LMT);
|
||||
}
|
||||
|
||||
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
|
||||
H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
|
||||
H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1,
|
||||
len);
|
||||
|
||||
ret = rtw89_h2c_tx(rtwdev, skb, false);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to send h2c\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
dev_kfree_skb_any(skb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl_g7);
|
||||
|
||||
int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_sta_link *rtwsta_link)
|
||||
@@ -3776,14 +3905,15 @@ int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev,
|
||||
}
|
||||
EXPORT_SYMBOL(rtw89_fw_h2c_update_beacon_be);
|
||||
|
||||
#define H2C_ROLE_MAINTAIN_LEN 4
|
||||
int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link,
|
||||
struct rtw89_sta_link *rtwsta_link,
|
||||
enum rtw89_upd_mode upd_mode)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
|
||||
struct rtw89_h2c_role_maintain *h2c;
|
||||
u32 len = sizeof(*h2c);
|
||||
struct sk_buff *skb;
|
||||
u8 self_role;
|
||||
int ret;
|
||||
|
||||
@@ -3796,21 +3926,27 @@ int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
|
||||
self_role = rtwvif_link->self_role;
|
||||
}
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_ROLE_MAINTAIN_LEN);
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
|
||||
if (!skb) {
|
||||
rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
skb_put(skb, H2C_ROLE_MAINTAIN_LEN);
|
||||
SET_FWROLE_MAINTAIN_MACID(skb->data, mac_id);
|
||||
SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, self_role);
|
||||
SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode);
|
||||
SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif_link->wifi_role);
|
||||
skb_put(skb, len);
|
||||
h2c = (struct rtw89_h2c_role_maintain *)skb->data;
|
||||
|
||||
h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_ROLE_MAINTAIN_W0_MACID) |
|
||||
le32_encode_bits(self_role, RTW89_H2C_ROLE_MAINTAIN_W0_SELF_ROLE) |
|
||||
le32_encode_bits(upd_mode, RTW89_H2C_ROLE_MAINTAIN_W0_UPD_MODE) |
|
||||
le32_encode_bits(rtwvif_link->wifi_role,
|
||||
RTW89_H2C_ROLE_MAINTAIN_W0_WIFI_ROLE) |
|
||||
le32_encode_bits(rtwvif_link->mac_idx,
|
||||
RTW89_H2C_ROLE_MAINTAIN_W0_BAND) |
|
||||
le32_encode_bits(rtwvif_link->port, RTW89_H2C_ROLE_MAINTAIN_W0_PORT);
|
||||
|
||||
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
|
||||
H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
|
||||
H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1,
|
||||
H2C_ROLE_MAINTAIN_LEN);
|
||||
len);
|
||||
|
||||
ret = rtw89_h2c_tx(rtwdev, skb, false);
|
||||
if (ret) {
|
||||
|
||||
@@ -663,6 +663,11 @@ struct rtw89_fw_mss_pool_hdr {
|
||||
} __packed;
|
||||
|
||||
union rtw89_fw_section_mssc_content {
|
||||
struct {
|
||||
u8 pad[0x20];
|
||||
u8 bit_in_chip_list;
|
||||
u8 ver;
|
||||
} __packed blacklist;
|
||||
struct {
|
||||
u8 pad[58];
|
||||
__le32 v;
|
||||
@@ -673,6 +678,13 @@ union rtw89_fw_section_mssc_content {
|
||||
} __packed key_sign_len;
|
||||
} __packed;
|
||||
|
||||
struct rtw89_fw_blacklist {
|
||||
u8 ver;
|
||||
u8 list[32];
|
||||
};
|
||||
|
||||
extern const struct rtw89_fw_blacklist rtw89_fw_blacklist_default;
|
||||
|
||||
static inline void SET_CTRL_INFO_MACID(void *table, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)(table) + 0, val, GENMASK(6, 0));
|
||||
@@ -1579,25 +1591,17 @@ struct rtw89_h2c_bcn_upd_be {
|
||||
#define RTW89_H2C_BCN_UPD_BE_W7_ECSA_OFST GENMASK(30, 16)
|
||||
#define RTW89_H2C_BCN_UPD_BE_W7_PROTECTION_KEY_ID BIT(31)
|
||||
|
||||
static inline void SET_FWROLE_MAINTAIN_MACID(void *h2c, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0));
|
||||
}
|
||||
struct rtw89_h2c_role_maintain {
|
||||
__le32 w0;
|
||||
};
|
||||
|
||||
static inline void SET_FWROLE_MAINTAIN_SELF_ROLE(void *h2c, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)h2c, val, GENMASK(9, 8));
|
||||
}
|
||||
|
||||
static inline void SET_FWROLE_MAINTAIN_UPD_MODE(void *h2c, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)h2c, val, GENMASK(12, 10));
|
||||
}
|
||||
|
||||
static inline void SET_FWROLE_MAINTAIN_WIFI_ROLE(void *h2c, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)h2c, val, GENMASK(16, 13));
|
||||
}
|
||||
#define RTW89_H2C_ROLE_MAINTAIN_W0_MACID GENMASK(7, 0)
|
||||
#define RTW89_H2C_ROLE_MAINTAIN_W0_SELF_ROLE GENMASK(9, 8)
|
||||
#define RTW89_H2C_ROLE_MAINTAIN_W0_UPD_MODE GENMASK(12, 10)
|
||||
#define RTW89_H2C_ROLE_MAINTAIN_W0_WIFI_ROLE GENMASK(16, 13)
|
||||
#define RTW89_H2C_ROLE_MAINTAIN_W0_BAND GENMASK(18, 17)
|
||||
#define RTW89_H2C_ROLE_MAINTAIN_W0_PORT GENMASK(21, 19)
|
||||
#define RTW89_H2C_ROLE_MAINTAIN_W0_MACID_EXT GENMASK(31, 24)
|
||||
|
||||
enum rtw89_fw_sta_type { /* value of RTW89_H2C_JOININFO_W1_STA_TYPE */
|
||||
RTW89_FW_N_AC_STA = 0,
|
||||
@@ -4539,6 +4543,12 @@ struct rtw89_c2h_rfk_report {
|
||||
u8 version;
|
||||
} __packed;
|
||||
|
||||
struct rtw89_c2h_rf_tas_info {
|
||||
struct rtw89_c2h_hdr hdr;
|
||||
__le32 cur_idx;
|
||||
__le16 txpwr_history[20];
|
||||
} __packed;
|
||||
|
||||
#define RTW89_FW_RSVD_PLE_SIZE 0x800
|
||||
|
||||
#define RTW89_FW_BACKTRACE_INFO_SIZE 8
|
||||
@@ -4588,6 +4598,8 @@ int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_sta_link *rtwsta_link);
|
||||
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_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_sta_link *rtwsta_link);
|
||||
int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
|
||||
@@ -4869,6 +4881,15 @@ static inline int rtw89_chip_h2c_ampdu_cmac_tbl(struct rtw89_dev *rtwdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
int rtw89_chip_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_sta_link *rtwsta_link)
|
||||
{
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
|
||||
return chip->ops->h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
|
||||
}
|
||||
|
||||
static inline
|
||||
int rtw89_chip_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
|
||||
bool valid, struct ieee80211_ampdu_params *params)
|
||||
|
||||
@@ -4837,6 +4837,32 @@ void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
|
||||
rtw89_write32_set(rtwdev, reg, mac->narrow_bw_ru_dis.mask);
|
||||
}
|
||||
|
||||
void rtw89_mac_set_he_tb(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link)
|
||||
{
|
||||
struct ieee80211_bss_conf *bss_conf;
|
||||
bool set;
|
||||
u32 reg;
|
||||
|
||||
if (rtwdev->chip->chip_gen != RTW89_CHIP_BE)
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
|
||||
set = bss_conf->he_support && !bss_conf->eht_support;
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CLIENT_OM_CTRL,
|
||||
rtwvif_link->mac_idx);
|
||||
|
||||
if (set)
|
||||
rtw89_write32_set(rtwdev, reg, B_BE_TRIG_DIS_EHTTB);
|
||||
else
|
||||
rtw89_write32_clr(rtwdev, reg, B_BE_TRIG_DIS_EHTTB);
|
||||
}
|
||||
|
||||
void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
|
||||
{
|
||||
rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif_link);
|
||||
@@ -6433,6 +6459,7 @@ __rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_
|
||||
u32 tx_time)
|
||||
{
|
||||
#define MAC_AX_DFLT_TX_TIME 5280
|
||||
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
|
||||
u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx;
|
||||
u32 max_tx_time = tx_time == 0 ? MAC_AX_DFLT_TX_TIME : tx_time;
|
||||
u32 reg;
|
||||
@@ -6440,7 +6467,7 @@ __rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_
|
||||
|
||||
if (rtwsta_link->cctl_tx_time) {
|
||||
rtwsta_link->ampdu_max_time = (max_tx_time - 512) >> 9;
|
||||
ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
|
||||
ret = rtw89_chip_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
|
||||
} else {
|
||||
ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
|
||||
if (ret) {
|
||||
@@ -6448,8 +6475,8 @@ __rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_
|
||||
return ret;
|
||||
}
|
||||
|
||||
reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_AMPDU_AGG_LIMIT, mac_idx);
|
||||
rtw89_write32_mask(rtwdev, reg, B_AX_AMPDU_MAX_TIME_MASK,
|
||||
reg = rtw89_mac_reg_by_idx(rtwdev, mac->agg_limit.addr, mac_idx);
|
||||
rtw89_write32_mask(rtwdev, reg, mac->agg_limit.mask,
|
||||
max_tx_time >> 5);
|
||||
}
|
||||
|
||||
@@ -6475,6 +6502,7 @@ int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwst
|
||||
int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
|
||||
u32 *tx_time)
|
||||
{
|
||||
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
|
||||
u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx;
|
||||
u32 reg;
|
||||
int ret = 0;
|
||||
@@ -6488,8 +6516,8 @@ int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwst
|
||||
return ret;
|
||||
}
|
||||
|
||||
reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_AMPDU_AGG_LIMIT, mac_idx);
|
||||
*tx_time = rtw89_read32_mask(rtwdev, reg, B_AX_AMPDU_MAX_TIME_MASK) << 5;
|
||||
reg = rtw89_mac_reg_by_idx(rtwdev, mac->agg_limit.addr, mac_idx);
|
||||
*tx_time = rtw89_read32_mask(rtwdev, reg, mac->agg_limit.mask) << 5;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -6505,9 +6533,9 @@ int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev,
|
||||
|
||||
if (!resume) {
|
||||
rtwsta_link->cctl_tx_retry_limit = true;
|
||||
ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
|
||||
ret = rtw89_chip_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
|
||||
} else {
|
||||
ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
|
||||
ret = rtw89_chip_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
|
||||
rtwsta_link->cctl_tx_retry_limit = false;
|
||||
}
|
||||
|
||||
@@ -6517,6 +6545,7 @@ int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev,
|
||||
int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_sta_link *rtwsta_link, u8 *tx_retry)
|
||||
{
|
||||
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
|
||||
u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx;
|
||||
u32 reg;
|
||||
int ret = 0;
|
||||
@@ -6530,8 +6559,8 @@ int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXCNT, mac_idx);
|
||||
*tx_retry = rtw89_read32_mask(rtwdev, reg, B_AX_L_TXCNT_LMT_MASK);
|
||||
reg = rtw89_mac_reg_by_idx(rtwdev, mac->txcnt_limit.addr, mac_idx);
|
||||
*tx_retry = rtw89_read32_mask(rtwdev, reg, mac->txcnt_limit.mask);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -6809,6 +6838,8 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
|
||||
.mask = B_AX_RXTRIG_RU26_DIS,
|
||||
},
|
||||
.wow_ctrl = {.addr = R_AX_WOW_CTRL, .mask = B_AX_WOW_WOWEN,},
|
||||
.agg_limit = {.addr = R_AX_AMPDU_AGG_LIMIT, .mask = B_AX_AMPDU_MAX_TIME_MASK,},
|
||||
.txcnt_limit = {.addr = R_AX_TXCNT, .mask = B_AX_L_TXCNT_LMT_MASK,},
|
||||
|
||||
.check_mac_en = rtw89_mac_check_mac_en_ax,
|
||||
.sys_init = sys_init_ax,
|
||||
|
||||
@@ -964,6 +964,8 @@ struct rtw89_mac_gen_def {
|
||||
struct rtw89_reg_def bfee_ctrl;
|
||||
struct rtw89_reg_def narrow_bw_ru_dis;
|
||||
struct rtw89_reg_def wow_ctrl;
|
||||
struct rtw89_reg_def agg_limit;
|
||||
struct rtw89_reg_def txcnt_limit;
|
||||
|
||||
int (*check_mac_en)(struct rtw89_dev *rtwdev, u8 band,
|
||||
enum rtw89_mac_hwmod_sel sel);
|
||||
@@ -1186,6 +1188,8 @@ void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link, bool en);
|
||||
void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link);
|
||||
void rtw89_mac_set_he_tb(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif_link *rtwvif_link);
|
||||
void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
|
||||
void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en);
|
||||
int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
|
||||
|
||||
@@ -656,6 +656,7 @@ static void __rtw89_ops_bss_link_assoc(struct rtw89_dev *rtwdev,
|
||||
rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, rtwvif_link);
|
||||
rtw89_mac_port_update(rtwdev, rtwvif_link);
|
||||
rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, rtwvif_link);
|
||||
rtw89_mac_set_he_tb(rtwdev, rtwvif_link);
|
||||
}
|
||||
|
||||
static void __rtw89_ops_bss_assoc(struct rtw89_dev *rtwdev,
|
||||
|
||||
@@ -708,8 +708,8 @@ static int sec_eng_init_be(struct rtw89_dev *rtwdev)
|
||||
val32 |= B_BE_CLK_EN_CGCMP | B_BE_CLK_EN_WAPI | B_BE_CLK_EN_WEP_TKIP |
|
||||
B_BE_SEC_TX_ENC | B_BE_SEC_RX_DEC |
|
||||
B_BE_MC_DEC | B_BE_BC_DEC |
|
||||
B_BE_BMC_MGNT_DEC | B_BE_UC_MGNT_DEC;
|
||||
val32 &= ~B_BE_SEC_PRE_ENQUE_TX;
|
||||
B_BE_BMC_MGNT_DEC | B_BE_UC_MGNT_DEC |
|
||||
B_BE_SEC_PRE_ENQUE_TX;
|
||||
rtw89_write32(rtwdev, R_BE_SEC_ENG_CTRL, val32);
|
||||
|
||||
rtw89_write32_set(rtwdev, R_BE_SEC_MPDU_PROC, B_BE_APPEND_ICV | B_BE_APPEND_MIC);
|
||||
@@ -2585,6 +2585,8 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
|
||||
.mask = B_BE_RXTRIG_RU26_DIS,
|
||||
},
|
||||
.wow_ctrl = {.addr = R_BE_WOW_CTRL, .mask = B_BE_WOW_WOWEN,},
|
||||
.agg_limit = {.addr = R_BE_AMPDU_AGG_LIMIT, .mask = B_BE_AMPDU_MAX_TIME_MASK,},
|
||||
.txcnt_limit = {.addr = R_BE_TXCNT, .mask = B_BE_L_TXCNT_LMT_MASK,},
|
||||
|
||||
.check_mac_en = rtw89_mac_check_mac_en_be,
|
||||
.sys_init = sys_init_be,
|
||||
|
||||
@@ -455,34 +455,36 @@
|
||||
#define B_BE_RX0DMA_INT_EN BIT(0)
|
||||
|
||||
#define R_BE_HAXI_HISR00 0xB0B4
|
||||
#define B_BE_RDU_CH6_INT BIT(28)
|
||||
#define B_BE_RDU_CH5_INT BIT(27)
|
||||
#define B_BE_RDU_CH4_INT BIT(26)
|
||||
#define B_BE_RDU_CH2_INT BIT(25)
|
||||
#define B_BE_RDU_CH1_INT BIT(24)
|
||||
#define B_BE_RDU_CH0_INT BIT(23)
|
||||
#define B_BE_RXDMA_STUCK_INT BIT(22)
|
||||
#define B_BE_TXDMA_STUCK_INT BIT(21)
|
||||
#define B_BE_TXDMA_CH14_INT BIT(20)
|
||||
#define B_BE_TXDMA_CH13_INT BIT(19)
|
||||
#define B_BE_TXDMA_CH12_INT BIT(18)
|
||||
#define B_BE_TXDMA_CH11_INT BIT(17)
|
||||
#define B_BE_TXDMA_CH10_INT BIT(16)
|
||||
#define B_BE_TXDMA_CH9_INT BIT(15)
|
||||
#define B_BE_TXDMA_CH8_INT BIT(14)
|
||||
#define B_BE_TXDMA_CH7_INT BIT(13)
|
||||
#define B_BE_TXDMA_CH6_INT BIT(12)
|
||||
#define B_BE_TXDMA_CH5_INT BIT(11)
|
||||
#define B_BE_TXDMA_CH4_INT BIT(10)
|
||||
#define B_BE_TXDMA_CH3_INT BIT(9)
|
||||
#define B_BE_TXDMA_CH2_INT BIT(8)
|
||||
#define B_BE_TXDMA_CH1_INT BIT(7)
|
||||
#define B_BE_TXDMA_CH0_INT BIT(6)
|
||||
#define B_BE_RPQ1DMA_INT BIT(5)
|
||||
#define B_BE_RX1P1DMA_INT BIT(4)
|
||||
#define B_BE_RDU_CH5_INT_V1 BIT(30)
|
||||
#define B_BE_RDU_CH4_INT_V1 BIT(29)
|
||||
#define B_BE_RDU_CH3_INT_V1 BIT(28)
|
||||
#define B_BE_RDU_CH2_INT_V1 BIT(27)
|
||||
#define B_BE_RDU_CH1_INT_V1 BIT(26)
|
||||
#define B_BE_RDU_CH0_INT_V1 BIT(25)
|
||||
#define B_BE_RXDMA_STUCK_INT_V1 BIT(24)
|
||||
#define B_BE_TXDMA_STUCK_INT_V1 BIT(23)
|
||||
#define B_BE_TXDMA_CH14_INT_V1 BIT(22)
|
||||
#define B_BE_TXDMA_CH13_INT_V1 BIT(21)
|
||||
#define B_BE_TXDMA_CH12_INT_V1 BIT(20)
|
||||
#define B_BE_TXDMA_CH11_INT_V1 BIT(19)
|
||||
#define B_BE_TXDMA_CH10_INT_V1 BIT(18)
|
||||
#define B_BE_TXDMA_CH9_INT_V1 BIT(17)
|
||||
#define B_BE_TXDMA_CH8_INT_V1 BIT(16)
|
||||
#define B_BE_TXDMA_CH7_INT_V1 BIT(15)
|
||||
#define B_BE_TXDMA_CH6_INT_V1 BIT(14)
|
||||
#define B_BE_TXDMA_CH5_INT_V1 BIT(13)
|
||||
#define B_BE_TXDMA_CH4_INT_V1 BIT(12)
|
||||
#define B_BE_TXDMA_CH3_INT_V1 BIT(11)
|
||||
#define B_BE_TXDMA_CH2_INT_V1 BIT(10)
|
||||
#define B_BE_TXDMA_CH1_INT_V1 BIT(9)
|
||||
#define B_BE_TXDMA_CH0_INT_V1 BIT(8)
|
||||
#define B_BE_RX1P1DMA_INT_V1 BIT(7)
|
||||
#define B_BE_RX0P1DMA_INT_V1 BIT(6)
|
||||
#define B_BE_RO1DMA_INT BIT(5)
|
||||
#define B_BE_RP1DMA_INT BIT(4)
|
||||
#define B_BE_RX1DMA_INT BIT(3)
|
||||
#define B_BE_RPQ0DMA_INT BIT(2)
|
||||
#define B_BE_RX0P1DMA_INT BIT(1)
|
||||
#define B_BE_RO0DMA_INT BIT(2)
|
||||
#define B_BE_RP0DMA_INT BIT(1)
|
||||
#define B_BE_RX0DMA_INT BIT(0)
|
||||
|
||||
/* TX/RX */
|
||||
|
||||
@@ -666,7 +666,7 @@ SIMPLE_DEV_PM_OPS(rtw89_pm_ops_be, rtw89_pci_suspend_be, rtw89_pci_resume_be);
|
||||
EXPORT_SYMBOL(rtw89_pm_ops_be);
|
||||
|
||||
const struct rtw89_pci_gen_def rtw89_pci_gen_be = {
|
||||
.isr_rdu = B_BE_RDU_CH1_INT | B_BE_RDU_CH0_INT,
|
||||
.isr_rdu = B_BE_RDU_CH1_INT_V1 | B_BE_RDU_CH0_INT_V1,
|
||||
.isr_halt_c2h = B_BE_HALT_C2H_INT,
|
||||
.isr_wdt_timeout = B_BE_WDT_TIMEOUT_INT,
|
||||
.isr_clear_rpq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RPQ0_ISR_V1},
|
||||
|
||||
@@ -2044,12 +2044,15 @@ static s8 rtw89_phy_ant_gain_offset(struct rtw89_dev *rtwdev, u8 band, u32 cente
|
||||
if (!chip->support_ant_gain)
|
||||
return 0;
|
||||
|
||||
if (!(ant_gain->regd_enabled & BIT(regd)))
|
||||
if (ant_gain->block_country || !(ant_gain->regd_enabled & BIT(regd)))
|
||||
return 0;
|
||||
|
||||
offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, center_freq);
|
||||
offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, center_freq);
|
||||
|
||||
if (RTW89_CHK_FW_FEATURE(NO_POWER_DIFFERENCE, &rtwdev->fw))
|
||||
return min(offset_patha, offset_pathb);
|
||||
|
||||
return max(offset_patha, offset_pathb);
|
||||
}
|
||||
|
||||
@@ -2057,10 +2060,17 @@ s16 rtw89_phy_ant_gain_pwr_offset(struct rtw89_dev *rtwdev,
|
||||
const struct rtw89_chan *chan)
|
||||
{
|
||||
struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain;
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
u8 regd = rtw89_regd_get(rtwdev, chan->band_type);
|
||||
s8 offset_patha, offset_pathb;
|
||||
|
||||
if (!(ant_gain->regd_enabled & BIT(regd)))
|
||||
if (!chip->support_ant_gain)
|
||||
return 0;
|
||||
|
||||
if (ant_gain->block_country || !(ant_gain->regd_enabled & BIT(regd)))
|
||||
return 0;
|
||||
|
||||
if (RTW89_CHK_FW_FEATURE(NO_POWER_DIFFERENCE, &rtwdev->fw))
|
||||
return 0;
|
||||
|
||||
offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, chan->freq);
|
||||
@@ -2079,7 +2089,8 @@ int rtw89_print_ant_gain(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
|
||||
char *p = buf, *end = buf + bufsz;
|
||||
s8 offset_patha, offset_pathb;
|
||||
|
||||
if (!chip->support_ant_gain || !(ant_gain->regd_enabled & BIT(regd))) {
|
||||
if (!(chip->support_ant_gain && (ant_gain->regd_enabled & BIT(regd))) ||
|
||||
ant_gain->block_country) {
|
||||
p += scnprintf(p, end - p, "no DAG is applied\n");
|
||||
goto out;
|
||||
}
|
||||
@@ -3459,6 +3470,30 @@ rtw89_phy_c2h_rfk_report_state(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u3
|
||||
static void
|
||||
rtw89_phy_c2h_rfk_log_tas_pwr(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
|
||||
{
|
||||
const struct rtw89_c2h_rf_tas_info *rf_tas =
|
||||
(const struct rtw89_c2h_rf_tas_info *)c2h->data;
|
||||
const enum rtw89_sar_sources src = rtwdev->sar.src;
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
u64 linear = 0;
|
||||
u32 i, cur_idx;
|
||||
s16 txpwr;
|
||||
|
||||
if (!tas->enable || src == RTW89_SAR_SOURCE_NONE)
|
||||
return;
|
||||
|
||||
cur_idx = le32_to_cpu(rf_tas->cur_idx);
|
||||
for (i = 0; i < cur_idx; i++) {
|
||||
txpwr = (s16)le16_to_cpu(rf_tas->txpwr_history[i]);
|
||||
linear += rtw89_db_quarter_to_linear(txpwr);
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SAR,
|
||||
"tas: index: %u, txpwr: %d\n", i, txpwr);
|
||||
}
|
||||
|
||||
if (cur_idx == 0)
|
||||
tas->instant_txpwr = rtw89_db_to_linear(0);
|
||||
else
|
||||
tas->instant_txpwr = DIV_ROUND_DOWN_ULL(linear, cur_idx);
|
||||
}
|
||||
|
||||
static
|
||||
|
||||
@@ -914,6 +914,13 @@ static inline s8 rtw89_phy_txpwr_rf_to_bb(struct rtw89_dev *rtwdev, s8 txpwr_rf)
|
||||
return txpwr_rf << (chip->txpwr_factor_bb - chip->txpwr_factor_rf);
|
||||
}
|
||||
|
||||
static inline s8 rtw89_phy_txpwr_bb_to_rf(struct rtw89_dev *rtwdev, s8 txpwr_bb)
|
||||
{
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
|
||||
return txpwr_bb >> (chip->txpwr_factor_bb - chip->txpwr_factor_rf);
|
||||
}
|
||||
|
||||
static inline s8 rtw89_phy_txpwr_rf_to_mac(struct rtw89_dev *rtwdev, s8 txpwr_rf)
|
||||
{
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
|
||||
@@ -6618,6 +6618,13 @@
|
||||
#define B_BE_RTS_LIMIT_IN_OFDM6 BIT(1)
|
||||
#define B_BE_CHECK_CCK_EN BIT(0)
|
||||
|
||||
#define R_BE_TXCNT 0x1082C
|
||||
#define R_BE_TXCNT_C1 0x1482C
|
||||
#define B_BE_ADD_TXCNT_BY BIT(31)
|
||||
#define B_BE_TOTAL_TC_OPT BIT(30)
|
||||
#define B_BE_S_TXCNT_LMT_MASK GENMASK(29, 24)
|
||||
#define B_BE_L_TXCNT_LMT_MASK GENMASK(21, 16)
|
||||
|
||||
#define R_BE_MBSSID_DROP_0 0x1083C
|
||||
#define R_BE_MBSSID_DROP_0_C1 0x1483C
|
||||
#define B_BE_GI_LTF_FB_SEL BIT(30)
|
||||
@@ -7095,6 +7102,10 @@
|
||||
#define B_BE_MACLBK_RDY_NUM_MASK GENMASK(7, 3)
|
||||
#define B_BE_MACLBK_EN BIT(0)
|
||||
|
||||
#define R_BE_CLIENT_OM_CTRL 0x11040
|
||||
#define R_BE_CLIENT_OM_CTRL_C1 0x15040
|
||||
#define B_BE_TRIG_DIS_EHTTB BIT(24)
|
||||
|
||||
#define R_BE_WMAC_NAV_CTL 0x11080
|
||||
#define R_BE_WMAC_NAV_CTL_C1 0x15080
|
||||
#define B_BE_WMAC_NAV_UPPER_EN BIT(26)
|
||||
@@ -9174,6 +9185,16 @@
|
||||
#define B_IQKINF2_FCNT GENMASK(23, 16)
|
||||
#define B_IQKINF2_KCNT GENMASK(15, 8)
|
||||
#define B_IQKINF2_NCTLV GENMASK(7, 0)
|
||||
#define R_TXAGC_REF_DBM_RF1_P0 0xBC04
|
||||
#define B_TXAGC_OFDM_REF_DBM_RF1_P0 GENMASK(10, 2)
|
||||
#define B_TXAGC_CCK_REF_DBM_RF1_P0 GENMASK(19, 11)
|
||||
#define R_TSSI_K_RF1_P0 0xBC28
|
||||
#define B_TSSI_K_OFDM_RF1_P0 GENMASK(9, 0)
|
||||
#define R_TXAGC_REF_DBM_RF1_P1 0xBD04
|
||||
#define B_TXAGC_OFDM_REF_DBM_RF1_P1 GENMASK(10, 2)
|
||||
#define B_TXAGC_CCK_REF_DBM_RF1_P1 GENMASK(19, 11)
|
||||
#define R_TSSI_K_RF1_P1 0xBD28
|
||||
#define B_TSSI_K_OFDM_RF1_P1 GENMASK(9, 0)
|
||||
#define R_RFK_ST 0xBFF8
|
||||
#define R_DCOF0 0xC000
|
||||
#define B_DCOF0_RST BIT(17)
|
||||
@@ -9343,16 +9364,18 @@
|
||||
#define R_TSSI_MAP_OFST_P1 0xE720
|
||||
#define B_TSSI_MAP_OFST_OFDM GENMASK(17, 9)
|
||||
#define B_TSSI_MAP_OFST_CCK GENMASK(26, 18)
|
||||
#define R_TXAGC_REF0_P0 0xE628
|
||||
#define R_TXAGC_REF0_P1 0xE728
|
||||
#define B_TXAGC_REF0_OFDM_DBM GENMASK(8, 0)
|
||||
#define B_TXAGC_REF0_CCK_DBM GENMASK(17, 9)
|
||||
#define B_TXAGC_REF0_OFDM_CW GENMASK(26, 18)
|
||||
#define R_TXAGC_REF1_P0 0xE62C
|
||||
#define R_TXAGC_REF1_P1 0xE72C
|
||||
#define B_TXAGC_REF1_CCK_CW GENMASK(8, 0)
|
||||
#define R_TXAGC_REF_DBM_P0 0xE628
|
||||
#define B_TXAGC_OFDM_REF_DBM_P0 GENMASK(8, 0)
|
||||
#define B_TXAGC_CCK_REF_DBM_P0 GENMASK(17, 9)
|
||||
#define R_TSSI_K_P0 0xE6A0
|
||||
#define B_TSSI_K_OFDM_P0 GENMASK(29, 20)
|
||||
#define R_TXPWR_RSTB 0xE70C
|
||||
#define B_TXPWR_RSTB BIT(16)
|
||||
#define R_TXAGC_REF_DBM_P1 0xE728
|
||||
#define B_TXAGC_OFDM_REF_DBM_P1 GENMASK(8, 0)
|
||||
#define B_TXAGC_CCK_REF_DBM_P1 GENMASK(17, 9)
|
||||
#define R_TSSI_K_P1 0xE7A0
|
||||
#define B_TSSI_K_OFDM_P1 GENMASK(29, 20)
|
||||
|
||||
/* WiFi CPU local domain */
|
||||
#define R_AX_WDT_CTRL 0x0040
|
||||
|
||||
@@ -721,6 +721,31 @@ static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev,
|
||||
sband->channels[i].flags |= IEEE80211_CHAN_DISABLED;
|
||||
}
|
||||
|
||||
static void rtw89_regd_apply_policy_tas(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
|
||||
const struct rtw89_regd *regd = regulatory->regd;
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
|
||||
if (!tas->enable)
|
||||
return;
|
||||
|
||||
tas->block_regd = !test_bit(RTW89_REGD_FUNC_TAS, regd->func_bitmap);
|
||||
}
|
||||
|
||||
static void rtw89_regd_apply_policy_ant_gain(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
|
||||
struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain;
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
const struct rtw89_regd *regd = regulatory->regd;
|
||||
|
||||
if (!chip->support_ant_gain)
|
||||
return;
|
||||
|
||||
ant_gain->block_country = !test_bit(RTW89_REGD_FUNC_DAG, regd->func_bitmap);
|
||||
}
|
||||
|
||||
static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev,
|
||||
struct wiphy *wiphy,
|
||||
struct regulatory_request *request)
|
||||
@@ -738,6 +763,8 @@ static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev,
|
||||
|
||||
rtw89_regd_apply_policy_unii4(rtwdev, wiphy);
|
||||
rtw89_regd_apply_policy_6ghz(rtwdev, wiphy);
|
||||
rtw89_regd_apply_policy_tas(rtwdev);
|
||||
rtw89_regd_apply_policy_ant_gain(rtwdev);
|
||||
}
|
||||
|
||||
static
|
||||
|
||||
@@ -2423,6 +2423,7 @@ static const struct rtw89_chip_ops rtw8851b_chip_ops = {
|
||||
.h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl,
|
||||
.h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl,
|
||||
.h2c_ampdu_cmac_tbl = NULL,
|
||||
.h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl,
|
||||
.h2c_default_dmac_tbl = NULL,
|
||||
.h2c_update_beacon = rtw89_fw_h2c_update_beacon,
|
||||
.h2c_ba_cam = rtw89_fw_h2c_ba_cam,
|
||||
@@ -2458,6 +2459,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
|
||||
.try_ce_fw = true,
|
||||
.bbmcu_nr = 0,
|
||||
.needed_fw_elms = 0,
|
||||
.fw_blacklist = NULL,
|
||||
.fifo_size = 196608,
|
||||
.small_fifo_size = true,
|
||||
.dle_scc_rsvd_size = 98304,
|
||||
@@ -2496,10 +2498,13 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
|
||||
BIT(NL80211_CHAN_WIDTH_80),
|
||||
.support_unii4 = true,
|
||||
.support_ant_gain = false,
|
||||
.support_tas = false,
|
||||
.ul_tb_waveform_ctrl = true,
|
||||
.ul_tb_pwr_diff = false,
|
||||
.rx_freq_frome_ie = true,
|
||||
.hw_sec_hdr = false,
|
||||
.hw_mgmt_tx_encrypt = false,
|
||||
.hw_tkip_crypto = false,
|
||||
.rf_path_num = 1,
|
||||
.tx_nss = 1,
|
||||
.rx_nss = 1,
|
||||
|
||||
@@ -2149,6 +2149,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
|
||||
.h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl,
|
||||
.h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl,
|
||||
.h2c_ampdu_cmac_tbl = NULL,
|
||||
.h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl,
|
||||
.h2c_default_dmac_tbl = NULL,
|
||||
.h2c_update_beacon = rtw89_fw_h2c_update_beacon,
|
||||
.h2c_ba_cam = rtw89_fw_h2c_ba_cam,
|
||||
@@ -2175,6 +2176,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
|
||||
.try_ce_fw = false,
|
||||
.bbmcu_nr = 0,
|
||||
.needed_fw_elms = 0,
|
||||
.fw_blacklist = NULL,
|
||||
.fifo_size = 458752,
|
||||
.small_fifo_size = false,
|
||||
.dle_scc_rsvd_size = 0,
|
||||
@@ -2214,10 +2216,13 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
|
||||
BIT(NL80211_CHAN_WIDTH_80),
|
||||
.support_unii4 = false,
|
||||
.support_ant_gain = false,
|
||||
.support_tas = false,
|
||||
.ul_tb_waveform_ctrl = false,
|
||||
.ul_tb_pwr_diff = false,
|
||||
.rx_freq_frome_ie = true,
|
||||
.hw_sec_hdr = false,
|
||||
.hw_mgmt_tx_encrypt = false,
|
||||
.hw_tkip_crypto = false,
|
||||
.rf_path_num = 2,
|
||||
.tx_nss = 2,
|
||||
.rx_nss = 2,
|
||||
|
||||
@@ -776,6 +776,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
|
||||
.h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl,
|
||||
.h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl,
|
||||
.h2c_ampdu_cmac_tbl = NULL,
|
||||
.h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl,
|
||||
.h2c_default_dmac_tbl = NULL,
|
||||
.h2c_update_beacon = rtw89_fw_h2c_update_beacon,
|
||||
.h2c_ba_cam = rtw89_fw_h2c_ba_cam,
|
||||
@@ -811,6 +812,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
|
||||
.try_ce_fw = true,
|
||||
.bbmcu_nr = 0,
|
||||
.needed_fw_elms = 0,
|
||||
.fw_blacklist = &rtw89_fw_blacklist_default,
|
||||
.fifo_size = 196608,
|
||||
.small_fifo_size = true,
|
||||
.dle_scc_rsvd_size = 98304,
|
||||
@@ -850,10 +852,13 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
|
||||
BIT(NL80211_CHAN_WIDTH_80),
|
||||
.support_unii4 = true,
|
||||
.support_ant_gain = true,
|
||||
.support_tas = false,
|
||||
.ul_tb_waveform_ctrl = true,
|
||||
.ul_tb_pwr_diff = false,
|
||||
.rx_freq_frome_ie = true,
|
||||
.hw_sec_hdr = false,
|
||||
.hw_mgmt_tx_encrypt = false,
|
||||
.hw_tkip_crypto = false,
|
||||
.rf_path_num = 2,
|
||||
.tx_nss = 2,
|
||||
.rx_nss = 2,
|
||||
|
||||
@@ -621,9 +621,9 @@ static void rtw8852bt_ext_loss_avg_update(struct rtw89_dev *rtwdev,
|
||||
if (ext_loss_a == ext_loss_b) {
|
||||
ext_loss_avg = ext_loss_a;
|
||||
} else {
|
||||
linear = rtw89_db_2_linear(abs(ext_loss_a - ext_loss_b)) + 1;
|
||||
linear = DIV_ROUND_CLOSEST_ULL(linear / 2, 1 << RTW89_LINEAR_FRAC_BITS);
|
||||
ext_loss_avg = rtw89_linear_2_db(linear);
|
||||
linear = rtw89_db_to_linear(abs(ext_loss_a - ext_loss_b)) + 1;
|
||||
linear /= 2;
|
||||
ext_loss_avg = rtw89_linear_to_db(linear);
|
||||
ext_loss_avg += min(ext_loss_a, ext_loss_b);
|
||||
}
|
||||
|
||||
|
||||
@@ -3585,9 +3585,10 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
|
||||
u8 ch_idx = _tssi_ch_to_idx(rtwdev, channel);
|
||||
struct rtw8852bx_bb_tssi_bak tssi_bak;
|
||||
s32 aliment_diff, tssi_cw_default;
|
||||
u32 start_time, finish_time;
|
||||
u32 bb_reg_backup[8] = {0};
|
||||
ktime_t start_time;
|
||||
const s16 *power;
|
||||
s64 this_time;
|
||||
u8 band;
|
||||
bool ok;
|
||||
u32 tmp;
|
||||
@@ -3613,7 +3614,7 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
|
||||
return;
|
||||
}
|
||||
|
||||
start_time = ktime_get_ns();
|
||||
start_time = ktime_get();
|
||||
|
||||
if (chan->band_type == RTW89_BAND_2G)
|
||||
power = power_2g;
|
||||
@@ -3738,12 +3739,12 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
|
||||
rtw8852bx_bb_restore_tssi(rtwdev, phy, &tssi_bak);
|
||||
rtw8852bx_bb_tx_mode_switch(rtwdev, phy, 0);
|
||||
|
||||
finish_time = ktime_get_ns();
|
||||
tssi_info->tssi_alimk_time += finish_time - start_time;
|
||||
this_time = ktime_us_delta(ktime_get(), start_time);
|
||||
tssi_info->tssi_alimk_time += this_time;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RFK,
|
||||
"[TSSI PA K] %s processing time = %d ms\n", __func__,
|
||||
tssi_info->tssi_alimk_time);
|
||||
"[TSSI PA K] %s processing time = %lld us (acc = %llu us)\n",
|
||||
__func__, this_time, tssi_info->tssi_alimk_time);
|
||||
}
|
||||
|
||||
void rtw8852b_dpk_init(struct rtw89_dev *rtwdev)
|
||||
|
||||
@@ -710,6 +710,7 @@ static const struct rtw89_chip_ops rtw8852bt_chip_ops = {
|
||||
.h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl,
|
||||
.h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl,
|
||||
.h2c_ampdu_cmac_tbl = NULL,
|
||||
.h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl,
|
||||
.h2c_default_dmac_tbl = NULL,
|
||||
.h2c_update_beacon = rtw89_fw_h2c_update_beacon,
|
||||
.h2c_ba_cam = rtw89_fw_h2c_ba_cam,
|
||||
@@ -745,6 +746,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
|
||||
.try_ce_fw = true,
|
||||
.bbmcu_nr = 0,
|
||||
.needed_fw_elms = RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_NO_6GHZ,
|
||||
.fw_blacklist = &rtw89_fw_blacklist_default,
|
||||
.fifo_size = 458752,
|
||||
.small_fifo_size = true,
|
||||
.dle_scc_rsvd_size = 98304,
|
||||
@@ -783,10 +785,13 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
|
||||
BIT(NL80211_CHAN_WIDTH_80),
|
||||
.support_unii4 = true,
|
||||
.support_ant_gain = true,
|
||||
.support_tas = false,
|
||||
.ul_tb_waveform_ctrl = true,
|
||||
.ul_tb_pwr_diff = false,
|
||||
.rx_freq_frome_ie = true,
|
||||
.hw_sec_hdr = false,
|
||||
.hw_mgmt_tx_encrypt = false,
|
||||
.hw_tkip_crypto = true,
|
||||
.rf_path_num = 2,
|
||||
.tx_nss = 2,
|
||||
.rx_nss = 2,
|
||||
|
||||
@@ -3663,9 +3663,10 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
|
||||
u8 ch_idx = _tssi_ch_to_idx(rtwdev, channel);
|
||||
struct rtw8852bx_bb_tssi_bak tssi_bak;
|
||||
s32 aliment_diff, tssi_cw_default;
|
||||
u32 start_time, finish_time;
|
||||
u32 bb_reg_backup[8] = {};
|
||||
ktime_t start_time;
|
||||
const s16 *power;
|
||||
s64 this_time;
|
||||
u8 band;
|
||||
bool ok;
|
||||
u32 tmp;
|
||||
@@ -3675,7 +3676,7 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
|
||||
"======> %s channel=%d path=%d\n", __func__, channel,
|
||||
path);
|
||||
|
||||
start_time = ktime_get_ns();
|
||||
start_time = ktime_get();
|
||||
|
||||
if (chan->band_type == RTW89_BAND_2G)
|
||||
power = power_2g;
|
||||
@@ -3802,12 +3803,12 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
|
||||
rtw8852bx_bb_restore_tssi(rtwdev, phy, &tssi_bak);
|
||||
rtw8852bx_bb_tx_mode_switch(rtwdev, phy, 0);
|
||||
|
||||
finish_time = ktime_get_ns();
|
||||
tssi_info->tssi_alimk_time += finish_time - start_time;
|
||||
this_time = ktime_us_delta(ktime_get(), start_time);
|
||||
tssi_info->tssi_alimk_time += this_time;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_RFK,
|
||||
"[TSSI PA K] %s processing time = %d ms\n", __func__,
|
||||
tssi_info->tssi_alimk_time);
|
||||
"[TSSI PA K] %s processing time = %lld us (acc = %llu us)\n",
|
||||
__func__, this_time, tssi_info->tssi_alimk_time);
|
||||
}
|
||||
|
||||
void rtw8852bt_dpk_init(struct rtw89_dev *rtwdev)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "rtw8852c.h"
|
||||
#include "rtw8852c_rfk.h"
|
||||
#include "rtw8852c_table.h"
|
||||
#include "sar.h"
|
||||
#include "util.h"
|
||||
|
||||
#define RTW8852C_FW_FORMAT_MAX 1
|
||||
@@ -2880,6 +2881,7 @@ static int rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
|
||||
|
||||
static const struct rtw89_chanctx_listener rtw8852c_chanctx_listener = {
|
||||
.callbacks[RTW89_CHANCTX_CALLBACK_RFK] = rtw8852c_rfk_chanctx_cb,
|
||||
.callbacks[RTW89_CHANCTX_CALLBACK_TAS] = rtw89_tas_chanctx_cb,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
@@ -2941,6 +2943,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
|
||||
.h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl,
|
||||
.h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl,
|
||||
.h2c_ampdu_cmac_tbl = NULL,
|
||||
.h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl,
|
||||
.h2c_default_dmac_tbl = NULL,
|
||||
.h2c_update_beacon = rtw89_fw_h2c_update_beacon,
|
||||
.h2c_ba_cam = rtw89_fw_h2c_ba_cam,
|
||||
@@ -2967,6 +2970,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
|
||||
.try_ce_fw = false,
|
||||
.bbmcu_nr = 0,
|
||||
.needed_fw_elms = 0,
|
||||
.fw_blacklist = &rtw89_fw_blacklist_default,
|
||||
.fifo_size = 458752,
|
||||
.small_fifo_size = false,
|
||||
.dle_scc_rsvd_size = 0,
|
||||
@@ -3009,10 +3013,13 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
|
||||
BIT(NL80211_CHAN_WIDTH_160),
|
||||
.support_unii4 = true,
|
||||
.support_ant_gain = true,
|
||||
.support_tas = true,
|
||||
.ul_tb_waveform_ctrl = false,
|
||||
.ul_tb_pwr_diff = true,
|
||||
.rx_freq_frome_ie = false,
|
||||
.hw_sec_hdr = true,
|
||||
.hw_mgmt_tx_encrypt = true,
|
||||
.hw_tkip_crypto = true,
|
||||
.rf_path_num = 2,
|
||||
.tx_nss = 2,
|
||||
.rx_nss = 2,
|
||||
|
||||
@@ -2156,6 +2156,56 @@ static void rtw8922a_set_txpwr_ref(struct rtw89_dev *rtwdev,
|
||||
B_BE_PWR_REF_CTRL_CCK, ref_cck);
|
||||
}
|
||||
|
||||
static const struct rtw89_reg_def rtw8922a_txpwr_ref[][3] = {
|
||||
{{ .addr = R_TXAGC_REF_DBM_P0, .mask = B_TXAGC_OFDM_REF_DBM_P0},
|
||||
{ .addr = R_TXAGC_REF_DBM_P0, .mask = B_TXAGC_CCK_REF_DBM_P0},
|
||||
{ .addr = R_TSSI_K_P0, .mask = B_TSSI_K_OFDM_P0}
|
||||
},
|
||||
{{ .addr = R_TXAGC_REF_DBM_RF1_P0, .mask = B_TXAGC_OFDM_REF_DBM_RF1_P0},
|
||||
{ .addr = R_TXAGC_REF_DBM_RF1_P0, .mask = B_TXAGC_CCK_REF_DBM_RF1_P0},
|
||||
{ .addr = R_TSSI_K_RF1_P0, .mask = B_TSSI_K_OFDM_RF1_P0}
|
||||
},
|
||||
};
|
||||
|
||||
static void rtw8922a_set_txpwr_diff(struct rtw89_dev *rtwdev,
|
||||
const struct rtw89_chan *chan,
|
||||
enum rtw89_phy_idx phy_idx)
|
||||
{
|
||||
s16 pwr_ofst = rtw89_phy_ant_gain_pwr_offset(rtwdev, chan);
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
static const u32 path_ofst[] = {0x0, 0x100};
|
||||
const struct rtw89_reg_def *txpwr_ref;
|
||||
static const s16 tssi_k_base = 0x12;
|
||||
s16 tssi_k_ofst = abs(pwr_ofst) + tssi_k_base;
|
||||
s16 ofst_dec[RF_PATH_NUM_8922A];
|
||||
s16 tssi_k[RF_PATH_NUM_8922A];
|
||||
s16 pwr_ref_ofst;
|
||||
s16 pwr_ref = 0;
|
||||
u8 i;
|
||||
|
||||
if (rtwdev->hal.cv == CHIP_CAV)
|
||||
pwr_ref = 16;
|
||||
|
||||
pwr_ref <<= chip->txpwr_factor_rf;
|
||||
pwr_ref_ofst = pwr_ref - rtw89_phy_txpwr_bb_to_rf(rtwdev, abs(pwr_ofst));
|
||||
|
||||
ofst_dec[RF_PATH_A] = pwr_ofst > 0 ? pwr_ref : pwr_ref_ofst;
|
||||
ofst_dec[RF_PATH_B] = pwr_ofst > 0 ? pwr_ref_ofst : pwr_ref;
|
||||
tssi_k[RF_PATH_A] = pwr_ofst > 0 ? tssi_k_base : tssi_k_ofst;
|
||||
tssi_k[RF_PATH_B] = pwr_ofst > 0 ? tssi_k_ofst : tssi_k_base;
|
||||
|
||||
for (i = 0; i < RF_PATH_NUM_8922A; i++) {
|
||||
txpwr_ref = rtw8922a_txpwr_ref[phy_idx];
|
||||
|
||||
rtw89_phy_write32_mask(rtwdev, txpwr_ref[0].addr + path_ofst[i],
|
||||
txpwr_ref[0].mask, ofst_dec[i]);
|
||||
rtw89_phy_write32_mask(rtwdev, txpwr_ref[1].addr + path_ofst[i],
|
||||
txpwr_ref[1].mask, ofst_dec[i]);
|
||||
rtw89_phy_write32_mask(rtwdev, txpwr_ref[2].addr + path_ofst[i],
|
||||
txpwr_ref[2].mask, tssi_k[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw8922a_bb_tx_triangular(struct rtw89_dev *rtwdev, bool en,
|
||||
enum rtw89_phy_idx phy_idx)
|
||||
{
|
||||
@@ -2192,6 +2242,8 @@ static void rtw8922a_set_txpwr(struct rtw89_dev *rtwdev,
|
||||
rtw8922a_set_tx_shape(rtwdev, chan, phy_idx);
|
||||
rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx);
|
||||
rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
|
||||
rtw8922a_set_txpwr_diff(rtwdev, chan, phy_idx);
|
||||
rtw8922a_set_txpwr_ref(rtwdev, phy_idx);
|
||||
}
|
||||
|
||||
static void rtw8922a_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
|
||||
@@ -2702,6 +2754,7 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = {
|
||||
.h2c_default_cmac_tbl = rtw89_fw_h2c_default_cmac_tbl_g7,
|
||||
.h2c_assoc_cmac_tbl = rtw89_fw_h2c_assoc_cmac_tbl_g7,
|
||||
.h2c_ampdu_cmac_tbl = rtw89_fw_h2c_ampdu_cmac_tbl_g7,
|
||||
.h2c_txtime_cmac_tbl = rtw89_fw_h2c_txtime_cmac_tbl_g7,
|
||||
.h2c_default_dmac_tbl = rtw89_fw_h2c_default_dmac_tbl_v2,
|
||||
.h2c_update_beacon = rtw89_fw_h2c_update_beacon_be,
|
||||
.h2c_ba_cam = rtw89_fw_h2c_ba_cam_v1,
|
||||
@@ -2728,6 +2781,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
|
||||
.try_ce_fw = false,
|
||||
.bbmcu_nr = 1,
|
||||
.needed_fw_elms = RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS,
|
||||
.fw_blacklist = &rtw89_fw_blacklist_default,
|
||||
.fifo_size = 589824,
|
||||
.small_fifo_size = false,
|
||||
.dle_scc_rsvd_size = 0,
|
||||
@@ -2767,11 +2821,14 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
|
||||
BIT(NL80211_CHAN_WIDTH_80) |
|
||||
BIT(NL80211_CHAN_WIDTH_160),
|
||||
.support_unii4 = true,
|
||||
.support_ant_gain = false,
|
||||
.support_ant_gain = true,
|
||||
.support_tas = false,
|
||||
.ul_tb_waveform_ctrl = false,
|
||||
.ul_tb_pwr_diff = false,
|
||||
.rx_freq_frome_ie = false,
|
||||
.hw_sec_hdr = true,
|
||||
.hw_mgmt_tx_encrypt = true,
|
||||
.hw_tkip_crypto = true,
|
||||
.rf_path_num = 2,
|
||||
.tx_nss = 2,
|
||||
.rx_nss = 2,
|
||||
|
||||
@@ -7,10 +7,16 @@
|
||||
#include "phy.h"
|
||||
#include "reg.h"
|
||||
#include "sar.h"
|
||||
#include "util.h"
|
||||
|
||||
#define RTW89_TAS_FACTOR 2 /* unit: 0.25 dBm */
|
||||
#define RTW89_TAS_SAR_GAP (1 << RTW89_TAS_FACTOR)
|
||||
#define RTW89_TAS_DPR_GAP (1 << RTW89_TAS_FACTOR)
|
||||
#define RTW89_TAS_DELTA (2 << RTW89_TAS_FACTOR)
|
||||
#define RTW89_TAS_TX_RATIO_THRESHOLD 70
|
||||
#define RTW89_TAS_DFLT_TX_RATIO 80
|
||||
#define RTW89_TAS_DPR_ON_OFFSET (RTW89_TAS_DELTA + RTW89_TAS_SAR_GAP)
|
||||
#define RTW89_TAS_DPR_OFF_OFFSET (4 << RTW89_TAS_FACTOR)
|
||||
|
||||
static enum rtw89_sar_subband rtw89_sar_get_subband(struct rtw89_dev *rtwdev,
|
||||
u32 center_freq)
|
||||
@@ -117,8 +123,8 @@ static s8 rtw89_txpwr_sar_to_mac(struct rtw89_dev *rtwdev, u8 fct, s32 cfg)
|
||||
RTW89_SAR_TXPWR_MAC_MAX);
|
||||
}
|
||||
|
||||
static s8 rtw89_txpwr_tas_to_sar(const struct rtw89_sar_handler *sar_hdl,
|
||||
s8 cfg)
|
||||
static s32 rtw89_txpwr_tas_to_sar(const struct rtw89_sar_handler *sar_hdl,
|
||||
s32 cfg)
|
||||
{
|
||||
const u8 fct = sar_hdl->txpwr_factor_sar;
|
||||
|
||||
@@ -128,8 +134,8 @@ static s8 rtw89_txpwr_tas_to_sar(const struct rtw89_sar_handler *sar_hdl,
|
||||
return cfg >> (RTW89_TAS_FACTOR - fct);
|
||||
}
|
||||
|
||||
static s8 rtw89_txpwr_sar_to_tas(const struct rtw89_sar_handler *sar_hdl,
|
||||
s8 cfg)
|
||||
static s32 rtw89_txpwr_sar_to_tas(const struct rtw89_sar_handler *sar_hdl,
|
||||
s32 cfg)
|
||||
{
|
||||
const u8 fct = sar_hdl->txpwr_factor_sar;
|
||||
|
||||
@@ -139,13 +145,43 @@ static s8 rtw89_txpwr_sar_to_tas(const struct rtw89_sar_handler *sar_hdl,
|
||||
return cfg << (RTW89_TAS_FACTOR - fct);
|
||||
}
|
||||
|
||||
static bool rtw89_tas_is_active(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
struct rtw89_vif *rtwvif;
|
||||
|
||||
if (!tas->enable)
|
||||
return false;
|
||||
|
||||
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
|
||||
if (ieee80211_vif_is_mld(rtwvif_to_vif(rtwvif)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *rtw89_tas_state_str(enum rtw89_tas_state state)
|
||||
{
|
||||
switch (state) {
|
||||
case RTW89_TAS_STATE_DPR_OFF:
|
||||
return "DPR OFF";
|
||||
case RTW89_TAS_STATE_DPR_ON:
|
||||
return "DPR ON";
|
||||
case RTW89_TAS_STATE_STATIC_SAR:
|
||||
return "STATIC SAR";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq)
|
||||
{
|
||||
const enum rtw89_sar_sources src = rtwdev->sar.src;
|
||||
/* its members are protected by rtw89_sar_set_src() */
|
||||
const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src];
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
s8 delta;
|
||||
s32 offset;
|
||||
int ret;
|
||||
s32 cfg;
|
||||
u8 fct;
|
||||
@@ -159,15 +195,17 @@ s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq)
|
||||
if (ret)
|
||||
return RTW89_SAR_TXPWR_MAC_MAX;
|
||||
|
||||
if (tas->enable) {
|
||||
if (rtw89_tas_is_active(rtwdev)) {
|
||||
switch (tas->state) {
|
||||
case RTW89_TAS_STATE_DPR_OFF:
|
||||
return RTW89_SAR_TXPWR_MAC_MAX;
|
||||
case RTW89_TAS_STATE_DPR_ON:
|
||||
delta = rtw89_txpwr_tas_to_sar(sar_hdl, tas->delta);
|
||||
cfg -= delta;
|
||||
offset = rtw89_txpwr_tas_to_sar(sar_hdl, RTW89_TAS_DPR_OFF_OFFSET);
|
||||
cfg += offset;
|
||||
break;
|
||||
case RTW89_TAS_STATE_DPR_FORBID:
|
||||
case RTW89_TAS_STATE_DPR_ON:
|
||||
offset = rtw89_txpwr_tas_to_sar(sar_hdl, RTW89_TAS_DPR_ON_OFFSET);
|
||||
cfg -= offset;
|
||||
break;
|
||||
case RTW89_TAS_STATE_STATIC_SAR:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -223,13 +261,23 @@ int rtw89_print_tas(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
char *p = buf, *end = buf + bufsz;
|
||||
|
||||
if (!tas->enable) {
|
||||
if (!rtw89_tas_is_active(rtwdev)) {
|
||||
p += scnprintf(p, end - p, "no TAS is applied\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
p += scnprintf(p, end - p, "DPR gap: %d\n", tas->dpr_gap);
|
||||
p += scnprintf(p, end - p, "TAS delta: %d\n", tas->delta);
|
||||
p += scnprintf(p, end - p, "State: %s\n",
|
||||
rtw89_tas_state_str(tas->state));
|
||||
p += scnprintf(p, end - p, "Average time: %d\n",
|
||||
tas->window_size * 2);
|
||||
p += scnprintf(p, end - p, "SAR gap: %d dBm\n",
|
||||
RTW89_TAS_SAR_GAP >> RTW89_TAS_FACTOR);
|
||||
p += scnprintf(p, end - p, "DPR gap: %d dBm\n",
|
||||
RTW89_TAS_DPR_GAP >> RTW89_TAS_FACTOR);
|
||||
p += scnprintf(p, end - p, "DPR ON offset: %d dBm\n",
|
||||
RTW89_TAS_DPR_ON_OFFSET >> RTW89_TAS_FACTOR);
|
||||
p += scnprintf(p, end - p, "DPR OFF offset: %d dBm\n",
|
||||
RTW89_TAS_DPR_OFF_OFFSET >> RTW89_TAS_FACTOR);
|
||||
|
||||
out:
|
||||
return p - buf;
|
||||
@@ -250,6 +298,7 @@ static int rtw89_apply_sar_common(struct rtw89_dev *rtwdev,
|
||||
|
||||
rtw89_sar_set_src(rtwdev, RTW89_SAR_SOURCE_COMMON, cfg_common, sar);
|
||||
rtw89_core_set_chip_txpwr(rtwdev);
|
||||
rtw89_tas_reset(rtwdev, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -314,65 +363,174 @@ int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw,
|
||||
return rtw89_apply_sar_common(rtwdev, &sar_common);
|
||||
}
|
||||
|
||||
static void rtw89_tas_state_update(struct rtw89_dev *rtwdev)
|
||||
static bool rtw89_tas_query_sar_config(struct rtw89_dev *rtwdev, s32 *cfg)
|
||||
{
|
||||
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
|
||||
const enum rtw89_sar_sources src = rtwdev->sar.src;
|
||||
/* its members are protected by rtw89_sar_set_src() */
|
||||
const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src];
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
s32 txpwr_avg = tas->total_txpwr / RTW89_TAS_MAX_WINDOW / PERCENT;
|
||||
s32 dpr_on_threshold, dpr_off_threshold, cfg;
|
||||
enum rtw89_tas_state state = tas->state;
|
||||
const struct rtw89_chan *chan;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_wiphy(rtwdev->hw->wiphy);
|
||||
|
||||
if (src == RTW89_SAR_SOURCE_NONE)
|
||||
return;
|
||||
return false;
|
||||
|
||||
chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
|
||||
ret = sar_hdl->query_sar_config(rtwdev, chan->freq, &cfg);
|
||||
ret = sar_hdl->query_sar_config(rtwdev, chan->freq, cfg);
|
||||
if (ret)
|
||||
return;
|
||||
return false;
|
||||
|
||||
cfg = rtw89_txpwr_sar_to_tas(sar_hdl, cfg);
|
||||
*cfg = rtw89_txpwr_sar_to_tas(sar_hdl, *cfg);
|
||||
|
||||
if (tas->delta >= cfg) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SAR,
|
||||
"TAS delta exceed SAR limit\n");
|
||||
state = RTW89_TAS_STATE_DPR_FORBID;
|
||||
goto out;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
dpr_on_threshold = cfg;
|
||||
dpr_off_threshold = cfg - tas->dpr_gap;
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SAR,
|
||||
"DPR_ON thold: %d, DPR_OFF thold: %d, txpwr_avg: %d\n",
|
||||
dpr_on_threshold, dpr_off_threshold, txpwr_avg);
|
||||
static void rtw89_tas_state_update(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_tas_state state)
|
||||
{
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
|
||||
if (txpwr_avg >= dpr_on_threshold)
|
||||
state = RTW89_TAS_STATE_DPR_ON;
|
||||
else if (txpwr_avg < dpr_off_threshold)
|
||||
state = RTW89_TAS_STATE_DPR_OFF;
|
||||
|
||||
out:
|
||||
if (tas->state == state)
|
||||
return;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SAR,
|
||||
"TAS old state: %d, new state: %d\n", tas->state, state);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SAR, "tas: switch state: %s -> %s\n",
|
||||
rtw89_tas_state_str(tas->state), rtw89_tas_state_str(state));
|
||||
|
||||
tas->state = state;
|
||||
rtw89_core_set_chip_txpwr(rtwdev);
|
||||
}
|
||||
|
||||
static u32 rtw89_tas_get_window_size(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
|
||||
u8 band = chan->band_type;
|
||||
u8 regd = rtw89_regd_get(rtwdev, band);
|
||||
|
||||
switch (regd) {
|
||||
default:
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SAR,
|
||||
"tas: regd: %u is unhandled\n", regd);
|
||||
fallthrough;
|
||||
case RTW89_IC:
|
||||
case RTW89_KCC:
|
||||
return 180;
|
||||
case RTW89_FCC:
|
||||
switch (band) {
|
||||
case RTW89_BAND_2G:
|
||||
return 50;
|
||||
case RTW89_BAND_5G:
|
||||
return 30;
|
||||
case RTW89_BAND_6G:
|
||||
default:
|
||||
return 15;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rtw89_tas_window_update(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
u32 window_size = rtw89_tas_get_window_size(rtwdev);
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
u64 total_txpwr = 0;
|
||||
u8 head_idx;
|
||||
u32 i, j;
|
||||
|
||||
WARN_ON_ONCE(tas->window_size > RTW89_TAS_TXPWR_WINDOW);
|
||||
|
||||
if (tas->window_size == window_size)
|
||||
return;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SAR, "tas: window update: %u -> %u\n",
|
||||
tas->window_size, window_size);
|
||||
|
||||
head_idx = (tas->txpwr_tail_idx - window_size + 1 + RTW89_TAS_TXPWR_WINDOW) %
|
||||
RTW89_TAS_TXPWR_WINDOW;
|
||||
for (i = 0; i < window_size; i++) {
|
||||
j = (head_idx + i) % RTW89_TAS_TXPWR_WINDOW;
|
||||
total_txpwr += tas->txpwr_history[j];
|
||||
}
|
||||
|
||||
tas->window_size = window_size;
|
||||
tas->total_txpwr = total_txpwr;
|
||||
tas->txpwr_head_idx = head_idx;
|
||||
}
|
||||
|
||||
static void rtw89_tas_history_update(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, RTW89_PHY_0);
|
||||
struct rtw89_env_monitor_info *env = &bb->env_monitor;
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
u8 tx_ratio = env->ifs_clm_tx_ratio;
|
||||
u64 instant_txpwr, txpwr;
|
||||
|
||||
/* txpwr in unit of linear(mW) multiply by percentage */
|
||||
if (tx_ratio == 0) {
|
||||
/* special case: idle tx power
|
||||
* use -40 dBm * 100 tx ratio
|
||||
*/
|
||||
instant_txpwr = rtw89_db_to_linear(-40);
|
||||
txpwr = instant_txpwr * 100;
|
||||
} else {
|
||||
instant_txpwr = tas->instant_txpwr;
|
||||
txpwr = instant_txpwr * tx_ratio;
|
||||
}
|
||||
|
||||
tas->total_txpwr += txpwr - tas->txpwr_history[tas->txpwr_head_idx];
|
||||
tas->total_tx_ratio += tx_ratio - tas->tx_ratio_history[tas->tx_ratio_idx];
|
||||
tas->tx_ratio_history[tas->tx_ratio_idx] = tx_ratio;
|
||||
|
||||
tas->txpwr_head_idx = (tas->txpwr_head_idx + 1) % RTW89_TAS_TXPWR_WINDOW;
|
||||
tas->txpwr_tail_idx = (tas->txpwr_tail_idx + 1) % RTW89_TAS_TXPWR_WINDOW;
|
||||
tas->tx_ratio_idx = (tas->tx_ratio_idx + 1) % RTW89_TAS_TX_RATIO_WINDOW;
|
||||
tas->txpwr_history[tas->txpwr_tail_idx] = txpwr;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SAR,
|
||||
"tas: instant_txpwr: %d, tx_ratio: %u, txpwr: %d\n",
|
||||
rtw89_linear_to_db_quarter(instant_txpwr), tx_ratio,
|
||||
rtw89_linear_to_db_quarter(div_u64(txpwr, PERCENT)));
|
||||
}
|
||||
|
||||
static void rtw89_tas_rolling_average(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
s32 dpr_on_threshold, dpr_off_threshold;
|
||||
enum rtw89_tas_state state;
|
||||
u16 tx_ratio_avg;
|
||||
s32 txpwr_avg;
|
||||
u64 linear;
|
||||
|
||||
linear = DIV_ROUND_DOWN_ULL(tas->total_txpwr, tas->window_size * PERCENT);
|
||||
txpwr_avg = rtw89_linear_to_db_quarter(linear);
|
||||
tx_ratio_avg = tas->total_tx_ratio / RTW89_TAS_TX_RATIO_WINDOW;
|
||||
dpr_on_threshold = tas->dpr_on_threshold;
|
||||
dpr_off_threshold = tas->dpr_off_threshold;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SAR,
|
||||
"tas: DPR_ON: %d, DPR_OFF: %d, txpwr_avg: %d, tx_ratio_avg: %u\n",
|
||||
dpr_on_threshold, dpr_off_threshold, txpwr_avg, tx_ratio_avg);
|
||||
|
||||
if (tx_ratio_avg >= RTW89_TAS_TX_RATIO_THRESHOLD)
|
||||
state = RTW89_TAS_STATE_STATIC_SAR;
|
||||
else if (txpwr_avg >= dpr_on_threshold)
|
||||
state = RTW89_TAS_STATE_DPR_ON;
|
||||
else if (txpwr_avg < dpr_off_threshold)
|
||||
state = RTW89_TAS_STATE_DPR_OFF;
|
||||
else
|
||||
return;
|
||||
|
||||
rtw89_tas_state_update(rtwdev, state);
|
||||
}
|
||||
|
||||
void rtw89_tas_init(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
struct rtw89_acpi_dsm_result res = {};
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
if (!chip->support_tas)
|
||||
return;
|
||||
|
||||
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_TAS_EN, &res);
|
||||
if (ret) {
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SAR,
|
||||
@@ -396,65 +554,116 @@ void rtw89_tas_init(struct rtw89_dev *rtwdev)
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SAR, "TAS not enable\n");
|
||||
return;
|
||||
}
|
||||
|
||||
tas->dpr_gap = RTW89_TAS_DPR_GAP;
|
||||
tas->delta = RTW89_TAS_DELTA;
|
||||
}
|
||||
|
||||
void rtw89_tas_reset(struct rtw89_dev *rtwdev)
|
||||
void rtw89_tas_reset(struct rtw89_dev *rtwdev, bool force)
|
||||
{
|
||||
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
u64 linear;
|
||||
s32 cfg;
|
||||
int i;
|
||||
|
||||
if (!tas->enable)
|
||||
if (!rtw89_tas_is_active(rtwdev))
|
||||
return;
|
||||
|
||||
memset(&tas->txpwr_history, 0, sizeof(tas->txpwr_history));
|
||||
tas->total_txpwr = 0;
|
||||
tas->cur_idx = 0;
|
||||
tas->state = RTW89_TAS_STATE_DPR_OFF;
|
||||
}
|
||||
if (!rtw89_tas_query_sar_config(rtwdev, &cfg))
|
||||
return;
|
||||
|
||||
static const struct rtw89_reg_def txpwr_regs[] = {
|
||||
{R_PATH0_TXPWR, B_PATH0_TXPWR},
|
||||
{R_PATH1_TXPWR, B_PATH1_TXPWR},
|
||||
};
|
||||
tas->dpr_on_threshold = cfg - RTW89_TAS_SAR_GAP;
|
||||
tas->dpr_off_threshold = cfg - RTW89_TAS_SAR_GAP - RTW89_TAS_DPR_GAP;
|
||||
|
||||
/* avoid history reset after new SAR apply */
|
||||
if (!force && tas->keep_history)
|
||||
return;
|
||||
|
||||
linear = rtw89_db_quarter_to_linear(cfg) * RTW89_TAS_DFLT_TX_RATIO;
|
||||
for (i = 0; i < RTW89_TAS_TXPWR_WINDOW; i++)
|
||||
tas->txpwr_history[i] = linear;
|
||||
|
||||
for (i = 0; i < RTW89_TAS_TX_RATIO_WINDOW; i++)
|
||||
tas->tx_ratio_history[i] = RTW89_TAS_DFLT_TX_RATIO;
|
||||
|
||||
tas->total_tx_ratio = RTW89_TAS_DFLT_TX_RATIO * RTW89_TAS_TX_RATIO_WINDOW;
|
||||
tas->total_txpwr = linear * RTW89_TAS_TXPWR_WINDOW;
|
||||
tas->window_size = RTW89_TAS_TXPWR_WINDOW;
|
||||
tas->txpwr_head_idx = 0;
|
||||
tas->txpwr_tail_idx = RTW89_TAS_TXPWR_WINDOW - 1;
|
||||
tas->tx_ratio_idx = 0;
|
||||
tas->state = RTW89_TAS_STATE_DPR_OFF;
|
||||
tas->backup_state = RTW89_TAS_STATE_DPR_OFF;
|
||||
tas->keep_history = true;
|
||||
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SAR,
|
||||
"tas: band: %u, freq: %u\n", chan->band_type, chan->freq);
|
||||
}
|
||||
|
||||
void rtw89_tas_track(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, RTW89_PHY_0);
|
||||
struct rtw89_env_monitor_info *env = &bb->env_monitor;
|
||||
const enum rtw89_sar_sources src = rtwdev->sar.src;
|
||||
u8 max_nss_num = rtwdev->chip->rf_path_num;
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
s16 tmp, txpwr, instant_txpwr = 0;
|
||||
u32 val;
|
||||
int i;
|
||||
struct rtw89_hal *hal = &rtwdev->hal;
|
||||
s32 cfg;
|
||||
|
||||
if (!tas->enable || src == RTW89_SAR_SOURCE_NONE)
|
||||
if (hal->disabled_dm_bitmap & BIT(RTW89_DM_TAS))
|
||||
return;
|
||||
|
||||
if (env->ccx_watchdog_result != RTW89_PHY_ENV_MON_IFS_CLM)
|
||||
if (!rtw89_tas_is_active(rtwdev))
|
||||
return;
|
||||
|
||||
for (i = 0; i < max_nss_num; i++) {
|
||||
val = rtw89_phy_read32_mask(rtwdev, txpwr_regs[i].addr,
|
||||
txpwr_regs[i].mask);
|
||||
tmp = sign_extend32(val, 8);
|
||||
if (tmp <= 0)
|
||||
return;
|
||||
instant_txpwr += tmp;
|
||||
if (!rtw89_tas_query_sar_config(rtwdev, &cfg) || tas->block_regd) {
|
||||
rtw89_tas_state_update(rtwdev, RTW89_TAS_STATE_STATIC_SAR);
|
||||
return;
|
||||
}
|
||||
|
||||
instant_txpwr /= max_nss_num;
|
||||
/* in unit of 0.25 dBm multiply by percentage */
|
||||
txpwr = instant_txpwr * env->ifs_clm_tx_ratio;
|
||||
tas->total_txpwr += txpwr - tas->txpwr_history[tas->cur_idx];
|
||||
tas->txpwr_history[tas->cur_idx] = txpwr;
|
||||
rtw89_debug(rtwdev, RTW89_DBG_SAR,
|
||||
"instant_txpwr: %d, tx_ratio: %d, txpwr: %d\n",
|
||||
instant_txpwr, env->ifs_clm_tx_ratio, txpwr);
|
||||
if (tas->pause)
|
||||
return;
|
||||
|
||||
tas->cur_idx = (tas->cur_idx + 1) % RTW89_TAS_MAX_WINDOW;
|
||||
|
||||
rtw89_tas_state_update(rtwdev);
|
||||
rtw89_tas_window_update(rtwdev);
|
||||
rtw89_tas_history_update(rtwdev);
|
||||
rtw89_tas_rolling_average(rtwdev);
|
||||
}
|
||||
|
||||
void rtw89_tas_scan(struct rtw89_dev *rtwdev, bool start)
|
||||
{
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
s32 cfg;
|
||||
|
||||
if (!rtw89_tas_is_active(rtwdev))
|
||||
return;
|
||||
|
||||
if (!rtw89_tas_query_sar_config(rtwdev, &cfg))
|
||||
return;
|
||||
|
||||
if (start) {
|
||||
tas->backup_state = tas->state;
|
||||
rtw89_tas_state_update(rtwdev, RTW89_TAS_STATE_STATIC_SAR);
|
||||
} else {
|
||||
rtw89_tas_state_update(rtwdev, tas->backup_state);
|
||||
}
|
||||
}
|
||||
|
||||
void rtw89_tas_chanctx_cb(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_chanctx_state state)
|
||||
{
|
||||
struct rtw89_tas_info *tas = &rtwdev->tas;
|
||||
s32 cfg;
|
||||
|
||||
if (!rtw89_tas_is_active(rtwdev))
|
||||
return;
|
||||
|
||||
if (!rtw89_tas_query_sar_config(rtwdev, &cfg))
|
||||
return;
|
||||
|
||||
switch (state) {
|
||||
case RTW89_CHANCTX_STATE_MCC_START:
|
||||
tas->pause = true;
|
||||
rtw89_tas_state_update(rtwdev, RTW89_TAS_STATE_STATIC_SAR);
|
||||
break;
|
||||
case RTW89_CHANCTX_STATE_MCC_STOP:
|
||||
tas->pause = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(rtw89_tas_chanctx_cb);
|
||||
|
||||
@@ -25,7 +25,10 @@ int rtw89_print_tas(struct rtw89_dev *rtwdev, char *buf, size_t bufsz);
|
||||
int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw,
|
||||
const struct cfg80211_sar_specs *sar);
|
||||
void rtw89_tas_init(struct rtw89_dev *rtwdev);
|
||||
void rtw89_tas_reset(struct rtw89_dev *rtwdev);
|
||||
void rtw89_tas_reset(struct rtw89_dev *rtwdev, bool force);
|
||||
void rtw89_tas_track(struct rtw89_dev *rtwdev);
|
||||
void rtw89_tas_scan(struct rtw89_dev *rtwdev, bool start);
|
||||
void rtw89_tas_chanctx_cb(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_chanctx_state state);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,106 +4,151 @@
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define FRAC_ROWS 3
|
||||
#define FRAC_ROW_MAX (FRAC_ROWS - 1)
|
||||
#define NORM_ROW_MIN FRAC_ROWS
|
||||
#define RTW89_DBM_QUARTER_FACTOR 2
|
||||
#define RTW89_MIN_DBM (-41.25 * (1 << RTW89_DBM_QUARTER_FACTOR))
|
||||
#define RTW89_MAX_DBM (96 * (1 << RTW89_DBM_QUARTER_FACTOR))
|
||||
#define RTW89_DB_INVERT_TABLE_OFFSET (-RTW89_MIN_DBM)
|
||||
|
||||
static const u32 db_invert_table[12][8] = {
|
||||
/* rows 0~2 in unit of U(32,3) */
|
||||
{10, 13, 16, 20, 25, 32, 40, 50},
|
||||
{64, 80, 101, 128, 160, 201, 256, 318},
|
||||
{401, 505, 635, 800, 1007, 1268, 1596, 2010},
|
||||
/* rows 3~11 in unit of U(32,0) */
|
||||
{316, 398, 501, 631, 794, 1000, 1259, 1585},
|
||||
{1995, 2512, 3162, 3981, 5012, 6310, 7943, 10000},
|
||||
{12589, 15849, 19953, 25119, 31623, 39811, 50119, 63098},
|
||||
{79433, 100000, 125893, 158489, 199526, 251189, 316228, 398107},
|
||||
{501187, 630957, 794328, 1000000, 1258925, 1584893, 1995262, 2511886},
|
||||
{3162278, 3981072, 5011872, 6309573, 7943282, 1000000, 12589254,
|
||||
15848932},
|
||||
{19952623, 25118864, 31622777, 39810717, 50118723, 63095734, 79432823,
|
||||
100000000},
|
||||
{125892541, 158489319, 199526232, 251188643, 316227766, 398107171,
|
||||
501187234, 630957345},
|
||||
{794328235, 1000000000, 1258925412, 1584893192, 1995262315, 2511886432U,
|
||||
3162277660U, 3981071706U},
|
||||
static const u64 db_invert_table[] = {
|
||||
/* in unit of 0.000001 */
|
||||
75, 79, 84, 89, 94, 100, 106, 112, 119, 126, 133, 141, 150, 158, 168, 178, 188,
|
||||
200, 211, 224, 237, 251, 266, 282, 299, 316, 335, 355, 376, 398, 422, 447, 473,
|
||||
501, 531, 562, 596, 631, 668, 708, 750, 794, 841, 891, 944, 1000, 1059, 1122, 1189,
|
||||
1259, 1334, 1413, 1496, 1585, 1679, 1778, 1884, 1995, 2113, 2239, 2371, 2512, 2661,
|
||||
2818, 2985, 3162, 3350, 3548, 3758, 3981, 4217, 4467, 4732, 5012, 5309, 5623, 5957,
|
||||
6310, 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, 10593, 11220, 11885, 12589,
|
||||
13335, 14125, 14962, 15849, 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
|
||||
26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, 42170, 44668, 47315, 50119,
|
||||
53088, 56234, 59566, 63096, 66834, 70795, 74989, 79433, 84140, 89125, 94406, 100000,
|
||||
105925, 112202, 118850, 125893, 133352, 141254, 149624, 158489, 167880, 177828,
|
||||
188365, 199526, 211349, 223872, 237137, 251189, 266073, 281838, 298538, 316228,
|
||||
334965, 354813, 375837, 398107, 421697, 446684, 473151, 501187, 530884, 562341,
|
||||
595662, 630957, 668344, 707946, 749894, 794328, 841395, 891251, 944061, 1000000,
|
||||
1059254, 1122018, 1188502, 1258925, 1333521, 1412538, 1496236, 1584893, 1678804,
|
||||
1778279, 1883649, 1995262, 2113489, 2238721, 2371374, 2511886, 2660725, 2818383,
|
||||
2985383, 3162278, 3349654, 3548134, 3758374, 3981072, 4216965, 4466836, 4731513,
|
||||
5011872, 5308844, 5623413, 5956621, 6309573, 6683439, 7079458, 7498942, 7943282,
|
||||
8413951, 8912509, 9440609, 10000000, 10592537, 11220185, 11885022, 12589254,
|
||||
13335214, 14125375, 14962357, 15848932, 16788040, 17782794, 18836491, 19952623,
|
||||
21134890, 22387211, 23713737, 25118864, 26607251, 28183829, 29853826, 31622777,
|
||||
33496544, 35481339, 37583740, 39810717, 42169650, 44668359, 47315126, 50118723,
|
||||
53088444, 56234133, 59566214, 63095734, 66834392, 70794578, 74989421, 79432823,
|
||||
84139514, 89125094, 94406088, 100000000, 105925373, 112201845, 118850223, 125892541,
|
||||
133352143, 141253754, 149623566, 158489319, 167880402, 177827941, 188364909, 199526231,
|
||||
211348904, 223872114, 237137371, 251188643, 266072506, 281838293, 298538262, 316227766,
|
||||
334965439, 354813389, 375837404, 398107171, 421696503, 446683592, 473151259, 501187234,
|
||||
530884444, 562341325, 595662144, 630957344, 668343918, 707945784, 749894209, 794328235,
|
||||
841395142, 891250938, 944060876, 1000000000, 1059253725, 1122018454, 1188502227,
|
||||
1258925412, 1333521432, 1412537545, 1496235656, 1584893192, 1678804018, 1778279410,
|
||||
1883649089, 1995262315, 2113489040, 2238721139, 2371373706, 2511886432, 2660725060,
|
||||
2818382931, 2985382619, 3162277660, 3349654392, 3548133892, 3758374043, 3981071706,
|
||||
4216965034, 4466835922ULL, 4731512590ULL, 5011872336ULL, 5308844442ULL, 5623413252ULL,
|
||||
5956621435ULL, 6309573445ULL, 6683439176ULL, 7079457844ULL, 7498942093ULL,
|
||||
7943282347ULL, 8413951416ULL, 8912509381ULL, 9440608763ULL, 10000000000ULL,
|
||||
10592537252ULL, 11220184543ULL, 11885022274ULL, 12589254118ULL, 13335214322ULL,
|
||||
14125375446ULL, 14962356561ULL, 15848931925ULL, 16788040181ULL, 17782794100ULL,
|
||||
18836490895ULL, 19952623150ULL, 21134890398ULL, 22387211386ULL, 23713737057ULL,
|
||||
25118864315ULL, 26607250598ULL, 28183829313ULL, 29853826189ULL, 31622776602ULL,
|
||||
33496543916ULL, 35481338923ULL, 37583740429ULL, 39810717055ULL, 42169650343ULL,
|
||||
44668359215ULL, 47315125896ULL, 50118723363ULL, 53088444423ULL, 56234132519ULL,
|
||||
59566214353ULL, 63095734448ULL, 66834391757ULL, 70794578438ULL, 74989420933ULL,
|
||||
79432823472ULL, 84139514165ULL, 89125093813ULL, 94406087629ULL, 100000000000ULL,
|
||||
105925372518ULL, 112201845430ULL, 118850222744ULL, 125892541179ULL, 133352143216ULL,
|
||||
141253754462ULL, 149623565609ULL, 158489319246ULL, 167880401812ULL, 177827941004ULL,
|
||||
188364908949ULL, 199526231497ULL, 211348903984ULL, 223872113857ULL, 237137370566ULL,
|
||||
251188643151ULL, 266072505980ULL, 281838293126ULL, 298538261892ULL, 316227766017ULL,
|
||||
334965439158ULL, 354813389234ULL, 375837404288ULL, 398107170553ULL, 421696503429ULL,
|
||||
446683592151ULL, 473151258961ULL, 501187233627ULL, 530884444231ULL, 562341325190ULL,
|
||||
595662143529ULL, 630957344480ULL, 668343917569ULL, 707945784384ULL, 749894209332ULL,
|
||||
794328234724ULL, 841395141645ULL, 891250938134ULL, 944060876286ULL, 1000000000000ULL,
|
||||
1059253725177ULL, 1122018454302ULL, 1188502227437ULL, 1258925411794ULL,
|
||||
1333521432163ULL, 1412537544623ULL, 1496235656094ULL, 1584893192461ULL,
|
||||
1678804018123ULL, 1778279410039ULL, 1883649089490ULL, 1995262314969ULL,
|
||||
2113489039837ULL, 2238721138568ULL, 2371373705662ULL, 2511886431510ULL,
|
||||
2660725059799ULL, 2818382931264ULL, 2985382618918ULL, 3162277660168ULL,
|
||||
3349654391578ULL, 3548133892336ULL, 3758374042884ULL, 3981071705535ULL,
|
||||
4216965034286ULL, 4466835921510ULL, 4731512589615ULL, 5011872336273ULL,
|
||||
5308844442310ULL, 5623413251904ULL, 5956621435290ULL, 6309573444802ULL,
|
||||
6683439175686ULL, 7079457843841ULL, 7498942093325ULL, 7943282347243ULL,
|
||||
8413951416452ULL, 8912509381337ULL, 9440608762859ULL, 10000000000000ULL,
|
||||
10592537251773ULL, 11220184543020ULL, 11885022274370ULL, 12589254117942ULL,
|
||||
13335214321633ULL, 14125375446228ULL, 14962356560944ULL, 15848931924611ULL,
|
||||
16788040181226ULL, 17782794100389ULL, 18836490894898ULL, 19952623149689ULL,
|
||||
21134890398367ULL, 22387211385683ULL, 23713737056617ULL, 25118864315096ULL,
|
||||
26607250597988ULL, 28183829312645ULL, 29853826189180ULL, 31622776601684ULL,
|
||||
33496543915783ULL, 35481338923358ULL, 37583740428845ULL, 39810717055350ULL,
|
||||
42169650342858ULL, 44668359215096ULL, 47315125896148ULL, 50118723362727ULL,
|
||||
53088444423099ULL, 56234132519035ULL, 59566214352901ULL, 63095734448019ULL,
|
||||
66834391756862ULL, 70794578438414ULL, 74989420933246ULL, 79432823472428ULL,
|
||||
84139514164520ULL, 89125093813375ULL, 94406087628593ULL, 100000000000000ULL,
|
||||
105925372517729ULL, 112201845430197ULL, 118850222743702ULL, 125892541179417ULL,
|
||||
133352143216332ULL, 141253754462276ULL, 149623565609444ULL, 158489319246111ULL,
|
||||
167880401812256ULL, 177827941003893ULL, 188364908948981ULL, 199526231496888ULL,
|
||||
211348903983664ULL, 223872113856834ULL, 237137370566166ULL, 251188643150958ULL,
|
||||
266072505979882ULL, 281838293126446ULL, 298538261891796ULL, 316227766016838ULL,
|
||||
334965439157829ULL, 354813389233577ULL, 375837404288444ULL, 398107170553497ULL,
|
||||
421696503428583ULL, 446683592150964ULL, 473151258961482ULL, 501187233627272ULL,
|
||||
530884444230989ULL, 562341325190350ULL, 595662143529011ULL, 630957344480196ULL,
|
||||
668343917568615ULL, 707945784384138ULL, 749894209332456ULL, 794328234724284ULL,
|
||||
841395141645198ULL, 891250938133745ULL, 944060876285923ULL, 1000000000000000ULL,
|
||||
1059253725177290ULL, 1122018454301970ULL, 1188502227437020ULL, 1258925411794170ULL,
|
||||
1333521432163330ULL, 1412537544622760ULL, 1496235656094440ULL, 1584893192461110ULL,
|
||||
1678804018122560ULL, 1778279410038920ULL, 1883649089489810ULL, 1995262314968890ULL,
|
||||
2113489039836650ULL, 2238721138568340ULL, 2371373705661660ULL, 2511886431509590ULL,
|
||||
2660725059798820ULL, 2818382931264460ULL, 2985382618917960ULL, 3162277660168380ULL,
|
||||
3349654391578280ULL, 3548133892335770ULL, 3758374042884440ULL, 3981071705534970ULL
|
||||
};
|
||||
|
||||
u32 rtw89_linear_2_db(u64 val)
|
||||
s32 rtw89_linear_to_db_quarter(u64 val)
|
||||
{
|
||||
u8 i, j;
|
||||
u32 dB;
|
||||
int r = ARRAY_SIZE(db_invert_table) - 1;
|
||||
int l = 0;
|
||||
int m;
|
||||
|
||||
for (i = 0; i < 12; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (i <= FRAC_ROW_MAX &&
|
||||
(val << RTW89_LINEAR_FRAC_BITS) <= db_invert_table[i][j])
|
||||
goto cnt;
|
||||
else if (i > FRAC_ROW_MAX && val <= db_invert_table[i][j])
|
||||
goto cnt;
|
||||
}
|
||||
while (l <= r) {
|
||||
m = l + (r - l) / 2;
|
||||
|
||||
if (db_invert_table[m] == val)
|
||||
return m - (s32)RTW89_DB_INVERT_TABLE_OFFSET;
|
||||
|
||||
if (db_invert_table[m] > val)
|
||||
r = m - 1;
|
||||
else
|
||||
l = m + 1;
|
||||
}
|
||||
|
||||
return 96; /* maximum 96 dB */
|
||||
|
||||
cnt:
|
||||
/* special cases */
|
||||
if (j == 0 && i == 0)
|
||||
goto end;
|
||||
|
||||
if (i == NORM_ROW_MIN && j == 0) {
|
||||
if (db_invert_table[NORM_ROW_MIN][0] - val >
|
||||
val - (db_invert_table[FRAC_ROW_MAX][7] >> RTW89_LINEAR_FRAC_BITS)) {
|
||||
i = FRAC_ROW_MAX;
|
||||
j = 7;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (i <= FRAC_ROW_MAX)
|
||||
val <<= RTW89_LINEAR_FRAC_BITS;
|
||||
|
||||
/* compare difference to get precise dB */
|
||||
if (j == 0) {
|
||||
if (db_invert_table[i][j] - val >
|
||||
val - db_invert_table[i - 1][7]) {
|
||||
i--;
|
||||
j = 7;
|
||||
}
|
||||
} else {
|
||||
if (db_invert_table[i][j] - val >
|
||||
val - db_invert_table[i][j - 1]) {
|
||||
j--;
|
||||
}
|
||||
}
|
||||
end:
|
||||
dB = (i << 3) + j + 1;
|
||||
|
||||
return dB;
|
||||
if (l >= ARRAY_SIZE(db_invert_table))
|
||||
return RTW89_MAX_DBM;
|
||||
else if (r < 0)
|
||||
return RTW89_MIN_DBM;
|
||||
else if (val - db_invert_table[r] <= db_invert_table[l] - val)
|
||||
return r - (s32)RTW89_DB_INVERT_TABLE_OFFSET;
|
||||
else
|
||||
return l - (s32)RTW89_DB_INVERT_TABLE_OFFSET;
|
||||
}
|
||||
EXPORT_SYMBOL(rtw89_linear_2_db);
|
||||
EXPORT_SYMBOL(rtw89_linear_to_db_quarter);
|
||||
|
||||
u64 rtw89_db_2_linear(u32 db)
|
||||
s32 rtw89_linear_to_db(u64 val)
|
||||
{
|
||||
u64 linear;
|
||||
u8 i, j;
|
||||
|
||||
if (db > 96)
|
||||
db = 96;
|
||||
else if (db < 1)
|
||||
return 1;
|
||||
|
||||
i = (db - 1) >> 3;
|
||||
j = (db - 1) & 0x7;
|
||||
|
||||
linear = db_invert_table[i][j];
|
||||
|
||||
if (i >= NORM_ROW_MIN)
|
||||
linear = linear << RTW89_LINEAR_FRAC_BITS;
|
||||
|
||||
return linear;
|
||||
return rtw89_linear_to_db_quarter(val) >> RTW89_DBM_QUARTER_FACTOR;
|
||||
}
|
||||
EXPORT_SYMBOL(rtw89_db_2_linear);
|
||||
EXPORT_SYMBOL(rtw89_linear_to_db);
|
||||
|
||||
u64 rtw89_db_quarter_to_linear(s32 db)
|
||||
{
|
||||
/* supported range -41.25 to 96 dBm, in unit of 0.25 dBm */
|
||||
db = clamp_t(s32, db, RTW89_MIN_DBM, RTW89_MAX_DBM);
|
||||
db += (s32)RTW89_DB_INVERT_TABLE_OFFSET;
|
||||
|
||||
return db_invert_table[db];
|
||||
}
|
||||
EXPORT_SYMBOL(rtw89_db_quarter_to_linear);
|
||||
|
||||
u64 rtw89_db_to_linear(s32 db)
|
||||
{
|
||||
return rtw89_db_quarter_to_linear(db << RTW89_DBM_QUARTER_FACTOR);
|
||||
}
|
||||
EXPORT_SYMBOL(rtw89_db_to_linear);
|
||||
|
||||
void rtw89_might_trailing_ellipsis(char *buf, size_t size, ssize_t used)
|
||||
{
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#define RTW89_LINEAR_FRAC_BITS 3
|
||||
|
||||
#define rtw89_iterate_vifs_bh(rtwdev, iterator, data) \
|
||||
ieee80211_iterate_active_interfaces_atomic((rtwdev)->hw, \
|
||||
IEEE80211_IFACE_ITER_NORMAL, iterator, data)
|
||||
@@ -75,8 +73,10 @@ static inline void ether_addr_copy_mask(u8 *dst, const u8 *src, u8 mask)
|
||||
}
|
||||
}
|
||||
|
||||
u32 rtw89_linear_2_db(u64 linear);
|
||||
u64 rtw89_db_2_linear(u32 db);
|
||||
s32 rtw89_linear_to_db_quarter(u64 val);
|
||||
s32 rtw89_linear_to_db(u64 val);
|
||||
u64 rtw89_db_quarter_to_linear(s32 db);
|
||||
u64 rtw89_db_to_linear(s32 db);
|
||||
void rtw89_might_trailing_ellipsis(char *buf, size_t size, ssize_t used);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user