rtw-next patches for v6.13

Major changes are listed:
 
 rtw88:
  - support two USB adapters 8821au and 8812au
 
 rtw89:
  - add thermal protection
  - fine tune BT-coexsitence to improve user experience
  - firmware secure boot for WiFi 6 chip
  - more materials for MLO
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEuyEnvMdOsBl1WjpdjlvZYmhshd8FAmcrHQ8ACgkQjlvZYmhs
 hd8Gvg/8C847J/bMveQNlqNw16WboNdIkvDd0hfELyicwekz1vumODW/JSeeJ8Ap
 F4i88UL4yTp6QYjDtI6R3Ox5i2FBmQ5lGPNMbyjYGfaKG2YXhR4U29Ge0Awcq2vP
 AmbXfcWuOTVrW3gQQFvzLpV9dWoy/NyTXAQsGwbEF0RzJ7ILzyacoYYTkr6+quxt
 AH+TC7dJCfHYGceZNL2llOorRWAgrV66jb2v527f2RIaaq90a8MFcpCnfpNQGmPP
 nbBvOzSERDfZEeBzOkwwolXbPyCvUuQs4WNgqDf/jUD1k5cs/qqyBDeHfsV6CK2q
 4FV1vHgE00c8Gaz7NXhnlKx3ixPDM4cQzUM/PKtrZ9ag8AZTXja7i176v4nIs/JI
 Cj77kBm9CPHVbJCk434RvezdVDtTJhEdG7v7FkqPu/kW5KaMus8moGGdKcCTHNUs
 UqjlM8PG7n/SPPGfutSdz5tTLbgkGkWczIe22L5OTGDDiv/+9hWnHdHiW8RROJJ8
 9eZKJyle4Susa8eOLk6888wMTAKo+4ZO6ijyST83ZIo72WLJmfjNrc0+NnxMrWZR
 1YOB6SUdnFJL6qHTvK1cQPrrmpAlz/MLCFS/vfSa78p8yy56OtRUTf/S0qv77H1a
 LlKouLy+L2LAq+Z7cL7tvV5mLTjTZsy+zyhEvDpQgAAR4TEJjYg=
 =7ogU
 -----END PGP SIGNATURE-----

Merge tag 'rtw-next-2024-11-06' of https://github.com/pkshih/rtw

rtw-next patches for v6.13

Major changes are listed:

rtw88:
 - support two USB adapters 8821au and 8812au

rtw89:
 - add thermal protection
 - fine tune BT-coexsitence to improve user experience
 - firmware secure boot for WiFi 6 chip
 - more materials for MLO
This commit is contained in:
Kalle Valo 2024-11-11 13:07:21 +02:00
commit 5255ee958f
84 changed files with 11392 additions and 502 deletions

View File

@ -3409,17 +3409,6 @@ void ex_btc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
}
}
void ex_btc8723b1ant_coex_dm_reset(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], *****************Coex DM Reset****************\n");
halbtc8723b1ant_init_hw_config(btcoexist, false, false);
halbtc8723b1ant_init_coex_dm(btcoexist);
}
void ex_btc8723b1ant_periodical(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;

View File

@ -197,7 +197,6 @@ void ex_btc8723b1ant_rf_status_notify(struct btc_coexist *btcoexist,
u8 type);
void ex_btc8723b1ant_halt_notify(struct btc_coexist *btcoexist);
void ex_btc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnpstate);
void ex_btc8723b1ant_coex_dm_reset(struct btc_coexist *btcoexist);
void ex_btc8723b1ant_periodical(struct btc_coexist *btcoexist);
void ex_btc8723b1ant_display_coex_info(struct btc_coexist *btcoexist,
struct seq_file *m);

View File

@ -1708,19 +1708,6 @@ void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist,
halbtc_normal_low_power(btcoexist);
}
void exhalbtc_rf_status_notify(struct btc_coexist *btcoexist, u8 type)
{
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
if (btcoexist->board_info.btdm_ant_num == 1)
ex_btc8723b1ant_rf_status_notify(btcoexist, type);
} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
}
}
void exhalbtc_halt_notify(struct btc_coexist *btcoexist)
{
if (!halbtc_is_bt_coexist_available(btcoexist))
@ -1768,31 +1755,6 @@ void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
}
}
void exhalbtc_coex_dm_switch(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->statistics.cnt_coex_dm_switch++;
halbtc_leave_low_power(btcoexist);
if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
if (btcoexist->board_info.btdm_ant_num == 1) {
btcoexist->stop_coex_dm = true;
ex_btc8723b1ant_coex_dm_reset(btcoexist);
exhalbtc_set_ant_num(rtlpriv,
BT_COEX_ANT_TYPE_DETECTED, 2);
ex_btc8723b2ant_init_hwconfig(btcoexist);
ex_btc8723b2ant_init_coex_dm(btcoexist);
btcoexist->stop_coex_dm = false;
}
}
halbtc_normal_low_power(btcoexist);
}
void exhalbtc_periodical(struct btc_coexist *btcoexist)
{
if (!halbtc_is_bt_coexist_available(btcoexist))
@ -1820,29 +1782,6 @@ void exhalbtc_periodical(struct btc_coexist *btcoexist)
halbtc_normal_low_power(btcoexist);
}
void exhalbtc_dbg_control(struct btc_coexist *btcoexist,
u8 code, u8 len, u8 *data)
{
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->statistics.cnt_dbg_ctrl++;
halbtc_leave_low_power(btcoexist);
halbtc_normal_low_power(btcoexist);
}
void exhalbtc_antenna_detection(struct btc_coexist *btcoexist, u32 cent_freq,
u32 offset, u32 span, u32 seconds)
{
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
}
void exhalbtc_stack_update_profile_info(void)
{
}
void exhalbtc_update_min_bt_rssi(struct btc_coexist *btcoexist, s8 bt_rssi)
{
if (!halbtc_is_bt_coexist_available(btcoexist))
@ -1851,24 +1790,6 @@ void exhalbtc_update_min_bt_rssi(struct btc_coexist *btcoexist, s8 bt_rssi)
btcoexist->stack_info.min_bt_rssi = bt_rssi;
}
void exhalbtc_set_hci_version(struct btc_coexist *btcoexist, u16 hci_version)
{
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->stack_info.hci_version = hci_version;
}
void exhalbtc_set_bt_patch_version(struct btc_coexist *btcoexist,
u16 bt_hci_version, u16 bt_patch_version)
{
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
btcoexist->bt_info.bt_real_fw_ver = bt_patch_version;
btcoexist->bt_info.bt_hci_ver = bt_hci_version;
}
void exhalbtc_set_chip_type(struct btc_coexist *btcoexist, u8 chip_type)
{
switch (chip_type) {

View File

@ -763,19 +763,9 @@ void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist,
void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type);
void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf,
u8 length);
void exhalbtc_rf_status_notify(struct btc_coexist *btcoexist, u8 type);
void exhalbtc_halt_notify(struct btc_coexist *btcoexist);
void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state);
void exhalbtc_coex_dm_switch(struct btc_coexist *btcoexist);
void exhalbtc_periodical(struct btc_coexist *btcoexist);
void exhalbtc_dbg_control(struct btc_coexist *btcoexist, u8 code, u8 len,
u8 *data);
void exhalbtc_antenna_detection(struct btc_coexist *btcoexist, u32 cent_freq,
u32 offset, u32 span, u32 seconds);
void exhalbtc_stack_update_profile_info(void);
void exhalbtc_set_hci_version(struct btc_coexist *btcoexist, u16 hci_version);
void exhalbtc_set_bt_patch_version(struct btc_coexist *btcoexist,
u16 bt_hci_version, u16 bt_patch_version);
void exhalbtc_update_min_bt_rssi(struct btc_coexist *btcoexist, s8 bt_rssi);
void exhalbtc_set_bt_exist(struct btc_coexist *btcoexist, bool bt_exist);
void exhalbtc_set_chip_type(struct btc_coexist *btcoexist, u8 chip_type);

View File

@ -162,10 +162,19 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u16 max_attempts = 10000;
u32 value32;
u8 readbyte;
u16 retry;
/*
* In case of USB devices, transfer speeds are limited, hence
* efuse I/O reads could be (way) slower. So, decrease (a lot)
* the read attempts in case of failures.
*/
if (rtlpriv->rtlhal.interface == INTF_USB)
max_attempts = 10;
rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
(_offset & 0xff));
readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
@ -178,7 +187,7 @@ void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
retry = 0;
value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < max_attempts)) {
value32 = rtl_read_dword(rtlpriv,
rtlpriv->cfg->maps[EFUSE_CTRL]);
retry++;

View File

@ -350,7 +350,8 @@ MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless");
MODULE_FIRMWARE("rtlwifi/rtl8723efw.bin");
MODULE_FIRMWARE("rtlwifi/rtl8723fw.bin");
MODULE_FIRMWARE("rtlwifi/rtl8723fw_B.bin");
module_param_named(swenc, rtl8723e_mod_params.sw_crypto, bool, 0444);
module_param_named(debug_level, rtl8723e_mod_params.debug_level, int, 0644);

View File

@ -407,6 +407,9 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8821ae 802.11ac PCI wireless");
MODULE_FIRMWARE("rtlwifi/rtl8821aefw.bin");
MODULE_FIRMWARE("rtlwifi/rtl8821aefw_29.bin");
MODULE_FIRMWARE("rtlwifi/rtl8821aefw_wowlan.bin");
MODULE_FIRMWARE("rtlwifi/rtl8812aefw.bin");
MODULE_FIRMWARE("rtlwifi/rtl8812aefw_wowlan.bin");
module_param_named(swenc, rtl8821ae_mod_params.sw_crypto, bool, 0444);
module_param_named(debug_level, rtl8821ae_mod_params.debug_level, int, 0644);

View File

@ -43,6 +43,17 @@ config RTW88_8723D
config RTW88_8821C
tristate
config RTW88_88XXA
tristate
config RTW88_8821A
tristate
select RTW88_88XXA
config RTW88_8812A
tristate
select RTW88_88XXA
config RTW88_8822BE
tristate "Realtek 8822BE PCI wireless network adapter"
depends on PCI
@ -189,6 +200,28 @@ config RTW88_8821CU
802.11ac USB wireless network adapter
config RTW88_8821AU
tristate "Realtek 8821AU/8811AU USB wireless network adapter"
depends on USB
select RTW88_CORE
select RTW88_USB
select RTW88_8821A
help
Select this option will enable support for 8821AU and 8811AU chipset
802.11ac USB wireless network adapter
config RTW88_8812AU
tristate "Realtek 8812AU USB wireless network adapter"
depends on USB
select RTW88_CORE
select RTW88_USB
select RTW88_8812A
help
Select this option will enable support for 8812AU chipset
802.11ac USB wireless network adapter
config RTW88_DEBUG
bool "Realtek rtw88 debug support"
depends on RTW88_CORE

View File

@ -77,6 +77,21 @@ rtw88_8821cs-objs := rtw8821cs.o
obj-$(CONFIG_RTW88_8821CU) += rtw88_8821cu.o
rtw88_8821cu-objs := rtw8821cu.o
obj-$(CONFIG_RTW88_88XXA) += rtw88_88xxa.o
rtw88_88xxa-objs := rtw88xxa.o
obj-$(CONFIG_RTW88_8821A) += rtw88_8821a.o
rtw88_8821a-objs := rtw8821a.o rtw8821a_table.o
obj-$(CONFIG_RTW88_8812A) += rtw88_8812a.o
rtw88_8812a-objs := rtw8812a.o rtw8812a_table.o
obj-$(CONFIG_RTW88_8821AU) += rtw88_8821au.o
rtw88_8821au-objs := rtw8821au.o
obj-$(CONFIG_RTW88_8812AU) += rtw88_8812au.o
rtw88_8812au-objs := rtw8812au.o
obj-$(CONFIG_RTW88_PCI) += rtw88_pci.o
rtw88_pci-objs := pci.o

View File

@ -446,7 +446,7 @@ static void rtw_coex_check_rfk(struct rtw_dev *rtwdev)
}
}
static void rtw_coex_query_bt_info(struct rtw_dev *rtwdev)
void rtw_coex_query_bt_info(struct rtw_dev *rtwdev)
{
struct rtw_coex *coex = &rtwdev->coex;
struct rtw_coex_stat *coex_stat = &coex->stat;
@ -494,11 +494,29 @@ static void rtw_coex_monitor_bt_enable(struct rtw_dev *rtwdev)
struct rtw_coex_stat *coex_stat = &coex->stat;
struct rtw_coex_dm *coex_dm = &coex->dm;
bool bt_disabled = false;
bool bt_active = true;
u16 score_board;
if (chip->scbd_support) {
score_board = rtw_coex_read_scbd(rtwdev);
bt_disabled = !(score_board & COEX_SCBD_ONOFF);
} else {
if (coex_stat->hi_pri_tx == 0 && coex_stat->hi_pri_rx == 0 &&
coex_stat->lo_pri_tx == 0 && coex_stat->lo_pri_rx == 0)
bt_active = false;
if (coex_stat->hi_pri_tx == 0xffff && coex_stat->hi_pri_rx == 0xffff &&
coex_stat->lo_pri_tx == 0xffff && coex_stat->lo_pri_rx == 0xffff)
bt_active = false;
if (bt_active) {
coex_stat->bt_disable_cnt = 0;
bt_disabled = false;
} else {
coex_stat->bt_disable_cnt++;
if (coex_stat->bt_disable_cnt >= 10)
bt_disabled = true;
}
}
if (coex_stat->bt_disabled != bt_disabled) {
@ -950,12 +968,18 @@ static void rtw_coex_coex_ctrl_owner(struct rtw_dev *rtwdev, bool wifi_control)
static void rtw_coex_set_gnt_bt(struct rtw_dev *rtwdev, u8 state)
{
if (!rtwdev->chip->ltecoex_addr)
return;
rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0xc000, state);
rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0c00, state);
}
static void rtw_coex_set_gnt_wl(struct rtw_dev *rtwdev, u8 state)
{
if (!rtwdev->chip->ltecoex_addr)
return;
rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x3000, state);
rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0300, state);
}
@ -2747,16 +2771,19 @@ void rtw_coex_power_on_setting(struct rtw_dev *rtwdev)
rtw_write8(rtwdev, 0xff1a, 0x0);
rtw_coex_set_gnt_debug(rtwdev);
}
EXPORT_SYMBOL(rtw_coex_power_on_setting);
void rtw_coex_power_off_setting(struct rtw_dev *rtwdev)
{
rtw_write16(rtwdev, REG_WIFI_BT_INFO, BIT_BT_INT_EN);
}
EXPORT_SYMBOL(rtw_coex_power_off_setting);
void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only)
{
__rtw_coex_init_hw_config(rtwdev, wifi_only);
}
EXPORT_SYMBOL(rtw_coex_init_hw_config);
void rtw_coex_ips_notify(struct rtw_dev *rtwdev, u8 type)
{
@ -3904,7 +3931,7 @@ void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m)
u8 sys_lte;
u16 score_board_WB, score_board_BW;
u32 wl_reg_6c0, wl_reg_6c4, wl_reg_6c8, wl_reg_778, wl_reg_6cc;
u32 lte_coex, bt_coex;
u32 lte_coex = 0, bt_coex = 0;
int i;
score_board_BW = rtw_coex_read_scbd(rtwdev);
@ -3916,8 +3943,10 @@ void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m)
wl_reg_778 = rtw_read8(rtwdev, REG_BT_STAT_CTRL);
sys_lte = rtw_read8(rtwdev, 0x73);
lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38);
bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54);
if (rtwdev->chip->ltecoex_addr) {
lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38);
bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54);
}
if (!coex_stat->wl_under_ips &&
(!coex_stat->wl_under_lps || coex_stat->wl_force_lps_ctrl) &&

View File

@ -384,6 +384,7 @@ u32 rtw_coex_read_indirect_reg(struct rtw_dev *rtwdev, u16 addr);
void rtw_coex_write_indirect_reg(struct rtw_dev *rtwdev, u16 addr,
u32 mask, u32 val);
void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set);
void rtw_coex_query_bt_info(struct rtw_dev *rtwdev);
void rtw_coex_bt_relink_work(struct work_struct *work);
void rtw_coex_bt_reenable_work(struct work_struct *work);
@ -419,4 +420,14 @@ static inline bool rtw_coex_disabled(struct rtw_dev *rtwdev)
return coex_stat->bt_disabled;
}
static inline void rtw_coex_active_query_bt_info(struct rtw_dev *rtwdev)
{
/* The RTL8821AU firmware doesn't send C2H_BT_INFO by itself
* when bluetooth headphones are disconnected, so we have to
* ask for it regularly.
*/
if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A && rtwdev->efuse.btcoex)
rtw_coex_query_bt_info(rtwdev);
}
#endif

View File

@ -308,7 +308,7 @@ static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v)
{
struct rtw_debugfs_priv *debugfs_priv = m->private;
struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
u8 page_size = rtwdev->chip->page_size;
u16 page_size = rtwdev->chip->page_size;
u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size;
u32 offset = debugfs_priv->rsvd_page.page_offset * page_size;
u8 *buf;

View File

@ -139,25 +139,30 @@ static u16 get_max_amsdu_len(u32 bit_rate)
struct rtw_fw_iter_ra_data {
struct rtw_dev *rtwdev;
u8 *payload;
u8 length;
};
static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw_fw_iter_ra_data *ra_data = data;
struct rtw_c2h_ra_rpt *ra_rpt = (struct rtw_c2h_ra_rpt *)ra_data->payload;
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
u8 mac_id, rate, sgi, bw;
u8 mcs, nss;
u32 bit_rate;
mac_id = GET_RA_REPORT_MACID(ra_data->payload);
mac_id = ra_rpt->mac_id;
if (si->mac_id != mac_id)
return;
si->ra_report.txrate.flags = 0;
rate = GET_RA_REPORT_RATE(ra_data->payload);
sgi = GET_RA_REPORT_SGI(ra_data->payload);
bw = GET_RA_REPORT_BW(ra_data->payload);
rate = u8_get_bits(ra_rpt->rate_sgi, RTW_C2H_RA_RPT_RATE);
sgi = u8_get_bits(ra_rpt->rate_sgi, RTW_C2H_RA_RPT_SGI);
if (ra_data->length >= offsetofend(typeof(*ra_rpt), bw))
bw = ra_rpt->bw;
else
bw = si->bw_mode;
if (rate < DESC_RATEMCS0) {
si->ra_report.txrate.legacy = rtw_desc_to_bitrate(rate);
@ -197,14 +202,18 @@ static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta)
static void rtw_fw_ra_report_handle(struct rtw_dev *rtwdev, u8 *payload,
u8 length)
{
struct rtw_c2h_ra_rpt *ra_rpt = (struct rtw_c2h_ra_rpt *)payload;
struct rtw_fw_iter_ra_data ra_data;
if (WARN(length < 7, "invalid ra report c2h length\n"))
if (WARN(length < rtwdev->chip->c2h_ra_report_size,
"invalid ra report c2h length %d\n", length))
return;
rtwdev->dm_info.tx_rate = GET_RA_REPORT_RATE(payload);
rtwdev->dm_info.tx_rate = u8_get_bits(ra_rpt->rate_sgi,
RTW_C2H_RA_RPT_RATE);
ra_data.rtwdev = rtwdev;
ra_data.payload = payload;
ra_data.length = length;
rtw_iterate_stas_atomic(rtwdev, rtw_fw_ra_report_iter, &ra_data);
}
@ -1281,16 +1290,16 @@ static void rtw_fill_rsvd_page_desc(struct rtw_dev *rtwdev, struct sk_buff *skb,
rtw_tx_rsvd_page_pkt_info_update(rtwdev, &pkt_info, skb, type);
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
rtw_tx_fill_tx_desc(&pkt_info, skb);
rtw_tx_fill_tx_desc(rtwdev, &pkt_info, skb);
}
static inline u8 rtw_len_to_page(unsigned int len, u8 page_size)
static inline u8 rtw_len_to_page(unsigned int len, u16 page_size)
{
return DIV_ROUND_UP(len, page_size);
}
static void rtw_rsvd_page_list_to_buf(struct rtw_dev *rtwdev, u8 page_size,
u8 page_margin, u32 page, u8 *buf,
static void rtw_rsvd_page_list_to_buf(struct rtw_dev *rtwdev, u16 page_size,
u16 page_margin, u32 page, u8 *buf,
struct rtw_rsvd_page *rsvd_pkt)
{
struct sk_buff *skb = rsvd_pkt->skb;
@ -1592,13 +1601,13 @@ static int __rtw_build_rsvd_page_from_vifs(struct rtw_dev *rtwdev)
static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev, u32 *size)
{
struct ieee80211_hw *hw = rtwdev->hw;
const struct rtw_chip_info *chip = rtwdev->chip;
struct sk_buff *iter;
struct ieee80211_hw *hw = rtwdev->hw;
struct rtw_rsvd_page *rsvd_pkt;
u32 page = 0;
struct sk_buff *iter;
u16 page_size, page_margin, tx_desc_sz;
u8 total_page = 0;
u8 page_size, page_margin, tx_desc_sz;
u32 page = 0;
u8 *buf;
int ret;
@ -2004,12 +2013,13 @@ static int _rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev, u8 num_probes,
{
const struct rtw_chip_info *chip = rtwdev->chip;
struct sk_buff *skb, *tmp;
u8 page_offset = 1, *buf, page_size = chip->page_size;
u16 pg_addr = rtwdev->fifo.rsvd_h2c_info_addr, loc;
u16 buf_offset = page_size * page_offset;
u8 tx_desc_sz = chip->tx_pkt_desc_sz;
u8 page_cnt, pages;
u16 page_size = chip->page_size;
u8 page_offset = 1, *buf;
u16 buf_offset = page_size * page_offset;
unsigned int pkt_len;
u8 page_cnt, pages;
int ret;
if (rtw_fw_feature_ext_check(&rtwdev->fw, FW_FEATURE_EXT_OLD_PAGE_NUM))

View File

@ -85,6 +85,19 @@ struct rtw_c2h_adaptivity {
u8 option;
} __packed;
struct rtw_c2h_ra_rpt {
u8 rate_sgi;
u8 mac_id;
u8 byte2;
u8 status;
u8 byte4;
u8 ra_ratio;
u8 bw;
} __packed;
#define RTW_C2H_RA_RPT_RATE GENMASK(6, 0)
#define RTW_C2H_RA_RPT_SGI BIT(7)
struct rtw_h2c_register {
u32 w0;
u32 w1;
@ -364,10 +377,6 @@ struct rtw_fw_hdr_legacy {
#define GET_CHAN_SWITCH_CENTRAL_CH(c2h_payload) (c2h_payload[2])
#define GET_CHAN_SWITCH_ID(c2h_payload) (c2h_payload[3])
#define GET_CHAN_SWITCH_STATUS(c2h_payload) (c2h_payload[4])
#define GET_RA_REPORT_RATE(c2h_payload) (c2h_payload[0] & 0x7f)
#define GET_RA_REPORT_SGI(c2h_payload) ((c2h_payload[0] & 0x80) >> 7)
#define GET_RA_REPORT_BW(c2h_payload) (c2h_payload[6])
#define GET_RA_REPORT_MACID(c2h_payload) (c2h_payload[1])
#define GET_BCN_FILTER_NOTIFY_TYPE(c2h_payload) (c2h_payload[1] & 0xf)
#define GET_BCN_FILTER_NOTIFY_EVENT(c2h_payload) (c2h_payload[1] & 0x10)

View File

@ -227,8 +227,8 @@ static int rtw_sub_pwr_seq_parser(struct rtw_dev *rtwdev, u8 intf_mask,
return 0;
}
static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
const struct rtw_pwr_seq_cmd * const *cmd_seq)
int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
const struct rtw_pwr_seq_cmd * const *cmd_seq)
{
u8 cut_mask;
u8 intf_mask;
@ -267,6 +267,7 @@ static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
return 0;
}
EXPORT_SYMBOL(rtw_pwr_seq_parser);
static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
{
@ -994,6 +995,7 @@ int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw)
return 0;
}
EXPORT_SYMBOL(rtw_download_firmware);
static u32 get_priority_queues(struct rtw_dev *rtwdev, u32 queues)
{
@ -1127,7 +1129,7 @@ static int txdma_queue_mapping(struct rtw_dev *rtwdev)
return 0;
}
static int set_trx_fifo_info(struct rtw_dev *rtwdev)
int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev)
{
const struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_fifo_conf *fifo = &rtwdev->fifo;
@ -1136,7 +1138,7 @@ static int set_trx_fifo_info(struct rtw_dev *rtwdev)
/* config rsvd page num */
fifo->rsvd_drv_pg_num = chip->rsvd_drv_pg_num;
fifo->txff_pg_num = chip->txff_size >> 7;
fifo->txff_pg_num = chip->txff_size / chip->page_size;
if (rtw_chip_wcpu_11n(rtwdev))
fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num;
else
@ -1179,6 +1181,7 @@ static int set_trx_fifo_info(struct rtw_dev *rtwdev)
return 0;
}
EXPORT_SYMBOL(rtw_set_trx_fifo_info);
static int __priority_queue_cfg(struct rtw_dev *rtwdev,
const struct rtw_page_table *pg_tbl,
@ -1256,7 +1259,7 @@ static int priority_queue_cfg(struct rtw_dev *rtwdev)
u16 pubq_num;
int ret;
ret = set_trx_fifo_info(rtwdev);
ret = rtw_set_trx_fifo_info(rtwdev);
if (ret)
return ret;

View File

@ -30,11 +30,14 @@
void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw,
u8 primary_ch_idx);
int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
const struct rtw_pwr_seq_cmd * const *cmd_seq);
int rtw_mac_power_on(struct rtw_dev *rtwdev);
void rtw_mac_power_off(struct rtw_dev *rtwdev);
int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw);
int rtw_mac_init(struct rtw_dev *rtwdev);
void rtw_mac_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop);
int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev);
int rtw_ddma_to_fw_fifo(struct rtw_dev *rtwdev, u32 ocp_src, u32 size);
static inline void rtw_mac_flush_all_queues(struct rtw_dev *rtwdev, bool drop)

View File

@ -202,6 +202,21 @@ static void rtw_vif_watch_dog_iter(void *data, struct ieee80211_vif *vif)
rtwvif->stats.rx_cnt = 0;
}
static void rtw_sw_beacon_loss_check(struct rtw_dev *rtwdev,
struct rtw_vif *rtwvif, int received_beacons)
{
int watchdog_delay = 2000000 / 1024; /* TU */
int beacon_int, expected_beacons;
if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER) || !rtwvif)
return;
beacon_int = rtwvif_to_vif(rtwvif)->bss_conf.beacon_int;
expected_beacons = DIV_ROUND_UP(watchdog_delay, beacon_int);
rtwdev->beacon_loss = received_beacons < expected_beacons / 2;
}
/* process TX/RX statistics periodically for hardware,
* the information helps hardware to enhance performance
*/
@ -212,6 +227,7 @@ static void rtw_watch_dog_work(struct work_struct *work)
struct rtw_traffic_stats *stats = &rtwdev->stats;
struct rtw_watch_dog_iter_data data = {};
bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
int received_beacons = rtwdev->dm_info.cur_pkt_count.num_bcn_pkt;
u32 tx_unicast_mbps, rx_unicast_mbps;
bool ps_active;
@ -258,6 +274,7 @@ static void rtw_watch_dog_work(struct work_struct *work)
rtw_leave_lps(rtwdev);
rtw_coex_wl_status_check(rtwdev);
rtw_coex_query_bt_hid_list(rtwdev);
rtw_coex_active_query_bt_info(rtwdev);
rtw_phy_dynamic_mechanism(rtwdev);
@ -270,6 +287,8 @@ static void rtw_watch_dog_work(struct work_struct *work)
*/
rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data);
rtw_sw_beacon_loss_check(rtwdev, data.rtwvif, received_beacons);
/* fw supports only one station associated to enter lps, if there are
* more than two stations associated to the AP, then we can not enter
* lps, because fw does not handle the overlapped beacon interval
@ -1309,7 +1328,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
rtw_fw_send_ra_info(rtwdev, si, reset_ra_mask);
}
static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev)
int rtw_wait_firmware_completion(struct rtw_dev *rtwdev)
{
const struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_fw_state *fw;
@ -1329,6 +1348,7 @@ static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev)
return ret;
}
EXPORT_SYMBOL(rtw_wait_firmware_completion);
static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev,
struct rtw_fw_state *fw)
@ -1350,7 +1370,7 @@ static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev,
return LPS_DEEP_MODE_NONE;
}
static int rtw_power_on(struct rtw_dev *rtwdev)
int rtw_power_on(struct rtw_dev *rtwdev)
{
const struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_fw_state *fw = &rtwdev->fw;
@ -1413,6 +1433,7 @@ static int rtw_power_on(struct rtw_dev *rtwdev)
err:
return ret;
}
EXPORT_SYMBOL(rtw_power_on);
void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start)
{
@ -1485,7 +1506,7 @@ int rtw_core_start(struct rtw_dev *rtwdev)
{
int ret;
ret = rtw_power_on(rtwdev);
ret = rtwdev->chip->ops->power_on(rtwdev);
if (ret)
return ret;
@ -1505,12 +1526,13 @@ int rtw_core_start(struct rtw_dev *rtwdev)
return 0;
}
static void rtw_power_off(struct rtw_dev *rtwdev)
void rtw_power_off(struct rtw_dev *rtwdev)
{
rtw_hci_stop(rtwdev);
rtw_coex_power_off_setting(rtwdev);
rtw_mac_power_off(rtwdev);
}
EXPORT_SYMBOL(rtw_power_off);
void rtw_core_stop(struct rtw_dev *rtwdev)
{
@ -1535,7 +1557,7 @@ void rtw_core_stop(struct rtw_dev *rtwdev)
mutex_lock(&rtwdev->mutex);
rtw_power_off(rtwdev);
rtwdev->chip->ops->power_off(rtwdev);
}
static void rtw_init_ht_cap(struct rtw_dev *rtwdev,
@ -1917,6 +1939,9 @@ static int rtw_dump_hw_feature(struct rtw_dev *rtwdev)
u8 bw;
int i;
if (!rtwdev->chip->hw_feature_report)
return 0;
id = rtw_read8(rtwdev, REG_C2HEVT);
if (id != C2H_HW_FEATURE_REPORT) {
rtw_err(rtwdev, "failed to read hw feature report\n");

View File

@ -189,6 +189,8 @@ enum rtw_chip_type {
RTW_CHIP_TYPE_8723D,
RTW_CHIP_TYPE_8821C,
RTW_CHIP_TYPE_8703B,
RTW_CHIP_TYPE_8821A,
RTW_CHIP_TYPE_8812A,
};
enum rtw_tx_queue_type {
@ -841,6 +843,8 @@ struct rtw_regd {
};
struct rtw_chip_ops {
int (*power_on)(struct rtw_dev *rtwdev);
void (*power_off)(struct rtw_dev *rtwdev);
int (*mac_init)(struct rtw_dev *rtwdev);
int (*dump_fw_crash)(struct rtw_dev *rtwdev);
void (*shutdown)(struct rtw_dev *rtwdev);
@ -1095,17 +1099,20 @@ enum rtw_rfe_fem {
struct rtw_rfe_def {
const struct rtw_table *phy_pg_tbl;
const struct rtw_table *txpwr_lmt_tbl;
const struct rtw_pwr_track_tbl *pwr_track_tbl;
const struct rtw_table *agc_btg_tbl;
};
#define RTW_DEF_RFE(chip, bb_pg, pwrlmt) { \
#define RTW_DEF_RFE(chip, bb_pg, pwrlmt, track) { \
.phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \
.txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \
.pwr_track_tbl = &rtw ## chip ## _pwr_track_type ## track ## _tbl, \
}
#define RTW_DEF_RFE_EXT(chip, bb_pg, pwrlmt, btg) { \
#define RTW_DEF_RFE_EXT(chip, bb_pg, pwrlmt, track, btg) { \
.phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \
.txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \
.pwr_track_tbl = &rtw ## chip ## _pwr_track_type ## track ## _tbl, \
.agc_btg_tbl = &rtw ## chip ## _agc_btg_type ## btg ## _tbl, \
}
@ -1183,7 +1190,7 @@ struct rtw_chip_info {
u32 fw_rxff_size;
u16 rsvd_drv_pg_num;
u8 band;
u8 page_size;
u16 page_size;
u8 csi_buf_pg_num;
u8 dig_max;
u8 dig_min;
@ -1198,6 +1205,9 @@ struct rtw_chip_info {
const struct rtw_fwcd_segs *fwcd_segs;
u8 usb_tx_agg_desc_num;
bool hw_feature_report;
u8 c2h_ra_report_size;
bool old_datarate_fb_limit;
u8 default_1ss_tx_path;
@ -1236,7 +1246,6 @@ struct rtw_chip_info {
u16 dpd_ratemask;
u8 iqk_threshold;
u8 lck_threshold;
const struct rtw_pwr_track_tbl *pwr_track_tbl;
u8 bfer_su_max_num;
u8 bfer_mu_max_num;
@ -1485,6 +1494,7 @@ struct rtw_coex_stat {
u8 bt_hid_slot;
u8 bt_a2dp_bitpool;
u8 bt_iqk_state;
u8 bt_disable_cnt;
u16 wl_beacon_interval;
u8 wl_noisy_level;
@ -1708,7 +1718,7 @@ struct rtw_dm_info {
bool pwr_trk_init_trigger;
struct ewma_thermal avg_thermal[RTW_RF_PATH_MAX];
s8 txagc_remnant_cck;
s8 txagc_remnant_ofdm;
s8 txagc_remnant_ofdm[RTW_RF_PATH_MAX];
u8 rx_cck_agc_report_type;
/* backup dack results for each path and I/Q */
@ -1831,6 +1841,20 @@ struct rtw_phy_cond {
#define BRANCH_ENDIF 3
};
struct rtw_phy_cond2 {
#ifdef __LITTLE_ENDIAN
u8 type_glna;
u8 type_gpa;
u8 type_alna;
u8 type_apa;
#else
u8 type_apa;
u8 type_alna;
u8 type_gpa;
u8 type_glna;
#endif
};
struct rtw_fifo_conf {
/* tx fifo information */
u16 rsvd_boundary;
@ -1912,6 +1936,7 @@ struct rtw_hal {
u8 oem_id;
u8 pkg_type;
struct rtw_phy_cond phy_cond;
struct rtw_phy_cond2 phy_cond2;
bool rfe_btg;
u8 ps_mode;
@ -1934,6 +1959,7 @@ struct rtw_hal {
u32 antenna_rx;
u8 bfee_sts_cap;
bool txrx_1ss;
bool cck_high_power;
/* protect tx power section */
struct mutex tx_power_mutex;
@ -2189,6 +2215,7 @@ void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,
void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
bool hw_scan);
int rtw_core_start(struct rtw_dev *rtwdev);
void rtw_power_off(struct rtw_dev *rtwdev);
void rtw_core_stop(struct rtw_dev *rtwdev);
int rtw_chip_info_setup(struct rtw_dev *rtwdev);
int rtw_core_init(struct rtw_dev *rtwdev);
@ -2203,6 +2230,8 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
bool fw_exist);
void rtw_fw_recovery(struct rtw_dev *rtwdev);
int rtw_wait_firmware_completion(struct rtw_dev *rtwdev);
int rtw_power_on(struct rtw_dev *rtwdev);
void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start);
int rtw_dump_fw(struct rtw_dev *rtwdev, const u32 ocp_src, u32 size,
u32 fwcd_item);

View File

@ -824,7 +824,7 @@ static int rtw_pci_tx_write_data(struct rtw_dev *rtwdev,
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
memset(pkt_desc, 0, tx_pkt_desc_sz);
pkt_info->qsel = rtw_pci_get_tx_qsel(skb, queue);
rtw_tx_fill_tx_desc(pkt_info, skb);
rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
dma = dma_map_single(&rtwpci->pdev->dev, skb->data, skb->len,
DMA_TO_DEVICE);
if (dma_mapping_error(&rtwpci->pdev->dev, dma))

View File

@ -18,7 +18,10 @@ struct phy_cfg_pair {
};
union phy_table_tile {
struct rtw_phy_cond cond;
struct {
struct rtw_phy_cond cond;
struct rtw_phy_cond2 cond2;
} __packed;
struct phy_cfg_pair cfg;
};
@ -527,6 +530,13 @@ static void rtw_phy_dig(struct rtw_dev *rtwdev)
*/
rtw_phy_dig_recorder(dm_info, cur_igi, fa_cnt);
/* Mitigate beacon loss and connectivity issues, mainly (only?)
* in the 5 GHz band
*/
if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A && rtwdev->beacon_loss &&
linked && dm_info->total_fa_cnt < DIG_PERF_FA_TH_EXTRA_HIGH)
cur_igi = DIG_CVRG_MIN;
if (cur_igi != pre_igi)
rtw_phy_dig_write(rtwdev, cur_igi);
}
@ -1041,7 +1051,8 @@ void rtw_phy_setup_phy_cond(struct rtw_dev *rtwdev, u32 pkg)
{
struct rtw_hal *hal = &rtwdev->hal;
struct rtw_efuse *efuse = &rtwdev->efuse;
struct rtw_phy_cond cond = {0};
struct rtw_phy_cond cond = {};
struct rtw_phy_cond2 cond2 = {};
cond.cut = hal->cut_version ? hal->cut_version : 15;
cond.pkg = pkg ? pkg : 15;
@ -1061,15 +1072,34 @@ void rtw_phy_setup_phy_cond(struct rtw_dev *rtwdev, u32 pkg)
break;
}
hal->phy_cond = cond;
if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A ||
rtwdev->chip->id == RTW_CHIP_TYPE_8821A) {
cond.rfe = 0;
cond.rfe |= efuse->ext_lna_2g;
cond.rfe |= efuse->ext_pa_2g << 1;
cond.rfe |= efuse->ext_lna_5g << 2;
cond.rfe |= efuse->ext_pa_5g << 3;
cond.rfe |= efuse->btcoex << 4;
rtw_dbg(rtwdev, RTW_DBG_PHY, "phy cond=0x%08x\n", *((u32 *)&hal->phy_cond));
cond2.type_alna = efuse->alna_type;
cond2.type_glna = efuse->glna_type;
cond2.type_apa = efuse->apa_type;
cond2.type_gpa = efuse->gpa_type;
}
hal->phy_cond = cond;
hal->phy_cond2 = cond2;
rtw_dbg(rtwdev, RTW_DBG_PHY, "phy cond=0x%08x cond2=0x%08x\n",
*((u32 *)&hal->phy_cond), *((u32 *)&hal->phy_cond2));
}
static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond)
static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond,
struct rtw_phy_cond2 cond2)
{
struct rtw_hal *hal = &rtwdev->hal;
struct rtw_phy_cond drv_cond = hal->phy_cond;
struct rtw_phy_cond2 drv_cond2 = hal->phy_cond2;
if (cond.cut && cond.cut != drv_cond.cut)
return false;
@ -1080,8 +1110,29 @@ static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond)
if (cond.intf && cond.intf != drv_cond.intf)
return false;
if (cond.rfe != drv_cond.rfe)
return false;
if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A ||
rtwdev->chip->id == RTW_CHIP_TYPE_8821A) {
if (!(cond.rfe & 0x0f))
return true;
if ((cond.rfe & drv_cond.rfe) != cond.rfe)
return false;
if ((cond.rfe & BIT(0)) && cond2.type_glna != drv_cond2.type_glna)
return false;
if ((cond.rfe & BIT(1)) && cond2.type_gpa != drv_cond2.type_gpa)
return false;
if ((cond.rfe & BIT(2)) && cond2.type_alna != drv_cond2.type_alna)
return false;
if ((cond.rfe & BIT(3)) && cond2.type_apa != drv_cond2.type_apa)
return false;
} else {
if (cond.rfe != drv_cond.rfe)
return false;
}
return true;
}
@ -1090,7 +1141,8 @@ void rtw_parse_tbl_phy_cond(struct rtw_dev *rtwdev, const struct rtw_table *tbl)
{
const union phy_table_tile *p = tbl->data;
const union phy_table_tile *end = p + tbl->size / 2;
struct rtw_phy_cond pos_cond = {0};
struct rtw_phy_cond pos_cond = {};
struct rtw_phy_cond2 pos_cond2 = {};
bool is_matched = true, is_skipped = false;
BUILD_BUG_ON(sizeof(union phy_table_tile) != sizeof(struct phy_cfg_pair));
@ -1109,11 +1161,12 @@ void rtw_parse_tbl_phy_cond(struct rtw_dev *rtwdev, const struct rtw_table *tbl)
case BRANCH_ELIF:
default:
pos_cond = p->cond;
pos_cond2 = p->cond2;
break;
}
} else if (p->cond.neg) {
if (!is_skipped) {
if (check_positive(rtwdev, pos_cond)) {
if (check_positive(rtwdev, pos_cond, pos_cond2)) {
is_matched = true;
is_skipped = true;
} else {
@ -1470,10 +1523,8 @@ static void rtw_phy_store_tx_power_by_rate(struct rtw_dev *rtwdev,
rate = rates[i];
if (band == PHY_BAND_2G)
hal->tx_pwr_by_rate_offset_2g[rfpath][rate] = offset;
else if (band == PHY_BAND_5G)
hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset;
else
continue;
hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset;
}
}
@ -2125,8 +2176,8 @@ void rtw_get_tx_power_params(struct rtw_dev *rtwdev, u8 path, u8 rate, u8 bw,
*limit = rtw_phy_get_tx_power_limit(rtwdev, band, bw, path,
rate, ch, regd);
*remnant = (rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck :
dm_info->txagc_remnant_ofdm);
*remnant = rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck :
dm_info->txagc_remnant_ofdm[path];
*sar = rtw_phy_get_tx_power_sar(rtwdev, hal->sar_band, path, rate);
}
@ -2340,7 +2391,8 @@ void rtw_phy_init_tx_power(struct rtw_dev *rtwdev)
void rtw_phy_config_swing_table(struct rtw_dev *rtwdev,
struct rtw_swing_table *swing_table)
{
const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl;
const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev);
const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl;
u8 channel = rtwdev->hal.current_channel;
if (IS_CH_2G_BAND(channel)) {

View File

@ -9,6 +9,7 @@
#define BIT_FEN_EN_25_1 BIT(13)
#define BIT_FEN_ELDR BIT(12)
#define BIT_FEN_CPUEN BIT(2)
#define BIT_FEN_USBA BIT(2)
#define BIT_FEN_BB_GLB_RST BIT(1)
#define BIT_FEN_BB_RSTB BIT(0)
#define BIT_R_DIS_PRST BIT(6)
@ -16,6 +17,10 @@
#define REG_SYS_PW_CTRL 0x0004
#define BIT_PFM_WOWL BIT(3)
#define BIT_APFM_OFFMAC BIT(9)
#define REG_APS_FSMCO 0x0004
#define APS_FSMCO_MAC_ENABLE BIT(8)
#define APS_FSMCO_MAC_OFF BIT(9)
#define APS_FSMCO_HW_POWERDOWN BIT(15)
#define REG_SYS_CLK_CTRL 0x0008
#define BIT_CPU_CLK_EN BIT(14)
@ -58,6 +63,8 @@
#define BIT_SHIFT_LDO25_VOLTAGE 4
#define BIT_LDO25_EN BIT(7)
#define REG_ACLK_MON 0x3e
#define REG_GPIO_MUXCFG 0x0040
#define BIT_FSPI_EN BIT(19)
#define BIT_EN_SIC BIT(12)
@ -90,6 +97,8 @@
#define BIT_USB_SUS_DIS BIT(8)
#define BIT_SDIO_PAD_E5 BIT(18)
#define REG_RF_B_CTRL 0x76
#define REG_AFE_CTRL_4 0x0078
#define BIT_CK320M_AFE_EN BIT(4)
#define BIT_EN_SYN BIT(15)
@ -134,6 +143,11 @@
#define REG_PMC_DBG_CTRL1 0xa8
#define BITS_PMC_BT_IQK_STS GENMASK(22, 21)
#define REG_HIMR0 0xb0
#define REG_HISR0 0xb4
#define REG_HIMR1 0xb8
#define REG_HISR1 0xbc
#define REG_PAD_CTRL2 0x00C4
#define BIT_RSM_EN_V1 BIT(16)
#define BIT_NO_PDN_CHIPOFF_V1 BIT(17)
@ -185,6 +199,15 @@
#define MAC_TRX_ENABLE (BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN | \
BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | \
BIT_MACTXEN | BIT_MACRXEN)
#define REG_PBP 0x104
#define PBP_RX_MASK 0x0f
#define PBP_TX_MASK 0xf0
#define PBP_64 0x0
#define PBP_128 0x1
#define PBP_256 0x2
#define PBP_512 0x3
#define PBP_1024 0x4
#define BIT_SHIFT_TXDMA_VOQ_MAP 4
#define BIT_MASK_TXDMA_VOQ_MAP 0x3
#define BIT_TXDMA_VOQ_MAP(x) \
@ -256,6 +279,8 @@
#define REG_HMEBOX1 0x01D4
#define REG_HMEBOX2 0x01D8
#define REG_HMEBOX3 0x01DC
#define REG_LLT_INIT 0x01E0
#define BIT_LLT_WRITE_ACCESS BIT(30)
#define REG_HMEBOX0_EX 0x01F0
#define REG_HMEBOX1_EX 0x01F4
#define REG_HMEBOX2_EX 0x01F8
@ -298,6 +323,7 @@
#define REG_AUTO_LLT 0x0224
#define BIT_AUTO_INIT_LLT BIT(16)
#define REG_DWBCN1_CTRL 0x0228
#define REG_RQPN_CTRL_1 0x0228
#define REG_RQPN_CTRL_2 0x022C
#define BIT_LD_RQPN BIT(31)
@ -329,6 +355,7 @@
#define BIT_DMA_BURST_SIZE_1024 0
#define REG_RXPKTNUM 0x02B0
#define REG_EARLY_MODE_CONTROL 0x02BC
#define REG_INT_MIG 0x0304
#define REG_HCI_MIX_CFG 0x03FC
@ -336,6 +363,7 @@
#define REG_BCNQ_INFO 0x0418
#define BIT_MGQ_CPU_EMPTY BIT(24)
#define REG_TXPKT_EMPTY 0x041A
#define REG_FWHW_TXQ_CTRL 0x0420
#define BIT_EN_BCNQ_DL BIT(22)
#define BIT_EN_WR_FREE_TAIL BIT(20)
@ -362,10 +390,12 @@
#define REG_AMPDU_MAX_TIME_V1 0x0455
#define REG_BCNQ1_BDNY_V1 0x0456
#define REG_AMPDU_MAX_TIME 0x0456
#define REG_AMPDU_MAX_LENGTH 0x0458
#define REG_WMAC_LBK_BF_HD 0x045D
#define REG_TX_HANG_CTRL 0x045E
#define BIT_EN_GNT_BT_AWAKE BIT(3)
#define BIT_EN_EOF_V1 BIT(2)
#define REG_FAST_EDCA_CTRL 0x0460
#define REG_DATA_SC 0x0483
#define REG_ARFR2_V1 0x048C
#define REG_ARFRH2_V1 0x0490
@ -390,6 +420,8 @@
#define REG_PRECNT_CTRL 0x04E5
#define BIT_BTCCA_CTRL (BIT(0) | BIT(1))
#define BIT_EN_PRECNT BIT(11)
#define REG_TX_RPT_CTRL 0x04EC
#define REG_TX_RPT_TIME 0x04F0
#define REG_DUMMY_PAGE4_V1 0x04FC
#define REG_EDCA_VO_PARAM 0x0500
@ -400,6 +432,7 @@
#define BIT_MASK_CWMAX GENMASK(15, 12)
#define BIT_MASK_CWMIN GENMASK(11, 8)
#define BIT_MASK_AIFS GENMASK(7, 0)
#define REG_BCNTCFG 0x0510
#define REG_PIFS 0x0512
#define REG_SIFS 0x0514
#define BIT_SHIFT_SIFS_OFDM_CTX 8
@ -526,6 +559,8 @@
#define REG_BT_COEX_V2 0x0762
#define BIT_GNT_BT_POLARITY BIT(12)
#define BIT_LTE_COEX_EN BIT(7)
#define REG_GNT_BT 0x0765
#define BIT_PTA_SW_CTL GENMASK(4, 3)
#define REG_BT_COEX_ENH_INTR_CTRL 0x76E
#define BIT_R_GRANTALL_WLMASK BIT(3)
#define BIT_STATIS_BT_EN BIT(2)
@ -543,14 +578,43 @@
#define REG_FPGA0_RFMOD 0x0800
#define BIT_CCKEN BIT(24)
#define BIT_OFDMEN BIT(25)
#define REG_CCK_RPT_FORMAT 0x0804
#define BIT_CCK_RPT_FORMAT BIT(16)
#define REG_RXPSEL 0x0808
#define BIT_RX_PSEL_RST (BIT(28) | BIT(29))
#define REG_TXPSEL 0x080C
#define REG_RX_GAIN_EN 0x081c
#define REG_CCASEL 0x082C
#define REG_PDMFTH 0x0830
#define REG_BWINDICATION 0x0834
#define REG_CCA2ND 0x0838
#define REG_L1PKTH 0x0848
#define REG_CLKTRK 0x0860
#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_ANTSEL_SW 0x0900
#define REG_DAC_RSTB 0x090c
#define REG_SINGLE_TONE_CONT_TX 0x0914
#define REG_RFE_CTRL_E 0x0974
#define REG_2ND_CCA_CTRL 0x0976
#define REG_IQK_COM00 0x0978
#define REG_IQK_COM32 0x097c
#define REG_IQK_COM64 0x0980
#define REG_IQK_COM96 0x0984
#define REG_FAS 0x09a4
#define REG_RXSB 0x0a00
#define REG_CCK_RX 0x0a04
#define REG_CCK_PD_TH 0x0a0a
#define REG_CCK0_FAREPORT 0xa2c
#define BIT_CCK0_2RX BIT(18)
#define BIT_CCK0_MRC BIT(22)
#define REG_FA_CCK 0x0a5c
#define REG_DIS_DPD 0x0a70
#define DIS_DPD_MASK GENMASK(9, 0)
@ -566,13 +630,109 @@
#define DIS_DPD_RATEVHT2SS_MCS1 BIT(9)
#define DIS_DPD_RATEALL GENMASK(9, 0)
#define REG_CNTRST 0x0b58
#define REG_3WIRE_SWA 0x0c00
#define REG_RX_IQC_AB_A 0x0c10
#define REG_TXSCALE_A 0x0c1c
#define BB_SWING_MASK GENMASK(31, 21)
#define REG_TX_AGC_A_CCK_11_CCK_1 0xc20
#define REG_TX_AGC_A_OFDM18_OFDM6 0xc24
#define REG_TX_AGC_A_OFDM54_OFDM24 0xc28
#define REG_TX_AGC_A_MCS3_MCS0 0xc2c
#define REG_TX_AGC_A_MCS7_MCS4 0xc30
#define REG_TX_AGC_A_MCS11_MCS8 0xc34
#define REG_TX_AGC_A_MCS15_MCS12 0xc38
#define REG_TX_AGC_A_NSS1_INDEX3_NSS1_INDEX0 0xc3c
#define REG_TX_AGC_A_NSS1_INDEX7_NSS1_INDEX4 0xc40
#define REG_TX_AGC_A_NSS2_INDEX1_NSS1_INDEX8 0xc44
#define REG_TX_AGC_A_NSS2_INDEX5_NSS2_INDEX2 0xc48
#define REG_TX_AGC_A_NSS2_INDEX9_NSS2_INDEX6 0xc4c
#define REG_RXIGI_A 0x0c50
#define REG_TX_PWR_TRAINING_A 0x0c54
#define REG_CK_MONHA 0x0c5c
#define REG_AFE_PWR1_A 0x0c60
#define REG_AFE_PWR2_A 0x0c64
#define REG_RX_WAIT_CCA_TX_CCK_RFON_A 0x0c68
#define REG_OFDM0_XA_TX_IQ_IMBALANCE 0x0c80
#define REG_OFDM0_A_TX_AFE 0x0c84
#define REG_OFDM0_XB_TX_IQ_IMBALANCE 0x0c88
#define REG_TSSI_TRK_SW 0x0c8c
#define REG_LSSI_WRITE_A 0x0c90
#define REG_PREDISTA 0x0c90
#define REG_TXAGCIDX 0x0c94
#define REG_RFE_PINMUX_A 0x0cb0
#define REG_RFE_INV_A 0x0cb4
#define REG_RFE_CTRL8 0x0cb4
#define BIT_MASK_RFE_SEL89 GENMASK(7, 0)
#define PTA_CTRL_PIN 0x66
#define DPDT_CTRL_PIN 0x77
#define RFE_INV_MASK 0x3ff00000
#define REG_RFECTL_A 0x0cb8
#define REG_RFE_INV8 0x0cbd
#define BIT_MASK_RFE_INV89 GENMASK(1, 0)
#define REG_RFE_INV16 0x0cbe
#define BIT_RFE_BUF_EN BIT(3)
#define REG_IQK_DPD_CFG 0x0cc4
#define REG_CFG_PMPD 0x0cc8
#define REG_IQC_Y 0x0ccc
#define REG_IQC_X 0x0cd4
#define REG_INTPO_SETA 0x0ce8
#define REG_IQKA_END 0x0d00
#define REG_PI_READ_A 0x0d04
#define REG_SI_READ_A 0x0d08
#define REG_IQKB_END 0x0d40
#define REG_PI_READ_B 0x0d44
#define REG_SI_READ_B 0x0d48
#define REG_3WIRE_SWB 0x0e00
#define REG_RX_IQC_AB_B 0x0e10
#define REG_TXSCALE_B 0x0e1c
#define REG_TX_AGC_B_CCK_11_CCK_1 0xe20
#define REG_TX_AGC_B_OFDM18_OFDM6 0xe24
#define REG_TX_AGC_B_OFDM54_OFDM24 0xe28
#define REG_TX_AGC_B_MCS3_MCS0 0xe2c
#define REG_TX_AGC_B_MCS7_MCS4 0xe30
#define REG_TX_AGC_B_MCS11_MCS8 0xe34
#define REG_TX_AGC_B_MCS15_MCS12 0xe38
#define REG_TX_AGC_B_NSS1_INDEX3_NSS1_INDEX0 0xe3c
#define REG_TX_AGC_B_NSS1_INDEX7_NSS1_INDEX4 0xe40
#define REG_TX_AGC_B_NSS2_INDEX1_NSS1_INDEX8 0xe44
#define REG_TX_AGC_B_NSS2_INDEX5_NSS2_INDEX2 0xe48
#define REG_TX_AGC_B_NSS2_INDEX9_NSS2_INDEX6 0xe4c
#define REG_RXIGI_B 0x0e50
#define REG_TX_PWR_TRAINING_B 0x0e54
#define REG_CK_MONHB 0x0e5c
#define REG_AFE_PWR1_B 0x0e60
#define REG_AFE_PWR2_B 0x0e64
#define REG_RX_WAIT_CCA_TX_CCK_RFON_B 0x0e68
#define REG_TXTONEB 0x0e80
#define REG_RXTONEB 0x0e84
#define REG_TXPITMB 0x0e88
#define REG_RXPITMB 0x0e8c
#define REG_LSSI_WRITE_B 0x0e90
#define REG_PREDISTB 0x0e90
#define REG_INIDLYB 0x0e94
#define REG_RFE_PINMUX_B 0x0eb0
#define REG_RFE_INV_B 0x0eb4
#define REG_RFECTL_B 0x0eb8
#define REG_BPBDB 0x0ec4
#define REG_PHYTXONB 0x0ec8
#define REG_IQKYB 0x0ecc
#define REG_IQKXB 0x0ed4
#define REG_INTPO_SETB 0x0ee8
#define REG_CRC_CCK 0x0f04
#define REG_CCA_OFDM 0x0f08
#define REG_CRC_VHT 0x0f0c
#define REG_CRC_HT 0x0f10
#define REG_CRC_OFDM 0x0f14
#define REG_FA_OFDM 0x0f48
#define REG_CCA_CCK 0x0fcc
#define REG_ANAPARSW_MAC_0 0x1010
#define BIT_CF_L_V2 GENMASK(29, 28)
@ -709,6 +869,10 @@
#define REG_IGN_GNTBT4 0x4160
#define REG_USB_MOD 0xf008
#define REG_USB3_RXITV 0xf050
#define REG_USB_HRPWM 0xfe58
#define RF_MODE 0x00
#define RF_MODOPT 0x01
#define RF_WLINT 0x01
@ -716,7 +880,13 @@
#define RF_DTXLOK 0x08
#define RF_CFGCH 0x18
#define BIT_BAND GENMASK(18, 16)
#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_RCK 0x1d
#define RF_MODE_TABLE_ADDR 0x30
#define RF_MODE_TABLE_DATA0 0x31
#define RF_MODE_TABLE_DATA1 0x32
#define RF_LUTWA 0x33
#define RF_LUTWD1 0x3e
#define RF_LUTWD0 0x3f
@ -725,10 +895,14 @@
#define RF_T_METER 0x42
#define RF_BSPAD 0x54
#define RF_GAINTX 0x56
#define RF_TXMOD 0x58
#define RF_TXATANK 0x64
#define RF_TXA_PREPAD 0x65
#define RF_TRXIQ 0x66
#define RF_RXIQGEN 0x8d
#define RF_RXBB2 0x8f
#define RF_SYN_PFD 0xb0
#define RF_LCK 0xb4
#define RF_XTALX2 0xb8
#define RF_SYN_CTRL 0xbb
#define RF_MALSEL 0xbe

View File

@ -493,11 +493,6 @@ static const struct rtw_pwr_seq_cmd * const card_disable_flow_8703b[] = {
NULL
};
static const struct rtw_rfe_def rtw8703b_rfe_defs[] = {
[0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl,
.txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl,},
};
static const struct rtw_page_table page_table_8703b[] = {
{12, 2, 2, 0, 1},
{12, 2, 2, 0, 1},
@ -637,7 +632,7 @@ static void rtw8703b_pwrtrack_init(struct rtw_dev *rtwdev)
dm_info->pwr_trk_init_trigger = true;
dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
dm_info->txagc_remnant_cck = 0;
dm_info->txagc_remnant_ofdm = 0;
dm_info->txagc_remnant_ofdm[RF_PATH_A] = 0;
}
static void rtw8703b_phy_set_param(struct rtw_dev *rtwdev)
@ -1589,7 +1584,7 @@ static void rtw8703b_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx,
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
dm_info->txagc_remnant_ofdm = txagc_idx;
dm_info->txagc_remnant_ofdm[RF_PATH_A] = txagc_idx;
/* Only path A is calibrated for rtl8703b */
rtw8703b_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A);
@ -1818,6 +1813,12 @@ static const struct rtw_pwr_track_tbl rtw8703b_rtw_pwr_track_tbl = {
.pwrtrk_xtal_p = rtw8703b_pwrtrk_xtal_p,
};
static const struct rtw_rfe_def rtw8703b_rfe_defs[] = {
[0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl,
.txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl,
.pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl, },
};
/* Shared-Antenna Coex Table */
static const struct coex_table_para table_sant_8703b[] = {
{0xffffffff, 0xffffffff}, /* case-0 */
@ -1888,6 +1889,8 @@ static const struct coex_tdma_para tdma_sant_8703b[] = {
};
static const struct rtw_chip_ops rtw8703b_ops = {
.power_on = rtw_power_on,
.power_off = rtw_power_off,
.mac_init = rtw8723x_mac_init,
.dump_fw_crash = NULL,
.shutdown = NULL,
@ -1960,6 +1963,9 @@ const struct rtw_chip_info rtw8703b_hw_spec = {
.max_power_index = 0x3f,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
.usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */
.hw_feature_report = true,
.c2h_ra_report_size = 7,
.old_datarate_fb_limit = true,
.path_div_supported = false,
.ht_supported = true,
@ -1992,7 +1998,6 @@ const struct rtw_chip_info rtw8703b_hw_spec = {
.rfe_defs_size = ARRAY_SIZE(rtw8703b_rfe_defs),
.iqk_threshold = 8,
.pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl,
/* WOWLAN firmware exists, but not implemented yet */
.wow_fw_name = "rtw88/rtw8703b_wow_fw.bin",

View File

@ -79,7 +79,7 @@ static void rtw8723d_pwrtrack_init(struct rtw_dev *rtwdev)
dm_info->pwr_trk_init_trigger = true;
dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
dm_info->txagc_remnant_cck = 0;
dm_info->txagc_remnant_ofdm = 0;
dm_info->txagc_remnant_ofdm[RF_PATH_A] = 0;
}
static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev)
@ -1265,7 +1265,7 @@ static void rtw8723d_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx,
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
dm_info->txagc_remnant_ofdm = txagc_idx;
dm_info->txagc_remnant_ofdm[RF_PATH_A] = txagc_idx;
rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A);
rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_B);
@ -1390,6 +1390,8 @@ static void rtw8723d_pwr_track(struct rtw_dev *rtwdev)
}
static const struct rtw_chip_ops rtw8723d_ops = {
.power_on = rtw_power_on,
.power_off = rtw_power_off,
.phy_set_param = rtw8723d_phy_set_param,
.read_efuse = rtw8723x_read_efuse,
.query_phy_status = query_phy_status,
@ -2018,11 +2020,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8723d = {
.n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8723d),
};
static const struct rtw_rfe_def rtw8723d_rfe_defs[] = {
[0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl,
.txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl,},
};
static const u8 rtw8723d_pwrtrk_2gb_n[] = {
0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5,
6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10
@ -2086,6 +2083,12 @@ static const struct rtw_pwr_track_tbl rtw8723d_rtw_pwr_track_tbl = {
.pwrtrk_xtal_n = rtw8723d_pwrtrk_xtal_n,
};
static const struct rtw_rfe_def rtw8723d_rfe_defs[] = {
[0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl,
.txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl,
.pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, },
};
static const struct rtw_reg_domain coex_info_hw_regs_8723d[] = {
{0x948, MASKDWORD, RTW_REG_DOMAIN_MAC32},
{0x67, BIT(7), RTW_REG_DOMAIN_MAC8},
@ -2131,6 +2134,9 @@ const struct rtw_chip_info rtw8723d_hw_spec = {
.page_size = TX_PAGE_SIZE,
.dig_min = 0x20,
.usb_tx_agg_desc_num = 1,
.hw_feature_report = true,
.c2h_ra_report_size = 7,
.old_datarate_fb_limit = true,
.ht_supported = true,
.vht_supported = false,
.lps_deep_mode_supported = 0,
@ -2154,7 +2160,6 @@ const struct rtw_chip_info rtw8723d_hw_spec = {
.rfe_defs = rtw8723d_rfe_defs,
.rfe_defs_size = ARRAY_SIZE(rtw8723d_rfe_defs),
.rx_ldpc = false,
.pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl,
.iqk_threshold = 8,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
.max_scan_ie_len = IEEE80211_MAX_DATA_LEN,

View File

@ -595,7 +595,8 @@ void __rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path,
u8 delta)
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl;
const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev);
const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl;
const s8 *pwrtrk_xtal;
s8 xtal_cap;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2024 Realtek Corporation
*/
#ifndef __RTW8812A_H__
#define __RTW8812A_H__
extern const struct rtw_chip_info rtw8812a_hw_spec;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2024 Realtek Corporation
*/
#ifndef __RTW8812A_TABLE_H__
#define __RTW8812A_TABLE_H__
extern const struct rtw_table rtw8812a_mac_tbl;
extern const struct rtw_table rtw8812a_agc_tbl;
extern const struct rtw_table rtw8812a_agc_diff_lb_tbl;
extern const struct rtw_table rtw8812a_agc_diff_hb_tbl;
extern const struct rtw_table rtw8812a_bb_tbl;
extern const struct rtw_table rtw8812a_bb_pg_tbl;
extern const struct rtw_table rtw8812a_bb_pg_rfe3_tbl;
extern const struct rtw_table rtw8812a_rf_a_tbl;
extern const struct rtw_table rtw8812a_rf_b_tbl;
extern const struct rtw_table rtw8812a_txpwr_lmt_tbl;
extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8812a[];
extern const struct rtw_pwr_seq_cmd * const enter_lps_flow_8812a[];
extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8812a[];
extern const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_tbl;
extern const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_rfe3_tbl;
#endif

View File

@ -0,0 +1,28 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2024 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/usb.h>
#include "main.h"
#include "rtw8812a.h"
#include "usb.h"
static const struct usb_device_id rtw_8812au_id_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x2604, 0x0012, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) },
{},
};
MODULE_DEVICE_TABLE(usb, rtw_8812au_id_table);
static struct usb_driver rtw_8812au_driver = {
.name = "rtw_8812au",
.id_table = rtw_8812au_id_table,
.probe = rtw_usb_probe,
.disconnect = rtw_usb_disconnect,
};
module_usb_driver(rtw_8812au_driver);
MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812au driver");
MODULE_LICENSE("Dual BSD/GPL");

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2024 Realtek Corporation
*/
#ifndef __RTW8821A_H__
#define __RTW8821A_H__
extern const struct rtw_chip_info rtw8821a_hw_spec;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2024 Realtek Corporation
*/
#ifndef __RTW8821A_TABLE_H__
#define __RTW8821A_TABLE_H__
extern const struct rtw_table rtw8821a_mac_tbl;
extern const struct rtw_table rtw8821a_agc_tbl;
extern const struct rtw_table rtw8821a_bb_tbl;
extern const struct rtw_table rtw8821a_bb_pg_tbl;
extern const struct rtw_table rtw8821a_rf_a_tbl;
extern const struct rtw_table rtw8821a_txpwr_lmt_tbl;
extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8821a[];
extern const struct rtw_pwr_seq_cmd * const enter_lps_flow_8821a[];
extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8821a[];
extern const struct rtw_pwr_track_tbl rtw8821a_rtw_pwr_track_tbl;
#endif

View File

@ -0,0 +1,28 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2024 Realtek Corporation
*/
#include <linux/module.h>
#include <linux/usb.h>
#include "main.h"
#include "rtw8821a.h"
#include "usb.h"
static const struct usb_device_id rtw_8821au_id_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011e, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) },
{},
};
MODULE_DEVICE_TABLE(usb, rtw_8821au_id_table);
static struct usb_driver rtw_8821au_driver = {
.name = "rtw_8821au",
.id_table = rtw_8821au_id_table,
.probe = rtw_usb_probe,
.disconnect = rtw_usb_disconnect,
};
module_usb_driver(rtw_8821au_driver);
MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>");
MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821au/8811au driver");
MODULE_LICENSE("Dual BSD/GPL");

View File

@ -1581,13 +1581,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8821c = {
.n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8821c),
};
static const struct rtw_rfe_def rtw8821c_rfe_defs[] = {
[0] = RTW_DEF_RFE(8821c, 0, 0),
[2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
[4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
[6] = RTW_DEF_RFE(8821c, 0, 0),
};
static const struct rtw_hw_reg rtw8821c_dig[] = {
[0] = { .addr = 0xc50, .mask = 0x7f },
};
@ -1643,6 +1636,8 @@ static const struct rtw_prioq_addrs prioq_addrs_8821c = {
};
static const struct rtw_chip_ops rtw8821c_ops = {
.power_on = rtw_power_on,
.power_off = rtw_power_off,
.phy_set_param = rtw8821c_phy_set_param,
.read_efuse = rtw8821c_read_efuse,
.query_phy_status = query_phy_status,
@ -1897,7 +1892,7 @@ static const u8 rtw8821c_pwrtrk_2g_cck_a_p[] = {
5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9
};
static const struct rtw_pwr_track_tbl rtw8821c_rtw_pwr_track_tbl = {
static const struct rtw_pwr_track_tbl rtw8821c_pwr_track_type0_tbl = {
.pwrtrk_5gb_n[0] = rtw8821c_pwrtrk_5gb_n[0],
.pwrtrk_5gb_n[1] = rtw8821c_pwrtrk_5gb_n[1],
.pwrtrk_5gb_n[2] = rtw8821c_pwrtrk_5gb_n[2],
@ -1920,6 +1915,13 @@ static const struct rtw_pwr_track_tbl rtw8821c_rtw_pwr_track_tbl = {
.pwrtrk_2g_ccka_p = rtw8821c_pwrtrk_2g_cck_a_p,
};
static const struct rtw_rfe_def rtw8821c_rfe_defs[] = {
[0] = RTW_DEF_RFE(8821c, 0, 0, 0),
[2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 0, 2),
[4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 0, 2),
[6] = RTW_DEF_RFE(8821c, 0, 0, 0),
};
static const struct rtw_reg_domain coex_info_hw_regs_8821c[] = {
{0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32},
{0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32},
@ -1968,6 +1970,9 @@ const struct rtw_chip_info rtw8821c_hw_spec = {
.page_size = TX_PAGE_SIZE,
.dig_min = 0x1c,
.usb_tx_agg_desc_num = 3,
.hw_feature_report = true,
.c2h_ra_report_size = 7,
.old_datarate_fb_limit = false,
.ht_supported = true,
.vht_supported = true,
.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
@ -1989,7 +1994,6 @@ const struct rtw_chip_info rtw8821c_hw_spec = {
.rfe_defs = rtw8821c_rfe_defs,
.rfe_defs_size = ARRAY_SIZE(rtw8821c_rfe_defs),
.rx_ldpc = false,
.pwr_track_tbl = &rtw8821c_rtw_pwr_track_tbl,
.iqk_threshold = 8,
.bfer_su_max_num = 2,
.bfer_mu_max_num = 1,

View File

@ -214,19 +214,10 @@ extern const struct rtw_chip_info rtw8821c_hw_spec;
#define BIT_FEN_EN BIT(26)
#define REG_INIRTS_RATE_SEL 0x0480
#define REG_HTSTFWT 0x800
#define REG_RXPSEL 0x808
#define BIT_RX_PSEL_RST (BIT(28) | BIT(29))
#define REG_TXPSEL 0x80c
#define REG_RXCCAMSK 0x814
#define REG_CCASEL 0x82c
#define REG_PDMFTH 0x830
#define REG_CCA2ND 0x838
#define REG_L1WT 0x83c
#define REG_L1PKWT 0x840
#define REG_MRC 0x850
#define REG_CLKTRK 0x860
#define REG_ADCCLK 0x8ac
#define REG_ADC160 0x8c4
#define REG_ADC40 0x8c8
#define REG_CHFIR 0x8f0
#define REG_CDDTXP 0x93c
@ -234,14 +225,11 @@ extern const struct rtw_chip_info rtw8821c_hw_spec;
#define REG_ACBB0 0x948
#define REG_ACBBRXFIR 0x94c
#define REG_ACGG2TBL 0x958
#define REG_FAS 0x9a4
#define REG_RXSB 0xa00
#define REG_ADCINI 0xa04
#define REG_PWRTH 0xa08
#define REG_CCA_FLTR 0xa20
#define REG_TXSF2 0xa24
#define REG_TXSF6 0xa28
#define REG_FA_CCK 0xa5c
#define REG_RXDESC 0xa2c
#define REG_ENTXCCK 0xa80
#define BTG_LNA 0xfc84
@ -252,12 +240,8 @@ extern const struct rtw_chip_info rtw8821c_hw_spec;
#define REG_PWRTH2 0xaa8
#define REG_CSRATIO 0xaaa
#define REG_TXFILTER 0xaac
#define REG_CNTRST 0xb58
#define REG_AGCTR_A 0xc08
#define REG_TXSCALE_A 0xc1c
#define REG_TXDFIR 0xc20
#define REG_RXIGI_A 0xc50
#define REG_TXAGCIDX 0xc94
#define REG_TRSW 0xca0
#define REG_RFESEL0 0xcb0
#define REG_RFESEL8 0xcb4
@ -269,14 +253,6 @@ extern const struct rtw_chip_info rtw8821c_hw_spec;
#define B_WLA_SWITCH BIT(23)
#define REG_RFEINV 0xcbc
#define REG_AGCTR_B 0xe08
#define REG_RXIGI_B 0xe50
#define REG_CRC_CCK 0xf04
#define REG_CRC_OFDM 0xf14
#define REG_CRC_HT 0xf10
#define REG_CRC_VHT 0xf0c
#define REG_CCA_OFDM 0xf08
#define REG_FA_OFDM 0xf48
#define REG_CCA_CCK 0xfcc
#define REG_DMEM_CTRL 0x1080
#define BIT_WL_RST BIT(16)
#define REG_ANTWT 0x1904

View File

@ -2072,12 +2072,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8822b = {
.n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822b),
};
static const struct rtw_rfe_def rtw8822b_rfe_defs[] = {
[2] = RTW_DEF_RFE(8822b, 2, 2),
[3] = RTW_DEF_RFE(8822b, 3, 0),
[5] = RTW_DEF_RFE(8822b, 5, 5),
};
static const struct rtw_hw_reg rtw8822b_dig[] = {
[0] = { .addr = 0xc50, .mask = 0x7f },
[1] = { .addr = 0xe50, .mask = 0x7f },
@ -2132,6 +2126,8 @@ static const struct rtw_prioq_addrs prioq_addrs_8822b = {
};
static const struct rtw_chip_ops rtw8822b_ops = {
.power_on = rtw_power_on,
.power_off = rtw_power_off,
.phy_set_param = rtw8822b_phy_set_param,
.read_efuse = rtw8822b_read_efuse,
.query_phy_status = query_phy_status,
@ -2430,7 +2426,7 @@ static const u8 rtw8822b_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = {
10, 11, 11, 12, 12, 13, 13, 14, 14, 15
};
static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = {
static const struct rtw_pwr_track_tbl rtw8822b_pwr_track_type0_tbl = {
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1],
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2],
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3],
@ -2453,6 +2449,12 @@ static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = {
.pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p,
};
static const struct rtw_rfe_def rtw8822b_rfe_defs[] = {
[2] = RTW_DEF_RFE(8822b, 2, 2, 0),
[3] = RTW_DEF_RFE(8822b, 3, 0, 0),
[5] = RTW_DEF_RFE(8822b, 5, 5, 0),
};
static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = {
{0xcb0, MASKDWORD, RTW_REG_DOMAIN_MAC32},
{0xcb4, MASKDWORD, RTW_REG_DOMAIN_MAC32},
@ -2509,6 +2511,9 @@ const struct rtw_chip_info rtw8822b_hw_spec = {
.page_size = TX_PAGE_SIZE,
.dig_min = 0x1c,
.usb_tx_agg_desc_num = 3,
.hw_feature_report = true,
.c2h_ra_report_size = 7,
.old_datarate_fb_limit = false,
.ht_supported = true,
.vht_supported = true,
.lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
@ -2530,7 +2535,6 @@ const struct rtw_chip_info rtw8822b_hw_spec = {
.rf_tbl = {&rtw8822b_rf_a_tbl, &rtw8822b_rf_b_tbl},
.rfe_defs = rtw8822b_rfe_defs,
.rfe_defs_size = ARRAY_SIZE(rtw8822b_rfe_defs),
.pwr_track_tbl = &rtw8822b_rtw_pwr_track_tbl,
.iqk_threshold = 8,
.bfer_su_max_num = 2,
.bfer_mu_max_num = 1,

View File

@ -151,21 +151,12 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
#define RTW8822B_EDCCA_MAX 0x7f
#define RTW8822B_EDCCA_SRC_DEF 1
#define REG_HTSTFWT 0x800
#define REG_RXPSEL 0x808
#define BIT_RX_PSEL_RST (BIT(28) | BIT(29))
#define REG_TXPSEL 0x80c
#define REG_RXCCAMSK 0x814
#define REG_CCASEL 0x82c
#define REG_PDMFTH 0x830
#define REG_CCA2ND 0x838
#define REG_L1WT 0x83c
#define REG_L1PKWT 0x840
#define REG_MRC 0x850
#define REG_CLKTRK 0x860
#define REG_EDCCA_POW_MA 0x8a0
#define BIT_MA_LEVEL GENMASK(1, 0)
#define REG_ADCCLK 0x8ac
#define REG_ADC160 0x8c4
#define REG_ADC40 0x8c8
#define REG_EDCCA_DECISION 0x8dc
#define BIT_EDCCA_OPTION BIT(5)
@ -176,7 +167,6 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
#define REG_ACBB0 0x948
#define REG_ACBBRXFIR 0x94c
#define REG_ACGG2TBL 0x958
#define REG_RXSB 0xa00
#define REG_ADCINI 0xa04
#define REG_TXSF2 0xa24
#define REG_TXSF6 0xa28
@ -184,14 +174,12 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
#define REG_ENTXCCK 0xa80
#define REG_AGCTR_A 0xc08
#define REG_TXDFIR 0xc20
#define REG_RXIGI_A 0xc50
#define REG_TRSW 0xca0
#define REG_RFESEL0 0xcb0
#define REG_RFESEL8 0xcb4
#define REG_RFECTL 0xcb8
#define REG_RFEINV 0xcbc
#define REG_AGCTR_B 0xe08
#define REG_RXIGI_B 0xe50
#define REG_ANTWT 0x1904
#define REG_IQKFAILMSK 0x1bf0

View File

@ -4883,16 +4883,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8822c = {
.n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822c),
};
static const struct rtw_rfe_def rtw8822c_rfe_defs[] = {
[0] = RTW_DEF_RFE(8822c, 0, 0),
[1] = RTW_DEF_RFE(8822c, 0, 0),
[2] = RTW_DEF_RFE(8822c, 0, 0),
[3] = RTW_DEF_RFE(8822c, 0, 0),
[4] = RTW_DEF_RFE(8822c, 0, 0),
[5] = RTW_DEF_RFE(8822c, 0, 5),
[6] = RTW_DEF_RFE(8822c, 0, 0),
};
static const struct rtw_hw_reg rtw8822c_dig[] = {
[0] = { .addr = 0x1d70, .mask = 0x7f },
[1] = { .addr = 0x1d70, .mask = 0x7f00 },
@ -4947,6 +4937,8 @@ static const struct rtw_prioq_addrs prioq_addrs_8822c = {
};
static const struct rtw_chip_ops rtw8822c_ops = {
.power_on = rtw_power_on,
.power_off = rtw_power_off,
.phy_set_param = rtw8822c_phy_set_param,
.read_efuse = rtw8822c_read_efuse,
.query_phy_status = query_phy_status,
@ -5236,7 +5228,7 @@ static const u8 rtw8822c_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = {
18, 18, 19, 20, 21, 22, 23, 24, 24, 25
};
static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = {
static const struct rtw_pwr_track_tbl rtw8822c_pwr_track_type0_tbl = {
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1],
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2],
.pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3],
@ -5259,6 +5251,16 @@ static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = {
.pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p,
};
static const struct rtw_rfe_def rtw8822c_rfe_defs[] = {
[0] = RTW_DEF_RFE(8822c, 0, 0, 0),
[1] = RTW_DEF_RFE(8822c, 0, 0, 0),
[2] = RTW_DEF_RFE(8822c, 0, 0, 0),
[3] = RTW_DEF_RFE(8822c, 0, 0, 0),
[4] = RTW_DEF_RFE(8822c, 0, 0, 0),
[5] = RTW_DEF_RFE(8822c, 0, 5, 0),
[6] = RTW_DEF_RFE(8822c, 0, 0, 0),
};
static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
[EDCCA_TH_L2H_IDX] = {
{.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80
@ -5329,6 +5331,9 @@ const struct rtw_chip_info rtw8822c_hw_spec = {
.page_size = TX_PAGE_SIZE,
.dig_min = 0x20,
.usb_tx_agg_desc_num = 3,
.hw_feature_report = true,
.c2h_ra_report_size = 7,
.old_datarate_fb_limit = false,
.default_1ss_tx_path = BB_PATH_A,
.path_div_supported = true,
.ht_supported = true,
@ -5355,7 +5360,6 @@ const struct rtw_chip_info rtw8822c_hw_spec = {
.rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs),
.en_dis_dpd = true,
.dpd_ratemask = DIS_DPD_RATEALL,
.pwr_track_tbl = &rtw8822c_rtw_pwr_track_tbl,
.iqk_threshold = 8,
.lck_threshold = 8,
.bfer_su_max_num = 2,

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,175 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2024 Realtek Corporation
*/
#ifndef __RTW88XXA_H__
#define __RTW88XXA_H__
#include <asm/byteorder.h>
#include "reg.h"
struct rtw8821au_efuse {
u8 res4[48]; /* 0xd0 */
u8 vid[2]; /* 0x100 */
u8 pid[2];
u8 res8[3];
u8 mac_addr[ETH_ALEN]; /* 0x107 */
u8 res9[243];
} __packed;
struct rtw8812au_efuse {
u8 vid[2]; /* 0xd0 */
u8 pid[2]; /* 0xd2 */
u8 res0[3];
u8 mac_addr[ETH_ALEN]; /* 0xd7 */
u8 res1[291];
} __packed;
struct rtw88xxa_efuse {
__le16 rtl_id;
u8 res0[6]; /* 0x02 */
u8 usb_mode; /* 0x08 */
u8 res1[7]; /* 0x09 */
/* power index for four RF paths */
struct rtw_txpwr_idx txpwr_idx_table[4];
u8 channel_plan; /* 0xb8 */
u8 xtal_k;
u8 thermal_meter;
u8 iqk_lck;
u8 pa_type; /* 0xbc */
u8 lna_type_2g; /* 0xbd */
u8 res2;
u8 lna_type_5g; /* 0xbf */
u8 res3;
u8 rf_board_option; /* 0xc1 */
u8 rf_feature_option;
u8 rf_bt_setting;
u8 eeprom_version;
u8 eeprom_customer_id; /* 0xc5 */
u8 tx_bb_swing_setting_2g;
u8 tx_bb_swing_setting_5g;
u8 tx_pwr_calibrate_rate;
u8 rf_antenna_option; /* 0xc9 */
u8 rfe_option;
u8 country_code[2];
u8 res4[3];
union {
struct rtw8821au_efuse rtw8821au;
struct rtw8812au_efuse rtw8812au;
};
} __packed;
static_assert(sizeof(struct rtw88xxa_efuse) == 512);
#define WLAN_BCN_DMA_TIME 0x02
#define WLAN_TBTT_PROHIBIT 0x04
#define WLAN_TBTT_HOLD_TIME 0x064
#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\
(WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP))
struct rtw_jaguar_phy_status_rpt {
__le32 w0;
__le32 w1;
__le32 w2;
__le32 w3;
__le32 w4;
__le32 w5;
__le32 w6;
} __packed;
#define RTW_JGRPHY_W0_GAIN_A GENMASK(6, 0)
#define RTW_JGRPHY_W0_TRSW_A BIT(7)
#define RTW_JGRPHY_W0_GAIN_B GENMASK(14, 8)
#define RTW_JGRPHY_W0_TRSW_B BIT(15)
#define RTW_JGRPHY_W0_CHL_NUM GENMASK(25, 16)
#define RTW_JGRPHY_W0_SUB_CHNL GENMASK(29, 26)
#define RTW_JGRPHY_W0_R_RFMOD GENMASK(31, 30)
/* CCK: */
#define RTW_JGRPHY_W1_SIG_QUAL GENMASK(7, 0)
#define RTW_JGRPHY_W1_AGC_RPT_VGA_IDX GENMASK(12, 8)
#define RTW_JGRPHY_W1_AGC_RPT_LNA_IDX GENMASK(15, 13)
#define RTW_JGRPHY_W1_BB_POWER GENMASK(23, 16)
/* OFDM: */
#define RTW_JGRPHY_W1_PWDB_ALL GENMASK(7, 0)
#define RTW_JGRPHY_W1_CFO_SHORT_A GENMASK(15, 8) /* s8 */
#define RTW_JGRPHY_W1_CFO_SHORT_B GENMASK(23, 16) /* s8 */
#define RTW_JGRPHY_W1_BT_RF_CH_MSB GENMASK(31, 30)
#define RTW_JGRPHY_W2_ANT_DIV_SW_A BIT(0)
#define RTW_JGRPHY_W2_ANT_DIV_SW_B BIT(1)
#define RTW_JGRPHY_W2_BT_RF_CH_LSB GENMASK(7, 2)
#define RTW_JGRPHY_W2_CFO_TAIL_A GENMASK(15, 8) /* s8 */
#define RTW_JGRPHY_W2_CFO_TAIL_B GENMASK(23, 16) /* s8 */
#define RTW_JGRPHY_W2_PCTS_MSK_RPT_0 GENMASK(31, 24)
#define RTW_JGRPHY_W3_PCTS_MSK_RPT_1 GENMASK(7, 0)
/* Stream 1 and 2 RX EVM: */
#define RTW_JGRPHY_W3_RXEVM_1 GENMASK(15, 8) /* s8 */
#define RTW_JGRPHY_W3_RXEVM_2 GENMASK(23, 16) /* s8 */
#define RTW_JGRPHY_W3_RXSNR_A GENMASK(31, 24) /* s8 */
#define RTW_JGRPHY_W4_RXSNR_B GENMASK(7, 0) /* s8 */
#define RTW_JGRPHY_W4_PCTS_MSK_RPT_2 GENMASK(21, 8)
#define RTW_JGRPHY_W4_PCTS_RPT_VALID BIT(22)
#define RTW_JGRPHY_W4_RXEVM_3 GENMASK(31, 24) /* s8 */
#define RTW_JGRPHY_W5_RXEVM_4 GENMASK(7, 0) /* s8 */
/* 8812a, stream 1 and 2 CSI: */
#define RTW_JGRPHY_W5_CSI_CURRENT_1 GENMASK(15, 8)
#define RTW_JGRPHY_W5_CSI_CURRENT_2 GENMASK(23, 16)
/* 8814a: */
#define RTW_JGRPHY_W5_RXSNR_C GENMASK(15, 8) /* s8 */
#define RTW_JGRPHY_W5_RXSNR_D GENMASK(23, 16) /* s8 */
#define RTW_JGRPHY_W5_GAIN_C GENMASK(30, 24)
#define RTW_JGRPHY_W5_TRSW_C BIT(31)
#define RTW_JGRPHY_W6_GAIN_D GENMASK(6, 0)
#define RTW_JGRPHY_W6_TRSW_D BIT(7)
#define RTW_JGRPHY_W6_SIGEVM GENMASK(15, 8) /* s8 */
#define RTW_JGRPHY_W6_ANTIDX_ANTC GENMASK(18, 16)
#define RTW_JGRPHY_W6_ANTIDX_ANTD GENMASK(21, 19)
#define RTW_JGRPHY_W6_DPDT_CTRL_KEEP BIT(22)
#define RTW_JGRPHY_W6_GNT_BT_KEEP BIT(23)
#define RTW_JGRPHY_W6_ANTIDX_ANTA GENMASK(26, 24)
#define RTW_JGRPHY_W6_ANTIDX_ANTB GENMASK(29, 27)
#define RTW_JGRPHY_W6_HW_ANTSW_OCCUR GENMASK(31, 30)
#define RF18_BW_MASK (BIT(11) | BIT(10))
void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on);
int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map);
void rtw88xxa_power_off(struct rtw_dev *rtwdev,
const struct rtw_pwr_seq_cmd *const *enter_lps_flow);
int rtw88xxa_power_on(struct rtw_dev *rtwdev);
u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev,
enum rtw_rf_path rf_path, u32 addr, u32 mask);
void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
u8 primary_chan_idx);
void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
struct rtw_rx_pkt_stat *pkt_stat,
s8 (*cck_rx_pwr)(u8 lna_idx, u8 vga_idx));
void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev);
void rtw88xxa_false_alarm_statistics(struct rtw_dev *rtwdev);
void rtw88xxa_iqk_backup_mac_bb(struct rtw_dev *rtwdev,
u32 *macbb_backup,
const u32 *backup_macbb_reg,
u32 macbb_num);
void rtw88xxa_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup,
const u32 *backup_afe_reg, u32 afe_num);
void rtw88xxa_iqk_restore_mac_bb(struct rtw_dev *rtwdev,
u32 *macbb_backup,
const u32 *backup_macbb_reg,
u32 macbb_num);
void rtw88xxa_iqk_configure_mac(struct rtw_dev *rtwdev);
bool rtw88xxa_iqk_finish(int average, int threshold,
int *x_temp, int *y_temp, int *x, int *y,
bool break_inner, bool break_outer);
void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev,
void (*do_lck)(struct rtw_dev *rtwdev),
void (*do_iqk)(struct rtw_dev *rtwdev));
void rtw88xxa_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl);
#endif

View File

@ -234,10 +234,14 @@ static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
else
rx_status->bw = RATE_INFO_BW_20;
rx_status->signal = pkt_stat->signal_power;
for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
rx_status->chains |= BIT(path);
rx_status->chain_signal[path] = pkt_stat->rx_power[path];
if (pkt_stat->phy_status) {
rx_status->signal = pkt_stat->signal_power;
for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
rx_status->chains |= BIT(path);
rx_status->chain_signal[path] = pkt_stat->rx_power[path];
}
} else {
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
}
rtw_rx_addr_match(rtwdev, pkt_stat, hdr);

View File

@ -864,7 +864,7 @@ static void rtw_sdio_tx_skb_prepare(struct rtw_dev *rtwdev,
pkt_info->qsel = rtw_sdio_get_tx_qsel(rtwdev, skb, queue);
rtw_tx_fill_tx_desc(pkt_info, skb);
rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc);
}

View File

@ -32,7 +32,8 @@ void rtw_tx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
}
}
void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
{
struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data;
bool more_data = false;
@ -67,6 +68,9 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE);
if (rtwdev->chip->old_datarate_fb_limit)
tx_desc->w4 |= le32_encode_bits(0x1f, RTW_TX_DESC_W4_DATARATE_FB_LIMIT);
tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) |
le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) |
le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) |

View File

@ -44,6 +44,7 @@ struct rtw_tx_desc {
#define RTW_TX_DESC_W3_NAVUSEHDR BIT(15)
#define RTW_TX_DESC_W3_MAX_AGG_NUM GENMASK(21, 17)
#define RTW_TX_DESC_W4_DATARATE GENMASK(6, 0)
#define RTW_TX_DESC_W4_DATARATE_FB_LIMIT GENMASK(12, 8)
#define RTW_TX_DESC_W4_RTSRATE GENMASK(28, 24)
#define RTW_TX_DESC_W5_DATA_SHORT BIT(4)
#define RTW_TX_DESC_W5_DATA_BW GENMASK(6, 5)
@ -94,7 +95,8 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
struct ieee80211_sta *sta,
struct sk_buff *skb);
void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn);
void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src);
void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,

View File

@ -458,7 +458,7 @@ static int rtw_usb_write_data(struct rtw_dev *rtwdev,
skb_put_data(skb, buf, size);
skb_push(skb, chip->tx_pkt_desc_sz);
memset(skb->data, 0, chip->tx_pkt_desc_sz);
rtw_tx_fill_tx_desc(pkt_info, skb);
rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
ret = rtw_usb_write_port(rtwdev, qsel, skb,
@ -478,6 +478,7 @@ static int rtw_usb_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf,
pkt_info.tx_pkt_size = size;
pkt_info.qsel = TX_DESC_QSEL_BEACON;
pkt_info.offset = chip->tx_pkt_desc_sz;
pkt_info.ls = true;
return rtw_usb_write_data(rtwdev, &pkt_info, buf);
}
@ -525,7 +526,7 @@ static int rtw_usb_tx_write(struct rtw_dev *rtwdev,
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
ep = qsel_to_ep(rtwusb, pkt_info->qsel);
rtw_tx_fill_tx_desc(pkt_info, skb);
rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
tx_data = rtw_usb_get_tx_data(skb);
tx_data->sn = pkt_info->sn;

View File

@ -961,16 +961,24 @@ void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_dctlinfo_ud_v2 *h2c)
{
struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link);
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link->rtwvif);
struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_addr_cam_entry *addr_cam =
rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
bool is_mld = sta ? sta->mlo : ieee80211_vif_is_mld(vif);
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv;
u8 *mld_sma, *mld_tma, *mld_bssid;
h2c->c0 = le32_encode_bits(rtwsta_link ? rtwsta_link->mac_id :
rtwvif_link->mac_id,
DCTLINFO_V2_C0_MACID) |
le32_encode_bits(1, DCTLINFO_V2_C0_OP);
h2c->w2 = le32_encode_bits(is_mld, DCTLINFO_V2_W2_IS_MLD);
h2c->m2 = cpu_to_le32(DCTLINFO_V2_W2_IS_MLD);
h2c->w4 = le32_encode_bits(addr_cam->sec_ent_keyid[0],
DCTLINFO_V2_W4_SEC_ENT0_KEYID) |
le32_encode_bits(addr_cam->sec_ent_keyid[1],
@ -1036,4 +1044,47 @@ void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
DCTLINFO_V2_W4_SEC_KEY_ID);
h2c->m4 |= cpu_to_le32(DCTLINFO_V2_W4_SEC_KEY_ID);
}
if (!is_mld)
return;
if (rtwvif_link->net_type == RTW89_NET_TYPE_INFRA) {
mld_sma = rtwvif->mac_addr;
mld_tma = vif->cfg.ap_addr;
mld_bssid = vif->cfg.ap_addr;
} else if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE && sta) {
mld_sma = rtwvif->mac_addr;
mld_tma = sta->addr;
mld_bssid = rtwvif->mac_addr;
} else {
return;
}
h2c->w8 = le32_encode_bits(mld_sma[0], DCTLINFO_V2_W8_MLD_SMA_0) |
le32_encode_bits(mld_sma[1], DCTLINFO_V2_W8_MLD_SMA_1) |
le32_encode_bits(mld_sma[2], DCTLINFO_V2_W8_MLD_SMA_2) |
le32_encode_bits(mld_sma[3], DCTLINFO_V2_W8_MLD_SMA_3);
h2c->m8 = cpu_to_le32(DCTLINFO_V2_W8_ALL);
h2c->w9 = le32_encode_bits(mld_sma[4], DCTLINFO_V2_W9_MLD_SMA_4) |
le32_encode_bits(mld_sma[5], DCTLINFO_V2_W9_MLD_SMA_5) |
le32_encode_bits(mld_tma[0], DCTLINFO_V2_W9_MLD_TMA_0) |
le32_encode_bits(mld_tma[1], DCTLINFO_V2_W9_MLD_TMA_1);
h2c->m9 = cpu_to_le32(DCTLINFO_V2_W9_ALL);
h2c->w10 = le32_encode_bits(mld_tma[2], DCTLINFO_V2_W10_MLD_TMA_2) |
le32_encode_bits(mld_tma[3], DCTLINFO_V2_W10_MLD_TMA_3) |
le32_encode_bits(mld_tma[4], DCTLINFO_V2_W10_MLD_TMA_4) |
le32_encode_bits(mld_tma[5], DCTLINFO_V2_W10_MLD_TMA_5);
h2c->m10 = cpu_to_le32(DCTLINFO_V2_W10_ALL);
h2c->w11 = le32_encode_bits(mld_bssid[0], DCTLINFO_V2_W11_MLD_BSSID_0) |
le32_encode_bits(mld_bssid[1], DCTLINFO_V2_W11_MLD_BSSID_1) |
le32_encode_bits(mld_bssid[2], DCTLINFO_V2_W11_MLD_BSSID_2) |
le32_encode_bits(mld_bssid[3], DCTLINFO_V2_W11_MLD_BSSID_3);
h2c->m11 = cpu_to_le32(DCTLINFO_V2_W11_ALL);
h2c->w12 = le32_encode_bits(mld_bssid[4], DCTLINFO_V2_W12_MLD_BSSID_4) |
le32_encode_bits(mld_bssid[5], DCTLINFO_V2_W12_MLD_BSSID_5);
h2c->m12 = cpu_to_le32(DCTLINFO_V2_W12_ALL);
}

View File

@ -514,16 +514,28 @@ struct rtw89_h2c_dctlinfo_ud_v2 {
#define DCTLINFO_V2_W7_SEC_ENT7 GENMASK(23, 16)
#define DCTLINFO_V2_W7_SEC_ENT8 GENMASK(31, 24)
#define DCTLINFO_V2_W7_ALL GENMASK(31, 0)
#define DCTLINFO_V2_W8_MLD_SMA_L_V1 GENMASK(31, 0)
#define DCTLINFO_V2_W8_MLD_SMA_0 GENMASK(7, 0)
#define DCTLINFO_V2_W8_MLD_SMA_1 GENMASK(15, 8)
#define DCTLINFO_V2_W8_MLD_SMA_2 GENMASK(23, 16)
#define DCTLINFO_V2_W8_MLD_SMA_3 GENMASK(31, 24)
#define DCTLINFO_V2_W8_ALL GENMASK(31, 0)
#define DCTLINFO_V2_W9_MLD_SMA_H_V1 GENMASK(15, 0)
#define DCTLINFO_V2_W9_MLD_TMA_L_V1 GENMASK(31, 16)
#define DCTLINFO_V2_W9_MLD_SMA_4 GENMASK(7, 0)
#define DCTLINFO_V2_W9_MLD_SMA_5 GENMASK(15, 8)
#define DCTLINFO_V2_W9_MLD_TMA_0 GENMASK(23, 16)
#define DCTLINFO_V2_W9_MLD_TMA_1 GENMASK(31, 24)
#define DCTLINFO_V2_W9_ALL GENMASK(31, 0)
#define DCTLINFO_V2_W10_MLD_TMA_H_V1 GENMASK(31, 0)
#define DCTLINFO_V2_W10_MLD_TMA_2 GENMASK(7, 0)
#define DCTLINFO_V2_W10_MLD_TMA_3 GENMASK(15, 8)
#define DCTLINFO_V2_W10_MLD_TMA_4 GENMASK(23, 16)
#define DCTLINFO_V2_W10_MLD_TMA_5 GENMASK(31, 24)
#define DCTLINFO_V2_W10_ALL GENMASK(31, 0)
#define DCTLINFO_V2_W11_MLD_TA_BSSID_L_V1 GENMASK(31, 0)
#define DCTLINFO_V2_W11_MLD_BSSID_0 GENMASK(7, 0)
#define DCTLINFO_V2_W11_MLD_BSSID_1 GENMASK(15, 8)
#define DCTLINFO_V2_W11_MLD_BSSID_2 GENMASK(23, 16)
#define DCTLINFO_V2_W11_MLD_BSSID_3 GENMASK(31, 24)
#define DCTLINFO_V2_W11_ALL GENMASK(31, 0)
#define DCTLINFO_V2_W12_MLD_TA_BSSID_H_V1 GENMASK(15, 0)
#define DCTLINFO_V2_W12_MLD_BSSID_4 GENMASK(7, 0)
#define DCTLINFO_V2_W12_MLD_BSSID_5 GENMASK(15, 8)
#define DCTLINFO_V2_W12_ALL GENMASK(15, 0)
int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);

View File

@ -10,6 +10,10 @@
#include "ps.h"
#include "util.h"
static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx idx1,
enum rtw89_chanctx_idx idx2);
static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band,
u8 center_chan)
{
@ -226,11 +230,15 @@ static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev)
void rtw89_entity_init(struct rtw89_dev *rtwdev)
{
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
hal->entity_pause = false;
bitmap_zero(hal->entity_map, NUM_OF_RTW89_CHANCTX);
bitmap_zero(hal->changes, NUM_OF_RTW89_CHANCTX_CHANGES);
atomic_set(&hal->roc_chanctx_idx, RTW89_CHANCTX_IDLE);
INIT_LIST_HEAD(&mgnt->active_list);
rtw89_config_default_chandef(rtwdev);
}
@ -272,6 +280,142 @@ static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev,
}
}
static void rtw89_normalize_link_chanctx(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_vif_link *cur;
if (unlikely(!rtwvif_link->chanctx_assigned))
return;
cur = rtw89_vif_get_link_inst(rtwvif, 0);
if (!cur || !cur->chanctx_assigned)
return;
if (cur == rtwvif_link)
return;
rtw89_swap_chanctx(rtwdev, rtwvif_link->chanctx_idx, cur->chanctx_idx);
}
const struct rtw89_chan *__rtw89_mgnt_chan_get(struct rtw89_dev *rtwdev,
const char *caller_message,
u8 link_index)
{
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
enum rtw89_chanctx_idx chanctx_idx;
enum rtw89_chanctx_idx roc_idx;
enum rtw89_entity_mode mode;
u8 role_index;
lockdep_assert_held(&rtwdev->mutex);
if (unlikely(link_index >= __RTW89_MLD_MAX_LINK_NUM)) {
WARN(1, "link index %u is invalid (max link inst num: %d)\n",
link_index, __RTW89_MLD_MAX_LINK_NUM);
goto dflt;
}
mode = rtw89_get_entity_mode(rtwdev);
switch (mode) {
case RTW89_ENTITY_MODE_SCC_OR_SMLD:
case RTW89_ENTITY_MODE_MCC:
role_index = 0;
break;
case RTW89_ENTITY_MODE_MCC_PREPARE:
role_index = 1;
break;
default:
WARN(1, "Invalid ent mode: %d\n", mode);
goto dflt;
}
chanctx_idx = mgnt->chanctx_tbl[role_index][link_index];
if (chanctx_idx == RTW89_CHANCTX_IDLE)
goto dflt;
roc_idx = atomic_read(&hal->roc_chanctx_idx);
if (roc_idx != RTW89_CHANCTX_IDLE) {
/* ROC is ongoing (given ROC runs on RTW89_ROC_BY_LINK_INDEX).
* If @link_index is the same as RTW89_ROC_BY_LINK_INDEX, get
* the ongoing ROC chanctx.
*/
if (link_index == RTW89_ROC_BY_LINK_INDEX)
chanctx_idx = roc_idx;
}
return rtw89_chan_get(rtwdev, chanctx_idx);
dflt:
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"%s (%s): prefetch NULL on link index %u\n",
__func__, caller_message ?: "", link_index);
return rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
}
EXPORT_SYMBOL(__rtw89_mgnt_chan_get);
static void rtw89_entity_recalc_mgnt_roles(struct rtw89_dev *rtwdev)
{
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
struct rtw89_vif_link *link;
struct rtw89_vif *role;
u8 pos = 0;
int i, j;
lockdep_assert_held(&rtwdev->mutex);
for (i = 0; i < RTW89_MAX_INTERFACE_NUM; i++)
mgnt->active_roles[i] = NULL;
for (i = 0; i < RTW89_MAX_INTERFACE_NUM; i++) {
for (j = 0; j < __RTW89_MLD_MAX_LINK_NUM; j++)
mgnt->chanctx_tbl[i][j] = RTW89_CHANCTX_IDLE;
}
/* To be consistent with legacy behavior, expect the first active role
* which uses RTW89_CHANCTX_0 to put at position 0, and make its first
* link instance take RTW89_CHANCTX_0. (normalizing)
*/
list_for_each_entry(role, &mgnt->active_list, mgnt_entry) {
for (i = 0; i < role->links_inst_valid_num; i++) {
link = rtw89_vif_get_link_inst(role, i);
if (!link || !link->chanctx_assigned)
continue;
if (link->chanctx_idx == RTW89_CHANCTX_0) {
rtw89_normalize_link_chanctx(rtwdev, link);
list_del(&role->mgnt_entry);
list_add(&role->mgnt_entry, &mgnt->active_list);
break;
}
}
}
list_for_each_entry(role, &mgnt->active_list, mgnt_entry) {
if (unlikely(pos >= RTW89_MAX_INTERFACE_NUM)) {
rtw89_warn(rtwdev,
"%s: active roles are over max iface num\n",
__func__);
break;
}
for (i = 0; i < role->links_inst_valid_num; i++) {
link = rtw89_vif_get_link_inst(role, i);
if (!link || !link->chanctx_assigned)
continue;
mgnt->chanctx_tbl[pos][i] = link->chanctx_idx;
}
mgnt->active_roles[pos++] = role;
}
}
enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
{
DECLARE_BITMAP(recalc_map, NUM_OF_RTW89_CHANCTX) = {};
@ -298,9 +442,14 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
set_bit(RTW89_CHANCTX_0, recalc_map);
fallthrough;
case 1:
mode = RTW89_ENTITY_MODE_SCC;
mode = RTW89_ENTITY_MODE_SCC_OR_SMLD;
break;
case 2 ... NUM_OF_RTW89_CHANCTX:
if (w.active_roles == 1) {
mode = RTW89_ENTITY_MODE_SCC_OR_SMLD;
break;
}
if (w.active_roles != NUM_OF_RTW89_MCC_ROLES) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"unhandled ent: %d chanctxs %d roles\n",
@ -327,6 +476,8 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
rtw89_assign_entity_chan(rtwdev, idx, &chan);
}
rtw89_entity_recalc_mgnt_roles(rtwdev);
if (hal->entity_pause)
return rtw89_get_entity_mode(rtwdev);
@ -716,6 +867,7 @@ struct rtw89_mcc_fill_role_selector {
};
static_assert((u8)NUM_OF_RTW89_CHANCTX >= NUM_OF_RTW89_MCC_ROLES);
static_assert(RTW89_MAX_INTERFACE_NUM >= NUM_OF_RTW89_MCC_ROLES);
static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *mcc_role,
@ -745,14 +897,18 @@ static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev)
{
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
struct rtw89_mcc_fill_role_selector sel = {};
struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
int ret;
int i;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
if (!rtw89_vif_is_active_role(rtwvif))
continue;
for (i = 0; i < NUM_OF_RTW89_MCC_ROLES; i++) {
rtwvif = mgnt->active_roles[i];
if (!rtwvif)
break;
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
if (unlikely(!rtwvif_link)) {
@ -760,14 +916,7 @@ static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev)
continue;
}
if (sel.bind_vif[rtwvif_link->chanctx_idx]) {
rtw89_warn(rtwdev,
"MCC skip extra vif <macid %d> on chanctx[%d]\n",
rtwvif_link->mac_id, rtwvif_link->chanctx_idx);
continue;
}
sel.bind_vif[rtwvif_link->chanctx_idx] = rtwvif_link;
sel.bind_vif[i] = rtwvif_link;
}
ret = rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_fill_role_iterator, &sel);
@ -2501,12 +2650,18 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
struct rtw89_entity_weight w = {};
rtwvif_link->chanctx_idx = cfg->idx;
rtwvif_link->chanctx_assigned = true;
cfg->ref_count++;
if (list_empty(&rtwvif->mgnt_entry))
list_add_tail(&rtwvif->mgnt_entry, &mgnt->active_list);
if (cfg->idx == RTW89_CHANCTX_0)
goto out;
@ -2526,6 +2681,7 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_hal *hal = &rtwdev->hal;
enum rtw89_chanctx_idx roll;
enum rtw89_entity_mode cur;
@ -2536,6 +2692,9 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
rtwvif_link->chanctx_assigned = false;
cfg->ref_count--;
if (!rtw89_vif_is_active_role(rtwvif))
list_del_init(&rtwvif->mgnt_entry);
if (cfg->ref_count != 0)
goto out;

View File

@ -101,6 +101,14 @@ void rtw89_chanctx_track(struct rtw89_dev *rtwdev);
void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_pause_reasons rsn);
void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev);
const struct rtw89_chan *__rtw89_mgnt_chan_get(struct rtw89_dev *rtwdev,
const char *caller_message,
u8 link_index);
#define rtw89_mgnt_chan_get(rtwdev, link_index) \
__rtw89_mgnt_chan_get(rtwdev, __func__, link_index)
int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx);
void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,

View File

@ -2507,6 +2507,8 @@ static void btc_fw_set_monreg(struct rtw89_dev *rtwdev)
if (ver->fcxmreg == 7) {
sz = struct_size(v7, regs, n);
v7 = kmalloc(sz, GFP_KERNEL);
if (!v7)
return;
v7->type = RPT_EN_MREG;
v7->fver = ver->fcxmreg;
v7->len = n;
@ -2521,6 +2523,8 @@ static void btc_fw_set_monreg(struct rtw89_dev *rtwdev)
} else {
sz = struct_size(v1, regs, n);
v1 = kmalloc(sz, GFP_KERNEL);
if (!v1)
return;
v1->fver = ver->fcxmreg;
v1->reg_num = n;
memcpy(v1->regs, chip->mon_reg, flex_array_size(v1, regs, n));
@ -3695,6 +3699,7 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_fbtc_tdma *t = &dm->tdma;
struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &btc->cx.wl.role_info_v1;
struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
struct rtw89_btc_bt_hid_desc *hid = &btc->cx.bt.link_info.hid_desc;
struct rtw89_btc_bt_hfp_desc *hfp = &btc->cx.bt.link_info.hfp_desc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
@ -3853,7 +3858,10 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype);
break;
case BTC_CXP_OFFE_2GBWMIXB:
_slot_set(btc, CXST_E2G, 0, 0xea5a5555, SLOT_MIX);
if (a2dp->exist)
_slot_set(btc, CXST_E2G, 0, cxtbl[2], SLOT_MIX);
else
_slot_set(btc, CXST_E2G, 0, tbl_w1, SLOT_MIX);
_slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur,
s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype);
break;

View File

@ -192,13 +192,13 @@ static const struct ieee80211_iface_combination rtw89_iface_combs[] = {
{
.limits = rtw89_iface_limits,
.n_limits = ARRAY_SIZE(rtw89_iface_limits),
.max_interfaces = 2,
.max_interfaces = RTW89_MAX_INTERFACE_NUM,
.num_different_channels = 1,
},
{
.limits = rtw89_iface_limits_mcc,
.n_limits = ARRAY_SIZE(rtw89_iface_limits_mcc),
.max_interfaces = 2,
.max_interfaces = RTW89_MAX_INTERFACE_NUM,
.num_different_channels = 2,
},
};
@ -341,84 +341,47 @@ void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
rtw89_chan_create(chan, center_chan, channel->hw_value, band, bandwidth);
}
void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
static void __rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
struct rtw89_hal *hal = &rtwdev->hal;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_chan *chan;
enum rtw89_chanctx_idx chanctx_idx;
enum rtw89_chanctx_idx roc_idx;
enum rtw89_phy_idx phy_idx;
enum rtw89_entity_mode mode;
bool entity_active;
mode = rtw89_get_entity_mode(rtwdev);
switch (mode) {
case RTW89_ENTITY_MODE_SCC:
case RTW89_ENTITY_MODE_MCC:
chanctx_idx = RTW89_CHANCTX_0;
break;
case RTW89_ENTITY_MODE_MCC_PREPARE:
chanctx_idx = RTW89_CHANCTX_1;
break;
default:
WARN(1, "Invalid ent mode: %d\n", mode);
return;
}
roc_idx = atomic_read(&hal->roc_chanctx_idx);
if (roc_idx != RTW89_CHANCTX_IDLE)
chanctx_idx = roc_idx;
phy_idx = RTW89_PHY_0;
entity_active = rtw89_get_entity_state(rtwdev, phy_idx);
if (!entity_active)
return;
chan = rtw89_chan_get(rtwdev, chanctx_idx);
chip->ops->set_txpwr(rtwdev, chan, phy_idx);
}
int rtw89_set_channel(struct rtw89_dev *rtwdev)
void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
{
const struct rtw89_chan *chan;
chan = rtw89_mgnt_chan_get(rtwdev, 0);
__rtw89_core_set_chip_txpwr(rtwdev, chan, RTW89_PHY_0);
if (!rtwdev->support_mlo)
return;
chan = rtw89_mgnt_chan_get(rtwdev, 1);
__rtw89_core_set_chip_txpwr(rtwdev, chan, RTW89_PHY_1);
}
static void __rtw89_set_channel(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_mac_idx mac_idx,
enum rtw89_phy_idx phy_idx)
{
struct rtw89_hal *hal = &rtwdev->hal;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_chan_rcd *chan_rcd;
const struct rtw89_chan *chan;
enum rtw89_chanctx_idx chanctx_idx;
enum rtw89_chanctx_idx roc_idx;
enum rtw89_mac_idx mac_idx;
enum rtw89_phy_idx phy_idx;
struct rtw89_channel_help_params bak;
enum rtw89_entity_mode mode;
bool entity_active;
mode = rtw89_entity_recalc(rtwdev);
switch (mode) {
case RTW89_ENTITY_MODE_SCC:
case RTW89_ENTITY_MODE_MCC:
chanctx_idx = RTW89_CHANCTX_0;
break;
case RTW89_ENTITY_MODE_MCC_PREPARE:
chanctx_idx = RTW89_CHANCTX_1;
break;
default:
WARN(1, "Invalid ent mode: %d\n", mode);
return -EINVAL;
}
roc_idx = atomic_read(&hal->roc_chanctx_idx);
if (roc_idx != RTW89_CHANCTX_IDLE)
chanctx_idx = roc_idx;
mac_idx = RTW89_MAC_0;
phy_idx = RTW89_PHY_0;
entity_active = rtw89_get_entity_state(rtwdev, phy_idx);
chan = rtw89_chan_get(rtwdev, chanctx_idx);
chan_rcd = rtw89_chan_rcd_get(rtwdev, chanctx_idx);
chan_rcd = rtw89_chan_rcd_get_by_chan(chan);
rtw89_chip_set_channel_prepare(rtwdev, &bak, chan, mac_idx, phy_idx);
@ -434,6 +397,28 @@ int rtw89_set_channel(struct rtw89_dev *rtwdev)
}
rtw89_set_entity_state(rtwdev, phy_idx, true);
}
int rtw89_set_channel(struct rtw89_dev *rtwdev)
{
const struct rtw89_chan *chan;
enum rtw89_entity_mode mode;
mode = rtw89_entity_recalc(rtwdev);
if (mode < 0 || mode >= NUM_OF_RTW89_ENTITY_MODE) {
WARN(1, "Invalid ent mode: %d\n", mode);
return -EINVAL;
}
chan = rtw89_mgnt_chan_get(rtwdev, 0);
__rtw89_set_channel(rtwdev, chan, RTW89_MAC_0, RTW89_PHY_0);
if (!rtwdev->support_mlo)
return 0;
chan = rtw89_mgnt_chan_get(rtwdev, 1);
__rtw89_set_channel(rtwdev, chan, RTW89_MAC_1, RTW89_PHY_1);
return 0;
}
@ -939,8 +924,10 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev,
struct sk_buff *skb = tx_req->skb;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (void *)skb->data;
struct rtw89_addr_cam_entry *addr_cam;
enum rtw89_core_tx_type tx_type;
enum btc_pkt_type pkt_type;
bool upd_wlan_hdr = false;
bool is_bmc;
u16 seq;
@ -948,6 +935,11 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev,
if (tx_req->tx_type != RTW89_CORE_TX_TYPE_FWCMD) {
tx_type = rtw89_core_get_tx_type(rtwdev, skb);
tx_req->tx_type = tx_type;
addr_cam = rtw89_get_addr_cam_of(tx_req->rtwvif_link,
tx_req->rtwsta_link);
if (addr_cam->valid)
upd_wlan_hdr = true;
}
is_bmc = (is_broadcast_ether_addr(hdr->addr1) ||
is_multicast_ether_addr(hdr->addr1));
@ -957,6 +949,7 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev,
desc_info->is_bmc = is_bmc;
desc_info->wd_page = true;
desc_info->hiq = info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM;
desc_info->upd_wlan_hdr = upd_wlan_hdr;
switch (tx_req->tx_type) {
case RTW89_CORE_TX_TYPE_MGMT:
@ -1355,6 +1348,13 @@ static __le32 rtw89_build_txwd_body5_v2(struct rtw89_tx_desc_info *desc_info)
return cpu_to_le32(dword);
}
static __le32 rtw89_build_txwd_body6_v2(struct rtw89_tx_desc_info *desc_info)
{
u32 dword = FIELD_PREP(BE_TXD_BODY6_UPD_WLAN_HDR, desc_info->upd_wlan_hdr);
return cpu_to_le32(dword);
}
static __le32 rtw89_build_txwd_body7_v2(struct rtw89_tx_desc_info *desc_info)
{
u32 dword = FIELD_PREP(BE_TXD_BODY7_USERATE_SEL, desc_info->use_rate) |
@ -1418,6 +1418,7 @@ void rtw89_core_fill_txdesc_v2(struct rtw89_dev *rtwdev,
txwd_body->dword4 = rtw89_build_txwd_body4_v2(desc_info);
txwd_body->dword5 = rtw89_build_txwd_body5_v2(desc_info);
}
txwd_body->dword6 = rtw89_build_txwd_body6_v2(desc_info);
txwd_body->dword7 = rtw89_build_txwd_body7_v2(desc_info);
if (!desc_info->en_wd_info)
@ -1858,32 +1859,58 @@ static void rtw89_core_rx_process_phy_sts(struct rtw89_dev *rtwdev,
phy_ppdu);
}
static u8 rtw89_rxdesc_to_nl_he_eht_gi(struct rtw89_dev *rtwdev,
u8 desc_info_gi,
bool rx_status, bool eht)
static u8 rtw89_rxdesc_to_nl_he_gi(struct rtw89_dev *rtwdev,
u8 desc_info_gi,
bool rx_status)
{
switch (desc_info_gi) {
case RTW89_GILTF_SGI_4XHE08:
case RTW89_GILTF_2XHE08:
case RTW89_GILTF_1XHE08:
return eht ? NL80211_RATE_INFO_EHT_GI_0_8 :
NL80211_RATE_INFO_HE_GI_0_8;
return NL80211_RATE_INFO_HE_GI_0_8;
case RTW89_GILTF_2XHE16:
case RTW89_GILTF_1XHE16:
return eht ? NL80211_RATE_INFO_EHT_GI_1_6 :
NL80211_RATE_INFO_HE_GI_1_6;
return NL80211_RATE_INFO_HE_GI_1_6;
case RTW89_GILTF_LGI_4XHE32:
return eht ? NL80211_RATE_INFO_EHT_GI_3_2 :
NL80211_RATE_INFO_HE_GI_3_2;
return NL80211_RATE_INFO_HE_GI_3_2;
default:
rtw89_warn(rtwdev, "invalid gi_ltf=%d", desc_info_gi);
if (rx_status)
return eht ? NL80211_RATE_INFO_EHT_GI_3_2 :
NL80211_RATE_INFO_HE_GI_3_2;
return NL80211_RATE_INFO_HE_GI_3_2;
return U8_MAX;
}
}
static u8 rtw89_rxdesc_to_nl_eht_gi(struct rtw89_dev *rtwdev,
u8 desc_info_gi,
bool rx_status)
{
switch (desc_info_gi) {
case RTW89_GILTF_SGI_4XHE08:
case RTW89_GILTF_2XHE08:
case RTW89_GILTF_1XHE08:
return NL80211_RATE_INFO_EHT_GI_0_8;
case RTW89_GILTF_2XHE16:
case RTW89_GILTF_1XHE16:
return NL80211_RATE_INFO_EHT_GI_1_6;
case RTW89_GILTF_LGI_4XHE32:
return NL80211_RATE_INFO_EHT_GI_3_2;
default:
rtw89_warn(rtwdev, "invalid gi_ltf=%d", desc_info_gi);
if (rx_status)
return NL80211_RATE_INFO_EHT_GI_3_2;
return U8_MAX;
}
}
static u8 rtw89_rxdesc_to_nl_he_eht_gi(struct rtw89_dev *rtwdev,
u8 desc_info_gi,
bool rx_status, bool eht)
{
return eht ? rtw89_rxdesc_to_nl_eht_gi(rtwdev, desc_info_gi, rx_status) :
rtw89_rxdesc_to_nl_he_gi(rtwdev, desc_info_gi, rx_status);
}
static
bool rtw89_check_rx_statu_gi_match(struct ieee80211_rx_status *status, u8 gi_ltf,
bool eht)
@ -3162,9 +3189,10 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
rtw89_leave_ips_by_hwflags(rtwdev);
rtw89_leave_lps(rtwdev);
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, RTW89_ROC_BY_LINK_INDEX);
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev, "roc start: find no link on HW-0\n");
rtw89_err(rtwdev, "roc start: find no link on HW-%u\n",
RTW89_ROC_BY_LINK_INDEX);
return;
}
@ -3217,9 +3245,10 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
rtw89_leave_ips_by_hwflags(rtwdev);
rtw89_leave_lps(rtwdev);
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, RTW89_ROC_BY_LINK_INDEX);
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev, "roc end: find no link on HW-0\n");
rtw89_err(rtwdev, "roc end: find no link on HW-%u\n",
RTW89_ROC_BY_LINK_INDEX);
return;
}
@ -4818,11 +4847,20 @@ static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev)
static void rtw89_core_setup_phycap(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
rtwdev->hal.support_cckpd =
!(rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv <= CHIP_CBV) &&
!(rtwdev->chip->chip_id == RTL8852B && rtwdev->hal.cv <= CHIP_CAV);
rtwdev->hal.support_igi =
rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv <= CHIP_CBV;
if (test_bit(RTW89_QUIRK_THERMAL_PROT_120C, rtwdev->quirks))
rtwdev->hal.thermal_prot_th = chip->thermal_th[1];
else if (test_bit(RTW89_QUIRK_THERMAL_PROT_110C, rtwdev->quirks))
rtwdev->hal.thermal_prot_th = chip->thermal_th[0];
else
rtwdev->hal.thermal_prot_th = 0;
}
static void rtw89_core_setup_rfe_parms(struct rtw89_dev *rtwdev)

View File

@ -1162,6 +1162,7 @@ struct rtw89_tx_desc_info {
bool er_cap;
bool stbc;
bool ldpc;
bool upd_wlan_hdr;
};
struct rtw89_core_tx_request {
@ -3427,6 +3428,8 @@ enum rtw89_roc_state {
RTW89_ROC_MGMT,
};
#define RTW89_ROC_BY_LINK_INDEX 0
struct rtw89_roc {
struct ieee80211_channel chan;
struct delayed_work roc_work;
@ -4244,6 +4247,7 @@ struct rtw89_chip_info {
u8 wde_qempty_acq_grpnum;
u8 wde_qempty_mgq_grpsel;
u32 rf_base_addr[2];
u8 thermal_th[2];
u8 support_macid_num;
u8 support_link_num;
u8 support_chanctx_num;
@ -4512,11 +4516,14 @@ enum rtw89_fw_mss_dev_type {
};
struct rtw89_fw_secure {
bool secure_boot;
bool secure_boot: 1;
bool can_mss_v1: 1;
bool can_mss_v0: 1;
u32 sb_sel_mgn;
u8 mss_dev_type;
u8 mss_cust_idx;
u8 mss_key_num;
u8 mss_idx; /* v0 */
};
struct rtw89_fw_info {
@ -4562,7 +4569,7 @@ enum rtw89_sar_subband {
RTW89_SAR_2GHZ_SUBBAND,
RTW89_SAR_5GHZ_SUBBAND_1_2, /* U-NII-1 and U-NII-2 */
RTW89_SAR_5GHZ_SUBBAND_2_E, /* U-NII-2-Extended */
RTW89_SAR_5GHZ_SUBBAND_3, /* U-NII-3 */
RTW89_SAR_5GHZ_SUBBAND_3_4, /* U-NII-3 and U-NII-4 */
RTW89_SAR_6GHZ_SUBBAND_5_L, /* U-NII-5 lower part */
RTW89_SAR_6GHZ_SUBBAND_5_H, /* U-NII-5 higher part */
RTW89_SAR_6GHZ_SUBBAND_6, /* U-NII-6 */
@ -4624,7 +4631,7 @@ enum rtw89_chanctx_changes {
};
enum rtw89_entity_mode {
RTW89_ENTITY_MODE_SCC,
RTW89_ENTITY_MODE_SCC_OR_SMLD,
RTW89_ENTITY_MODE_MCC_PREPARE,
RTW89_ENTITY_MODE_MCC,
@ -4633,6 +4640,16 @@ enum rtw89_entity_mode {
RTW89_ENTITY_MODE_UNHANDLED = -ESRCH,
};
#define RTW89_MAX_INTERFACE_NUM 2
/* only valid when running with chanctx_ops */
struct rtw89_entity_mgnt {
struct list_head active_list;
struct rtw89_vif *active_roles[RTW89_MAX_INTERFACE_NUM];
enum rtw89_chanctx_idx chanctx_tbl[RTW89_MAX_INTERFACE_NUM]
[__RTW89_MLD_MAX_LINK_NUM];
};
struct rtw89_chanctx {
struct cfg80211_chan_def chandef;
struct rtw89_chan chan;
@ -4651,8 +4668,12 @@ struct rtw89_edcca_bak {
enum rtw89_dm_type {
RTW89_DM_DYNAMIC_EDCCA,
RTW89_DM_THERMAL_PROTECT,
};
#define RTW89_THERMAL_PROT_LV_MAX 5
#define RTW89_THERMAL_PROT_STEP 19 /* -19% for each level */
struct rtw89_hal {
u32 rx_fltr;
u8 cv;
@ -4676,9 +4697,13 @@ struct rtw89_hal {
bool entity_active[RTW89_PHY_MAX];
bool entity_pause;
enum rtw89_entity_mode entity_mode;
struct rtw89_entity_mgnt entity_mgnt;
struct rtw89_edcca_bak edcca_bak;
u32 disabled_dm_bitmap; /* bitmap of enum rtw89_dm_type */
u8 thermal_prot_th;
u8 thermal_prot_lv; /* 0 ~ RTW89_THERMAL_PROT_LV_MAX */
};
#define RTW89_MAX_MAC_ID_NUM 128
@ -4711,10 +4736,22 @@ enum rtw89_flags {
enum rtw89_quirks {
RTW89_QUIRK_PCI_BER,
RTW89_QUIRK_THERMAL_PROT_120C,
RTW89_QUIRK_THERMAL_PROT_110C,
NUM_OF_RTW89_QUIRKS,
};
enum rtw89_custid {
RTW89_CUSTID_NONE,
RTW89_CUSTID_ACER,
RTW89_CUSTID_AMD,
RTW89_CUSTID_ASUS,
RTW89_CUSTID_DELL,
RTW89_CUSTID_HP,
RTW89_CUSTID_LENOVO,
};
enum rtw89_pkt_drop_sel {
RTW89_PKT_DROP_SEL_MACID_BE_ONCE,
RTW89_PKT_DROP_SEL_MACID_BK_ONCE,
@ -4751,6 +4788,7 @@ DECLARE_EWMA(thermal, 4, 4);
struct rtw89_phy_stat {
struct ewma_thermal avg_thermal[RF_PATH_MAX];
u8 last_thermal_max;
struct ewma_rssi bcn_rssi;
struct rtw89_pkt_stat cur_pkt_stat;
struct rtw89_pkt_stat last_pkt_stat;
@ -4793,13 +4831,17 @@ enum rtw89_rfk_chs_nrs {
RTW89_RFK_CHS_NR = __RTW89_RFK_CHS_NR_V1,
};
struct rtw89_rfk_mcc_info {
struct rtw89_rfk_mcc_info_data {
u8 ch[RTW89_RFK_CHS_NR];
u8 band[RTW89_RFK_CHS_NR];
u8 bw[RTW89_RFK_CHS_NR];
u8 table_idx;
};
struct rtw89_rfk_mcc_info {
struct rtw89_rfk_mcc_info_data data[2];
};
#define RTW89_IQK_CHS_NR 2
#define RTW89_IQK_PATH_NR 4
@ -4904,6 +4946,7 @@ struct rtw89_agc_gaincode_set {
#define IGI_RSSI_TH_NUM 5
#define FA_TH_NUM 4
#define TIA_LNA_OP1DB_NUM 8
#define LNA_GAIN_NUM 7
#define TIA_GAIN_NUM 2
struct rtw89_dig_info {
@ -5511,6 +5554,7 @@ struct rtw89_dev {
struct rtw89_efuse efuse;
struct rtw89_traffic_stats stats;
struct rtw89_rfe_data *rfe_data;
enum rtw89_custid custid;
/* ensures exclusive access from mac80211 callbacks */
struct mutex mutex;
@ -5613,6 +5657,7 @@ struct rtw89_dev {
struct rtw89_vif {
struct rtw89_dev *rtwdev;
struct list_head list;
struct list_head mgnt_entry;
u8 mac_addr[ETH_ALEN];
__be32 ip_addr;
@ -6367,6 +6412,15 @@ const struct rtw89_chan_rcd *rtw89_chan_rcd_get(struct rtw89_dev *rtwdev,
return &hal->chanctx[idx].rcd;
}
static inline
const struct rtw89_chan_rcd *rtw89_chan_rcd_get_by_chan(const struct rtw89_chan *chan)
{
const struct rtw89_chanctx *chanctx =
container_of_const(chan, struct rtw89_chanctx, chan);
return &chanctx->rcd;
}
static inline
const struct rtw89_chan *rtw89_scan_chan_get(struct rtw89_dev *rtwdev)
{

View File

@ -3672,14 +3672,19 @@ static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v)
struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.last_pkt_stat;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_rx_rate_cnt_info *info;
struct rtw89_hal *hal = &rtwdev->hal;
enum rtw89_hw_rate first_rate;
u8 rssi;
int i;
rssi = ewma_rssi_read(&rtwdev->phystat.bcn_rssi);
seq_printf(m, "TP TX: %u [%u] Mbps (lv: %d), RX: %u [%u] Mbps (lv: %d)\n",
stats->tx_throughput, stats->tx_throughput_raw, stats->tx_tfc_lv,
seq_printf(m, "TP TX: %u [%u] Mbps (lv: %d",
stats->tx_throughput, stats->tx_throughput_raw, stats->tx_tfc_lv);
if (hal->thermal_prot_lv)
seq_printf(m, ", duty: %d%%",
100 - hal->thermal_prot_lv * RTW89_THERMAL_PROT_STEP);
seq_printf(m, "), RX: %u [%u] Mbps (lv: %d)\n",
stats->rx_throughput, stats->rx_throughput_raw, stats->rx_tfc_lv);
seq_printf(m, "Beacon: %u (%d dBm), TF: %u\n", pkt_stat->beacon_nr,
RTW89_RSSI_RAW_TO_DBM(rssi), stats->rx_tf_periodic);
@ -3886,6 +3891,7 @@ static const struct rtw89_disabled_dm_info {
const char *name;
} rtw89_disabled_dm_infos[] = {
DM_INFO(DYNAMIC_EDCCA),
DM_INFO(THERMAL_PROTECT),
};
static int

View File

@ -11,11 +11,38 @@
#define EF_CV_MASK GENMASK(7, 4)
#define EF_CV_INV 15
#define EFUSE_B1_MSSDEVTYPE_MASK GENMASK(3, 0)
#define EFUSE_B1_MSSCUSTIDX0_MASK GENMASK(7, 4)
#define EFUSE_B2_MSSKEYNUM_MASK GENMASK(3, 0)
#define EFUSE_B2_MSSCUSTIDX1_MASK BIT(6)
#define EFUSE_EXTERNALPN_ADDR_AX 0x5EC
#define EFUSE_CUSTOMER_ADDR_AX 0x5ED
#define EFUSE_SERIALNUM_ADDR_AX 0x5ED
#define EFUSE_B1_EXTERNALPN_MASK GENMASK(7, 0)
#define EFUSE_B2_CUSTOMER_MASK GENMASK(3, 0)
#define EFUSE_B2_SERIALNUM_MASK GENMASK(6, 4)
#define OTP_KEY_INFO_NUM 2
static const u8 otp_key_info_externalPN[OTP_KEY_INFO_NUM] = {0x0, 0x0};
static const u8 otp_key_info_customer[OTP_KEY_INFO_NUM] = {0x0, 0x1};
static const u8 otp_key_info_serialNum[OTP_KEY_INFO_NUM] = {0x0, 0x1};
enum rtw89_efuse_bank {
RTW89_EFUSE_BANK_WIFI,
RTW89_EFUSE_BANK_BT,
};
enum rtw89_efuse_mss_dev_type {
MSS_DEV_TYPE_FWSEC_DEF = 0xF,
MSS_DEV_TYPE_FWSEC_WINLIN_INBOX = 0xC,
MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB = 0xA,
MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB = 0x9,
MSS_DEV_TYPE_FWSEC_NONWIN_INBOX = 0x6,
};
static int rtw89_switch_efuse_bank(struct rtw89_dev *rtwdev,
enum rtw89_efuse_bank bank)
{
@ -354,3 +381,126 @@ int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *ecv)
return 0;
}
EXPORT_SYMBOL(rtw89_read_efuse_ver);
static u8 get_mss_dev_type_idx(struct rtw89_dev *rtwdev, u8 mss_dev_type)
{
switch (mss_dev_type) {
case MSS_DEV_TYPE_FWSEC_WINLIN_INBOX:
mss_dev_type = 0x0;
break;
case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB:
mss_dev_type = 0x1;
break;
case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB:
mss_dev_type = 0x2;
break;
case MSS_DEV_TYPE_FWSEC_NONWIN_INBOX:
mss_dev_type = 0x3;
break;
case MSS_DEV_TYPE_FWSEC_DEF:
mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF;
break;
default:
rtw89_warn(rtwdev, "unknown mss_dev_type %d", mss_dev_type);
mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_INV;
break;
}
return mss_dev_type;
}
int rtw89_efuse_recognize_mss_info_v1(struct rtw89_dev *rtwdev, u8 b1, u8 b2)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
u8 mss_dev_type;
if (chip->chip_id == RTL8852B && b1 == 0xFF && b2 == 0x6E) {
mss_dev_type = MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB;
sec->mss_cust_idx = 0;
sec->mss_key_num = 0;
goto mss_dev_type;
}
mss_dev_type = u8_get_bits(b1, EFUSE_B1_MSSDEVTYPE_MASK);
sec->mss_cust_idx = 0x1F - (u8_get_bits(b1, EFUSE_B1_MSSCUSTIDX0_MASK) |
u8_get_bits(b2, EFUSE_B2_MSSCUSTIDX1_MASK) << 4);
sec->mss_key_num = 0xF - u8_get_bits(b2, EFUSE_B2_MSSKEYNUM_MASK);
mss_dev_type:
sec->mss_dev_type = get_mss_dev_type_idx(rtwdev, mss_dev_type);
if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_INV) {
rtw89_warn(rtwdev, "invalid mss_dev_type %d\n", mss_dev_type);
return -ENOENT;
}
sec->can_mss_v1 = true;
return 0;
}
static
int rtw89_efuse_recognize_mss_index_v0(struct rtw89_dev *rtwdev, u8 b1, u8 b2)
{
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
u8 externalPN;
u8 serialNum;
u8 customer;
u8 i;
externalPN = 0xFF - u8_get_bits(b1, EFUSE_B1_EXTERNALPN_MASK);
customer = 0xF - u8_get_bits(b2, EFUSE_B2_CUSTOMER_MASK);
serialNum = 0x7 - u8_get_bits(b2, EFUSE_B2_SERIALNUM_MASK);
for (i = 0; i < OTP_KEY_INFO_NUM; i++) {
if (externalPN == otp_key_info_externalPN[i] &&
customer == otp_key_info_customer[i] &&
serialNum == otp_key_info_serialNum[i]) {
sec->mss_idx = i;
sec->can_mss_v0 = true;
return 0;
}
}
return -ENOENT;
}
int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev)
{
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
u32 sec_addr = EFUSE_EXTERNALPN_ADDR_AX;
u32 sec_size = 2;
u8 sec_map[2];
u8 b1, b2;
int ret;
ret = rtw89_dump_physical_efuse_map(rtwdev, sec_map,
sec_addr, sec_size, false);
if (ret) {
rtw89_warn(rtwdev, "failed to dump secsel map\n");
return ret;
}
b1 = sec_map[0];
b2 = sec_map[1];
if (b1 == 0xFF && b2 == 0xFF)
return 0;
rtw89_efuse_recognize_mss_index_v0(rtwdev, b1, b2);
rtw89_efuse_recognize_mss_info_v1(rtwdev, b1, b2);
if (!sec->can_mss_v1 && !sec->can_mss_v0)
goto out;
sec->secure_boot = true;
out:
rtw89_debug(rtwdev, RTW89_DBG_FW,
"MSS secure_boot=%d(%d/%d) dev_type=%d cust_idx=%d key_num=%d mss_index=%d\n",
sec->secure_boot, sec->can_mss_v0, sec->can_mss_v1,
sec->mss_dev_type, sec->mss_cust_idx,
sec->mss_key_num, sec->mss_idx);
return 0;
}

View File

@ -23,6 +23,8 @@ int rtw89_parse_efuse_map_be(struct rtw89_dev *rtwdev);
int rtw89_parse_phycap_map_be(struct rtw89_dev *rtwdev);
int rtw89_cnv_efuse_state_be(struct rtw89_dev *rtwdev, bool idle);
int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *efv);
int rtw89_efuse_recognize_mss_info_v1(struct rtw89_dev *rtwdev, u8 b1, u8 b2);
int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev);
int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev);
#endif

View File

@ -8,11 +8,7 @@
#include "reg.h"
#define EFUSE_EXTERNALPN_ADDR_BE 0x1580
#define EFUSE_B1_MSSDEVTYPE_MASK GENMASK(3, 0)
#define EFUSE_B1_MSSCUSTIDX0_MASK GENMASK(7, 4)
#define EFUSE_SERIALNUM_ADDR_BE 0x1581
#define EFUSE_B2_MSSKEYNUM_MASK GENMASK(3, 0)
#define EFUSE_B2_MSSCUSTIDX1_MASK BIT(6)
#define EFUSE_SB_CRYP_SEL_ADDR 0x1582
#define EFUSE_SB_CRYP_SEL_SIZE 2
#define EFUSE_SB_CRYP_SEL_DEFAULT 0xFFFF
@ -20,14 +16,6 @@
#define EFUSE_SEC_BE_START 0x1580
#define EFUSE_SEC_BE_SIZE 4
enum rtw89_efuse_mss_dev_type {
MSS_DEV_TYPE_FWSEC_DEF = 0xF,
MSS_DEV_TYPE_FWSEC_WINLIN_INBOX = 0xC,
MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB = 0xA,
MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB = 0x9,
MSS_DEV_TYPE_FWSEC_NONWIN_INBOX = 0x6,
};
static const u32 sb_sel_mgn[SB_SEL_MGN_MAX_SIZE] = {
0x8000100, 0xC000180
};
@ -477,33 +465,6 @@ static u16 get_sb_cryp_sel_idx(u16 sb_cryp_sel)
return sb_cryp_sel_v + low_bit;
}
static u8 get_mss_dev_type_idx(struct rtw89_dev *rtwdev, u8 mss_dev_type)
{
switch (mss_dev_type) {
case MSS_DEV_TYPE_FWSEC_WINLIN_INBOX:
mss_dev_type = 0x0;
break;
case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB:
mss_dev_type = 0x1;
break;
case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB:
mss_dev_type = 0x2;
break;
case MSS_DEV_TYPE_FWSEC_NONWIN_INBOX:
mss_dev_type = 0x3;
break;
case MSS_DEV_TYPE_FWSEC_DEF:
mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF;
break;
default:
rtw89_warn(rtwdev, "unknown mss_dev_type %d", mss_dev_type);
mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_INV;
break;
}
return mss_dev_type;
}
int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
{
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
@ -511,7 +472,6 @@ int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
u32 sec_size = EFUSE_SEC_BE_SIZE;
u16 sb_cryp_sel, sb_cryp_sel_idx;
u8 sec_map[EFUSE_SEC_BE_SIZE];
u8 mss_dev_type;
u8 b1, b2;
int ret;
@ -538,16 +498,9 @@ int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
b1 = sec_map[EFUSE_EXTERNALPN_ADDR_BE - sec_addr];
b2 = sec_map[EFUSE_SERIALNUM_ADDR_BE - sec_addr];
mss_dev_type = u8_get_bits(b1, EFUSE_B1_MSSDEVTYPE_MASK);
sec->mss_cust_idx = 0x1F - (u8_get_bits(b1, EFUSE_B1_MSSCUSTIDX0_MASK) |
u8_get_bits(b2, EFUSE_B2_MSSCUSTIDX1_MASK) << 4);
sec->mss_key_num = 0xF - u8_get_bits(b2, EFUSE_B2_MSSKEYNUM_MASK);
sec->mss_dev_type = get_mss_dev_type_idx(rtwdev, mss_dev_type);
if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_INV) {
rtw89_warn(rtwdev, "invalid mss_dev_type %d\n", mss_dev_type);
ret = rtw89_efuse_recognize_mss_info_v1(rtwdev, b1, b2);
if (ret)
goto out;
}
sec->secure_boot = true;
@ -559,4 +512,3 @@ int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
return 0;
}
EXPORT_SYMBOL(rtw89_efuse_read_fw_secure_be);

View File

@ -56,6 +56,11 @@ static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
struct sk_buff *skb);
static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb,
struct rtw89_wait_info *wait, unsigned int cond);
static int __parse_security_section(struct rtw89_dev *rtwdev,
struct rtw89_fw_bin_info *info,
struct rtw89_fw_hdr_section_info *section_info,
const void *content,
u32 *mssc_len);
static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len,
bool header)
@ -124,13 +129,16 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
struct rtw89_fw_bin_info *info)
{
const struct rtw89_fw_hdr *fw_hdr = (const struct rtw89_fw_hdr *)fw;
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_fw_hdr_section_info *section_info;
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
const struct rtw89_fw_dynhdr_hdr *fwdynhdr;
const struct rtw89_fw_hdr_section *section;
const u8 *fw_end = fw + len;
const u8 *bin;
u32 base_hdr_len;
u32 mssc_len = 0;
u32 mssc_len;
int ret;
u32 i;
if (!info)
@ -139,6 +147,7 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_W6_SEC_NUM);
base_hdr_len = struct_size(fw_hdr, sections, info->section_num);
info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_W7_DYN_HDR);
info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_W7_IDMEM_SHARE_MODE);
if (info->dynamic_hdr_en) {
info->hdr_len = le32_get_bits(fw_hdr->w3, FW_HDR_W3_LEN);
@ -161,26 +170,47 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
section = &fw_hdr->sections[i];
section_info->type =
le32_get_bits(section->w1, FWSECTION_HDR_W1_SECTIONTYPE);
if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
section_info->mssc =
le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC);
mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN;
} else {
section_info->mssc = 0;
}
section_info->len = le32_get_bits(section->w1, FWSECTION_HDR_W1_SEC_SIZE);
if (le32_get_bits(section->w1, FWSECTION_HDR_W1_CHECKSUM))
section_info->len += FWDL_SECTION_CHKSUM_LEN;
section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_W1_REDL);
section_info->dladdr =
le32_get_bits(section->w0, FWSECTION_HDR_W0_DL_ADDR) & 0x1fffffff;
section_info->addr = bin;
bin += section_info->len;
if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
section_info->mssc =
le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC);
ret = __parse_security_section(rtwdev, info, section_info,
bin, &mssc_len);
if (ret)
return ret;
if (sec->secure_boot && chip->chip_id == RTL8852B)
section_info->len_override = 960;
} else {
section_info->mssc = 0;
mssc_len = 0;
}
rtw89_debug(rtwdev, RTW89_DBG_FW,
"section[%d] type=%d len=0x%-6x mssc=%d mssc_len=%d addr=%tx\n",
i, section_info->type, section_info->len,
section_info->mssc, mssc_len, bin - fw);
rtw89_debug(rtwdev, RTW89_DBG_FW,
" ignore=%d key_addr=%p (0x%tx) key_len=%d key_idx=%d\n",
section_info->ignore, section_info->key_addr,
section_info->key_addr ?
section_info->key_addr - section_info->addr : 0,
section_info->key_len, section_info->key_idx);
bin += section_info->len + mssc_len;
section_info++;
}
if (fw_end != bin + mssc_len) {
if (fw_end != bin) {
rtw89_err(rtwdev, "[ERR]fw bin size\n");
return -EINVAL;
}
@ -235,7 +265,6 @@ static int __get_mssc_key_idx(struct rtw89_dev *rtwdev,
static int __parse_formatted_mssc(struct rtw89_dev *rtwdev,
struct rtw89_fw_bin_info *info,
struct rtw89_fw_hdr_section_info *section_info,
const struct rtw89_fw_hdr_section_v1 *section,
const void *content,
u32 *mssc_len)
{
@ -318,18 +347,15 @@ static int __parse_formatted_mssc(struct rtw89_dev *rtwdev,
static int __parse_security_section(struct rtw89_dev *rtwdev,
struct rtw89_fw_bin_info *info,
struct rtw89_fw_hdr_section_info *section_info,
const struct rtw89_fw_hdr_section_v1 *section,
const void *content,
u32 *mssc_len)
{
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
int ret;
section_info->mssc =
le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC);
if (section_info->mssc == FORMATTED_MSSC) {
if ((section_info->mssc & FORMATTED_MSSC_MASK) == FORMATTED_MSSC) {
ret = __parse_formatted_mssc(rtwdev, info, section_info,
section, content, mssc_len);
content, mssc_len);
if (ret)
return -EINVAL;
} else {
@ -337,6 +363,14 @@ static int __parse_security_section(struct rtw89_dev *rtwdev,
if (info->dsp_checksum)
*mssc_len += section_info->mssc * FWDL_SECURITY_CHKSUM_LEN;
if (sec->secure_boot) {
if (sec->mss_idx >= section_info->mssc)
return -EFAULT;
section_info->key_addr = content + section_info->len +
sec->mss_idx * FWDL_SECURITY_SIGLEN;
section_info->key_len = FWDL_SECURITY_SIGLEN;
}
info->secure_section_exist = true;
}
@ -361,6 +395,7 @@ static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
info->dsp_checksum = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_DSP_CHKSUM);
base_hdr_len = struct_size(fw_hdr, sections, info->section_num);
info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_DYN_HDR);
info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_IDMEM_SHARE_MODE);
if (info->dynamic_hdr_en) {
info->hdr_len = le32_get_bits(fw_hdr->w5, FW_HDR_V1_W5_HDR_SIZE);
@ -394,8 +429,11 @@ static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
section_info->addr = bin;
if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
section_info->mssc =
le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC);
ret = __parse_security_section(rtwdev, info, section_info,
section, bin, &mssc_len);
bin, &mssc_len);
if (ret)
return ret;
} else {
@ -1155,9 +1193,24 @@ static u32 __rtw89_fw_download_tweak_hdr_v0(struct rtw89_dev *rtwdev,
struct rtw89_fw_bin_info *info,
struct rtw89_fw_hdr *fw_hdr)
{
struct rtw89_fw_hdr_section_info *section_info;
struct rtw89_fw_hdr_section *section;
int i;
le32p_replace_bits(&fw_hdr->w7, FWDL_SECTION_PER_PKT_LEN,
FW_HDR_W7_PART_SIZE);
for (i = 0; i < info->section_num; i++) {
section_info = &info->section_info[i];
if (!section_info->len_override)
continue;
section = &fw_hdr->sections[i];
le32p_replace_bits(&section->w1, section_info->len_override,
FWSECTION_HDR_W1_SEC_SIZE);
}
return 0;
}
@ -1286,10 +1339,20 @@ static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev,
if (info->ignore)
return 0;
if (info->len_override) {
if (info->len_override > info->len)
rtw89_warn(rtwdev, "override length %u larger than original %u\n",
info->len_override, info->len);
else
residue_len = info->len_override;
}
if (info->key_addr && info->key_len) {
if (info->len > FWDL_SECTION_PER_PKT_LEN || info->len < info->key_len)
rtw89_warn(rtwdev, "ignore to copy key data because of len %d, %d, %d\n",
info->len, FWDL_SECTION_PER_PKT_LEN, info->key_len);
if (residue_len > FWDL_SECTION_PER_PKT_LEN || info->len < info->key_len)
rtw89_warn(rtwdev,
"ignore to copy key data because of len %d, %d, %d, %d\n",
info->len, FWDL_SECTION_PER_PKT_LEN,
info->key_len, residue_len);
else
copy_key = true;
}
@ -1425,6 +1488,8 @@ static int rtw89_fw_download_suit(struct rtw89_dev *rtwdev,
return ret;
}
rtw89_fwdl_secure_idmem_share_mode(rtwdev, info.idmem_share_mode);
if (rtwdev->chip->chip_id == RTL8922A &&
(fw_suit->type == RTW89_FW_NORMAL || fw_suit->type == RTW89_FW_WOWLAN))
rtw89_write32(rtwdev, R_BE_SECURE_BOOT_MALLOC_INFO, 0x20248000);
@ -2508,7 +2573,7 @@ int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
H2C_CL_MAC_PS,
H2C_FUNC_MAC_LPS_PARM, 0, 1,
H2C_FUNC_MAC_LPS_PARM, 0, !lps_param->psmode,
H2C_LPS_PARM_LEN);
ret = rtw89_h2c_tx(rtwdev, skb, false);
@ -3795,6 +3860,52 @@ int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev)
return ret;
}
int rtw89_fw_h2c_tx_duty(struct rtw89_dev *rtwdev, u8 lv)
{
struct rtw89_h2c_tx_duty *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
u16 pause, active;
int ret;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c tx duty\n");
return -ENOMEM;
}
skb_put(skb, len);
h2c = (struct rtw89_h2c_tx_duty *)skb->data;
static_assert(RTW89_THERMAL_PROT_LV_MAX * RTW89_THERMAL_PROT_STEP < 100);
if (lv == 0 || lv > RTW89_THERMAL_PROT_LV_MAX) {
h2c->w1 = le32_encode_bits(1, RTW89_H2C_TX_DUTY_W1_STOP);
} else {
active = 100 - lv * RTW89_THERMAL_PROT_STEP;
pause = 100 - active;
h2c->w0 = le32_encode_bits(pause, RTW89_H2C_TX_DUTY_W0_PAUSE_INTVL_MASK) |
le32_encode_bits(active, RTW89_H2C_TX_DUTY_W0_TX_INTVL_MASK);
}
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
H2C_FUNC_TX_DUTY, 0, 0, len);
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
rtw89_err(rtwdev, "failed to send h2c\n");
goto fail;
}
return 0;
fail:
dev_kfree_skb_any(skb);
return ret;
}
int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool connect)
@ -4965,7 +5076,7 @@ int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
scan_mode = RTW89_SCAN_IMMEDIATE;
} else {
scan_mode = RTW89_SCAN_DELAY;
tsf += option->delay * RTW89_SCAN_DELAY_TSF_UNIT;
tsf += (u64)option->delay * RTW89_SCAN_DELAY_TSF_UNIT;
}
}
@ -5260,7 +5371,7 @@ int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,
int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
{
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_fw_h2c_rf_get_mccch *mccch;
struct sk_buff *skb;
int ret;
@ -5307,7 +5418,7 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
struct rtw89_fw_h2c_rfk_pre_info_v0 *h2c_v0;
struct rtw89_fw_h2c_rfk_pre_info *h2c;
u8 tbl_sel = rfk_mcc->table_idx;
u8 tbl_sel[NUM_OF_RTW89_FW_RFK_PATH];
u32 len = sizeof(*h2c);
struct sk_buff *skb;
u8 ver = U8_MAX;
@ -5331,19 +5442,24 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
h2c->common.mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR);
BUILD_BUG_ON(ARRAY_SIZE(rfk_mcc->data) < NUM_OF_RTW89_FW_RFK_PATH);
for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) {
for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) {
h2c->common.dbcc.ch[path][tbl] =
cpu_to_le32(rfk_mcc->ch[tbl]);
cpu_to_le32(rfk_mcc->data[path].ch[tbl]);
h2c->common.dbcc.band[path][tbl] =
cpu_to_le32(rfk_mcc->band[tbl]);
cpu_to_le32(rfk_mcc->data[path].band[tbl]);
}
}
for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) {
h2c->common.tbl.cur_ch[path] = cpu_to_le32(rfk_mcc->ch[tbl_sel]);
h2c->common.tbl.cur_band[path] = cpu_to_le32(rfk_mcc->band[tbl_sel]);
tbl_sel[path] = rfk_mcc->data[path].table_idx;
h2c->common.tbl.cur_ch[path] =
cpu_to_le32(rfk_mcc->data[path].ch[tbl_sel[path]]);
h2c->common.tbl.cur_band[path] =
cpu_to_le32(rfk_mcc->data[path].band[tbl_sel[path]]);
}
h2c->common.phy_idx = cpu_to_le32(phy_idx);
@ -5351,9 +5467,9 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
if (ver == 0) { /* RFK_PRE_NOTIFY_V0 */
h2c_v0 = (struct rtw89_fw_h2c_rfk_pre_info_v0 *)skb->data;
h2c_v0->cur_band = cpu_to_le32(rfk_mcc->band[tbl_sel]);
h2c_v0->cur_bw = cpu_to_le32(rfk_mcc->bw[tbl_sel]);
h2c_v0->cur_center_ch = cpu_to_le32(rfk_mcc->ch[tbl_sel]);
h2c_v0->cur_band = cpu_to_le32(rfk_mcc->data[0].band[tbl_sel[0]]);
h2c_v0->cur_bw = cpu_to_le32(rfk_mcc->data[0].bw[tbl_sel[0]]);
h2c_v0->cur_center_ch = cpu_to_le32(rfk_mcc->data[0].ch[tbl_sel[0]]);
val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_IQC_V1);
h2c_v0->ktbl_sel0 = cpu_to_le32(val32);
@ -6252,8 +6368,10 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
ch_info->period = max_t(u8, ch_info->period,
RTW89_DFS_CHAN_TIME);
ch_info->dwell_time = RTW89_DWELL_TIME;
ch_info->pause_data = true;
break;
case RTW89_CHAN_ACTIVE:
ch_info->pause_data = true;
break;
default:
rtw89_err(rtwdev, "Channel type out of bound\n");
@ -6352,8 +6470,10 @@ static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type,
ch_info->period =
max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME);
ch_info->dwell_time = RTW89_DWELL_TIME;
ch_info->pause_data = true;
break;
case RTW89_CHAN_ACTIVE:
ch_info->pause_data = true;
break;
default:
rtw89_warn(rtwdev, "Channel type out of bound\n");
@ -6675,6 +6795,8 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev,
if (!rtwvif_link)
return;
rtw89_chanctx_proceed(rtwdev);
rtwvif = rtwvif_link->rtwvif;
reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx);
@ -6692,8 +6814,6 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev,
scan_info->last_chan_idx = 0;
scan_info->scanning_vif = NULL;
scan_info->abort = false;
rtw89_chanctx_proceed(rtwdev);
}
void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev,

View File

@ -261,6 +261,7 @@ struct rtw89_fw_hdr_section_info {
u8 redl;
const u8 *addr;
u32 len;
u32 len_override;
u32 dladdr;
u32 mssc;
u8 type;
@ -275,6 +276,7 @@ struct rtw89_fw_bin_info {
u32 hdr_len;
bool dynamic_hdr_en;
u32 dynamic_hdr_len;
u8 idmem_share_mode;
bool dsp_checksum;
bool secure_section_exist;
struct rtw89_fw_hdr_section_info section_info[FWDL_SECTION_MAX_NUM];
@ -563,6 +565,7 @@ struct rtw89_fw_hdr {
#define FW_HDR_W6_SEC_NUM GENMASK(15, 8)
#define FW_HDR_W7_PART_SIZE GENMASK(15, 0)
#define FW_HDR_W7_DYN_HDR BIT(16)
#define FW_HDR_W7_IDMEM_SHARE_MODE GENMASK(21, 18)
#define FW_HDR_W7_CMD_VERSERION GENMASK(31, 24)
struct rtw89_fw_hdr_section_v1 {
@ -580,6 +583,7 @@ struct rtw89_fw_hdr_section_v1 {
#define FWSECTION_HDR_V1_W1_REDL BIT(29)
#define FWSECTION_HDR_V1_W2_MSSC GENMASK(7, 0)
#define FORMATTED_MSSC 0xFF
#define FORMATTED_MSSC_MASK GENMASK(7, 0)
#define FWSECTION_HDR_V1_W2_BBMCU_IDX GENMASK(27, 24)
struct rtw89_fw_hdr_v1 {
@ -615,6 +619,7 @@ struct rtw89_fw_hdr_v1 {
#define FW_HDR_V1_W6_DSP_CHKSUM BIT(24)
#define FW_HDR_V1_W7_PART_SIZE GENMASK(15, 0)
#define FW_HDR_V1_W7_DYN_HDR BIT(16)
#define FW_HDR_V1_W7_IDMEM_SHARE_MODE GENMASK(21, 18)
enum rtw89_fw_mss_pool_rmp_tbl_type {
MSS_POOL_RMP_TBL_BITMASK = 0x0,
@ -3689,6 +3694,13 @@ struct rtw89_c2h_pkt_ofld_rsp {
#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_OP GENMASK(10, 8)
#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_LEN GENMASK(31, 16)
struct rtw89_c2h_tx_duty_rpt {
struct rtw89_c2h_hdr c2h_hdr;
__le32 w2;
} __packed;
#define RTW89_C2H_TX_DUTY_RPT_W2_TIMER_ERR GENMASK(2, 0)
struct rtw89_c2h_wow_aoac_report {
struct rtw89_c2h_hdr c2h_hdr;
u8 rpt_ver;
@ -3713,6 +3725,15 @@ struct rtw89_c2h_wow_aoac_report {
#define RTW89_C2H_WOW_AOAC_RPT_REKEY_IDX BIT(0)
struct rtw89_h2c_tx_duty {
__le32 w0;
__le32 w1;
} __packed;
#define RTW89_H2C_TX_DUTY_W0_PAUSE_INTVL_MASK GENMASK(15, 0)
#define RTW89_H2C_TX_DUTY_W0_TX_INTVL_MASK GENMASK(31, 16)
#define RTW89_H2C_TX_DUTY_W1_STOP BIT(0)
struct rtw89_h2c_bcnfltr {
__le32 w0;
} __packed;
@ -4071,6 +4092,7 @@ enum rtw89_fw_ofld_h2c_func {
H2C_FUNC_OFLD_CFG = 0x14,
H2C_FUNC_ADD_SCANOFLD_CH = 0x16,
H2C_FUNC_SCANOFLD = 0x17,
H2C_FUNC_TX_DUTY = 0x18,
H2C_FUNC_PKT_DROP = 0x1b,
H2C_FUNC_CFG_BCNFLTR = 0x1e,
H2C_FUNC_OFLD_RSSI = 0x1f,
@ -4506,6 +4528,7 @@ int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u8 ac, u32 val);
int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_tx_duty(struct rtw89_dev *rtwdev, u8 lv);
int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool connect);

View File

@ -1444,6 +1444,7 @@ void rtw89_mac_notify_wake(struct rtw89_dev *rtwdev)
static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
{
#define PWR_ACT 1
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_pwr_cfg * const *cfg_seq;
int (*cfg_func)(struct rtw89_dev *rtwdev);
@ -1472,6 +1473,9 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
return ret;
if (on) {
if (!test_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags))
mac->efuse_read_fw_secure(rtwdev);
set_bit(RTW89_FLAG_POWERON, rtwdev->flags);
set_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags);
set_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags);
@ -3996,9 +4000,10 @@ int rtw89_mac_init(struct rtw89_dev *rtwdev)
static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
{
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
u8 i;
if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
if (rtwdev->chip->chip_gen != RTW89_CHIP_AX || sec->secure_boot)
return;
for (i = 0; i < 4; i++) {
@ -4010,7 +4015,9 @@ static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
{
if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
if (rtwdev->chip->chip_gen != RTW89_CHIP_AX || sec->secure_boot)
return;
rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR,
@ -5028,6 +5035,18 @@ rtw89_mac_c2h_pkt_ofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h,
rtw89_complete_cond(wait, cond, &data);
}
static void
rtw89_mac_c2h_tx_duty_rpt(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len)
{
struct rtw89_c2h_tx_duty_rpt *c2h =
(struct rtw89_c2h_tx_duty_rpt *)skb_c2h->data;
u8 err;
err = le32_get_bits(c2h->w2, RTW89_C2H_TX_DUTY_RPT_W2_TIMER_ERR);
rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "C2H TX duty rpt with err=%d\n", err);
}
static void
rtw89_mac_c2h_tsf32_toggle_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
u32 len)
@ -5354,6 +5373,7 @@ void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev,
[RTW89_MAC_C2H_FUNC_BCN_RESEND] = NULL,
[RTW89_MAC_C2H_FUNC_MACID_PAUSE] = rtw89_mac_c2h_macid_pause,
[RTW89_MAC_C2H_FUNC_SCANOFLD_RSP] = rtw89_mac_c2h_scanofld_rsp,
[RTW89_MAC_C2H_FUNC_TX_DUTY_RPT] = rtw89_mac_c2h_tx_duty_rpt,
[RTW89_MAC_C2H_FUNC_TSF32_TOGL_RPT] = rtw89_mac_c2h_tsf32_toggle_rpt,
[RTW89_MAC_C2H_FUNC_BCNFLTR_RPT] = rtw89_mac_c2h_bcn_fltr_rpt,
};
@ -6604,6 +6624,20 @@ int rtw89_fwdl_check_path_ready_ax(struct rtw89_dev *rtwdev,
rtwdev, R_AX_WCPU_FW_CTRL);
}
static
void rtw89_fwdl_secure_idmem_share_mode_ax(struct rtw89_dev *rtwdev, u8 mode)
{
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
if (!sec->secure_boot)
return;
rtw89_write32_mask(rtwdev, R_AX_WCPU_FW_CTRL,
B_AX_IDMEM_SHARE_MODE_RECORD_MASK, mode);
rtw89_write32_set(rtwdev, R_AX_WCPU_FW_CTRL,
B_AX_IDMEM_SHARE_MODE_RECORD_VALID);
}
const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.band1_offset = RTW89_MAC_AX_BAND_REG_OFFSET,
.filter_model_addr = R_AX_FILTER_MODEL_ADDR,
@ -6657,9 +6691,11 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.fwdl_enable_wcpu = rtw89_mac_enable_cpu_ax,
.fwdl_get_status = rtw89_fw_get_rdy_ax,
.fwdl_check_path_ready = rtw89_fwdl_check_path_ready_ax,
.fwdl_secure_idmem_share_mode = rtw89_fwdl_secure_idmem_share_mode_ax,
.parse_efuse_map = rtw89_parse_efuse_map_ax,
.parse_phycap_map = rtw89_parse_phycap_map_ax,
.cnv_efuse_state = rtw89_cnv_efuse_state_ax,
.efuse_read_fw_secure = rtw89_efuse_read_fw_secure_ax,
.cfg_plt = rtw89_mac_cfg_plt_ax,
.get_plt_cnt = rtw89_mac_get_plt_cnt_ax,

View File

@ -391,6 +391,7 @@ enum rtw89_mac_c2h_ofld_func {
RTW89_MAC_C2H_FUNC_MACID_PAUSE,
RTW89_MAC_C2H_FUNC_TSF32_TOGL_RPT = 0x6,
RTW89_MAC_C2H_FUNC_SCANOFLD_RSP = 0x9,
RTW89_MAC_C2H_FUNC_TX_DUTY_RPT = 0xa,
RTW89_MAC_C2H_FUNC_BCNFLTR_RPT = 0xd,
RTW89_MAC_C2H_FUNC_OFLD_MAX,
};
@ -984,9 +985,11 @@ struct rtw89_mac_gen_def {
bool dlfw, bool include_bb);
u8 (*fwdl_get_status)(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type);
int (*fwdl_check_path_ready)(struct rtw89_dev *rtwdev, bool h2c_or_fwdl);
void (*fwdl_secure_idmem_share_mode)(struct rtw89_dev *rtwdev, u8 mode);
int (*parse_efuse_map)(struct rtw89_dev *rtwdev);
int (*parse_phycap_map)(struct rtw89_dev *rtwdev);
int (*cnv_efuse_state)(struct rtw89_dev *rtwdev, bool idle);
int (*efuse_read_fw_secure)(struct rtw89_dev *rtwdev);
int (*cfg_plt)(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt);
u16 (*get_plt_cnt)(struct rtw89_dev *rtwdev, u8 band);
@ -1493,4 +1496,14 @@ int rtw89_mac_get_dle_rsvd_qt_cfg(struct rtw89_dev *rtwdev,
struct rtw89_mac_dle_rsvd_qt_cfg *cfg);
int rtw89_mac_cpu_io_rx(struct rtw89_dev *rtwdev, bool wow_enable);
static inline
void rtw89_fwdl_secure_idmem_share_mode(struct rtw89_dev *rtwdev, u8 mode)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
if (!mac->fwdl_secure_idmem_share_mode)
return;
return mac->fwdl_secure_idmem_share_mode(rtwdev, mode);
}
#endif

View File

@ -192,6 +192,8 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
if (!rtw89_rtwvif_in_list(rtwdev, rtwvif))
list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
INIT_LIST_HEAD(&rtwvif->mgnt_entry);
ether_addr_copy(rtwvif->mac_addr, vif->addr);
rtwvif->offchan = false;
@ -1375,6 +1377,7 @@ static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw,
rtwvif_link = rtwvif->links[link_conf->link_id];
if (unlikely(!rtwvif_link)) {
mutex_unlock(&rtwdev->mutex);
rtw89_err(rtwdev,
"%s: rtwvif link (link_id %u) is not active\n",
__func__, link_conf->link_id);

View File

@ -2600,9 +2600,11 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
.fwdl_enable_wcpu = rtw89_mac_fwdl_enable_wcpu_be,
.fwdl_get_status = fwdl_get_status_be,
.fwdl_check_path_ready = rtw89_fwdl_check_path_ready_be,
.fwdl_secure_idmem_share_mode = NULL,
.parse_efuse_map = rtw89_parse_efuse_map_be,
.parse_phycap_map = rtw89_parse_phycap_map_be,
.cnv_efuse_state = rtw89_cnv_efuse_state_be,
.efuse_read_fw_secure = rtw89_efuse_read_fw_secure_be,
.cfg_plt = rtw89_mac_cfg_plt_be,
.get_plt_cnt = rtw89_mac_get_plt_cnt_be,

View File

@ -2671,9 +2671,10 @@ static void rtw89_pci_clr_idx_all_ax(struct rtw89_dev *rtwdev)
static int rtw89_pci_poll_txdma_ch_idle_ax(struct rtw89_dev *rtwdev)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
u32 ret, check, dma_busy;
u32 dma_busy1 = info->dma_busy1.addr;
u32 dma_busy2 = info->dma_busy2_reg;
u32 check, dma_busy;
int ret;
check = info->dma_busy1.mask;
@ -2698,8 +2699,9 @@ static int rtw89_pci_poll_txdma_ch_idle_ax(struct rtw89_dev *rtwdev)
static int rtw89_pci_poll_rxdma_ch_idle_ax(struct rtw89_dev *rtwdev)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
u32 ret, check, dma_busy;
u32 dma_busy3 = info->dma_busy3_reg;
u32 check, dma_busy;
int ret;
check = B_AX_RXQ_BUSY | B_AX_RPQ_BUSY;
@ -4175,6 +4177,36 @@ static int rtw89_pci_napi_poll(struct napi_struct *napi, int budget)
return work_done;
}
static
void rtw89_check_pci_ssid_quirks(struct rtw89_dev *rtwdev,
struct pci_dev *pdev,
const struct rtw89_pci_ssid_quirk *ssid_quirks)
{
int i;
if (!ssid_quirks)
return;
for (i = 0; i < 200; i++, ssid_quirks++) {
if (ssid_quirks->vendor == 0 && ssid_quirks->device == 0)
break;
if (ssid_quirks->vendor != pdev->vendor ||
ssid_quirks->device != pdev->device ||
ssid_quirks->subsystem_vendor != pdev->subsystem_vendor ||
ssid_quirks->subsystem_device != pdev->subsystem_device)
continue;
bitmap_or(rtwdev->quirks, rtwdev->quirks, &ssid_quirks->bitmap,
NUM_OF_RTW89_QUIRKS);
rtwdev->custid = ssid_quirks->custid;
break;
}
rtw89_debug(rtwdev, RTW89_DBG_HCI, "quirks=%*ph custid=%d\n",
(int)sizeof(rtwdev->quirks), rtwdev->quirks, rtwdev->custid);
}
static int __maybe_unused rtw89_pci_suspend(struct device *dev)
{
struct ieee80211_hw *hw = dev_get_drvdata(dev);
@ -4349,6 +4381,7 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
rtwdev->hci.cpwm_addr = pci_info->cpwm_addr;
rtw89_check_quirks(rtwdev, info->quirks);
rtw89_check_pci_ssid_quirks(rtwdev, pdev, pci_info->ssid_quirks);
SET_IEEE80211_DEV(rtwdev->hw, &pdev->dev);

View File

@ -1292,6 +1292,19 @@ struct rtw89_pci_gen_def {
void (*disable_eq)(struct rtw89_dev *rtwdev);
};
#define RTW89_PCI_SSID(v, d, ssv, ssd, cust) \
.vendor = v, .device = d, .subsystem_vendor = ssv, .subsystem_device = ssd, \
.custid = RTW89_CUSTID_ ##cust
struct rtw89_pci_ssid_quirk {
unsigned short vendor;
unsigned short device;
unsigned short subsystem_vendor;
unsigned short subsystem_device;
enum rtw89_custid custid;
unsigned long bitmap; /* bitmap of rtw89_quirks */
};
struct rtw89_pci_info {
const struct rtw89_pci_gen_def *gen_def;
enum mac_ax_bd_trunc_mode txbd_trunc_mode;
@ -1345,6 +1358,8 @@ struct rtw89_pci_info {
void (*recognize_intrs)(struct rtw89_dev *rtwdev,
struct rtw89_pci *rtwpci,
struct rtw89_pci_isrs *isrs);
const struct rtw89_pci_ssid_quirk *ssid_quirks;
};
struct rtw89_pci_tx_data {

View File

@ -4836,11 +4836,36 @@ static void rtw89_phy_antdiv_init(struct rtw89_dev *rtwdev)
rtw89_phy_antdiv_reg_init(rtwdev);
}
static void rtw89_phy_thermal_protect(struct rtw89_dev *rtwdev)
{
struct rtw89_phy_stat *phystat = &rtwdev->phystat;
struct rtw89_hal *hal = &rtwdev->hal;
u8 th_max = phystat->last_thermal_max;
u8 lv = hal->thermal_prot_lv;
if (!hal->thermal_prot_th ||
(hal->disabled_dm_bitmap & BIT(RTW89_DM_THERMAL_PROTECT)))
return;
if (th_max > hal->thermal_prot_th && lv < RTW89_THERMAL_PROT_LV_MAX)
lv++;
else if (th_max < hal->thermal_prot_th - 2 && lv > 0)
lv--;
else
return;
hal->thermal_prot_lv = lv;
rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "thermal protection lv=%d\n", lv);
rtw89_fw_h2c_tx_duty(rtwdev, hal->thermal_prot_lv);
}
static void rtw89_phy_stat_thermal_update(struct rtw89_dev *rtwdev)
{
struct rtw89_phy_stat *phystat = &rtwdev->phystat;
u8 th, th_max = 0;
int i;
u8 th;
for (i = 0; i < rtwdev->chip->rf_path_num; i++) {
th = rtw89_chip_get_thermal(rtwdev, i);
@ -4850,7 +4875,11 @@ static void rtw89_phy_stat_thermal_update(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
"path(%d) thermal cur=%u avg=%ld", i, th,
ewma_thermal_read(&phystat->avg_thermal[i]));
th_max = max(th_max, th);
}
phystat->last_thermal_max = th_max;
}
struct rtw89_phy_iter_rssi_data {
@ -4923,6 +4952,8 @@ static void rtw89_phy_stat_init(struct rtw89_dev *rtwdev)
memset(&phystat->last_pkt_stat, 0, sizeof(phystat->last_pkt_stat));
ewma_rssi_init(&phystat->bcn_rssi);
rtwdev->hal.thermal_prot_lv = 0;
}
void rtw89_phy_stat_track(struct rtw89_dev *rtwdev)
@ -4930,6 +4961,7 @@ void rtw89_phy_stat_track(struct rtw89_dev *rtwdev)
struct rtw89_phy_stat *phystat = &rtwdev->phystat;
rtw89_phy_stat_thermal_update(rtwdev);
rtw89_phy_thermal_protect(rtwdev);
rtw89_phy_stat_rssi_update(rtwdev);
phystat->last_pkt_stat = phystat->cur_pkt_stat;

View File

@ -196,6 +196,8 @@
#define R_AX_HALT_C2H 0x016C
#define R_AX_WCPU_FW_CTRL 0x01E0
#define B_AX_IDMEM_SHARE_MODE_RECORD_MASK GENMASK(27, 24)
#define B_AX_IDMEM_SHARE_MODE_RECORD_VALID BIT(23)
#define B_AX_WCPU_FWDL_STS_MASK GENMASK(7, 5)
#define B_AX_FWDL_PATH_RDY BIT(2)
#define B_AX_H2C_PATH_RDY BIT(1)

View File

@ -646,22 +646,44 @@ static void rtw89_regd_apply_policy_unii4(struct rtw89_dev *rtwdev,
sband->channels[i].flags |= IEEE80211_CHAN_DISABLED;
}
static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev,
struct wiphy *wiphy)
static bool regd_is_6ghz_blocked(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_regd *regd = regulatory->regd;
struct ieee80211_supported_band *sband;
u8 index;
int i;
index = rtw89_regd_get_index(regd);
if (index != RTW89_REGD_MAX_COUNTRY_NUM &&
!test_bit(index, regulatory->block_6ghz))
return;
return false;
rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is blocked by policy\n",
regd->alpha2[0], regd->alpha2[1]);
return true;
}
static bool regd_is_6ghz_not_applicable(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_regd *regd = regulatory->regd;
if (regd->txpwr_regd[RTW89_BAND_6G] != RTW89_NA)
return false;
rtw89_debug(rtwdev, RTW89_DBG_REGD, "%c%c 6 GHz is N/A in regd map\n",
regd->alpha2[0], regd->alpha2[1]);
return true;
}
static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev,
struct wiphy *wiphy)
{
struct ieee80211_supported_band *sband;
int i;
if (!regd_is_6ghz_blocked(rtwdev) &&
!regd_is_6ghz_not_applicable(rtwdev))
return;
sband = wiphy->bands[NL80211_BAND_6GHZ];
if (!sband)

View File

@ -282,7 +282,7 @@ static int rtw8851b_pwr_on_func(struct rtw89_dev *rtwdev)
{
u32 val32;
u8 val8;
u32 ret;
int ret;
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN |
B_AX_AFSM_PCIE_SUS_EN);
@ -401,7 +401,7 @@ static void rtw8851b_patch_swr_pfm2pwm(struct rtw89_dev *rtwdev)
static int rtw8851b_pwr_off_func(struct rtw89_dev *rtwdev)
{
u32 val32;
u32 ret;
int ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
XTAL_SI_RFC2RF);
@ -2454,6 +2454,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.wde_qempty_acq_grpnum = 4,
.wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000},
.thermal_th = {0x32, 0x35},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
.bb_table = &rtw89_8851b_phy_bb_table,

View File

@ -60,6 +60,8 @@ static const struct rtw89_pci_info rtw8851b_pci_info = {
.enable_intr = rtw89_pci_enable_intr,
.disable_intr = rtw89_pci_disable_intr,
.recognize_intrs = rtw89_pci_recognize_intrs,
.ssid_quirks = NULL,
};
static const struct rtw89_driver_info rtw89_8851be_info = {

View File

@ -2170,6 +2170,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.wde_qempty_acq_grpnum = 16,
.wde_qempty_mgq_grpsel = 16,
.rf_base_addr = {0xc000, 0xd000},
.thermal_th = {0x32, 0x35},
.pwr_on_seq = pwr_on_seq_8852a,
.pwr_off_seq = pwr_off_seq_8852a,
.bb_table = &rtw89_8852a_phy_bb_table,

View File

@ -58,6 +58,8 @@ static const struct rtw89_pci_info rtw8852a_pci_info = {
.enable_intr = rtw89_pci_enable_intr,
.disable_intr = rtw89_pci_disable_intr,
.recognize_intrs = rtw89_pci_recognize_intrs,
.ssid_quirks = NULL,
};
static const struct rtw89_driver_info rtw89_8852ae_info = {

View File

@ -254,7 +254,7 @@ static void rtw8852b_pwr_sps_ana(struct rtw89_dev *rtwdev)
static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev)
{
u32 val32;
u32 ret;
int ret;
rtw8852b_pwr_sps_ana(rtwdev);
@ -383,7 +383,7 @@ static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev)
static int rtw8852b_pwr_off_func(struct rtw89_dev *rtwdev)
{
u32 val32;
u32 ret;
int ret;
rtw8852b_pwr_sps_ana(rtwdev);
@ -808,6 +808,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.wde_qempty_acq_grpnum = 4,
.wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000, 0xf000},
.thermal_th = {0x32, 0x35},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
.bb_table = &rtw89_8852b_phy_bb_table,

View File

@ -905,7 +905,6 @@ static void rtw8852bx_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw,
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
u32 rx_path_0;
u32 val;
rx_path_0 = rtw89_phy_read32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, phy_idx);
@ -985,12 +984,11 @@ static void rtw8852bx_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw,
rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD_V1, B_CHBW_MOD_PRICH,
pri_ch, phy_idx);
/*Set RF mode at A */
val = chip_id == RTL8852BT ? 0x333 : 0xaaa;
/*Set RF mode at 3 */
rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX,
B_P0_RFMODE_ORI_RX_ALL, val, phy_idx);
B_P0_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX,
B_P1_RFMODE_ORI_RX_ALL, val, phy_idx);
B_P1_RFMODE_ORI_RX_ALL, 0x333, phy_idx);
break;
default:
rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw,

View File

@ -60,6 +60,8 @@ static const struct rtw89_pci_info rtw8852b_pci_info = {
.enable_intr = rtw89_pci_enable_intr,
.disable_intr = rtw89_pci_disable_intr,
.recognize_intrs = rtw89_pci_recognize_intrs,
.ssid_quirks = NULL,
};
static const struct rtw89_driver_info rtw89_8852be_info = {

View File

@ -244,7 +244,7 @@ static const u8 rtw89_btc_8852bt_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30,
static int rtw8852bt_pwr_on_func(struct rtw89_dev *rtwdev)
{
u32 val32;
u32 ret;
int ret;
rtw89_write32_set(rtwdev, R_AX_LDO_AON_CTRL0, B_AX_PD_REGU_L);
rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN |
@ -357,7 +357,7 @@ static int rtw8852bt_pwr_on_func(struct rtw89_dev *rtwdev)
static int rtw8852bt_pwr_off_func(struct rtw89_dev *rtwdev)
{
u32 val32;
u32 ret;
int ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
XTAL_SI_RFC2RF);
@ -742,6 +742,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
.wde_qempty_acq_grpnum = 4,
.wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000, 0xf000},
.thermal_th = {0x32, 0x35},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
.bb_table = NULL,

View File

@ -60,6 +60,8 @@ static const struct rtw89_pci_info rtw8852bt_pci_info = {
.enable_intr = rtw89_pci_enable_intr,
.disable_intr = rtw89_pci_disable_intr,
.recognize_intrs = rtw89_pci_recognize_intrs,
.ssid_quirks = NULL,
};
static const struct rtw89_driver_info rtw89_8852bte_info = {

View File

@ -203,7 +203,7 @@ static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path,
static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
{
u32 val32;
u32 ret;
int ret;
val32 = rtw89_read32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_PAD_HCI_SEL_V2_MASK);
if (val32 == MAC_AX_HCI_SEL_PCIE_USB)
@ -324,7 +324,7 @@ static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
{
u32 val32;
u32 ret;
int ret;
ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
XTAL_SI_RFC2RF);
@ -2947,6 +2947,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.wde_qempty_acq_grpnum = 16,
.wde_qempty_mgq_grpsel = 16,
.rf_base_addr = {0xe000, 0xf000},
.thermal_th = {0x32, 0x35},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
.bb_table = &rtw89_8852c_phy_bb_table,

View File

@ -1065,7 +1065,7 @@ static bool _iqk_nbtxk(struct rtw89_dev *rtwdev,
static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path)
{
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
u8 idx = rfk_mcc->table_idx;
bool is_fail1, is_fail2;
@ -1408,7 +1408,7 @@ static void _iqk_afebb_restore(struct rtw89_dev *rtwdev,
static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path)
{
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
u8 idx = 0;
idx = rfk_mcc->table_idx;
@ -4105,7 +4105,7 @@ void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev,
void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V0] = {};
const struct rtw89_chan *chan;
enum rtw89_entity_mode mode;

View File

@ -67,6 +67,8 @@ static const struct rtw89_pci_info rtw8852c_pci_info = {
.enable_intr = rtw89_pci_enable_intr_v1,
.disable_intr = rtw89_pci_disable_intr_v1,
.recognize_intrs = rtw89_pci_recognize_intrs_v1,
.ssid_quirks = NULL,
};
static const struct dmi_system_id rtw8852c_pci_quirks[] = {

View File

@ -2,6 +2,7 @@
/* Copyright(c) 2023 Realtek Corporation
*/
#include "chan.h"
#include "coex.h"
#include "debug.h"
#include "efuse.h"
@ -398,9 +399,6 @@ static int rtw8922a_pwr_on_func(struct rtw89_dev *rtwdev)
rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_FEN_BB_IP_RSTN |
B_BE_FEN_BBPLAT_RSTB);
if (!test_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags))
rtw89_efuse_read_fw_secure_be(rtwdev);
return 0;
}
@ -965,6 +963,42 @@ static const struct rtw8922a_bb_gain bb_gain_tia[TIA_GAIN_NUM] = {
.gain_g_mask = 0x1FF, .gain_a_mask = 0x3FE00 },
};
static const struct rtw8922a_bb_gain bb_op1db_lna[LNA_GAIN_NUM] = {
{ .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x4078, 0x4478},
.gain_g_mask = 0xFF00, .gain_a_mask = 0xFF000000},
{ .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x407c, 0x447c},
.gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF},
{ .gain_g = {0x40ac, 0x44ac}, .gain_a = {0x407c, 0x447c},
.gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF00},
{ .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x407c, 0x447c},
.gain_g_mask = 0xFF, .gain_a_mask = 0xFF0000},
{ .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x407c, 0x447c},
.gain_g_mask = 0xFF00, .gain_a_mask = 0xFF000000},
{ .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x4080, 0x4480},
.gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF},
{ .gain_g = {0x40b0, 0x44b0}, .gain_a = {0x4080, 0x4480},
.gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF00},
};
static const struct rtw8922a_bb_gain bb_op1db_tia_lna[TIA_LNA_OP1DB_NUM] = {
{ .gain_g = {0x40b4, 0x44b4}, .gain_a = {0x4080, 0x4480},
.gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF000000},
{ .gain_g = {0x40b4, 0x44b4}, .gain_a = {0x4084, 0x4484},
.gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF},
{ .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484},
.gain_g_mask = 0xFF, .gain_a_mask = 0xFF00},
{ .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484},
.gain_g_mask = 0xFF00, .gain_a_mask = 0xFF0000},
{ .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4084, 0x4484},
.gain_g_mask = 0xFF0000, .gain_a_mask = 0xFF000000},
{ .gain_g = {0x40b8, 0x44b8}, .gain_a = {0x4088, 0x4488},
.gain_g_mask = 0xFF000000, .gain_a_mask = 0xFF},
{ .gain_g = {0x40bc, 0x44bc}, .gain_a = {0x4088, 0x4488},
.gain_g_mask = 0xFF, .gain_a_mask = 0xFF00},
{ .gain_g = {0x40bc, 0x44bc}, .gain_a = {0x4088, 0x4488},
.gain_g_mask = 0xFF00, .gain_a_mask = 0xFF0000},
};
struct rtw8922a_bb_gain_bypass {
u32 gain_g[BB_PATH_NUM_8922A];
u32 gain_a[BB_PATH_NUM_8922A];
@ -1056,6 +1090,30 @@ static void rtw8922a_set_lna_tia_gain(struct rtw89_dev *rtwdev,
val = gain->tia_gain[gain_band][bw_type][path][i];
rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
}
for (i = 0; i < LNA_GAIN_NUM; i++) {
if (chan->band_type == RTW89_BAND_2G) {
reg = bb_op1db_lna[i].gain_g[path];
mask = bb_op1db_lna[i].gain_g_mask;
} else {
reg = bb_op1db_lna[i].gain_a[path];
mask = bb_op1db_lna[i].gain_a_mask;
}
val = gain->lna_op1db[gain_band][bw_type][path][i];
rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
}
for (i = 0; i < TIA_LNA_OP1DB_NUM; i++) {
if (chan->band_type == RTW89_BAND_2G) {
reg = bb_op1db_tia_lna[i].gain_g[path];
mask = bb_op1db_tia_lna[i].gain_g_mask;
} else {
reg = bb_op1db_tia_lna[i].gain_a[path];
mask = bb_op1db_tia_lna[i].gain_a_mask;
}
val = gain->tia_lna_op1db[gain_band][bw_type][path][i];
rtw89_phy_write32_idx(rtwdev, reg, mask, val, phy_idx);
}
}
static void rtw8922a_set_gain(struct rtw89_dev *rtwdev,
@ -1745,7 +1803,7 @@ static void rtw8922a_digital_pwr_comp(struct rtw89_dev *rtwdev,
static int rtw8922a_ctrl_mlo(struct rtw89_dev *rtwdev, enum rtw89_mlo_dbcc_mode mode)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
const struct rtw89_chan *chan0, *chan1;
if (mode == MLO_1_PLUS_1_1RF || mode == DBCC_LEGACY) {
rtw89_phy_write32_mask(rtwdev, R_DBCC, B_DBCC_EN, 0x1);
@ -1758,13 +1816,20 @@ static int rtw8922a_ctrl_mlo(struct rtw89_dev *rtwdev, enum rtw89_mlo_dbcc_mode
return -EOPNOTSUPP;
}
if (mode == MLO_2_PLUS_0_1RF) {
rtw8922a_ctrl_afe_dac(rtwdev, chan->band_width, RF_PATH_A);
rtw8922a_ctrl_afe_dac(rtwdev, chan->band_width, RF_PATH_B);
if (mode == MLO_1_PLUS_1_1RF) {
chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
} else if (mode == MLO_0_PLUS_2_1RF) {
chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
chan0 = chan1;
} else {
rtw89_warn(rtwdev, "unsupported MLO mode %d\n", mode);
chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
chan1 = chan0;
}
rtw8922a_ctrl_afe_dac(rtwdev, chan0->band_width, RF_PATH_A);
rtw8922a_ctrl_afe_dac(rtwdev, chan1->band_width, RF_PATH_B);
rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x6180);
if (mode == MLO_2_PLUS_0_1RF) {
@ -2218,10 +2283,12 @@ static void rtw8922a_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
static u8 rtw8922a_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path)
{
struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
struct rtw89_hal *hal = &rtwdev->hal;
int th;
/* read thermal only if debugging */
if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_CFO | RTW89_DBG_RFK_TRACK))
/* read thermal only if debugging or thermal protection enabled */
if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_CFO | RTW89_DBG_RFK_TRACK) &&
!hal->thermal_prot_th)
return 80;
rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1);
@ -2652,6 +2719,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.wde_qempty_acq_grpnum = 4,
.wde_qempty_mgq_grpsel = 4,
.rf_base_addr = {0xe000, 0xf000},
.thermal_th = {0xad, 0xb4},
.pwr_on_seq = NULL,
.pwr_off_seq = NULL,
.bb_table = NULL,

View File

@ -252,49 +252,58 @@ static void rtw8922a_chlk_ktbl_sel(struct rtw89_dev *rtwdev, u8 kpath, u8 idx)
}
}
static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev)
static u8 rtw8922a_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan, u8 path)
{
struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {};
enum rtw89_chanctx_idx chanctx_idx;
const struct rtw89_chan *chan;
enum rtw89_entity_mode mode;
u8 s0_tbl, s1_tbl;
u8 tbl_sel;
mode = rtw89_get_entity_mode(rtwdev);
switch (mode) {
case RTW89_ENTITY_MODE_MCC_PREPARE:
chanctx_idx = RTW89_CHANCTX_1;
break;
default:
chanctx_idx = RTW89_CHANCTX_0;
break;
}
chan = rtw89_chan_get(rtwdev, chanctx_idx);
for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) {
struct rtw89_rfk_chan_desc *p = &desc[tbl_sel];
p->ch = rfk_mcc->ch[tbl_sel];
p->ch = rfk_mcc->data[path].ch[tbl_sel];
p->has_band = true;
p->band = rfk_mcc->band[tbl_sel];
p->band = rfk_mcc->data[path].band[tbl_sel];
p->has_bw = true;
p->bw = rfk_mcc->bw[tbl_sel];
p->bw = rfk_mcc->data[path].bw[tbl_sel];
}
tbl_sel = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan);
rfk_mcc->ch[tbl_sel] = chan->channel;
rfk_mcc->band[tbl_sel] = chan->band_type;
rfk_mcc->bw[tbl_sel] = chan->band_width;
rfk_mcc->table_idx = tbl_sel;
rfk_mcc->data[path].ch[tbl_sel] = chan->channel;
rfk_mcc->data[path].band[tbl_sel] = chan->band_type;
rfk_mcc->data[path].bw[tbl_sel] = chan->band_width;
rfk_mcc->data[path].table_idx = tbl_sel;
s0_tbl = tbl_sel;
s1_tbl = tbl_sel;
return tbl_sel;
}
static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev)
{
const struct rtw89_chan *chan0, *chan1;
u8 s0_tbl, s1_tbl;
switch (rtwdev->mlo_dbcc_mode) {
default:
case MLO_2_PLUS_0_1RF:
chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
chan1 = chan0;
break;
case MLO_0_PLUS_2_1RF:
chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
chan0 = chan1;
break;
case MLO_1_PLUS_1_1RF:
chan0 = rtw89_mgnt_chan_get(rtwdev, 0);
chan1 = rtw89_mgnt_chan_get(rtwdev, 1);
break;
}
s0_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, chan0, 0);
s1_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, chan1, 1);
rtw8922a_chlk_ktbl_sel(rtwdev, RF_A, s0_tbl);
rtw8922a_chlk_ktbl_sel(rtwdev, RF_B, s1_tbl);

View File

@ -9,6 +9,12 @@
#include "reg.h"
#include "rtw8922a.h"
static const struct rtw89_pci_ssid_quirk rtw8922a_pci_ssid_quirks[] = {
{RTW89_PCI_SSID(PCI_VENDOR_ID_REALTEK, 0x8922, 0x10EC, 0xA891, DELL),
.bitmap = BIT(RTW89_QUIRK_THERMAL_PROT_120C)},
{},
};
static const struct rtw89_pci_info rtw8922a_pci_info = {
.gen_def = &rtw89_pci_gen_be,
.txbd_trunc_mode = MAC_AX_BD_TRUNC,
@ -58,6 +64,8 @@ static const struct rtw89_pci_info rtw8922a_pci_info = {
.enable_intr = rtw89_pci_enable_intr_v2,
.disable_intr = rtw89_pci_disable_intr_v2,
.recognize_intrs = rtw89_pci_recognize_intrs_v2,
.ssid_quirks = rtw8922a_pci_ssid_quirks,
};
static const struct rtw89_driver_info rtw89_8922ae_info = {

View File

@ -27,8 +27,8 @@ static enum rtw89_sar_subband rtw89_sar_get_subband(struct rtw89_dev *rtwdev,
return RTW89_SAR_5GHZ_SUBBAND_1_2;
case 5500 ... 5720:
return RTW89_SAR_5GHZ_SUBBAND_2_E;
case 5745 ... 5825:
return RTW89_SAR_5GHZ_SUBBAND_3;
case 5745 ... 5885:
return RTW89_SAR_5GHZ_SUBBAND_3_4;
case 5955 ... 6155:
return RTW89_SAR_6GHZ_SUBBAND_5_L;
case 6175 ... 6415:
@ -295,7 +295,7 @@ static const struct cfg80211_sar_freq_ranges rtw89_common_sar_freq_ranges[] = {
{ .start_freq = 2412, .end_freq = 2484, },
{ .start_freq = 5180, .end_freq = 5320, },
{ .start_freq = 5500, .end_freq = 5720, },
{ .start_freq = 5745, .end_freq = 5825, },
{ .start_freq = 5745, .end_freq = 5885, },
{ .start_freq = 5955, .end_freq = 6155, },
{ .start_freq = 6175, .end_freq = 6415, },
{ .start_freq = 6435, .end_freq = 6515, },