diff options
| author | Johannes Berg <johannes.berg@intel.com> | 2026-01-19 12:15:00 +0300 |
|---|---|---|
| committer | Johannes Berg <johannes.berg@intel.com> | 2026-01-19 12:15:23 +0300 |
| commit | 0acd76b728f35b799fb4beee9853a33acb5e2888 (patch) | |
| tree | 53f1972873a4d1965adf5a3b27d32e91a1995f92 | |
| parent | 3d2515fdd336b2c785f0568c3b015920261cca10 (diff) | |
| parent | 5e632c7ca9e15a1bc1e114bcfd5210add909e7a4 (diff) | |
| download | linux-0acd76b728f35b799fb4beee9853a33acb5e2888.tar.xz | |
Merge tag 'rtw-next-2026-01-15' of https://github.com/pkshih/rtw
Ping-Ke Shih says:
==================
rtw-next patches for -next release.
Main changes are to prepare to support RTL8922DE, including refactor/add
register settings in common flow, and add newly firmware command/event
handlers.
Others are some random fixes and improvements across all drivers.
==================
Link: https://patch.msgid.link/006be16d-61ba-4af8-b76a-bc94100c3555@RTKEXHMBS03.realtek.com.tw
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
46 files changed, 3681 insertions, 397 deletions
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c index c06ad064f37c..f9a527f6a175 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c @@ -7826,6 +7826,7 @@ static int rtl8xxxu_probe(struct usb_interface *interface, goto err_set_intfdata; hw->vif_data_size = sizeof(struct rtl8xxxu_vif); + hw->sta_data_size = sizeof(struct rtl8xxxu_sta_info); hw->wiphy->max_scan_ssids = 1; hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; diff --git a/drivers/net/wireless/realtek/rtlwifi/regd.c b/drivers/net/wireless/realtek/rtlwifi/regd.c index 0bc4afa4fda3..fd967006b3e1 100644 --- a/drivers/net/wireless/realtek/rtlwifi/regd.c +++ b/drivers/net/wireless/realtek/rtlwifi/regd.c @@ -206,7 +206,7 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy, } /* - *If a country IE has been recieved check its rule for this + *If a country IE has been received check its rule for this *channel first before enabling active scan. The passive scan *would have been enforced by the initial processing of our *custom regulatory domain. diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index fa0ed39cb199..c4f9758b4e96 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -730,10 +730,10 @@ void rtw_set_rx_freq_band(struct rtw_rx_pkt_stat *pkt_stat, u8 channel) } EXPORT_SYMBOL(rtw_set_rx_freq_band); -void rtw_set_dtim_period(struct rtw_dev *rtwdev, int dtim_period) +void rtw_set_dtim_period(struct rtw_dev *rtwdev, u8 dtim_period) { rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_TIMIE); - rtw_write8(rtwdev, REG_DTIM_COUNTER_ROOT, dtim_period - 1); + rtw_write8(rtwdev, REG_DTIM_COUNTER_ROOT, dtim_period ? dtim_period - 1 : 0); } void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel, @@ -1483,6 +1483,8 @@ void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif, set_bit(RTW_FLAG_DIG_DISABLE, rtwdev->flags); set_bit(RTW_FLAG_SCANNING, rtwdev->flags); + + rtw_phy_dig_set_max_coverage(rtwdev); } void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, @@ -1494,6 +1496,7 @@ void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, if (!rtwvif) return; + rtw_phy_dig_reset(rtwdev); clear_bit(RTW_FLAG_SCANNING, rtwdev->flags); clear_bit(RTW_FLAG_DIG_DISABLE, rtwdev->flags); @@ -1658,14 +1661,41 @@ static u16 rtw_get_max_scan_ie_len(struct rtw_dev *rtwdev) return len; } +static struct ieee80211_supported_band * +rtw_sband_dup(struct rtw_dev *rtwdev, + const struct ieee80211_supported_band *sband) +{ + struct ieee80211_supported_band *dup; + + dup = devm_kmemdup(rtwdev->dev, sband, sizeof(*sband), GFP_KERNEL); + if (!dup) + return NULL; + + dup->channels = devm_kmemdup_array(rtwdev->dev, sband->channels, + sband->n_channels, + sizeof(*sband->channels), + GFP_KERNEL); + if (!dup->channels) + return NULL; + + dup->bitrates = devm_kmemdup_array(rtwdev->dev, sband->bitrates, + sband->n_bitrates, + sizeof(*sband->bitrates), + GFP_KERNEL); + if (!dup->bitrates) + return NULL; + + return dup; +} + static void rtw_set_supported_band(struct ieee80211_hw *hw, const struct rtw_chip_info *chip) { - struct rtw_dev *rtwdev = hw->priv; struct ieee80211_supported_band *sband; + struct rtw_dev *rtwdev = hw->priv; if (chip->band & RTW_BAND_2G) { - sband = kmemdup(&rtw_band_2ghz, sizeof(*sband), GFP_KERNEL); + sband = rtw_sband_dup(rtwdev, &rtw_band_2ghz); if (!sband) goto err_out; if (chip->ht_supported) @@ -1674,7 +1704,7 @@ static void rtw_set_supported_band(struct ieee80211_hw *hw, } if (chip->band & RTW_BAND_5G) { - sband = kmemdup(&rtw_band_5ghz, sizeof(*sband), GFP_KERNEL); + sband = rtw_sband_dup(rtwdev, &rtw_band_5ghz); if (!sband) goto err_out; if (chip->ht_supported) @@ -1690,13 +1720,6 @@ err_out: rtw_err(rtwdev, "failed to set supported band\n"); } -static void rtw_unset_supported_band(struct ieee80211_hw *hw, - const struct rtw_chip_info *chip) -{ - kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]); - kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]); -} - static void rtw_vif_smps_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { @@ -2320,10 +2343,7 @@ EXPORT_SYMBOL(rtw_register_hw); void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) { - const struct rtw_chip_info *chip = rtwdev->chip; - ieee80211_unregister_hw(hw); - rtw_unset_supported_band(hw, chip); rtw_debugfs_deinit(rtwdev); rtw_led_deinit(rtwdev); } @@ -2444,10 +2464,10 @@ void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool enable) if (enable) { rtw_write32_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); - rtw_write32_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); + rtw_write8_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); } else { rtw_write32_clr(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); - rtw_write32_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); + rtw_write8_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); } } diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 43ed6d6b4291..1ab70214ce36 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -2226,7 +2226,7 @@ enum nl80211_band rtw_hw_to_nl80211_band(enum rtw_supported_band hw_band) } void rtw_set_rx_freq_band(struct rtw_rx_pkt_stat *pkt_stat, u8 channel); -void rtw_set_dtim_period(struct rtw_dev *rtwdev, int dtim_period); +void rtw_set_dtim_period(struct rtw_dev *rtwdev, u8 dtim_period); void rtw_get_channel_params(struct cfg80211_chan_def *chandef, struct rtw_channel_params *ch_param); bool check_hw_ready(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target); diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c index 55be0d8e0c28..e2ac5c6fd500 100644 --- a/drivers/net/wireless/realtek/rtw88/phy.c +++ b/drivers/net/wireless/realtek/rtw88/phy.c @@ -370,6 +370,26 @@ static void rtw_phy_statistics(struct rtw_dev *rtwdev) #define DIG_CVRG_MIN 0x1c #define DIG_RSSI_GAIN_OFFSET 15 +void rtw_phy_dig_set_max_coverage(struct rtw_dev *rtwdev) +{ + /* Lower values result in greater coverage. */ + rtw_dbg(rtwdev, RTW_DBG_PHY, "Setting IGI=%#x for max coverage\n", + DIG_CVRG_MIN); + + rtw_phy_dig_write(rtwdev, DIG_CVRG_MIN); +} + +void rtw_phy_dig_reset(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 last_igi; + + last_igi = dm_info->igi_history[0]; + rtw_dbg(rtwdev, RTW_DBG_PHY, "Resetting IGI=%#x\n", last_igi); + + rtw_phy_dig_write(rtwdev, last_igi); +} + static bool rtw_phy_dig_check_damping(struct rtw_dm_info *dm_info) { diff --git a/drivers/net/wireless/realtek/rtw88/phy.h b/drivers/net/wireless/realtek/rtw88/phy.h index c9e6b869661d..8449936497bb 100644 --- a/drivers/net/wireless/realtek/rtw88/phy.h +++ b/drivers/net/wireless/realtek/rtw88/phy.h @@ -146,6 +146,8 @@ static inline int rtw_check_supported_rfe(struct rtw_dev *rtwdev) } void rtw_phy_dig_write(struct rtw_dev *rtwdev, u8 igi); +void rtw_phy_dig_reset(struct rtw_dev *rtwdev); +void rtw_phy_dig_set_max_coverage(struct rtw_dev *rtwdev); struct rtw_power_params { u8 pwr_base; diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821cu.c b/drivers/net/wireless/realtek/rtw88/rtw8821cu.c index 7a0fffc359e2..8cd09d66655d 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821cu.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8821cu.c @@ -37,6 +37,8 @@ static const struct usb_device_id rtw_8821cu_id_table[] = { .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Edimax */ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd811, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0105, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Mercusys */ {}, }; MODULE_DEVICE_TABLE(usb, rtw_8821cu_id_table); diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c index 89b6485b229a..4d88cc2f4148 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c @@ -1005,7 +1005,8 @@ static int rtw8822b_set_antenna(struct rtw_dev *rtwdev, hal->antenna_tx = antenna_tx; hal->antenna_rx = antenna_rx; - rtw8822b_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false); + if (test_bit(RTW_FLAG_POWERON, rtwdev->flags)) + rtw8822b_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false); return 0; } diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index 9370cbda945c..9f63d67777fa 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -1140,3 +1140,137 @@ void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev, le32_encode_bits(mld_bssid[5], DCTLINFO_V2_W12_MLD_BSSID_5); h2c->m12 = cpu_to_le32(DCTLINFO_V2_W12_ALL); } + +void rtw89_cam_fill_dctl_sec_cam_info_v3(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct rtw89_h2c_dctlinfo_ud_v3 *h2c) +{ + 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_V3_C0_MACID) | + le32_encode_bits(1, DCTLINFO_V3_C0_OP); + + h2c->w2 = le32_encode_bits(is_mld, DCTLINFO_V3_W2_IS_MLD); + h2c->m2 = cpu_to_le32(DCTLINFO_V3_W2_IS_MLD); + + h2c->w4 = le32_encode_bits(addr_cam->sec_ent_keyid[0], + DCTLINFO_V3_W4_SEC_ENT0_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[1], + DCTLINFO_V3_W4_SEC_ENT1_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[2], + DCTLINFO_V3_W4_SEC_ENT2_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[3], + DCTLINFO_V3_W4_SEC_ENT3_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[4], + DCTLINFO_V3_W4_SEC_ENT4_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[5], + DCTLINFO_V3_W4_SEC_ENT5_KEYID) | + le32_encode_bits(addr_cam->sec_ent_keyid[6], + DCTLINFO_V3_W4_SEC_ENT6_KEYID); + h2c->m4 = cpu_to_le32(DCTLINFO_V3_W4_SEC_ENT0_KEYID | + DCTLINFO_V3_W4_SEC_ENT1_KEYID | + DCTLINFO_V3_W4_SEC_ENT2_KEYID | + DCTLINFO_V3_W4_SEC_ENT3_KEYID | + DCTLINFO_V3_W4_SEC_ENT4_KEYID | + DCTLINFO_V3_W4_SEC_ENT5_KEYID | + DCTLINFO_V3_W4_SEC_ENT6_KEYID); + + h2c->w5 = le32_encode_bits(addr_cam->sec_cam_map[0], + DCTLINFO_V3_W5_SEC_ENT_VALID_V1); + h2c->m5 = cpu_to_le32(DCTLINFO_V3_W5_SEC_ENT_VALID_V1); + + h2c->w6 = le32_encode_bits(addr_cam->sec_ent[0], + DCTLINFO_V3_W6_SEC_ENT0_V2) | + le32_encode_bits(addr_cam->sec_ent[1], + DCTLINFO_V3_W6_SEC_ENT1_V2) | + le32_encode_bits(addr_cam->sec_ent[2], + DCTLINFO_V3_W6_SEC_ENT2_V2); + h2c->m6 = cpu_to_le32(DCTLINFO_V3_W6_SEC_ENT0_V2 | + DCTLINFO_V3_W6_SEC_ENT1_V2 | + DCTLINFO_V3_W6_SEC_ENT2_V2); + + h2c->w7 = le32_encode_bits(addr_cam->sec_ent[3], + DCTLINFO_V3_W7_SEC_ENT3_V2) | + le32_encode_bits(addr_cam->sec_ent[4], + DCTLINFO_V3_W7_SEC_ENT4_V2) | + le32_encode_bits(addr_cam->sec_ent[5], + DCTLINFO_V3_W7_SEC_ENT5_V2); + h2c->m7 = cpu_to_le32(DCTLINFO_V3_W7_SEC_ENT3_V2 | + DCTLINFO_V3_W7_SEC_ENT4_V2 | + DCTLINFO_V3_W7_SEC_ENT5_V2); + + h2c->w8 = le32_encode_bits(addr_cam->sec_ent[6], + DCTLINFO_V3_W8_SEC_ENT6_V2); + h2c->m8 = cpu_to_le32(DCTLINFO_V3_W8_SEC_ENT6_V2); + + if (rtw_wow->ptk_alg) { + h2c->w0 = le32_encode_bits(ptk_tx_iv[0] | ptk_tx_iv[1] << 8, + DCTLINFO_V3_W0_AES_IV_L); + h2c->m0 = cpu_to_le32(DCTLINFO_V3_W0_AES_IV_L); + + h2c->w1 = le32_encode_bits(ptk_tx_iv[4] | + ptk_tx_iv[5] << 8 | + ptk_tx_iv[6] << 16 | + ptk_tx_iv[7] << 24, + DCTLINFO_V3_W1_AES_IV_H); + h2c->m1 = cpu_to_le32(DCTLINFO_V3_W1_AES_IV_H); + + h2c->w4 |= le32_encode_bits(rtw_wow->ptk_keyidx, + DCTLINFO_V3_W4_SEC_KEY_ID); + h2c->m4 |= cpu_to_le32(DCTLINFO_V3_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->w9 = le32_encode_bits(mld_sma[0], DCTLINFO_V3_W9_MLD_SMA_0_V2) | + le32_encode_bits(mld_sma[1], DCTLINFO_V3_W9_MLD_SMA_1_V2) | + le32_encode_bits(mld_sma[2], DCTLINFO_V3_W9_MLD_SMA_2_V2) | + le32_encode_bits(mld_sma[3], DCTLINFO_V3_W9_MLD_SMA_3_V2); + h2c->m9 = cpu_to_le32(DCTLINFO_V3_W9_ALL); + + h2c->w10 = le32_encode_bits(mld_sma[4], DCTLINFO_V3_W10_MLD_SMA_4_V2) | + le32_encode_bits(mld_sma[5], DCTLINFO_V3_W10_MLD_SMA_5_V2) | + le32_encode_bits(mld_tma[0], DCTLINFO_V3_W10_MLD_TMA_0_V2) | + le32_encode_bits(mld_tma[1], DCTLINFO_V3_W10_MLD_TMA_1_V2); + h2c->m10 = cpu_to_le32(DCTLINFO_V3_W10_ALL); + + h2c->w11 = le32_encode_bits(mld_tma[2], DCTLINFO_V3_W11_MLD_TMA_2_V2) | + le32_encode_bits(mld_tma[3], DCTLINFO_V3_W11_MLD_TMA_3_V2) | + le32_encode_bits(mld_tma[4], DCTLINFO_V3_W11_MLD_TMA_4_V2) | + le32_encode_bits(mld_tma[5], DCTLINFO_V3_W11_MLD_TMA_5_V2); + h2c->m11 = cpu_to_le32(DCTLINFO_V3_W11_ALL); + + h2c->w12 = le32_encode_bits(mld_bssid[0], DCTLINFO_V3_W12_MLD_TA_BSSID_0_V2) | + le32_encode_bits(mld_bssid[1], DCTLINFO_V3_W12_MLD_TA_BSSID_1_V2) | + le32_encode_bits(mld_bssid[2], DCTLINFO_V3_W12_MLD_TA_BSSID_2_V2) | + le32_encode_bits(mld_bssid[3], DCTLINFO_V3_W12_MLD_TA_BSSID_3_V2); + h2c->m12 = cpu_to_le32(DCTLINFO_V3_W12_ALL); + + h2c->w13 = le32_encode_bits(mld_bssid[4], DCTLINFO_V3_W13_MLD_TA_BSSID_4_V2) | + le32_encode_bits(mld_bssid[5], DCTLINFO_V3_W13_MLD_TA_BSSID_5_V2); + h2c->m13 = cpu_to_le32(DCTLINFO_V3_W13_ALL); +} diff --git a/drivers/net/wireless/realtek/rtw89/cam.h b/drivers/net/wireless/realtek/rtw89/cam.h index c46b6f91bbdb..22868f262243 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.h +++ b/drivers/net/wireless/realtek/rtw89/cam.h @@ -302,6 +302,131 @@ struct rtw89_h2c_dctlinfo_ud_v2 { #define DCTLINFO_V2_W12_MLD_BSSID_5 GENMASK(15, 8) #define DCTLINFO_V2_W12_ALL GENMASK(15, 0) +struct rtw89_h2c_dctlinfo_ud_v3 { + __le32 c0; + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; + __le32 w9; + __le32 w10; + __le32 w11; + __le32 w12; + __le32 w13; + __le32 w14; + __le32 w15; + __le32 m0; + __le32 m1; + __le32 m2; + __le32 m3; + __le32 m4; + __le32 m5; + __le32 m6; + __le32 m7; + __le32 m8; + __le32 m9; + __le32 m10; + __le32 m11; + __le32 m12; + __le32 m13; + __le32 m14; + __le32 m15; +} __packed; + +#define DCTLINFO_V3_C0_MACID GENMASK(15, 0) +#define DCTLINFO_V3_C0_OP BIT(16) + +#define DCTLINFO_V3_W0_QOS_FIELD_H GENMASK(7, 0) +#define DCTLINFO_V3_W0_HW_EXSEQ_MACID GENMASK(14, 8) +#define DCTLINFO_V3_W0_QOS_DATA BIT(15) +#define DCTLINFO_V3_W0_AES_IV_L GENMASK(31, 16) +#define DCTLINFO_V3_W0_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W1_AES_IV_H GENMASK(31, 0) +#define DCTLINFO_V3_W1_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W2_SEQ0 GENMASK(11, 0) +#define DCTLINFO_V3_W2_SEQ1 GENMASK(23, 12) +#define DCTLINFO_V3_W2_AMSDU_MAX_LEN GENMASK(26, 24) +#define DCTLINFO_V3_W2_STA_AMSDU_EN BIT(27) +#define DCTLINFO_V3_W2_CHKSUM_OFLD_EN BIT(28) +#define DCTLINFO_V3_W2_WITH_LLC BIT(29) +#define DCTLINFO_V3_W2_NAT25_EN BIT(30) +#define DCTLINFO_V3_W2_IS_MLD BIT(31) +#define DCTLINFO_V3_W2_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W3_SEQ2 GENMASK(11, 0) +#define DCTLINFO_V3_W3_SEQ3 GENMASK(23, 12) +#define DCTLINFO_V3_W3_TGT_IND GENMASK(27, 24) +#define DCTLINFO_V3_W3_TGT_IND_EN BIT(28) +#define DCTLINFO_V3_W3_HTC_LB GENMASK(31, 29) +#define DCTLINFO_V3_W3_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W4_VLAN_TAG_SEL GENMASK(7, 5) +#define DCTLINFO_V3_W4_HTC_ORDER BIT(8) +#define DCTLINFO_V3_W4_SEC_KEY_ID GENMASK(10, 9) +#define DCTLINFO_V3_W4_VLAN_RX_DYNAMIC_PCP_EN BIT(11) +#define DCTLINFO_V3_W4_VLAN_RX_PKT_DROP BIT(12) +#define DCTLINFO_V3_W4_VLAN_RX_VALID BIT(13) +#define DCTLINFO_V3_W4_VLAN_TX_VALID BIT(14) +#define DCTLINFO_V3_W4_WAPI BIT(15) +#define DCTLINFO_V3_W4_SEC_ENT_MODE GENMASK(17, 16) +#define DCTLINFO_V3_W4_SEC_ENT0_KEYID GENMASK(19, 18) +#define DCTLINFO_V3_W4_SEC_ENT1_KEYID GENMASK(21, 20) +#define DCTLINFO_V3_W4_SEC_ENT2_KEYID GENMASK(23, 22) +#define DCTLINFO_V3_W4_SEC_ENT3_KEYID GENMASK(25, 24) +#define DCTLINFO_V3_W4_SEC_ENT4_KEYID GENMASK(27, 26) +#define DCTLINFO_V3_W4_SEC_ENT5_KEYID GENMASK(29, 28) +#define DCTLINFO_V3_W4_SEC_ENT6_KEYID GENMASK(31, 30) +#define DCTLINFO_V3_W4_ALL GENMASK(31, 5) +#define DCTLINFO_V3_W5_SEC_ENT7_KEYID GENMASK(1, 0) +#define DCTLINFO_V3_W5_SEC_ENT8_KEYID GENMASK(3, 2) +#define DCTLINFO_V3_W5_SEC_ENT_VALID_V1 GENMASK(23, 8) +#define DCTLINFO_V3_W5_ALL (GENMASK(23, 8) | GENMASK(3, 0)) +#define DCTLINFO_V3_W6_SEC_ENT0_V2 GENMASK(8, 0) +#define DCTLINFO_V3_W6_SEC_ENT1_V2 GENMASK(18, 10) +#define DCTLINFO_V3_W6_SEC_ENT2_V2 GENMASK(28, 20) +#define DCTLINFO_V3_W6_ALL GENMASK(28, 0) +#define DCTLINFO_V3_W7_SEC_ENT3_V2 GENMASK(8, 0) +#define DCTLINFO_V3_W7_SEC_ENT4_V2 GENMASK(18, 10) +#define DCTLINFO_V3_W7_SEC_ENT5_V2 GENMASK(28, 20) +#define DCTLINFO_V3_W7_ALL GENMASK(28, 0) +#define DCTLINFO_V3_W8_SEC_ENT6_V2 GENMASK(8, 0) +#define DCTLINFO_V3_W8_SEC_ENT7_V1 GENMASK(18, 10) +#define DCTLINFO_V3_W8_SEC_ENT8_V1 GENMASK(28, 20) +#define DCTLINFO_V3_W8_ALL GENMASK(28, 0) +#define DCTLINFO_V3_W9_MLD_SMA_0_V2 GENMASK(7, 0) +#define DCTLINFO_V3_W9_MLD_SMA_1_V2 GENMASK(15, 8) +#define DCTLINFO_V3_W9_MLD_SMA_2_V2 GENMASK(23, 16) +#define DCTLINFO_V3_W9_MLD_SMA_3_V2 GENMASK(31, 24) +#define DCTLINFO_V3_W9_MLD_SMA_L_V2 GENMASK(31, 0) +#define DCTLINFO_V3_W9_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W10_MLD_SMA_4_V2 GENMASK(7, 0) +#define DCTLINFO_V3_W10_MLD_SMA_5_V2 GENMASK(15, 8) +#define DCTLINFO_V3_W10_MLD_SMA_H_V2 GENMASK(15, 0) +#define DCTLINFO_V3_W10_MLD_TMA_0_V2 GENMASK(23, 16) +#define DCTLINFO_V3_W10_MLD_TMA_1_V2 GENMASK(31, 24) +#define DCTLINFO_V3_W10_MLD_TMA_L_V2 GENMASK(31, 16) +#define DCTLINFO_V3_W10_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W11_MLD_TMA_2_V2 GENMASK(7, 0) +#define DCTLINFO_V3_W11_MLD_TMA_3_V2 GENMASK(15, 8) +#define DCTLINFO_V3_W11_MLD_TMA_4_V2 GENMASK(23, 16) +#define DCTLINFO_V3_W11_MLD_TMA_5_V2 GENMASK(31, 24) +#define DCTLINFO_V3_W11_MLD_TMA_H_V2 GENMASK(31, 0) +#define DCTLINFO_V3_W11_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W12_MLD_TA_BSSID_0_V2 GENMASK(7, 0) +#define DCTLINFO_V3_W12_MLD_TA_BSSID_1_V2 GENMASK(15, 8) +#define DCTLINFO_V3_W12_MLD_TA_BSSID_2_V2 GENMASK(23, 16) +#define DCTLINFO_V3_W12_MLD_TA_BSSID_3_V2 GENMASK(31, 24) +#define DCTLINFO_V3_W12_MLD_TA_BSSID_L_V2 GENMASK(31, 0) +#define DCTLINFO_V3_W12_ALL GENMASK(31, 0) +#define DCTLINFO_V3_W13_MLD_TA_BSSID_4_V2 GENMASK(7, 0) +#define DCTLINFO_V3_W13_MLD_TA_BSSID_5_V2 GENMASK(15, 8) +#define DCTLINFO_V3_W13_MLD_TA_BSSID_H_V2 GENMASK(15, 0) +#define DCTLINFO_V3_W13_HW_EXSEQ_MACID_V1 GENMASK(24, 16) +#define DCTLINFO_V3_W13_ALL GENMASK(24, 0) + int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif); void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif); int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev, @@ -328,6 +453,10 @@ void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link, struct rtw89_h2c_dctlinfo_ud_v2 *h2c); +void rtw89_cam_fill_dctl_sec_cam_info_v3(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + struct rtw89_h2c_dctlinfo_ud_v3 *h2c); int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link, diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c index 86f1b39a967f..0b5509468582 100644 --- a/drivers/net/wireless/realtek/rtw89/chan.c +++ b/drivers/net/wireless/realtek/rtw89/chan.c @@ -295,6 +295,8 @@ void rtw89_entity_init(struct rtw89_dev *rtwdev) mgnt->chanctx_tbl[i][j] = RTW89_CHANCTX_IDLE; } + hal->entity_force_hw = RTW89_PHY_NUM; + rtw89_config_default_chandef(rtwdev); } @@ -417,12 +419,43 @@ dflt: } EXPORT_SYMBOL(__rtw89_mgnt_chan_get); +bool rtw89_entity_check_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + switch (rtwdev->mlo_dbcc_mode) { + case MLO_2_PLUS_0_1RF: + return phy_idx == RTW89_PHY_0; + case MLO_0_PLUS_2_1RF: + return phy_idx == RTW89_PHY_1; + default: + return false; + } +} + +void rtw89_entity_force_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + rtwdev->hal.entity_force_hw = phy_idx; + + if (phy_idx != RTW89_PHY_NUM) + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "%s: %d\n", __func__, phy_idx); + else + rtw89_debug(rtwdev, RTW89_DBG_CHAN, "%s: (none)\n", __func__); +} + static enum rtw89_mlo_dbcc_mode rtw89_entity_sel_mlo_dbcc_mode(struct rtw89_dev *rtwdev, u8 active_hws) { if (rtwdev->chip->chip_gen != RTW89_CHIP_BE) return MLO_DBCC_NOT_SUPPORT; + switch (rtwdev->hal.entity_force_hw) { + case RTW89_PHY_0: + return MLO_2_PLUS_0_1RF; + case RTW89_PHY_1: + return MLO_0_PLUS_2_1RF; + default: + break; + } + switch (active_hws) { case BIT(0): return MLO_2_PLUS_0_1RF; @@ -2608,17 +2641,20 @@ bool rtw89_mcc_detect_go_bcn(struct rtw89_dev *rtwdev, static void rtw89_mcc_detect_connection(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role) { + struct rtw89_vif_link *rtwvif_link = role->rtwvif_link; struct ieee80211_vif *vif; bool start_detect; int ret; ret = rtw89_core_send_nullfunc(rtwdev, role->rtwvif_link, true, false, RTW89_MCC_PROBE_TIMEOUT); - if (ret) + if (ret && + READ_ONCE(rtwvif_link->sync_bcn_tsf) == rtwvif_link->last_sync_bcn_tsf) role->probe_count++; else role->probe_count = 0; + rtwvif_link->last_sync_bcn_tsf = READ_ONCE(rtwvif_link->sync_bcn_tsf); if (role->probe_count < RTW89_MCC_PROBE_MAX_TRIES) return; diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h index 5b22764d5329..c797cda2e763 100644 --- a/drivers/net/wireless/realtek/rtw89/chan.h +++ b/drivers/net/wireless/realtek/rtw89/chan.h @@ -166,6 +166,8 @@ void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev, const struct cfg80211_chan_def *chandef); void rtw89_entity_init(struct rtw89_dev *rtwdev); enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev); +bool rtw89_entity_check_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); +void rtw89_entity_force_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); void rtw89_chanctx_work(struct wiphy *wiphy, struct wiphy_work *work); void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev); void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 0824940c91ae..6e77522bcd8f 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -470,6 +470,32 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev) __rtw89_core_set_chip_txpwr(rtwdev, chan, RTW89_PHY_1); } +void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + bool mon = !!rtwdev->pure_monitor_mode_vif; + bool prehdl_link = false; + + if (chip->chip_gen != RTW89_CHIP_AX && + !RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw) && + !mon && !rtw89_entity_check_hw(rtwdev, rtwvif_link->phy_idx)) + prehdl_link = true; + + if (prehdl_link) { + rtw89_entity_force_hw(rtwdev, rtwvif_link->phy_idx); + rtw89_set_channel(rtwdev); + } + + if (chip->ops->rfk_channel) + chip->ops->rfk_channel(rtwdev, rtwvif_link); + + if (prehdl_link) { + rtw89_entity_force_hw(rtwdev, RTW89_PHY_NUM); + rtw89_set_channel(rtwdev); + } +} + static void rtw89_chip_rfk_channel_for_pure_mon_vif(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) { @@ -548,7 +574,7 @@ rtw89_core_get_tx_type(struct rtw89_dev *rtwdev, struct ieee80211_hdr *hdr = (void *)skb->data; __le16 fc = hdr->frame_control; - if (ieee80211_is_mgmt(fc) || ieee80211_is_nullfunc(fc)) + if (ieee80211_is_mgmt(fc) || ieee80211_is_any_nullfunc(fc)) return RTW89_CORE_TX_TYPE_MGMT; return RTW89_CORE_TX_TYPE_DATA; @@ -833,6 +859,7 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, desc_info->qsel = qsel; desc_info->ch_dma = ch_dma; + desc_info->sw_mld = true; desc_info->port = desc_info->hiq ? rtwvif_link->port : 0; desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req); desc_info->hw_ssn_sel = RTW89_MGMT_HW_SSN_SEL; @@ -1051,6 +1078,7 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, desc_info->ch_dma = ch_dma; desc_info->tid_indicate = tid_indicate; desc_info->qsel = qsel; + desc_info->sw_mld = false; desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req); desc_info->port = desc_info->hiq ? rtwvif_link->port : 0; desc_info->er_cap = rtwsta_link ? rtwsta_link->er_cap : false; @@ -1207,7 +1235,7 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev, if (addr_cam->valid && desc_info->mlo) upd_wlan_hdr = true; - if (rtw89_is_tx_rpt_skb(rtwdev, tx_req->skb)) + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS || tx_req->with_wait) rtw89_tx_rpt_init(rtwdev, tx_req); is_bmc = (is_broadcast_ether_addr(hdr->addr1) || @@ -1326,7 +1354,7 @@ int rtw89_h2c_tx(struct rtw89_dev *rtwdev, static int rtw89_core_tx_write_link(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link, - struct sk_buff *skb, int *qsel, bool sw_mld, + struct sk_buff *skb, int *qsel, struct rtw89_tx_wait_info *wait) { struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link); @@ -1341,14 +1369,15 @@ static int rtw89_core_tx_write_link(struct rtw89_dev *rtwdev, tx_req.sta = sta; tx_req.rtwvif_link = rtwvif_link; tx_req.rtwsta_link = rtwsta_link; - tx_req.desc_info.sw_mld = sw_mld; - rcu_assign_pointer(skb_data->wait, wait); + tx_req.with_wait = !!wait; rtw89_traffic_stats_accu(rtwdev, rtwvif, skb, true, true); rtw89_wow_parse_akm(rtwdev, skb); rtw89_core_tx_update_desc_info(rtwdev, &tx_req); rtw89_core_tx_wake(rtwdev, &tx_req); + rcu_assign_pointer(skb_data->wait, wait); + ret = rtw89_hci_tx_write(rtwdev, &tx_req); if (ret) { rtw89_err(rtwdev, "failed to transmit skb to HCI\n"); @@ -1385,8 +1414,7 @@ int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, } } - return rtw89_core_tx_write_link(rtwdev, rtwvif_link, rtwsta_link, skb, qsel, false, - NULL); + return rtw89_core_tx_write_link(rtwdev, rtwvif_link, rtwsta_link, skb, qsel, NULL); } static __le32 rtw89_build_txwd_body0(struct rtw89_tx_desc_info *desc_info) @@ -1631,6 +1659,17 @@ static __le32 rtw89_build_txwd_body2_v2(struct rtw89_tx_desc_info *desc_info) return cpu_to_le32(dword); } +static __le32 rtw89_build_txwd_body2_v3(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_BODY2_TID_IND_V1, desc_info->tid_indicate) | + FIELD_PREP(BE_TXD_BODY2_QSEL_V1, desc_info->qsel) | + FIELD_PREP(BE_TXD_BODY2_TXPKTSIZE, desc_info->pkt_size) | + FIELD_PREP(BE_TXD_BODY2_AGG_EN, desc_info->agg_en) | + FIELD_PREP(BE_TXD_BODY2_MACID_V1, desc_info->mac_id); + + return cpu_to_le32(dword); +} + static __le32 rtw89_build_txwd_body3_v2(struct rtw89_tx_desc_info *desc_info) { u32 dword = FIELD_PREP(BE_TXD_BODY3_WIFI_SEQ, desc_info->seq) | @@ -1640,6 +1679,16 @@ static __le32 rtw89_build_txwd_body3_v2(struct rtw89_tx_desc_info *desc_info) return cpu_to_le32(dword); } +static __le32 rtw89_build_txwd_body3_v3(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_BODY3_WIFI_SEQ, desc_info->seq) | + FIELD_PREP(BE_TXD_BODY3_MLO_FLAG, desc_info->mlo) | + FIELD_PREP(BE_TXD_BODY3_IS_MLD_SW_EN, desc_info->sw_mld) | + FIELD_PREP(BE_TXD_BODY3_BK_V1, desc_info->bk); + + return cpu_to_le32(dword); +} + static __le32 rtw89_build_txwd_body4_v2(struct rtw89_tx_desc_info *desc_info) { u32 dword = FIELD_PREP(BE_TXD_BODY4_SEC_IV_L0, desc_info->sec_seq[0]) | @@ -1711,6 +1760,15 @@ static __le32 rtw89_build_txwd_info2_v2(struct rtw89_tx_desc_info *desc_info) return cpu_to_le32(dword); } +static __le32 rtw89_build_txwd_info2_v3(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword = FIELD_PREP(BE_TXD_INFO2_AMPDU_DENSITY, desc_info->ampdu_density) | + FIELD_PREP(BE_TXD_INFO2_FORCE_KEY_EN_V1, desc_info->sec_en) | + FIELD_PREP(BE_TXD_INFO2_SEC_CAM_IDX_V1, desc_info->sec_cam_idx); + + return cpu_to_le32(dword); +} + static __le32 rtw89_build_txwd_info4_v2(struct rtw89_tx_desc_info *desc_info) { bool rts_en = !desc_info->is_bmc; @@ -1749,6 +1807,35 @@ void rtw89_core_fill_txdesc_v2(struct rtw89_dev *rtwdev, } EXPORT_SYMBOL(rtw89_core_fill_txdesc_v2); +void rtw89_core_fill_txdesc_v3(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc) +{ + struct rtw89_txwd_body_v2 *txwd_body = txdesc; + struct rtw89_txwd_info_v2 *txwd_info; + + txwd_body->dword0 = rtw89_build_txwd_body0_v2(desc_info); + txwd_body->dword1 = rtw89_build_txwd_body1_v2(desc_info); + txwd_body->dword2 = rtw89_build_txwd_body2_v3(desc_info); + txwd_body->dword3 = rtw89_build_txwd_body3_v3(desc_info); + if (desc_info->sec_en) { + 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) + return; + + txwd_info = (struct rtw89_txwd_info_v2 *)(txwd_body + 1); + txwd_info->dword0 = rtw89_build_txwd_info0_v2(desc_info); + txwd_info->dword1 = rtw89_build_txwd_info1_v2(desc_info); + txwd_info->dword2 = rtw89_build_txwd_info2_v3(desc_info); + txwd_info->dword4 = rtw89_build_txwd_info4_v2(desc_info); +} +EXPORT_SYMBOL(rtw89_core_fill_txdesc_v3); + static __le32 rtw89_build_txwd_fwcmd0_v1(struct rtw89_tx_desc_info *desc_info) { u32 dword = FIELD_PREP(AX_RXD_RPKT_LEN_MASK, desc_info->pkt_size) | @@ -2785,7 +2872,7 @@ static void rtw89_core_bcn_track_assoc(struct rtw89_dev *rtwdev, rcu_read_lock(); bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); - beacon_int = bss_conf->beacon_int; + beacon_int = bss_conf->beacon_int ?: 100; dtim = bss_conf->dtim_period; rcu_read_unlock(); @@ -2815,9 +2902,7 @@ static void rtw89_core_bcn_track_reset(struct rtw89_dev *rtwdev) memset(&rtwdev->bcn_track, 0, sizeof(rtwdev->bcn_track)); } -static void rtw89_vif_rx_bcn_stat(struct rtw89_dev *rtwdev, - struct ieee80211_bss_conf *bss_conf, - struct sk_buff *skb) +static void rtw89_vif_rx_bcn_stat(struct rtw89_dev *rtwdev, struct sk_buff *skb) { #define RTW89_APPEND_TSF_2GHZ 384 #define RTW89_APPEND_TSF_5GHZ 52 @@ -2826,7 +2911,7 @@ static void rtw89_vif_rx_bcn_stat(struct rtw89_dev *rtwdev, struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); struct rtw89_beacon_stat *bcn_stat = &rtwdev->phystat.bcn_stat; struct rtw89_beacon_track_info *bcn_track = &rtwdev->bcn_track; - u32 bcn_intvl_us = ieee80211_tu_to_usec(bss_conf->beacon_int); + u32 bcn_intvl_us = ieee80211_tu_to_usec(bcn_track->beacon_int); u64 tsf = le64_to_cpu(mgmt->u.beacon.timestamp); u8 wp, num = bcn_stat->num; u16 append; @@ -2834,6 +2919,10 @@ static void rtw89_vif_rx_bcn_stat(struct rtw89_dev *rtwdev, if (!RTW89_CHK_FW_FEATURE(BEACON_TRACKING, &rtwdev->fw)) return; + /* Skip if not yet associated */ + if (!bcn_intvl_us) + return; + switch (rx_status->band) { default: case NL80211_BAND_2GHZ: @@ -2921,7 +3010,7 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, pkt_stat->beacon_rate = desc_info->data_rate; pkt_stat->beacon_len = skb->len; - rtw89_vif_rx_bcn_stat(rtwdev, bss_conf, skb); + rtw89_vif_rx_bcn_stat(rtwdev, skb); } if (!ether_addr_equal(bss_conf->addr, hdr->addr1)) @@ -3408,6 +3497,79 @@ void rtw89_core_query_rxdesc_v2(struct rtw89_dev *rtwdev, } EXPORT_SYMBOL(rtw89_core_query_rxdesc_v2); +void rtw89_core_query_rxdesc_v3(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + u8 *data, u32 data_offset) +{ + struct rtw89_rxdesc_phy_rpt_v2 *rxd_rpt; + struct rtw89_rxdesc_short_v3 *rxd_s; + struct rtw89_rxdesc_long_v3 *rxd_l; + u16 shift_len, drv_info_len, phy_rtp_len, hdr_cnv_len; + + rxd_s = (struct rtw89_rxdesc_short_v3 *)(data + data_offset); + + desc_info->pkt_size = le32_get_bits(rxd_s->dword0, BE_RXD_RPKT_LEN_MASK); + desc_info->drv_info_size = le32_get_bits(rxd_s->dword0, BE_RXD_DRV_INFO_SZ_MASK); + desc_info->phy_rpt_size = le32_get_bits(rxd_s->dword0, BE_RXD_PHY_RPT_SZ_MASK); + desc_info->hdr_cnv_size = le32_get_bits(rxd_s->dword0, BE_RXD_HDR_CNV_SZ_MASK); + desc_info->shift = le32_get_bits(rxd_s->dword0, BE_RXD_SHIFT_MASK); + desc_info->long_rxdesc = le32_get_bits(rxd_s->dword0, BE_RXD_LONG_RXD); + desc_info->pkt_type = le32_get_bits(rxd_s->dword0, BE_RXD_RPKT_TYPE_MASK); + desc_info->bb_sel = le32_get_bits(rxd_s->dword0, BE_RXD_BB_SEL); + if (desc_info->pkt_type == RTW89_CORE_RX_TYPE_PPDU_STAT) + desc_info->mac_info_valid = true; + + desc_info->frame_type = le32_get_bits(rxd_s->dword2, BE_RXD_TYPE_MASK); + desc_info->mac_id = le32_get_bits(rxd_s->dword2, BE_RXD_MAC_ID_V1); + desc_info->addr_cam_valid = le32_get_bits(rxd_s->dword2, BE_RXD_ADDR_CAM_VLD); + + desc_info->icv_err = le32_get_bits(rxd_s->dword3, BE_RXD_ICV_ERR); + desc_info->crc32_err = le32_get_bits(rxd_s->dword3, BE_RXD_CRC32_ERR); + desc_info->hw_dec = le32_get_bits(rxd_s->dword3, BE_RXD_HW_DEC); + desc_info->sw_dec = le32_get_bits(rxd_s->dword3, BE_RXD_SW_DEC); + desc_info->addr1_match = le32_get_bits(rxd_s->dword3, BE_RXD_A1_MATCH); + + desc_info->bw = le32_get_bits(rxd_s->dword4, BE_RXD_BW_MASK); + desc_info->data_rate = le32_get_bits(rxd_s->dword4, BE_RXD_RX_DATARATE_MASK); + desc_info->gi_ltf = le32_get_bits(rxd_s->dword4, BE_RXD_RX_GI_LTF_MASK); + desc_info->ppdu_cnt = le32_get_bits(rxd_s->dword4, BE_RXD_PPDU_CNT_MASK); + desc_info->ppdu_type = le32_get_bits(rxd_s->dword4, BE_RXD_PPDU_TYPE_MASK); + + desc_info->free_run_cnt = le32_to_cpu(rxd_s->dword5); + + shift_len = desc_info->shift << 1; /* 2-byte unit */ + drv_info_len = desc_info->drv_info_size << 3; /* 8-byte unit */ + phy_rtp_len = desc_info->phy_rpt_size << 3; /* 8-byte unit */ + hdr_cnv_len = desc_info->hdr_cnv_size << 4; /* 16-byte unit */ + desc_info->offset = data_offset + shift_len + drv_info_len + + phy_rtp_len + hdr_cnv_len; + + if (desc_info->long_rxdesc) + desc_info->rxd_len = sizeof(struct rtw89_rxdesc_long_v3); + else + desc_info->rxd_len = sizeof(struct rtw89_rxdesc_short_v3); + desc_info->ready = true; + + if (phy_rtp_len == sizeof(*rxd_rpt)) { + rxd_rpt = (struct rtw89_rxdesc_phy_rpt_v2 *)(data + data_offset + + desc_info->rxd_len); + desc_info->rssi = le32_get_bits(rxd_rpt->dword0, BE_RXD_PHY_RSSI); + } + + if (!desc_info->long_rxdesc) + return; + + rxd_l = (struct rtw89_rxdesc_long_v3 *)(data + data_offset); + + desc_info->sr_en = le32_get_bits(rxd_l->dword6, BE_RXD_SR_EN); + desc_info->user_id = le32_get_bits(rxd_l->dword6, BE_RXD_USER_ID_MASK); + desc_info->addr_cam_id = le32_get_bits(rxd_l->dword6, BE_RXD_ADDR_CAM_V1); + desc_info->sec_cam_id = le32_get_bits(rxd_l->dword6, BE_RXD_SEC_CAM_IDX_V1); + + desc_info->rx_pl_id = le32_get_bits(rxd_l->dword7, BE_RXD_RX_PL_ID_MASK); +} +EXPORT_SYMBOL(rtw89_core_query_rxdesc_v3); + struct rtw89_core_iter_rx_status { struct rtw89_dev *rtwdev; struct ieee80211_rx_status *rx_status; @@ -4091,8 +4253,7 @@ int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rt goto out; } - ret = rtw89_core_tx_write_link(rtwdev, rtwvif_link, rtwsta_link, skb, &qsel, true, - wait); + ret = rtw89_core_tx_write_link(rtwdev, rtwvif_link, rtwsta_link, skb, &qsel, wait); if (ret) { rtw89_warn(rtwdev, "nullfunc transmit failed: %d\n", ret); dev_kfree_skb_any(skb); @@ -5085,7 +5246,7 @@ static void rtw89_init_vht_cap(struct rtw89_dev *rtwdev, } vht_cap->vht_supported = true; - vht_cap->cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | + vht_cap->cap = chip->max_vht_mpdu_cap | IEEE80211_VHT_CAP_SHORT_GI_80 | IEEE80211_VHT_CAP_RXSTBC_1 | IEEE80211_VHT_CAP_HTC_VHT | @@ -5213,7 +5374,7 @@ static void rtw89_init_he_cap(struct rtw89_dev *rtwdev, IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START) | le16_encode_bits(IEEE80211_VHT_MAX_AMPDU_1024K, IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP) | - le16_encode_bits(IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454, + le16_encode_bits(chip->max_vht_mpdu_cap, IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN); iftype_data->he_6ghz_capa.capa = capa; } @@ -5234,7 +5395,7 @@ static void rtw89_init_eht_cap(struct rtw89_dev *rtwdev, u8 val, val_mcs13; int sts = 8; - if (chip->chip_gen == RTW89_CHIP_AX) + if (chip->chip_gen == RTW89_CHIP_AX || hal->no_eht) return; if (hal->no_mcs_12_13) @@ -5251,7 +5412,7 @@ static void rtw89_init_eht_cap(struct rtw89_dev *rtwdev, eht_cap->has_eht = true; eht_cap_elem->mac_cap_info[0] = - u8_encode_bits(IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_7991, + u8_encode_bits(chip->max_eht_mpdu_cap, IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK); eht_cap_elem->mac_cap_info[1] = 0; @@ -5657,6 +5818,7 @@ int rtw89_core_start(struct rtw89_dev *rtwdev) rtw89_phy_dm_init(rtwdev); + rtw89_mac_set_edcca_mode_bands(rtwdev, true); rtw89_mac_cfg_ppdu_status_bands(rtwdev, true); rtw89_mac_cfg_phy_rpt_bands(rtwdev, true); rtw89_mac_update_rts_threshold(rtwdev); @@ -5923,6 +6085,9 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) struct rtw89_btc *btc = &rtwdev->btc; u8 band; + bitmap_or(rtwdev->quirks, rtwdev->quirks, &rtwdev->chip->default_quirks, + NUM_OF_RTW89_QUIRKS); + INIT_LIST_HEAD(&rtwdev->ba_list); INIT_LIST_HEAD(&rtwdev->forbid_ba_list); INIT_LIST_HEAD(&rtwdev->rtwvifs_list); @@ -6080,7 +6245,9 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev) { const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_hal *hal = &rtwdev->hal; int ret; + u8 val2; u8 val; u8 cv; @@ -6092,14 +6259,28 @@ static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev) cv = CHIP_CBV; } - rtwdev->hal.cv = cv; + hal->cv = cv; - if (rtw89_is_rtl885xb(rtwdev)) { + if (rtw89_is_rtl885xb(rtwdev) || chip->chip_gen >= RTW89_CHIP_BE) { ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_CV, &val); if (ret) return; - rtwdev->hal.acv = u8_get_bits(val, XTAL_SI_ACV_MASK); + hal->acv = u8_get_bits(val, XTAL_SI_ACV_MASK); + } + + if (chip->chip_gen >= RTW89_CHIP_BE) { + hal->cid = + rtw89_read32_mask(rtwdev, R_BE_SYS_CHIPINFO, B_BE_HW_ID_MASK); + + ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_CHIP_ID_L, &val); + if (ret) + return; + ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_CHIP_ID_H, &val2); + if (ret) + return; + + hal->aid = val | val2 << 8; } } @@ -6198,7 +6379,8 @@ int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, goto wake_queue; } - rtw89_chip_rfk_channel(rtwdev, target); + if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw)) + rtw89_chip_rfk_channel(rtwdev, target); rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR; @@ -6309,6 +6491,8 @@ void rtw89_core_rfkill_poll(struct rtw89_dev *rtwdev, bool force) int rtw89_chip_info_setup(struct rtw89_dev *rtwdev) { + struct rtw89_efuse *efuse = &rtwdev->efuse; + struct rtw89_hal *hal = &rtwdev->hal; int ret; rtw89_read_chip_ver(rtwdev); @@ -6348,6 +6532,9 @@ int rtw89_chip_info_setup(struct rtw89_dev *rtwdev) rtw89_core_setup_rfe_parms(rtwdev); rtwdev->ps_mode = rtw89_update_ps_mode(rtwdev); + rtw89_info(rtwdev, "chip info CID: %x, CV: %x, AID: %x, ACV: %x, RFE: %d\n", + hal->cid, hal->cv, hal->aid, hal->acv, efuse->rfe_type); + out: rtw89_mac_pwr_off(rtwdev); @@ -6398,8 +6585,8 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) hw->extra_tx_headroom = tx_headroom; hw->queues = IEEE80211_NUM_ACS; - hw->max_rx_aggregation_subframes = RTW89_MAX_RX_AGG_NUM; - hw->max_tx_aggregation_subframes = RTW89_MAX_TX_AGG_NUM; + hw->max_rx_aggregation_subframes = chip->max_rx_agg_num; + hw->max_tx_aggregation_subframes = chip->max_tx_agg_num; hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL; hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FEC | diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index a9cb47ea0b93..1abd09d9d29c 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -25,6 +25,7 @@ struct rtw89_fw_txpwr_track_cfg; struct rtw89_phy_rfk_log_fmt; struct rtw89_debugfs; struct rtw89_regd_data; +struct rtw89_wow_cam_info; extern const struct ieee80211_ops rtw89_ops; @@ -158,6 +159,17 @@ enum rtw89_core_chip_id { RTL8922D, }; +enum rtw89_core_chip_cid { + RTL8922D_CID7025 = 0x74, + RTL8922D_CID7090 = 0x79, +}; + +enum rtw89_core_chip_aid { + RTL8922D_AID1348 = 0x1348, + RTL8922D_AID7060 = 0x7060, + RTL8922D_AID7102 = 0x7102, +}; + enum rtw89_chip_gen { RTW89_CHIP_AX, RTW89_CHIP_BE, @@ -1125,6 +1137,15 @@ struct rtw89_rxdesc_short_v2 { __le32 dword5; } __packed; +struct rtw89_rxdesc_short_v3 { + __le32 dword0; + __le32 dword1; + __le32 dword2; + __le32 dword3; + __le32 dword4; + __le32 dword5; +} __packed; + struct rtw89_rxdesc_long { __le32 dword0; __le32 dword1; @@ -1149,6 +1170,19 @@ struct rtw89_rxdesc_long_v2 { __le32 dword9; } __packed; +struct rtw89_rxdesc_long_v3 { + __le32 dword0; + __le32 dword1; + __le32 dword2; + __le32 dword3; + __le32 dword4; + __le32 dword5; + __le32 dword6; + __le32 dword7; + __le32 dword8; + __le32 dword9; +} __packed; + struct rtw89_rxdesc_phy_rpt_v2 { __le32 dword0; __le32 dword1; @@ -1211,6 +1245,8 @@ struct rtw89_core_tx_request { struct rtw89_vif_link *rtwvif_link; struct rtw89_sta_link *rtwsta_link; struct rtw89_tx_desc_info desc_info; + + bool with_wait; }; struct rtw89_txq { @@ -3404,9 +3440,6 @@ struct rtw89_ra_info { #define RTW89_PPDU_MAC_RX_CNT_SIZE 96 #define RTW89_PPDU_MAC_RX_CNT_SIZE_V1 128 -#define RTW89_MAX_RX_AGG_NUM 64 -#define RTW89_MAX_TX_AGG_NUM 128 - struct rtw89_ampdu_params { u16 agg_num; bool amsdu; @@ -3833,6 +3866,8 @@ struct rtw89_chip_ops { struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link, bool valid, struct ieee80211_ampdu_params *params); + int (*h2c_wow_cam_update)(struct rtw89_dev *rtwdev, + struct rtw89_wow_cam_info *cam_info); void (*btc_set_rfe)(struct rtw89_dev *rtwdev); void (*btc_init_cfg)(struct rtw89_dev *rtwdev); @@ -3965,6 +4000,11 @@ struct rtw89_hfc_prec_cfg { u8 h2c_full_cond; u8 wp_ch07_full_cond; u8 wp_ch811_full_cond; + /* for WiFi 7 chips after 8922D */ + u16 ch011_full_page; + u16 h2c_full_page; + u16 wp_ch07_full_page; + u16 wp_ch811_full_page; }; struct rtw89_hfc_param { @@ -3989,13 +4029,14 @@ struct rtw89_dle_size { u16 pge_size; u16 lnk_pge_num; u16 unlnk_pge_num; - /* for WiFi 7 chips below */ + /* for WiFi 7 chips below (suffix v1) */ u32 srt_ofst; }; struct rtw89_wde_quota { u16 hif; u16 wcpu; + /* unused dcpu isn't listed */ u16 pkt_in; u16 cpu_io; }; @@ -4013,8 +4054,10 @@ struct rtw89_ple_quota { u16 wd_rel; u16 cpu_io; u16 tx_rpt; - /* for WiFi 7 chips below */ + /* for WiFi 7 chips below (suffix v1) */ u16 h2d; + /* for WiFi 7 chips after 8922D (suffix v2) */ + u16 snrpt; }; struct rtw89_rsvd_quota { @@ -4035,6 +4078,17 @@ struct rtw89_dle_rsvd_size { u32 size; }; +struct rtw89_dle_input { + u32 tx_ampdu_num_b0; + u32 tx_ampdu_num_b1; + u32 tx_amsdu_size; /* unit: KB */ + u32 h2c_max_size; + u32 rx_amsdu_size; /* unit: KB */ + u32 c2h_max_size; + u32 mpdu_info_tbl_b0; + u32 mpdu_info_tbl_b1; +}; + struct rtw89_dle_mem { enum rtw89_qta_mode mode; const struct rtw89_dle_size *wde_size; @@ -4047,6 +4101,8 @@ struct rtw89_dle_mem { const struct rtw89_rsvd_quota *rsvd_qt; const struct rtw89_dle_rsvd_size *rsvd0_size; const struct rtw89_dle_rsvd_size *rsvd1_size; + /* for WiFi 7 chips after 8922D */ + const struct rtw89_dle_input *dle_input; }; struct rtw89_reg_def { @@ -4325,6 +4381,13 @@ struct rtw89_rfkill_regs { struct rtw89_reg3_def mode; }; +struct rtw89_sb_regs { + struct { + u32 cfg; + u32 get; + } n[2]; +}; + struct rtw89_dig_regs { u32 seg0_pd_reg; u32 pd_lower_bound_mask; @@ -4424,6 +4487,10 @@ struct rtw89_chip_info { bool small_fifo_size; u32 dle_scc_rsvd_size; u16 max_amsdu_limit; + u16 max_vht_mpdu_cap; + u16 max_eht_mpdu_cap; + u16 max_tx_agg_num; + u16 max_rx_agg_num; bool dis_2g_40m_ul_ofdma; u32 rsvd_ple_ofst; const struct rtw89_hfc_param_ini *hfc_param_ini[RTW89_HCI_TYPE_NUM]; @@ -4538,10 +4605,12 @@ struct rtw89_chip_info { u32 bss_clr_map_reg; const struct rtw89_rfkill_regs *rfkill_init; struct rtw89_reg_def rfkill_get; + struct rtw89_sb_regs btc_sb; u32 dma_ch_mask; const struct rtw89_edcca_regs *edcca_regs; const struct wiphy_wowlan_support *wowlan_stub; const struct rtw89_xtal_info *xtal_info; + unsigned long default_quirks; /* bitmap of rtw89_quirks */ }; struct rtw89_chip_variant { @@ -4572,6 +4641,7 @@ enum rtw89_hcifc_mode { struct rtw89_dle_info { const struct rtw89_rsvd_quota *rsvd_qt; + const struct rtw89_dle_input *dle_input; enum rtw89_qta_mode qta_mode; u16 ple_pg_size; u16 ple_free_pg; @@ -4664,8 +4734,17 @@ enum rtw89_fw_feature { RTW89_FW_FEATURE_MACID_PAUSE_SLEEP, RTW89_FW_FEATURE_SCAN_OFFLOAD_BE_V0, RTW89_FW_FEATURE_WOW_REASON_V1, - RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0, - RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V1, + RTW89_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, + RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0, + RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V1, + RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V2, + RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V3, + ), + RTW89_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY_MCC, + RTW89_FW_FEATURE_RFK_PRE_NOTIFY_MCC_V0, + RTW89_FW_FEATURE_RFK_PRE_NOTIFY_MCC_V1, + RTW89_FW_FEATURE_RFK_PRE_NOTIFY_MCC_V2, + ), RTW89_FW_FEATURE_RFK_RXDCK_V0, RTW89_FW_FEATURE_RFK_IQK_V0, RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX, @@ -4680,6 +4759,10 @@ enum rtw89_fw_feature { RTW89_FW_FEATURE_LPS_DACK_BY_C2H_REG, RTW89_FW_FEATURE_BEACON_TRACKING, RTW89_FW_FEATURE_ADDR_CAM_V0, + RTW89_FW_FEATURE_SER_L1_BY_EVENT, + RTW89_FW_FEATURE_SIM_SER_L0L1_BY_HALT_H2C, + + NUM_OF_RTW89_FW_FEATURES, }; struct rtw89_fw_suit { @@ -4771,20 +4854,28 @@ struct rtw89_fw_info { struct rtw89_fw_suit bbmcu0; struct rtw89_fw_suit bbmcu1; struct rtw89_fw_log log; - u32 feature_map; struct rtw89_fw_elm_info elm_info; struct rtw89_fw_secure sec; + + DECLARE_BITMAP(feature_map, NUM_OF_RTW89_FW_FEATURES); }; #define RTW89_CHK_FW_FEATURE(_feat, _fw) \ - (!!((_fw)->feature_map & BIT(RTW89_FW_FEATURE_ ## _feat))) + test_bit(RTW89_FW_FEATURE_ ## _feat, (_fw)->feature_map) #define RTW89_CHK_FW_FEATURE_GROUP(_grp, _fw) \ - (!!((_fw)->feature_map & GENMASK(RTW89_FW_FEATURE_ ## _grp ## _MAX, \ - RTW89_FW_FEATURE_ ## _grp ## _MIN))) +({ \ + unsigned int bit = find_next_bit((_fw)->feature_map, \ + NUM_OF_RTW89_FW_FEATURES, \ + RTW89_FW_FEATURE_ ## _grp ## _MIN); \ + bit <= RTW89_FW_FEATURE_ ## _grp ## _MAX; \ +}) #define RTW89_SET_FW_FEATURE(_fw_feature, _fw) \ - ((_fw)->feature_map |= BIT(_fw_feature)) + set_bit(_fw_feature, (_fw)->feature_map) + +#define RTW89_CLR_FW_FEATURE(_fw_feature, _fw) \ + clear_bit(_fw_feature, (_fw)->feature_map) struct rtw89_cam_info { DECLARE_BITMAP(addr_cam_map, RTW89_MAX_ADDR_CAM_NUM); @@ -5026,7 +5117,9 @@ enum rtw89_dm_type { struct rtw89_hal { u32 rx_fltr; u8 cv; + u8 cid; /* enum rtw89_core_chip_cid */ u8 acv; + u16 aid; /* enum rtw89_core_chip_aid */ u32 antenna_tx; u32 antenna_rx; u8 tx_nss; @@ -5037,6 +5130,7 @@ struct rtw89_hal { bool support_cckpd; bool support_igi; bool no_mcs_12_13; + bool no_eht; atomic_t roc_chanctx_idx; u8 roc_link_index; @@ -5051,6 +5145,8 @@ struct rtw89_hal { enum rtw89_entity_mode entity_mode; struct rtw89_entity_mgnt entity_mgnt; + enum rtw89_phy_idx entity_force_hw; + u32 disabled_dm_bitmap; /* bitmap of enum rtw89_dm_type */ u8 thermal_prot_th; @@ -5065,6 +5161,8 @@ enum rtw89_flags { RTW89_FLAG_DMAC_FUNC, RTW89_FLAG_CMAC0_FUNC, RTW89_FLAG_CMAC1_FUNC, + RTW89_FLAG_CMAC0_PWR, + RTW89_FLAG_CMAC1_PWR, RTW89_FLAG_FW_RDY, RTW89_FLAG_RUNNING, RTW89_FLAG_PROBE_DONE, @@ -5095,13 +5193,15 @@ enum 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, + RTW89_CUSTID_NONE = 0, + RTW89_CUSTID_HP = 1, + RTW89_CUSTID_ASUS = 2, + RTW89_CUSTID_ACER = 3, + RTW89_CUSTID_LENOVO = 4, + RTW89_CUSTID_NEC = 5, + RTW89_CUSTID_AMD = 6, + RTW89_CUSTID_FUJITSU = 7, + RTW89_CUSTID_DELL = 8, }; enum rtw89_pkt_drop_sel { @@ -5216,6 +5316,7 @@ struct rtw89_rfk_mcc_info_data { u8 ch[RTW89_RFK_CHS_NR]; u8 band[RTW89_RFK_CHS_NR]; u8 bw[RTW89_RFK_CHS_NR]; + u32 rf18[RTW89_RFK_CHS_NR]; u8 table_idx; }; @@ -5793,7 +5894,7 @@ struct rtw89_phy_efuse_gain { struct rtw89_wow_cam_info { bool r_w; u8 idx; - u32 mask[RTW89_MAX_PATTERN_MASK_SIZE]; + __le32 mask[RTW89_MAX_PATTERN_MASK_SIZE]; u16 crc; bool negative_pattern_match; bool skip_mac_hdr; @@ -7100,15 +7201,6 @@ static inline void rtw89_chip_rfk_init_late(struct rtw89_dev *rtwdev) chip->ops->rfk_init_late(rtwdev); } -static inline void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev, - struct rtw89_vif_link *rtwvif_link) -{ - const struct rtw89_chip_info *chip = rtwdev->chip; - - if (chip->ops->rfk_channel) - chip->ops->rfk_channel(rtwdev, rtwvif_link); -} - static inline void rtw89_chip_rfk_band_changed(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, const struct rtw89_chan *chan) @@ -7558,6 +7650,9 @@ void rtw89_core_fill_txdesc_v1(struct rtw89_dev *rtwdev, void rtw89_core_fill_txdesc_v2(struct rtw89_dev *rtwdev, struct rtw89_tx_desc_info *desc_info, void *txdesc); +void rtw89_core_fill_txdesc_v3(struct rtw89_dev *rtwdev, + struct rtw89_tx_desc_info *desc_info, + void *txdesc); void rtw89_core_fill_txdesc_fwcmd_v1(struct rtw89_dev *rtwdev, struct rtw89_tx_desc_info *desc_info, void *txdesc); @@ -7576,6 +7671,9 @@ void rtw89_core_query_rxdesc(struct rtw89_dev *rtwdev, void rtw89_core_query_rxdesc_v2(struct rtw89_dev *rtwdev, struct rtw89_rx_desc_info *desc_info, u8 *data, u32 data_offset); +void rtw89_core_query_rxdesc_v3(struct rtw89_dev *rtwdev, + struct rtw89_rx_desc_info *desc_info, + u8 *data, u32 data_offset); void rtw89_core_napi_start(struct rtw89_dev *rtwdev); void rtw89_core_napi_stop(struct rtw89_dev *rtwdev); int rtw89_core_napi_init(struct rtw89_dev *rtwdev); @@ -7622,6 +7720,8 @@ struct rtw89_sta_link *rtw89_sta_set_link(struct rtw89_sta *rtwsta, unsigned int link_id); void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id); void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev); +void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); const struct rtw89_6ghz_span * rtw89_get_6ghz_span(struct rtw89_dev *rtwdev, u32 center_freq); void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef); diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index 1264c2f82600..2b48ccea27fb 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -79,6 +79,7 @@ struct rtw89_debugfs { struct rtw89_debugfs_priv send_h2c; struct rtw89_debugfs_priv early_h2c; struct rtw89_debugfs_priv fw_crash; + struct rtw89_debugfs_priv ser_counters; struct rtw89_debugfs_priv btc_info; struct rtw89_debugfs_priv btc_manual; struct rtw89_debugfs_priv fw_log_manual; @@ -3537,6 +3538,14 @@ out: return count; } +static int rtw89_dbg_trigger_ctrl_error_by_halt_h2c(struct rtw89_dev *rtwdev) +{ + if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) + return -EBUSY; + + return rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_RESET_FORCE); +} + static int rtw89_dbg_trigger_ctrl_error(struct rtw89_dev *rtwdev) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; @@ -3544,6 +3553,9 @@ static int rtw89_dbg_trigger_ctrl_error(struct rtw89_dev *rtwdev) u16 pkt_id; int ret; + if (RTW89_CHK_FW_FEATURE(SIM_SER_L0L1_BY_HALT_H2C, &rtwdev->fw)) + return rtw89_dbg_trigger_ctrl_error_by_halt_h2c(rtwdev); + rtw89_leave_ps_mode(rtwdev); ret = mac->dle_buf_req(rtwdev, 0x20, true, &pkt_id); @@ -3600,10 +3612,21 @@ static int rtw89_dbg_trigger_mac_error_be(struct rtw89_dev *rtwdev) return 0; } +static int rtw89_dbg_trigger_mac_error_by_halt_h2c(struct rtw89_dev *rtwdev) +{ + if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) + return -EBUSY; + + return rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L0_RESET_FORCE); +} + static int rtw89_dbg_trigger_mac_error(struct rtw89_dev *rtwdev) { const struct rtw89_chip_info *chip = rtwdev->chip; + if (RTW89_CHK_FW_FEATURE(SIM_SER_L0L1_BY_HALT_H2C, &rtwdev->fw)) + return rtw89_dbg_trigger_mac_error_by_halt_h2c(rtwdev); + rtw89_leave_ps_mode(rtwdev); switch (chip->chip_gen) { @@ -3680,6 +3703,60 @@ rtw89_debug_priv_fw_crash_set(struct rtw89_dev *rtwdev, return count; } +struct rtw89_dbg_ser_counters { + unsigned int l0; + unsigned int l1; + unsigned int l0_to_l1; +}; + +static void rtw89_dbg_get_ser_counters_ax(struct rtw89_dev *rtwdev, + struct rtw89_dbg_ser_counters *cnt) +{ + const u32 val = rtw89_read32(rtwdev, R_AX_SER_DBG_INFO); + + cnt->l0 = u32_get_bits(val, B_AX_SER_L0_COUNTER_MASK); + cnt->l1 = u32_get_bits(val, B_AX_SER_L1_COUNTER_MASK); + cnt->l0_to_l1 = u32_get_bits(val, B_AX_L0_TO_L1_EVENT_MASK); +} + +static void rtw89_dbg_get_ser_counters_be(struct rtw89_dev *rtwdev, + struct rtw89_dbg_ser_counters *cnt) +{ + const u32 val = rtw89_read32(rtwdev, R_BE_SER_DBG_INFO); + + cnt->l0 = u32_get_bits(val, B_BE_SER_L0_COUNTER_MASK); + cnt->l1 = u32_get_bits(val, B_BE_SER_L1_COUNTER_MASK); + cnt->l0_to_l1 = u32_get_bits(val, B_BE_SER_L0_PROMOTE_L1_EVENT_MASK); +} + +static ssize_t rtw89_debug_priv_ser_counters_get(struct rtw89_dev *rtwdev, + struct rtw89_debugfs_priv *debugfs_priv, + char *buf, size_t bufsz) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_dbg_ser_counters cnt = {}; + char *p = buf, *end = buf + bufsz; + + rtw89_leave_ps_mode(rtwdev); + + switch (chip->chip_gen) { + case RTW89_CHIP_AX: + rtw89_dbg_get_ser_counters_ax(rtwdev, &cnt); + break; + case RTW89_CHIP_BE: + rtw89_dbg_get_ser_counters_be(rtwdev, &cnt); + break; + default: + return -EOPNOTSUPP; + } + + p += scnprintf(p, end - p, "SER L0 Count: %d\n", cnt.l0); + p += scnprintf(p, end - p, "SER L1 Count: %d\n", cnt.l1); + p += scnprintf(p, end - p, "SER L0 promote event: %d\n", cnt.l0_to_l1); + + return p - buf; +} + static ssize_t rtw89_debug_priv_btc_info_get(struct rtw89_dev *rtwdev, struct rtw89_debugfs_priv *debugfs_priv, char *buf, size_t bufsz) @@ -4767,6 +4844,7 @@ static const struct rtw89_debugfs rtw89_debugfs_templ = { .send_h2c = rtw89_debug_priv_set(send_h2c), .early_h2c = rtw89_debug_priv_set_and_get(early_h2c, RWLOCK), .fw_crash = rtw89_debug_priv_set_and_get(fw_crash, WLOCK), + .ser_counters = rtw89_debug_priv_get(ser_counters, RLOCK), .btc_info = rtw89_debug_priv_get(btc_info, RSIZE_12K), .btc_manual = rtw89_debug_priv_set(btc_manual), .fw_log_manual = rtw89_debug_priv_set(fw_log_manual, WLOCK), @@ -4814,6 +4892,7 @@ void rtw89_debugfs_add_sec1(struct rtw89_dev *rtwdev, struct dentry *debugfs_top rtw89_debugfs_add_w(send_h2c); rtw89_debugfs_add_rw(early_h2c); rtw89_debugfs_add_rw(fw_crash); + rtw89_debugfs_add_r(ser_counters); rtw89_debugfs_add_r(btc_info); rtw89_debugfs_add_w(btc_manual); rtw89_debugfs_add_w(fw_log_manual); diff --git a/drivers/net/wireless/realtek/rtw89/efuse.c b/drivers/net/wireless/realtek/rtw89/efuse.c index 6c6c763510af..a2757a88d55d 100644 --- a/drivers/net/wireless/realtek/rtw89/efuse.c +++ b/drivers/net/wireless/realtek/rtw89/efuse.c @@ -7,10 +7,6 @@ #include "mac.h" #include "reg.h" -#define EF_FV_OFSET 0x5ea -#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) diff --git a/drivers/net/wireless/realtek/rtw89/efuse.h b/drivers/net/wireless/realtek/rtw89/efuse.h index a96fc1044791..a14a9dfed8e8 100644 --- a/drivers/net/wireless/realtek/rtw89/efuse.h +++ b/drivers/net/wireless/realtek/rtw89/efuse.h @@ -11,6 +11,11 @@ #define RTW89_EFUSE_BLOCK_SIZE_MASK GENMASK(15, 0) #define RTW89_EFUSE_MAX_BLOCK_SIZE 0x10000 +#define EF_FV_OFSET 0x5EA +#define EF_FV_OFSET_BE_V1 0x17CA +#define EF_CV_MASK GENMASK(7, 4) +#define EF_CV_INV 15 + struct rtw89_efuse_block_cfg { u32 offset; u32 size; @@ -26,5 +31,6 @@ int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *efv); int rtw89_efuse_recognize_mss_info_v1(struct rtw89_dev *rtwdev, u8 b1, u8 b2); int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev); int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev); +int rtw89_efuse_read_ecv_be(struct rtw89_dev *rtwdev); #endif diff --git a/drivers/net/wireless/realtek/rtw89/efuse_be.c b/drivers/net/wireless/realtek/rtw89/efuse_be.c index 64768923b0f0..70c1b8be662e 100644 --- a/drivers/net/wireless/realtek/rtw89/efuse_be.c +++ b/drivers/net/wireless/realtek/rtw89/efuse_be.c @@ -512,3 +512,29 @@ out: return 0; } + +int rtw89_efuse_read_ecv_be(struct rtw89_dev *rtwdev) +{ + u32 dump_addr; + u8 buff[4]; /* efuse access must 4 bytes align */ + int ret; + u8 ecv; + u8 val; + + dump_addr = ALIGN_DOWN(EF_FV_OFSET_BE_V1, 4); + + ret = rtw89_dump_physical_efuse_map_be(rtwdev, buff, dump_addr, 4, false); + if (ret) + return ret; + + val = buff[EF_FV_OFSET_BE_V1 & 0x3]; + + ecv = u8_get_bits(val, EF_CV_MASK); + if (ecv == EF_CV_INV) + return -ENOENT; + + rtwdev->hal.cv = ecv; + + return 0; +} +EXPORT_SYMBOL(rtw89_efuse_read_ecv_be); diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 7b9d9989e517..f09387e089a2 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -812,6 +812,8 @@ struct __fw_feat_cfg { enum rtw89_fw_feature feature; u32 ver_code; bool (*cond)(u32 suit_ver_code, u32 comp_ver_code); + bool disable; + int size; }; #define __CFG_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \ @@ -822,10 +824,36 @@ struct __fw_feat_cfg { .cond = __fw_feat_cond_ ## _cond, \ } +#define __S_DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \ + { \ + .chip_id = _chip, \ + .feature = RTW89_FW_FEATURE_ ## _feat, \ + .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \ + .cond = __fw_feat_cond_ ## _cond, \ + .disable = true, \ + .size = 1, \ + } + +#define __G_DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _grp) \ + { \ + .chip_id = _chip, \ + .feature = RTW89_FW_FEATURE_ ## _grp ## _MIN, \ + .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \ + .cond = __fw_feat_cond_ ## _cond, \ + .disable = true, \ + .size = RTW89_FW_FEATURE_ ## _grp ## _MAX - \ + RTW89_FW_FEATURE_ ## _grp ## _MIN + 1, \ + } + +#define __DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat, _type) \ + __##_type##_DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) + static const struct __fw_feat_cfg fw_feat_tbl[] = { __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, TX_WAKE), __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, SCAN_OFFLOAD), __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 41, 0, CRASH_TRIGGER_TYPE_0), + __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 127, 0, SER_L1_BY_EVENT), + __CFG_FW_FEAT(RTL8851B, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C), __CFG_FW_FEAT(RTL8852A, le, 0, 13, 29, 0, OLD_HT_RA_FORMAT), __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD), __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), @@ -837,11 +865,14 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = { __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER_TYPE_0), __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD), __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 7, BEACON_FILTER), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 15, BEACON_LOSS_COUNT_V1), __CFG_FW_FEAT(RTL8852B, lt, 0, 29, 30, 0, NO_WOW_CPU_IO_RX), __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 127, 0, LPS_DACK_BY_C2H_REG), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 127, 0, SER_L1_BY_EVENT), __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, CRASH_TRIGGER_TYPE_1), __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, SCAN_OFFLOAD_EXTRA_OP), __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 128, 0, BEACON_TRACKING), + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C), __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, NO_LPS_PG), __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 74, 0, TX_WAKE), __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 90, 0, CRASH_TRIGGER_TYPE_0), @@ -851,8 +882,10 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = { __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, SCAN_OFFLOAD_EXTRA_OP), __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, LPS_DACK_BY_C2H_REG), __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, CRASH_TRIGGER_TYPE_1), - __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), + __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, SER_L1_BY_EVENT), + __CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C), __CFG_FW_FEAT(RTL8852C, ge, 0, 0, 0, 0, RFK_NTFY_MCC_V0), + __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD), __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER_TYPE_0), @@ -862,25 +895,32 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = { __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 128, 0, LPS_DACK_BY_C2H_REG), __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 128, 0, CRASH_TRIGGER_TYPE_1), __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 129, 1, BEACON_TRACKING), - __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER_TYPE_0), + __CFG_FW_FEAT(RTL8852C, ge, 0, 29, 94, 0, SER_L1_BY_EVENT), + __CFG_FW_FEAT(RTL8852C, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C), + __CFG_FW_FEAT(RTL8922A, ge, 0, 0, 0, 0, RFK_PRE_NOTIFY_V0), __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 11, 0, MACID_PAUSE_SLEEP), + __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER_TYPE_0), __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD), - __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 21, 0, SCAN_OFFLOAD_BE_V0), + __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD_EXTRA_OP), __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 12, 0, BEACON_FILTER), + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 21, 0, SCAN_OFFLOAD_BE_V0), __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 22, 0, WOW_REASON_V1), __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 28, 0, RFK_IQK_V0), - __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, RFK_PRE_NOTIFY_V0), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 31, 0, RFK_PRE_NOTIFY_V1), __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, LPS_CH_INFO), __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 42, 0, RFK_RXDCK_V0), __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 46, 0, NOTIFY_AP_INFO), __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 47, 0, CH_INFO_BE_V0), - __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 49, 0, RFK_PRE_NOTIFY_V1), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 49, 0, RFK_PRE_NOTIFY_V2), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 49, 0, RFK_PRE_NOTIFY_MCC_V0), __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 51, 0, NO_PHYCAP_P1), __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 64, 0, NO_POWER_DIFFERENCE), __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 71, 0, BEACON_LOSS_COUNT_V1), __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 76, 0, LPS_DACK_BY_C2H_REG), __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 79, 0, CRASH_TRIGGER_TYPE_1), __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 80, 0, BEACON_TRACKING), + __DIS_FW_FEAT(RTL8922A, ge, 0, 35, 84, 0, WITH_RFK_PRE_NOTIFY, G), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 84, 0, RFK_PRE_NOTIFY_MCC_V1), __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 84, 0, ADDR_CAM_V0), }; @@ -896,8 +936,16 @@ static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw, if (chip->chip_id != ent->chip_id) continue; - if (ent->cond(ver_code, ent->ver_code)) + if (!ent->cond(ver_code, ent->ver_code)) + continue; + + if (!ent->disable) { RTW89_SET_FW_FEATURE(ent->feature, fw); + continue; + } + + for (int n = 0; n < ent->size; n++) + RTW89_CLR_FW_FEATURE(ent->feature + n, fw); } } @@ -1013,42 +1061,47 @@ int rtw89_build_phy_tbl_from_elm(struct rtw89_dev *rtwdev, const union rtw89_fw_element_arg arg) { struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; - struct rtw89_phy_table *tbl; + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_phy_table *tbl, **pp; struct rtw89_reg2_def *regs; - enum rtw89_rf_path rf_path; + bool radio = false; u32 n_regs, i; + u16 aid; u8 idx; - tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); - if (!tbl) - return -ENOMEM; - switch (le32_to_cpu(elm->id)) { case RTW89_FW_ELEMENT_ID_BB_REG: - elm_info->bb_tbl = tbl; + pp = &elm_info->bb_tbl; break; case RTW89_FW_ELEMENT_ID_BB_GAIN: - elm_info->bb_gain = tbl; + pp = &elm_info->bb_gain; break; case RTW89_FW_ELEMENT_ID_RADIO_A: case RTW89_FW_ELEMENT_ID_RADIO_B: case RTW89_FW_ELEMENT_ID_RADIO_C: case RTW89_FW_ELEMENT_ID_RADIO_D: - rf_path = arg.rf_path; idx = elm->u.reg2.idx; + pp = &elm_info->rf_radio[idx]; - elm_info->rf_radio[idx] = tbl; - tbl->rf_path = rf_path; - tbl->config = rtw89_phy_config_rf_reg_v1; + radio = true; break; case RTW89_FW_ELEMENT_ID_RF_NCTL: - elm_info->rf_nctl = tbl; + pp = &elm_info->rf_nctl; break; default: - kfree(tbl); return -ENOENT; } + aid = le16_to_cpu(elm->aid); + if (aid && aid != hal->aid) + return 1; /* ignore if aid not matched */ + else if (*pp) + return 1; /* ignore if an element is existing */ + + tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); + if (!tbl) + return -ENOMEM; + n_regs = le32_to_cpu(elm->size) / sizeof(tbl->regs[0]); regs = kcalloc(n_regs, sizeof(*regs), GFP_KERNEL); if (!regs) @@ -1062,6 +1115,13 @@ int rtw89_build_phy_tbl_from_elm(struct rtw89_dev *rtwdev, tbl->n_regs = n_regs; tbl->regs = regs; + if (radio) { + tbl->rf_path = arg.rf_path; + tbl->config = rtw89_phy_config_rf_reg_v1; + } + + *pp = tbl; + return 0; out: @@ -1481,11 +1541,12 @@ void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb, u8 type, u8 cat, u8 class, u8 func, bool rack, bool dack, u32 len) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct fwcmd_hdr *hdr; hdr = (struct fwcmd_hdr *)skb_push(skb, 8); - if (!(rtwdev->fw.h2c_seq % 4)) + if (chip->chip_gen == RTW89_CHIP_AX && !(rtwdev->fw.h2c_seq % 4)) rack = true; hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | FIELD_PREP(H2C_HDR_CAT, cat) | @@ -2267,6 +2328,45 @@ fail: } EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v2); +int rtw89_fw_h2c_dctl_sec_cam_v3(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_h2c_dctlinfo_ud_v3 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for dctl sec cam\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_dctlinfo_ud_v3 *)skb->data; + + rtw89_cam_fill_dctl_sec_cam_info_v3(rtwdev, rtwvif_link, rtwsta_link, h2c); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_DCTLINFO_UD_V3, 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; +} +EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v3); + int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link) @@ -2322,6 +2422,62 @@ fail: } EXPORT_SYMBOL(rtw89_fw_h2c_default_dmac_tbl_v2); +int rtw89_fw_h2c_default_dmac_tbl_v3(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; + struct rtw89_h2c_dctlinfo_ud_v3 *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for dctl v2\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_dctlinfo_ud_v3 *)skb->data; + + h2c->c0 = le32_encode_bits(mac_id, DCTLINFO_V3_C0_MACID) | + le32_encode_bits(1, DCTLINFO_V3_C0_OP); + + h2c->m0 = cpu_to_le32(DCTLINFO_V3_W0_ALL); + h2c->m1 = cpu_to_le32(DCTLINFO_V3_W1_ALL); + h2c->m2 = cpu_to_le32(DCTLINFO_V3_W2_ALL); + h2c->m3 = cpu_to_le32(DCTLINFO_V3_W3_ALL); + h2c->m4 = cpu_to_le32(DCTLINFO_V3_W4_ALL); + h2c->m5 = cpu_to_le32(DCTLINFO_V3_W5_ALL); + h2c->m6 = cpu_to_le32(DCTLINFO_V3_W6_ALL); + h2c->m7 = cpu_to_le32(DCTLINFO_V3_W7_ALL); + h2c->m8 = cpu_to_le32(DCTLINFO_V3_W8_ALL); + h2c->m9 = cpu_to_le32(DCTLINFO_V3_W9_ALL); + h2c->m10 = cpu_to_le32(DCTLINFO_V3_W10_ALL); + h2c->m11 = cpu_to_le32(DCTLINFO_V3_W11_ALL); + h2c->m12 = cpu_to_le32(DCTLINFO_V3_W12_ALL); + h2c->m13 = cpu_to_le32(DCTLINFO_V3_W13_ALL); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_DCTLINFO_UD_V3, 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; +} +EXPORT_SYMBOL(rtw89_fw_h2c_default_dmac_tbl_v3); + int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link, @@ -3318,6 +3474,92 @@ fail: } EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl_g7); +int rtw89_fw_h2c_default_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; + bool preld = rtw89_mac_chk_preload_allow(rtwdev); + struct rtw89_h2c_cctlinfo_ud_be *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for default cmac be\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; + + h2c->c0 = le32_encode_bits(mac_id, BE_CCTL_INFO_C0_V1_MACID) | + le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); + + h2c->w0 = le32_encode_bits(4, BE_CCTL_INFO_W0_DATARATE); + h2c->m0 = cpu_to_le32(BE_CCTL_INFO_W0_ALL); + + h2c->w1 = le32_encode_bits(4, BE_CCTL_INFO_W1_DATA_RTY_LOWEST_RATE) | + le32_encode_bits(0xa, BE_CCTL_INFO_W1_RTSRATE) | + le32_encode_bits(4, BE_CCTL_INFO_W1_RTS_RTY_LOWEST_RATE); + h2c->m1 = cpu_to_le32(BE_CCTL_INFO_W1_ALL); + + h2c->w1 = le32_encode_bits(preld, BE_CCTL_INFO_W2_PRELOAD_ENABLE); + h2c->m2 = cpu_to_le32(BE_CCTL_INFO_W2_ALL); + + h2c->m3 = cpu_to_le32(BE_CCTL_INFO_W3_ALL); + + h2c->w4 = le32_encode_bits(0xFFFF, BE_CCTL_INFO_W4_ACT_SUBCH_CBW); + h2c->m4 = cpu_to_le32(BE_CCTL_INFO_W4_ALL); + + h2c->w5 = le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING0_V1) | + le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING1_V1) | + le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING2_V1) | + le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING3_V1) | + le32_encode_bits(2, BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING4_V1); + h2c->m5 = cpu_to_le32(BE_CCTL_INFO_W5_ALL); + + h2c->w6 = le32_encode_bits(0xb, BE_CCTL_INFO_W6_RESP_REF_RATE); + h2c->m6 = cpu_to_le32(BE_CCTL_INFO_W6_ALL); + + h2c->w7 = le32_encode_bits(1, BE_CCTL_INFO_W7_NC) | + le32_encode_bits(1, BE_CCTL_INFO_W7_NR) | + le32_encode_bits(1, BE_CCTL_INFO_W7_CB) | + le32_encode_bits(0x1, BE_CCTL_INFO_W7_CSI_PARA_EN) | + le32_encode_bits(0xb, BE_CCTL_INFO_W7_CSI_FIX_RATE); + h2c->m7 = cpu_to_le32(BE_CCTL_INFO_W7_ALL); + + h2c->m8 = cpu_to_le32(BE_CCTL_INFO_W8_ALL); + + h2c->w14 = le32_encode_bits(0, BE_CCTL_INFO_W14_VO_CURR_RATE) | + le32_encode_bits(0, BE_CCTL_INFO_W14_VI_CURR_RATE) | + le32_encode_bits(0, BE_CCTL_INFO_W14_BE_CURR_RATE_L); + h2c->m14 = cpu_to_le32(BE_CCTL_INFO_W14_ALL); + + h2c->w15 = le32_encode_bits(0, BE_CCTL_INFO_W15_BE_CURR_RATE_H) | + le32_encode_bits(0, BE_CCTL_INFO_W15_BK_CURR_RATE) | + le32_encode_bits(0, BE_CCTL_INFO_W15_MGNT_CURR_RATE); + h2c->m15 = cpu_to_le32(BE_CCTL_INFO_W15_ALL); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_default_cmac_tbl_be); + static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev, struct ieee80211_link_sta *link_sta, u8 *pads) @@ -3648,6 +3890,134 @@ fail: } EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl_g7); +int rtw89_fw_h2c_assoc_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx); + u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; + struct rtw89_h2c_cctlinfo_ud_be *h2c; + struct ieee80211_bss_conf *bss_conf; + struct ieee80211_link_sta *link_sta; + u8 pads[RTW89_PPE_BW_NUM]; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u16 lowest_rate; + int ret; + + memset(pads, 0, sizeof(pads)); + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for assoc cmac be\n"); + return -ENOMEM; + } + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + + if (rtwsta_link) { + link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); + + if (link_sta->eht_cap.has_eht) + __get_sta_eht_pkt_padding(rtwdev, link_sta, pads); + else if (link_sta->he_cap.has_he) + __get_sta_he_pkt_padding(rtwdev, link_sta, pads); + } + + if (vif->p2p) + lowest_rate = RTW89_HW_RATE_OFDM6; + else if (chan->band_type == RTW89_BAND_2G) + lowest_rate = RTW89_HW_RATE_CCK1; + else + lowest_rate = RTW89_HW_RATE_OFDM6; + + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; + + h2c->c0 = le32_encode_bits(mac_id, BE_CCTL_INFO_C0_V1_MACID) | + le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); + + h2c->w0 = le32_encode_bits(1, BE_CCTL_INFO_W0_DISRTSFB) | + le32_encode_bits(1, BE_CCTL_INFO_W0_DISDATAFB); + h2c->m0 = cpu_to_le32(BE_CCTL_INFO_W0_DISRTSFB | + BE_CCTL_INFO_W0_DISDATAFB); + + h2c->w1 = le32_encode_bits(lowest_rate, BE_CCTL_INFO_W1_RTS_RTY_LOWEST_RATE); + h2c->m1 = cpu_to_le32(BE_CCTL_INFO_W1_RTS_RTY_LOWEST_RATE); + + h2c->w2 = le32_encode_bits(0, BE_CCTL_INFO_W2_DATA_TXCNT_LMT_SEL); + h2c->m2 = cpu_to_le32(BE_CCTL_INFO_W2_DATA_TXCNT_LMT_SEL); + + h2c->w3 = le32_encode_bits(0, BE_CCTL_INFO_W3_RTS_TXCNT_LMT_SEL); + h2c->m3 = cpu_to_le32(BE_CCTL_INFO_W3_RTS_TXCNT_LMT_SEL); + + h2c->w4 = le32_encode_bits(rtwvif_link->port, BE_CCTL_INFO_W4_MULTI_PORT_ID); + h2c->m4 = cpu_to_le32(BE_CCTL_INFO_W4_MULTI_PORT_ID); + + if (bss_conf->eht_support) { + u16 punct = bss_conf->chanreq.oper.punctured; + + h2c->w4 |= le32_encode_bits(~punct, + BE_CCTL_INFO_W4_ACT_SUBCH_CBW); + h2c->m4 |= cpu_to_le32(BE_CCTL_INFO_W4_ACT_SUBCH_CBW); + } + + h2c->w5 = le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_20], + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING0_V1) | + le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_40], + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING1_V1) | + le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_80], + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING2_V1) | + le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_160], + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING3_V1) | + le32_encode_bits(pads[RTW89_CHANNEL_WIDTH_320], + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING4_V1); + h2c->m5 = cpu_to_le32(BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING0_V1 | + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING1_V1 | + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING2_V1 | + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING3_V1 | + BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING4_V1); + + if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) { + h2c->w5 |= le32_encode_bits(0, BE_CCTL_INFO_W5_DATA_DCM_V1); + h2c->m5 |= cpu_to_le32(BE_CCTL_INFO_W5_DATA_DCM_V1); + } + + h2c->w6 = le32_encode_bits(vif->cfg.aid, BE_CCTL_INFO_W6_AID12_PAID) | + le32_encode_bits(vif->type == NL80211_IFTYPE_STATION ? 1 : 0, + BE_CCTL_INFO_W6_ULDL); + h2c->m6 = cpu_to_le32(BE_CCTL_INFO_W6_AID12_PAID | BE_CCTL_INFO_W6_ULDL); + + if (rtwsta_link) { + h2c->w8 = le32_encode_bits(link_sta->he_cap.has_he, + BE_CCTL_INFO_W8_BSR_QUEUE_SIZE_FORMAT_V1); + h2c->m8 = cpu_to_le32(BE_CCTL_INFO_W8_BSR_QUEUE_SIZE_FORMAT_V1); + } + + rcu_read_unlock(); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl_be); + int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link) @@ -3714,6 +4084,72 @@ fail: } EXPORT_SYMBOL(rtw89_fw_h2c_ampdu_cmac_tbl_g7); +int rtw89_fw_h2c_ampdu_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_sta *rtwsta = rtwsta_link->rtwsta; + struct rtw89_h2c_cctlinfo_ud_be *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u16 agg_num = 0; + u8 ba_bmap = 0; + int ret; + u8 tid; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for ampdu cmac be\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; + + for_each_set_bit(tid, rtwsta->ampdu_map, IEEE80211_NUM_TIDS) { + if (agg_num == 0) + agg_num = rtwsta->ampdu_params[tid].agg_num; + else + agg_num = min(agg_num, rtwsta->ampdu_params[tid].agg_num); + } + + if (agg_num <= 0x20) + ba_bmap = 3; + else if (agg_num > 0x20 && agg_num <= 0x40) + ba_bmap = 0; + else if (agg_num > 0x40 && agg_num <= 0x80) + ba_bmap = 1; + else if (agg_num > 0x80 && agg_num <= 0x100) + ba_bmap = 2; + else if (agg_num > 0x100 && agg_num <= 0x200) + ba_bmap = 4; + else if (agg_num > 0x200 && agg_num <= 0x400) + ba_bmap = 5; + + h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, BE_CCTL_INFO_C0_V1_MACID) | + le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); + + h2c->w3 = le32_encode_bits(ba_bmap, BE_CCTL_INFO_W3_BA_BMAP); + h2c->m3 = cpu_to_le32(BE_CCTL_INFO_W3_BA_BMAP); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 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; +} +EXPORT_SYMBOL(rtw89_fw_h2c_ampdu_cmac_tbl_be); + int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link) { @@ -3811,6 +4247,60 @@ fail: } EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl_g7); +int rtw89_fw_h2c_txtime_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link) +{ + struct rtw89_h2c_cctlinfo_ud_be *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for txtime_cmac_be\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; + + h2c->c0 = le32_encode_bits(rtwsta_link->mac_id, BE_CCTL_INFO_C0_V1_MACID) | + le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); + + if (rtwsta_link->cctl_tx_time) { + h2c->w3 |= le32_encode_bits(1, BE_CCTL_INFO_W3_AMPDU_TIME_SEL); + h2c->m3 |= cpu_to_le32(BE_CCTL_INFO_W3_AMPDU_TIME_SEL); + + h2c->w2 |= le32_encode_bits(rtwsta_link->ampdu_max_time, + BE_CCTL_INFO_W2_AMPDU_MAX_TIME); + h2c->m2 |= cpu_to_le32(BE_CCTL_INFO_W2_AMPDU_MAX_TIME); + } + if (rtwsta_link->cctl_tx_retry_limit) { + h2c->w2 |= le32_encode_bits(1, BE_CCTL_INFO_W2_DATA_TXCNT_LMT_SEL) | + le32_encode_bits(rtwsta_link->data_tx_cnt_lmt, + BE_CCTL_INFO_W2_DATA_TX_CNT_LMT); + h2c->m2 |= cpu_to_le32(BE_CCTL_INFO_W2_DATA_TXCNT_LMT_SEL | + BE_CCTL_INFO_W2_DATA_TX_CNT_LMT); + } + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_txtime_cmac_tbl_be); + int rtw89_fw_h2c_punctured_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u16 punctured) @@ -3854,6 +4344,48 @@ fail: } EXPORT_SYMBOL(rtw89_fw_h2c_punctured_cmac_tbl_g7); +int rtw89_fw_h2c_punctured_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + u16 punctured) +{ + struct rtw89_h2c_cctlinfo_ud_be *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for punctured cmac be\n"); + return -ENOMEM; + } + skb_put(skb, len); + h2c = (struct rtw89_h2c_cctlinfo_ud_be *)skb->data; + + h2c->c0 = le32_encode_bits(rtwvif_link->mac_id, BE_CCTL_INFO_C0_V1_MACID) | + le32_encode_bits(1, BE_CCTL_INFO_C0_V1_OP); + + h2c->w4 = le32_encode_bits(~punctured, BE_CCTL_INFO_W4_ACT_SUBCH_CBW); + h2c->m4 = cpu_to_le32(BE_CCTL_INFO_W4_ACT_SUBCH_CBW); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, + H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_punctured_cmac_tbl_be); + int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link) { @@ -5935,27 +6467,18 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, u8 scan_offload_ver = U8_MAX; u8 cfg_len = sizeof(*h2c); unsigned int cond; - u8 ap_idx = U8_MAX; u8 ver = U8_MAX; u8 policy_val; void *ptr; + u8 txnull; u8 txbcn; int ret; u32 len; u8 i; - scan_op[0].macid = rtwvif_link->mac_id; - scan_op[0].port = rtwvif_link->port; - scan_op[0].chan = *op; - vif = rtwvif_to_vif(rtwvif_link->rtwvif); - if (vif->type == NL80211_IFTYPE_AP) - ap_idx = 0; - - if (ext->set) { - scan_op[1] = *ext; - vif = rtwvif_to_vif(ext->rtwvif_link->rtwvif); - if (vif->type == NL80211_IFTYPE_AP) - ap_idx = 1; + if (option->num_opch > RTW89_MAX_OP_NUM_BE) { + rtw89_err(rtwdev, "num of scan OP chan %d over limit\n", option->num_opch); + return -ENOENT; } rtw89_scan_get_6g_disabled_chan(rtwdev, option); @@ -6060,11 +6583,29 @@ flex_member: } for (i = 0; i < option->num_opch; i++) { - bool is_ap_idx = i == ap_idx; + struct rtw89_vif_link *rtwvif_link_op; + bool is_ap; + + switch (i) { + case 0: + scan_op[0].macid = rtwvif_link->mac_id; + scan_op[0].port = rtwvif_link->port; + scan_op[0].chan = *op; + rtwvif_link_op = rtwvif_link; + break; + case 1: + scan_op[1] = *ext; + rtwvif_link_op = ext->rtwvif_link; + break; + } - opmode = is_ap_idx ? RTW89_SCAN_OPMODE_TBTT : RTW89_SCAN_OPMODE_INTV; - policy_val = is_ap_idx ? 2 : RTW89_OFF_CHAN_TIME / 10; - txbcn = is_ap_idx ? 1 : 0; + vif = rtwvif_to_vif(rtwvif_link_op->rtwvif); + is_ap = vif->type == NL80211_IFTYPE_AP; + txnull = !is_zero_ether_addr(rtwvif_link_op->bssid) && + vif->type != NL80211_IFTYPE_AP; + opmode = is_ap ? RTW89_SCAN_OPMODE_TBTT : RTW89_SCAN_OPMODE_INTV; + policy_val = is_ap ? 2 : RTW89_OFF_CHAN_TIME / 10; + txbcn = is_ap ? 1 : 0; opch = ptr; opch->w0 = le32_encode_bits(scan_op[i].macid, @@ -6075,7 +6616,7 @@ flex_member: RTW89_H2C_SCANOFLD_BE_OPCH_W0_PORT) | le32_encode_bits(opmode, RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY) | - le32_encode_bits(true, + le32_encode_bits(txnull, RTW89_H2C_SCANOFLD_BE_OPCH_W0_TXNULL) | le32_encode_bits(policy_val, RTW89_H2C_SCANOFLD_BE_OPCH_W0_POLICY_VAL); @@ -6349,6 +6890,7 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, struct rtw89_fw_h2c_rfk_pre_info_common *common; struct rtw89_fw_h2c_rfk_pre_info_v0 *h2c_v0; struct rtw89_fw_h2c_rfk_pre_info_v1 *h2c_v1; + struct rtw89_fw_h2c_rfk_pre_info_v2 *h2c_v2; struct rtw89_fw_h2c_rfk_pre_info *h2c; u8 tbl_sel[NUM_OF_RTW89_FW_RFK_PATH]; u32 len = sizeof(*h2c); @@ -6358,7 +6900,11 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, u32 val32; int ret; - if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V1, &rtwdev->fw)) { + if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V3, &rtwdev->fw)) { + } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V2, &rtwdev->fw)) { + len = sizeof(*h2c_v2); + ver = 2; + } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V1, &rtwdev->fw)) { len = sizeof(*h2c_v1); ver = 1; } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V0, &rtwdev->fw)) { @@ -6372,8 +6918,21 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, return -ENOMEM; } skb_put(skb, len); + + if (ver <= 2) + goto old_format; + h2c = (struct rtw89_fw_h2c_rfk_pre_info *)skb->data; - common = &h2c->base_v1.common; + + h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); + h2c->phy_idx = cpu_to_le32(phy_idx); + h2c->mlo_1_1 = cpu_to_le32(rtw89_is_mlo_1_1(rtwdev)); + + goto done; + +old_format: + h2c_v2 = (struct rtw89_fw_h2c_rfk_pre_info_v2 *)skb->data; + common = &h2c_v2->base_v1.common; common->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); @@ -6400,7 +6959,7 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, if (ver <= 1) continue; - h2c->cur_bandwidth[path] = + h2c_v2->cur_bandwidth[path] = cpu_to_le32(rfk_mcc->data[path].bw[tbl_sel[path]]); } @@ -6431,7 +6990,7 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, } if (rtw89_is_mlo_1_1(rtwdev)) { - h2c_v1 = &h2c->base_v1; + h2c_v1 = &h2c_v2->base_v1; h2c_v1->mlo_1_1 = cpu_to_le32(1); } done: @@ -6453,6 +7012,104 @@ fail: return ret; } +int rtw89_fw_h2c_rf_pre_ntfy_mcc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + struct rtw89_rfk_mcc_info *rfk_mcc_v0 = &rtwdev->rfk_mcc; + struct rtw89_fw_h2c_rfk_pre_info_mcc_v0 *h2c_v0; + struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 *h2c_v1; + struct rtw89_fw_h2c_rfk_pre_info_mcc *h2c; + struct rtw89_hal *hal = &rtwdev->hal; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + u8 ver = U8_MAX; + u8 tbl, path; + u8 tbl_sel; + int ret; + + if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V2, &rtwdev->fw)) { + } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V1, &rtwdev->fw)) { + len = sizeof(*h2c_v1); + ver = 1; + } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V0, &rtwdev->fw)) { + len = sizeof(*h2c_v0); + ver = 0; + } + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c rfk_pre_ntfy_mcc\n"); + return -ENOMEM; + } + skb_put(skb, len); + + if (ver != 0) + goto v1; + + h2c_v0 = (struct rtw89_fw_h2c_rfk_pre_info_mcc_v0 *)skb->data; + for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) { + for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) { + h2c_v0->tbl_18[tbl][path] = + cpu_to_le32(rfk_mcc_v0->data[path].rf18[tbl]); + tbl_sel = rfk_mcc_v0->data[path].table_idx; + h2c_v0->cur_18[path] = + cpu_to_le32(rfk_mcc_v0->data[path].rf18[tbl_sel]); + } + } + + h2c_v0->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); + goto done; + +v1: + h2c_v1 = (struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 *)skb->data; + + BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR); + + for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) + h2c_v1->tbl_18[tbl] = cpu_to_le32(rfk_mcc->rf18[tbl]); + + BUILD_BUG_ON(ARRAY_SIZE(rtwdev->rfk_mcc.data) < NUM_OF_RTW89_FW_RFK_PATH); + + /* shared table array, but tbl_sel can be independent by path */ + for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) { + tbl = rfk_mcc[path].table_idx; + h2c_v1->cur_18[path] = cpu_to_le32(rfk_mcc->rf18[tbl]); + + if (path == phy_idx) + h2c_v1->tbl_idx = tbl; + } + + h2c_v1->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); + h2c_v1->phy_idx = phy_idx; + + if (rtw89_is_mlo_1_1(rtwdev)) + h2c_v1->mlo_1_1 = cpu_to_le32(1); + + if (ver == 1) + goto done; + + h2c = (struct rtw89_fw_h2c_rfk_pre_info_mcc *)skb->data; + + h2c->aid = cpu_to_le32(hal->aid); + +done: + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY, + H2C_FUNC_OUTSRC_RF_MCC_INFO, 0, 0, len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} + int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, const struct rtw89_chan *chan, enum rtw89_tssi_mode tssi_mode) { @@ -7044,6 +7701,9 @@ static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev, else timeout = RTW89_C2H_TIMEOUT; + if (info->timeout) + timeout = info->timeout; + ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1, timeout, false, rtwdev, chip->c2h_ctrl_reg); @@ -7384,6 +8044,7 @@ static void rtw89_hw_scan_add_chan_ax(struct rtw89_dev *rtwdev, int chan_type, struct cfg80211_scan_request *req = rtwvif->scan_req; struct rtw89_chan *op = &rtwdev->scan_info.op_chan; struct rtw89_pktofld_info *info; + struct ieee80211_vif *vif; u8 band, probe_count = 0; int ret; @@ -7436,7 +8097,9 @@ static void rtw89_hw_scan_add_chan_ax(struct rtw89_dev *rtwdev, int chan_type, ch_info->pri_ch = op->primary_channel; ch_info->ch_band = op->band_type; ch_info->bw = op->band_width; - ch_info->tx_null = true; + vif = rtwvif_link_to_vif(rtwvif_link); + ch_info->tx_null = !is_zero_ether_addr(rtwvif_link->bssid) && + vif->type != NL80211_IFTYPE_AP; ch_info->num_pkt = 0; break; case RTW89_CHAN_DFS: @@ -7454,7 +8117,9 @@ static void rtw89_hw_scan_add_chan_ax(struct rtw89_dev *rtwdev, int chan_type, ch_info->pri_ch = ext->chan.primary_channel; ch_info->ch_band = ext->chan.band_type; ch_info->bw = ext->chan.band_width; - ch_info->tx_null = true; + vif = rtwvif_link_to_vif(ext->rtwvif_link); + ch_info->tx_null = !is_zero_ether_addr(ext->rtwvif_link->bssid) && + vif->type != NL80211_IFTYPE_AP; ch_info->num_pkt = 0; ch_info->macid_tx = true; break; @@ -8705,44 +9370,106 @@ fail: return ret; } -#define H2C_WOW_CAM_UPD_LEN 24 -int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev, - struct rtw89_wow_cam_info *cam_info) +int rtw89_fw_h2c_wow_cam_update(struct rtw89_dev *rtwdev, + struct rtw89_wow_cam_info *cam_info) { + struct rtw89_h2c_wow_cam_update *h2c; + u32 len = sizeof(*h2c); struct sk_buff *skb; int ret; - skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_CAM_UPD_LEN); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); if (!skb) { - rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); + rtw89_err(rtwdev, "failed to alloc skb for wow cam update\n"); return -ENOMEM; } + skb_put(skb, len); + h2c = (struct rtw89_h2c_wow_cam_update *)skb->data; + + h2c->w0 = le32_encode_bits(cam_info->r_w, RTW89_H2C_WOW_CAM_UPD_W0_R_W) | + le32_encode_bits(cam_info->idx, RTW89_H2C_WOW_CAM_UPD_W0_IDX); + + if (!cam_info->valid) + goto fill_valid; + + h2c->wkfm0 = cam_info->mask[0]; + h2c->wkfm1 = cam_info->mask[1]; + h2c->wkfm2 = cam_info->mask[2]; + h2c->wkfm3 = cam_info->mask[3]; + h2c->w5 = le32_encode_bits(cam_info->crc, RTW89_H2C_WOW_CAM_UPD_W5_CRC) | + le32_encode_bits(cam_info->negative_pattern_match, + RTW89_H2C_WOW_CAM_UPD_W5_NEGATIVE_PATTERN_MATCH) | + le32_encode_bits(cam_info->skip_mac_hdr, + RTW89_H2C_WOW_CAM_UPD_W5_SKIP_MAC_HDR) | + le32_encode_bits(cam_info->uc, RTW89_H2C_WOW_CAM_UPD_W5_UC) | + le32_encode_bits(cam_info->mc, RTW89_H2C_WOW_CAM_UPD_W5_MC) | + le32_encode_bits(cam_info->bc, RTW89_H2C_WOW_CAM_UPD_W5_BC); +fill_valid: + h2c->w5 |= le32_encode_bits(cam_info->valid, RTW89_H2C_WOW_CAM_UPD_W5_VALID); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_WOW, + H2C_FUNC_WOW_CAM_UPD, 0, 1, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); + goto fail; + } + + return 0; +fail: + dev_kfree_skb_any(skb); + + return ret; +} +EXPORT_SYMBOL(rtw89_fw_h2c_wow_cam_update); - skb_put(skb, H2C_WOW_CAM_UPD_LEN); +int rtw89_fw_h2c_wow_cam_update_v1(struct rtw89_dev *rtwdev, + struct rtw89_wow_cam_info *cam_info) +{ + struct rtw89_h2c_wow_payload_cam_update *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; - RTW89_SET_WOW_CAM_UPD_R_W(skb->data, cam_info->r_w); - RTW89_SET_WOW_CAM_UPD_IDX(skb->data, cam_info->idx); - if (cam_info->valid) { - RTW89_SET_WOW_CAM_UPD_WKFM1(skb->data, cam_info->mask[0]); - RTW89_SET_WOW_CAM_UPD_WKFM2(skb->data, cam_info->mask[1]); - RTW89_SET_WOW_CAM_UPD_WKFM3(skb->data, cam_info->mask[2]); - RTW89_SET_WOW_CAM_UPD_WKFM4(skb->data, cam_info->mask[3]); - RTW89_SET_WOW_CAM_UPD_CRC(skb->data, cam_info->crc); - RTW89_SET_WOW_CAM_UPD_NEGATIVE_PATTERN_MATCH(skb->data, - cam_info->negative_pattern_match); - RTW89_SET_WOW_CAM_UPD_SKIP_MAC_HDR(skb->data, - cam_info->skip_mac_hdr); - RTW89_SET_WOW_CAM_UPD_UC(skb->data, cam_info->uc); - RTW89_SET_WOW_CAM_UPD_MC(skb->data, cam_info->mc); - RTW89_SET_WOW_CAM_UPD_BC(skb->data, cam_info->bc); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for wow payload cam update\n"); + return -ENOMEM; } - RTW89_SET_WOW_CAM_UPD_VALID(skb->data, cam_info->valid); + skb_put(skb, len); + h2c = (struct rtw89_h2c_wow_payload_cam_update *)skb->data; + h2c->w0 = le32_encode_bits(cam_info->r_w, RTW89_H2C_WOW_PLD_CAM_UPD_W0_R_W) | + le32_encode_bits(cam_info->idx, RTW89_H2C_WOW_PLD_CAM_UPD_W0_IDX); + h2c->w8 = le32_encode_bits(cam_info->valid, RTW89_H2C_WOW_PLD_CAM_UPD_W8_VALID) | + le32_encode_bits(1, RTW89_H2C_WOW_PLD_CAM_UPD_W8_WOW_PTR); + + if (!cam_info->valid) + goto done; + + h2c->wkfm0 = cam_info->mask[0]; + h2c->wkfm1 = cam_info->mask[1]; + h2c->wkfm2 = cam_info->mask[2]; + h2c->wkfm3 = cam_info->mask[3]; + h2c->w5 = le32_encode_bits(cam_info->uc, RTW89_H2C_WOW_PLD_CAM_UPD_W5_UC) | + le32_encode_bits(cam_info->mc, RTW89_H2C_WOW_PLD_CAM_UPD_W5_MC) | + le32_encode_bits(cam_info->bc, RTW89_H2C_WOW_PLD_CAM_UPD_W5_BC) | + le32_encode_bits(cam_info->skip_mac_hdr, + RTW89_H2C_WOW_PLD_CAM_UPD_W5_SKIP_MAC_HDR); + h2c->w6 = le32_encode_bits(cam_info->crc, RTW89_H2C_WOW_PLD_CAM_UPD_W6_CRC); + h2c->w7 = le32_encode_bits(cam_info->negative_pattern_match, + RTW89_H2C_WOW_PLD_CAM_UPD_W7_NEGATIVE_PATTERN_MATCH); + +done: rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, H2C_CL_MAC_WOW, - H2C_FUNC_WOW_CAM_UPD, 0, 1, - H2C_WOW_CAM_UPD_LEN); + H2C_FUNC_WOW_PLD_CAM_UPD, 0, 1, + len); ret = rtw89_h2c_tx(rtwdev, skb, false); if (ret) { @@ -8756,6 +9483,7 @@ fail: return ret; } +EXPORT_SYMBOL(rtw89_fw_h2c_wow_cam_update_v1); int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index cedb4a47a769..018b3bed57d2 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -42,6 +42,10 @@ struct rtw89_c2hreg_phycap { #define RTW89_C2HREG_PHYCAP_W0_BW GENMASK(31, 24) #define RTW89_C2HREG_PHYCAP_W1_TX_NSS GENMASK(7, 0) #define RTW89_C2HREG_PHYCAP_W1_PROT GENMASK(15, 8) +#define RTW89_C2HREG_PHYCAP_W1_PROT_11N 1 +#define RTW89_C2HREG_PHYCAP_W1_PROT_11AC 2 +#define RTW89_C2HREG_PHYCAP_W1_PROT_11AX 3 +#define RTW89_C2HREG_PHYCAP_W1_PROT_11BE 4 #define RTW89_C2HREG_PHYCAP_W1_NIC GENMASK(23, 16) #define RTW89_C2HREG_PHYCAP_W1_WL_FUNC GENMASK(31, 24) #define RTW89_C2HREG_PHYCAP_W2_HW_TYPE GENMASK(7, 0) @@ -120,6 +124,7 @@ struct rtw89_h2creg_sch_tx_en { struct rtw89_mac_c2h_info { u8 id; u8 content_len; + u32 timeout; union { u32 c2hreg[RTW89_C2HREG_MAX]; struct rtw89_c2hreg_hdr hdr; @@ -1517,6 +1522,153 @@ struct rtw89_h2c_cctlinfo_ud_g7 { #define CCTLINFO_G7_W15_MGNT_CURR_RATE GENMASK(27, 16) #define CCTLINFO_G7_W15_ALL GENMASK(27, 0) +struct rtw89_h2c_cctlinfo_ud_be { + __le32 c0; + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; + __le32 w9; + __le32 w10; + __le32 w11; + __le32 w12; + __le32 w13; + __le32 w14; + __le32 w15; + __le32 m0; + __le32 m1; + __le32 m2; + __le32 m3; + __le32 m4; + __le32 m5; + __le32 m6; + __le32 m7; + __le32 m8; + __le32 m9; + __le32 m10; + __le32 m11; + __le32 m12; + __le32 m13; + __le32 m14; + __le32 m15; +} __packed; + +#define BE_CCTL_INFO_C0_V1_MACID GENMASK(9, 0) +#define BE_CCTL_INFO_C0_V1_OP BIT(10) + +#define BE_CCTL_INFO_W0_DATARATE GENMASK(11, 0) +#define BE_CCTL_INFO_W0_DATA_GI_LTF GENMASK(14, 12) +#define BE_CCTL_INFO_W0_TRYRATE BIT(15) +#define BE_CCTL_INFO_W0_ARFR_CTRL GENMASK(17, 16) +#define BE_CCTL_INFO_W0_DIS_HE1SS_STBC BIT(18) +#define BE_CCTL_INFO_W0_ACQ_RPT_EN BIT(20) +#define BE_CCTL_INFO_W0_MGQ_RPT_EN BIT(21) +#define BE_CCTL_INFO_W0_ULQ_RPT_EN BIT(22) +#define BE_CCTL_INFO_W0_TWTQ_RPT_EN BIT(23) +#define BE_CCTL_INFO_W0_FORCE_TXOP BIT(24) +#define BE_CCTL_INFO_W0_DISRTSFB BIT(25) +#define BE_CCTL_INFO_W0_DISDATAFB BIT(26) +#define BE_CCTL_INFO_W0_NSTR_EN BIT(27) +#define BE_CCTL_INFO_W0_AMPDU_DENSITY GENMASK(31, 28) +#define BE_CCTL_INFO_W0_ALL (GENMASK(31, 20) | GENMASK(18, 0)) +#define BE_CCTL_INFO_W1_DATA_RTY_LOWEST_RATE GENMASK(11, 0) +#define BE_CCTL_INFO_W1_RTS_TXCNT_LMT GENMASK(15, 12) +#define BE_CCTL_INFO_W1_RTSRATE GENMASK(27, 16) +#define BE_CCTL_INFO_W1_RTS_RTY_LOWEST_RATE GENMASK(31, 28) +#define BE_CCTL_INFO_W1_ALL GENMASK(31, 0) +#define BE_CCTL_INFO_W2_DATA_TX_CNT_LMT GENMASK(5, 0) +#define BE_CCTL_INFO_W2_DATA_TXCNT_LMT_SEL BIT(6) +#define BE_CCTL_INFO_W2_MAX_AGG_NUM_SEL BIT(7) +#define BE_CCTL_INFO_W2_RTS_EN BIT(8) +#define BE_CCTL_INFO_W2_CTS2SELF_EN BIT(9) +#define BE_CCTL_INFO_W2_CCA_RTS GENMASK(11, 10) +#define BE_CCTL_INFO_W2_HW_RTS_EN BIT(12) +#define BE_CCTL_INFO_W2_RTS_DROP_DATA_MODE GENMASK(14, 13) +#define BE_CCTL_INFO_W2_PRELOAD_ENABLE BIT(15) +#define BE_CCTL_INFO_W2_AMPDU_MAX_LEN GENMASK(26, 16) +#define BE_CCTL_INFO_W2_UL_MU_DIS BIT(27) +#define BE_CCTL_INFO_W2_AMPDU_MAX_TIME GENMASK(31, 28) +#define BE_CCTL_INFO_W2_ALL GENMASK(31, 0) +#define BE_CCTL_INFO_W3_MAX_AGG_NUM GENMASK(7, 0) +#define BE_CCTL_INFO_W3_DATA_BW GENMASK(10, 8) +#define BE_CCTL_INFO_W3_DATA_BW_ER BIT(11) +#define BE_CCTL_INFO_W3_BA_BMAP GENMASK(14, 12) +#define BE_CCTL_INFO_W3_VCS_STBC BIT(15) +#define BE_CCTL_INFO_W3_VO_LFTIME_SEL GENMASK(18, 16) +#define BE_CCTL_INFO_W3_VI_LFTIME_SEL GENMASK(21, 19) +#define BE_CCTL_INFO_W3_BE_LFTIME_SEL GENMASK(24, 22) +#define BE_CCTL_INFO_W3_BK_LFTIME_SEL GENMASK(27, 25) +#define BE_CCTL_INFO_W3_AMPDU_TIME_SEL BIT(28) +#define BE_CCTL_INFO_W3_AMPDU_LEN_SEL BIT(29) +#define BE_CCTL_INFO_W3_RTS_TXCNT_LMT_SEL BIT(30) +#define BE_CCTL_INFO_W3_LSIG_TXOP_EN BIT(31) +#define BE_CCTL_INFO_W3_ALL GENMASK(31, 0) +#define BE_CCTL_INFO_W4_MULTI_PORT_ID GENMASK(2, 0) +#define BE_CCTL_INFO_W4_BYPASS_PUNC BIT(3) +#define BE_CCTL_INFO_W4_MBSSID GENMASK(7, 4) +#define BE_CCTL_INFO_W4_TID_DISABLE_V1 GENMASK(15, 8) +#define BE_CCTL_INFO_W4_ACT_SUBCH_CBW GENMASK(31, 16) +#define BE_CCTL_INFO_W4_ALL GENMASK(31, 0) +#define BE_CCTL_INFO_W5_ADDR_CAM_INDEX_V1 GENMASK(9, 0) +#define BE_CCTL_INFO_W5_SR_MCS_SU GENMASK(14, 10) +#define BE_CCTL_INFO_W5_A_CTRL_BQR_V1 BIT(15) +#define BE_CCTL_INFO_W5_A_CTRL_BSR_V1 BIT(16) +#define BE_CCTL_INFO_W5_A_CTRL_CAS_V1 BIT(17) +#define BE_CCTL_INFO_W5_DATA_ER_V1 BIT(18) +#define BE_CCTL_INFO_W5_DATA_DCM_V1 BIT(19) +#define BE_CCTL_INFO_W5_DATA_LDPC_V1 BIT(20) +#define BE_CCTL_INFO_W5_DATA_STBC_V1 BIT(21) +#define BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING0_V1 GENMASK(23, 22) +#define BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING1_V1 GENMASK(25, 24) +#define BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING2_V1 GENMASK(27, 26) +#define BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING3_V1 GENMASK(29, 28) +#define BE_CCTL_INFO_W5_NOMINAL_PKT_PADDING4_V1 GENMASK(31, 30) +#define BE_CCTL_INFO_W5_ALL GENMASK(31, 0) +#define BE_CCTL_INFO_W6_AID12_PAID GENMASK(11, 0) +#define BE_CCTL_INFO_W6_RESP_REF_RATE GENMASK(23, 12) +#define BE_CCTL_INFO_W6_ULDL BIT(31) +#define BE_CCTL_INFO_W6_ALL (BIT(31) | GENMASK(23, 0)) +#define BE_CCTL_INFO_W7_NC GENMASK(2, 0) +#define BE_CCTL_INFO_W7_NR GENMASK(5, 3) +#define BE_CCTL_INFO_W7_NG GENMASK(7, 6) +#define BE_CCTL_INFO_W7_CB GENMASK(9, 8) +#define BE_CCTL_INFO_W7_CS GENMASK(11, 10) +#define BE_CCTL_INFO_W7_CSI_STBC_EN BIT(13) +#define BE_CCTL_INFO_W7_CSI_LDPC_EN BIT(14) +#define BE_CCTL_INFO_W7_CSI_PARA_EN BIT(15) +#define BE_CCTL_INFO_W7_CSI_FIX_RATE GENMASK(27, 16) +#define BE_CCTL_INFO_W7_CSI_BW GENMASK(31, 29) +#define BE_CCTL_INFO_W7_ALL GENMASK(31, 0) +#define BE_CCTL_INFO_W8_ALL_ACK_SUPPORT_V1 BIT(0) +#define BE_CCTL_INFO_W8_BSR_QUEUE_SIZE_FORMAT_V1 BIT(1) +#define BE_CCTL_INFO_W8_BSR_OM_UPD_EN_V1 BIT(2) +#define BE_CCTL_INFO_W8_MACID_FWD_IDC_V1 BIT(3) +#define BE_CCTL_INFO_W8_AZ_SEC_EN BIT(4) +#define BE_CCTL_INFO_W8_BF_SEC_EN BIT(5) +#define BE_CCTL_INFO_W8_FIX_UL_ADDRCAM_IDX_V1 BIT(6) +#define BE_CCTL_INFO_W8_CTRL_CNT_VLD_V1 BIT(7) +#define BE_CCTL_INFO_W8_CTRL_CNT_V1 GENMASK(11, 8) +#define BE_CCTL_INFO_W8_RESP_SEC_TYPE GENMASK(15, 12) +#define BE_CCTL_INFO_W8_ALL GENMASK(15, 0) +#define BE_CCTL_INFO_W9_EMLSR_TRANS_DLY GENMASK(2, 0) +#define BE_CCTL_INFO_W9_ALL GENMASK(2, 0) +#define BE_CCTL_INFO_W10_SW_EHT_NLTF GENMASK(1, 0) +#define BE_CCTL_INFO_W10_TB_MLO_MODE BIT(2) +#define BE_CCTL_INFO_W10_ALL GENMASK(2, 0) +#define BE_CCTL_INFO_W14_VO_CURR_RATE GENMASK(11, 0) +#define BE_CCTL_INFO_W14_VI_CURR_RATE GENMASK(23, 12) +#define BE_CCTL_INFO_W14_BE_CURR_RATE_L GENMASK(31, 24) +#define BE_CCTL_INFO_W14_ALL GENMASK(31, 0) +#define BE_CCTL_INFO_W15_BE_CURR_RATE_H GENMASK(3, 0) +#define BE_CCTL_INFO_W15_BK_CURR_RATE GENMASK(15, 4) +#define BE_CCTL_INFO_W15_MGNT_CURR_RATE GENMASK(27, 16) +#define BE_CCTL_INFO_W15_ALL GENMASK(27, 0) + struct rtw89_h2c_bcn_upd { __le32 w0; __le32 w1; @@ -2052,70 +2204,55 @@ static inline void RTW89_SET_WOW_WAKEUP_CTRL_MAC_ID(void *h2c, u32 val) le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)); } -static inline void RTW89_SET_WOW_CAM_UPD_R_W(void *h2c, u32 val) -{ - le32p_replace_bits((__le32 *)h2c, val, BIT(0)); -} - -static inline void RTW89_SET_WOW_CAM_UPD_IDX(void *h2c, u32 val) -{ - le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 1)); -} - -static inline void RTW89_SET_WOW_CAM_UPD_WKFM1(void *h2c, u32 val) -{ - le32p_replace_bits((__le32 *)h2c + 1, val, GENMASK(31, 0)); -} - -static inline void RTW89_SET_WOW_CAM_UPD_WKFM2(void *h2c, u32 val) -{ - le32p_replace_bits((__le32 *)h2c + 2, val, GENMASK(31, 0)); -} - -static inline void RTW89_SET_WOW_CAM_UPD_WKFM3(void *h2c, u32 val) -{ - le32p_replace_bits((__le32 *)h2c + 3, val, GENMASK(31, 0)); -} - -static inline void RTW89_SET_WOW_CAM_UPD_WKFM4(void *h2c, u32 val) -{ - le32p_replace_bits((__le32 *)h2c + 4, val, GENMASK(31, 0)); -} - -static inline void RTW89_SET_WOW_CAM_UPD_CRC(void *h2c, u32 val) -{ - le32p_replace_bits((__le32 *)h2c + 5, val, GENMASK(15, 0)); -} - -static inline void RTW89_SET_WOW_CAM_UPD_NEGATIVE_PATTERN_MATCH(void *h2c, u32 val) -{ - le32p_replace_bits((__le32 *)h2c + 5, val, BIT(22)); -} - -static inline void RTW89_SET_WOW_CAM_UPD_SKIP_MAC_HDR(void *h2c, u32 val) -{ - le32p_replace_bits((__le32 *)h2c + 5, val, BIT(23)); -} - -static inline void RTW89_SET_WOW_CAM_UPD_UC(void *h2c, u32 val) -{ - le32p_replace_bits((__le32 *)h2c + 5, val, BIT(24)); -} - -static inline void RTW89_SET_WOW_CAM_UPD_MC(void *h2c, u32 val) -{ - le32p_replace_bits((__le32 *)h2c + 5, val, BIT(25)); -} +struct rtw89_h2c_wow_cam_update { + __le32 w0; + __le32 wkfm0; + __le32 wkfm1; + __le32 wkfm2; + __le32 wkfm3; + __le32 w5; +} __packed; -static inline void RTW89_SET_WOW_CAM_UPD_BC(void *h2c, u32 val) -{ - le32p_replace_bits((__le32 *)h2c + 5, val, BIT(26)); -} +#define RTW89_H2C_WOW_CAM_UPD_W0_R_W BIT(0) +#define RTW89_H2C_WOW_CAM_UPD_W0_IDX GENMASK(7, 1) +#define RTW89_H2C_WOW_CAM_UPD_WKFM0 GENMASK(31, 0) +#define RTW89_H2C_WOW_CAM_UPD_WKFM1 GENMASK(31, 0) +#define RTW89_H2C_WOW_CAM_UPD_WKFM2 GENMASK(31, 0) +#define RTW89_H2C_WOW_CAM_UPD_WKFM3 GENMASK(31, 0) +#define RTW89_H2C_WOW_CAM_UPD_W5_CRC GENMASK(15, 0) +#define RTW89_H2C_WOW_CAM_UPD_W5_NEGATIVE_PATTERN_MATCH BIT(22) +#define RTW89_H2C_WOW_CAM_UPD_W5_SKIP_MAC_HDR BIT(23) +#define RTW89_H2C_WOW_CAM_UPD_W5_UC BIT(24) +#define RTW89_H2C_WOW_CAM_UPD_W5_MC BIT(25) +#define RTW89_H2C_WOW_CAM_UPD_W5_BC BIT(26) +#define RTW89_H2C_WOW_CAM_UPD_W5_VALID BIT(31) + +struct rtw89_h2c_wow_payload_cam_update { + __le32 w0; + __le32 wkfm0; + __le32 wkfm1; + __le32 wkfm2; + __le32 wkfm3; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; +} __packed; -static inline void RTW89_SET_WOW_CAM_UPD_VALID(void *h2c, u32 val) -{ - le32p_replace_bits((__le32 *)h2c + 5, val, BIT(31)); -} +#define RTW89_H2C_WOW_PLD_CAM_UPD_W0_R_W BIT(0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W0_IDX GENMASK(7, 1) +#define RTW89_H2C_WOW_PLD_CAM_UPD_WKFM0 GENMASK(31, 0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_WKFM1 GENMASK(31, 0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_WKFM2 GENMASK(31, 0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_WKFM3 GENMASK(31, 0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W5_UC BIT(0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W5_MC BIT(1) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W5_BC BIT(2) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W5_SKIP_MAC_HDR BIT(7) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W6_CRC GENMASK(15, 0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W7_NEGATIVE_PATTERN_MATCH BIT(0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W8_VALID BIT(0) +#define RTW89_H2C_WOW_PLD_CAM_UPD_W8_WOW_PTR BIT(1) struct rtw89_h2c_wow_gtk_ofld { __le32 w0; @@ -2826,6 +2963,7 @@ struct rtw89_h2c_scanofld_be_macc_role { __le32 w0; } __packed; +#define RTW89_MAX_OP_NUM_BE 2 #define RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_BAND GENMASK(1, 0) #define RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_PORT GENMASK(4, 2) #define RTW89_H2C_SCANOFLD_BE_MACC_ROLE_W0_MACID GENMASK(23, 8) @@ -4177,7 +4315,8 @@ struct rtw89_fw_element_hdr { __le32 id; /* enum rtw89_fw_element_id */ __le32 size; /* exclude header size */ u8 ver[4]; - __le32 rsvd0; + __le16 aid; /* should match rtw89_hal::aid */ + __le16 rsvd0; __le32 rsvd1; __le32 rsvd2; union { @@ -4307,6 +4446,7 @@ enum rtw89_wow_h2c_func { H2C_FUNC_WAKEUP_CTRL = 0x8, H2C_FUNC_WOW_CAM_UPD = 0xC, H2C_FUNC_AOAC_REPORT_REQ = 0xD, + H2C_FUNC_WOW_PLD_CAM_UPD = 0x12, NUM_OF_RTW89_WOW_H2C_FUNC, }; @@ -4347,6 +4487,7 @@ enum rtw89_ps_h2c_func { #define H2C_FUNC_MAC_CCTLINFO_UD_V1 0xa #define H2C_FUNC_MAC_DCTLINFO_UD_V2 0xc #define H2C_FUNC_MAC_BCN_UPD_BE 0xd +#define H2C_FUNC_MAC_DCTLINFO_UD_V3 0x10 #define H2C_FUNC_MAC_CCTLINFO_UD_G7 0x11 /* CLASS 6 - Address CAM */ @@ -4483,6 +4624,7 @@ enum rtw89_mrc_h2c_func { #define H2C_CL_OUTSRC_RF_REG_B 0x9 #define H2C_CL_OUTSRC_RF_FW_NOTIFY 0xa #define H2C_FUNC_OUTSRC_RF_GET_MCCCH 0x2 +#define H2C_FUNC_OUTSRC_RF_MCC_INFO 0xf #define H2C_FUNC_OUTSRC_RF_PS_INFO 0x10 #define H2C_CL_OUTSRC_RF_FW_RFK 0xb @@ -4586,11 +4728,38 @@ struct rtw89_fw_h2c_rfk_pre_info_v1 { __le32 mlo_1_1; } __packed; -struct rtw89_fw_h2c_rfk_pre_info { +struct rtw89_fw_h2c_rfk_pre_info_v2 { struct rtw89_fw_h2c_rfk_pre_info_v1 base_v1; __le32 cur_bandwidth[NUM_OF_RTW89_FW_RFK_PATH]; } __packed; +struct rtw89_fw_h2c_rfk_pre_info { + __le32 mlo_mode; + __le32 phy_idx; + __le32 mlo_1_1; +} __packed; + +struct rtw89_fw_h2c_rfk_pre_info_mcc_v0 { + __le32 tbl_18[NUM_OF_RTW89_FW_RFK_TBL][NUM_OF_RTW89_FW_RFK_PATH]; + __le32 cur_18[NUM_OF_RTW89_FW_RFK_PATH]; + __le32 mlo_mode; +} __packed; + +struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 { + __le32 tbl_18[NUM_OF_RTW89_FW_RFK_TBL]; + __le32 cur_18[NUM_OF_RTW89_FW_RFK_PATH]; + __le32 mlo_mode; + __le32 mlo_1_1; + u8 phy_idx; + u8 tbl_idx; +} __packed; + +struct rtw89_fw_h2c_rfk_pre_info_mcc { + struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 base; + u8 rsvd[2]; + __le32 aid; +} __packed; + struct rtw89_h2c_rf_tssi { __le16 len; u8 phy; @@ -4858,25 +5027,42 @@ int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_default_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_default_dmac_tbl_v3(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_assoc_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_ampdu_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_txtime_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_txtime_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_punctured_cmac_tbl_g7(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u16 punctured); +int rtw89_fw_h2c_punctured_cmac_tbl_be(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + u16 punctured); int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link); int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, @@ -4895,6 +5081,9 @@ int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link); +int rtw89_fw_h2c_dctl_sec_cam_v3(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link); void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h); void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work); void rtw89_fw_c2h_purge_obsoleted_scan_events(struct rtw89_dev *rtwdev); @@ -4948,6 +5137,7 @@ int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev); int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); +int rtw89_fw_h2c_rf_pre_ntfy_mcc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); int rtw89_fw_h2c_mcc_dig(struct rtw89_dev *rtwdev, enum rtw89_chanctx_idx chanctx_idx, u8 mcc_role_idx, u8 pd_val, bool en); @@ -5054,8 +5244,10 @@ int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtw bool enable); int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool enable); -int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev, - struct rtw89_wow_cam_info *cam_info); +int rtw89_fw_h2c_wow_cam_update(struct rtw89_dev *rtwdev, + struct rtw89_wow_cam_info *cam_info); +int rtw89_fw_h2c_wow_cam_update_v1(struct rtw89_dev *rtwdev, + struct rtw89_wow_cam_info *cam_info); int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool enable); @@ -5219,6 +5411,15 @@ int rtw89_chip_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, return 0; } +static inline +int rtw89_chip_h2c_wow_cam_update(struct rtw89_dev *rtwdev, + struct rtw89_wow_cam_info *cam_info) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return chip->ops->h2c_wow_cam_update(rtwdev, cam_info); +} + /* Must consider compatibility; don't insert new in the mid. * Fill each field's default value in rtw89_regd_entcpy(). */ diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index d78fbe73e365..1435e4c664b6 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -848,6 +848,7 @@ EXPORT_SYMBOL(rtw89_mac_get_err_status); int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err) { struct rtw89_ser *ser = &rtwdev->ser; + bool ser_l1_hdl = false; u32 halt; int ret = 0; @@ -856,6 +857,12 @@ int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err) return -EINVAL; } + if (err == MAC_AX_ERR_L1_DISABLE_EN || err == MAC_AX_ERR_L1_RCVY_EN) + ser_l1_hdl = true; + + if (RTW89_CHK_FW_FEATURE(SER_L1_BY_EVENT, &rtwdev->fw) && ser_l1_hdl) + goto set; + ret = read_poll_timeout(rtw89_read32, halt, (halt == 0x0), 1000, 100000, false, rtwdev, R_AX_HALT_H2C_CTRL); if (ret) { @@ -863,10 +870,10 @@ int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err) return -EFAULT; } +set: rtw89_write32(rtwdev, R_AX_HALT_H2C, err); - if (ser->prehandle_l1 && - (err == MAC_AX_ERR_L1_DISABLE_EN || err == MAC_AX_ERR_L1_RCVY_EN)) + if (ser->prehandle_l1 && ser_l1_hdl) return 0; rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, B_AX_HALT_H2C_TRIGGER); @@ -1476,15 +1483,37 @@ static void rtw89_mac_power_switch_boot_mode(struct rtw89_dev *rtwdev) rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST); } +static int rtw89_mac_pwr_off_func_for_unplugged(struct rtw89_dev *rtwdev) +{ + /* + * Avoid accessing IO for unplugged power-off to prevent warnings, + * especially XTAL SI. + */ + return 0; +} + +static void rtw89_mac_update_scoreboard(struct rtw89_dev *rtwdev, u8 val) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 reg; + int i; + + for (i = 0; i < ARRAY_SIZE(chip->btc_sb.n); i++) { + reg = chip->btc_sb.n[i].cfg; + if (!reg) + continue; + + rtw89_write8(rtwdev, reg + 3, val); + } +} + 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); int ret; - u8 val; rtw89_mac_power_switch_boot_mode(rtwdev); @@ -1492,17 +1521,22 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on) cfg_seq = chip->pwr_on_seq; cfg_func = chip->ops->pwr_on_func; } else { - cfg_seq = chip->pwr_off_seq; - cfg_func = chip->ops->pwr_off_func; + if (test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) { + cfg_seq = NULL; + cfg_func = rtw89_mac_pwr_off_func_for_unplugged; + } else { + cfg_seq = chip->pwr_off_seq; + cfg_func = chip->ops->pwr_off_func; + } } if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) __rtw89_leave_ps_mode(rtwdev); - val = rtw89_read32_mask(rtwdev, R_AX_IC_PWR_STATE, B_AX_WLMAC_PWR_STE_MASK); - if (on && val == PWR_ACT) { - rtw89_err(rtwdev, "MAC has already powered on\n"); - return -EBUSY; + if (on) { + ret = mac->reset_pwr_state(rtwdev); + if (ret) + return ret; } ret = cfg_func ? cfg_func(rtwdev) : rtw89_mac_pwr_seq(rtwdev, cfg_seq); @@ -1510,26 +1544,31 @@ 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)) + if (!test_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags)) { + rtw89_mac_efuse_read_ecv(rtwdev); 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); - rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_TP_MAJOR); + + rtw89_mac_update_scoreboard(rtwdev, MAC_AX_NOTIFY_TP_MAJOR); } else { clear_bit(RTW89_FLAG_POWERON, rtwdev->flags); clear_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags); clear_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags); clear_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags); + clear_bit(RTW89_FLAG_CMAC0_PWR, rtwdev->flags); + clear_bit(RTW89_FLAG_CMAC1_PWR, rtwdev->flags); clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); - rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_PWR_MAJOR); + + rtw89_mac_update_scoreboard(rtwdev, MAC_AX_NOTIFY_PWR_MAJOR); rtw89_set_entity_state(rtwdev, RTW89_PHY_0, false); rtw89_set_entity_state(rtwdev, RTW89_PHY_1, false); } return 0; -#undef PWR_ACT } int rtw89_mac_pwr_on(struct rtw89_dev *rtwdev) @@ -1664,8 +1703,8 @@ static int sys_init_ax(struct rtw89_dev *rtwdev) const struct rtw89_mac_size_set rtw89_mac_size = { .hfc_preccfg_pcie = {2, 40, 0, 0, 1, 0, 0, 0}, - .hfc_prec_cfg_c0 = {2, 32, 0, 0, 0, 0, 0, 0}, - .hfc_prec_cfg_c2 = {0, 256, 0, 0, 0, 0, 0, 0}, + .hfc_prec_cfg_c0 = {2, 32, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0}, + .hfc_prec_cfg_c2 = {0, 256, 0, 0, 0, 0, 0, 0, 0, 256, 0, 0}, /* PCIE 64 */ .wde_size0 = {RTW89_WDE_PG_64, 4095, 1,}, .wde_size0_v1 = {RTW89_WDE_PG_64, 3328, 0, 0,}, @@ -1680,10 +1719,12 @@ const struct rtw89_mac_size_set rtw89_mac_size = { .wde_size7 = {RTW89_WDE_PG_64, 510, 2,}, /* DLFW */ .wde_size9 = {RTW89_WDE_PG_64, 0, 1024,}, + .wde_size16_v1 = {RTW89_WDE_PG_64, 639, 1, 0,}, /* 8852C USB3.0 */ .wde_size17 = {RTW89_WDE_PG_64, 354, 30,}, /* 8852C DLFW */ .wde_size18 = {RTW89_WDE_PG_64, 0, 2048,}, + .wde_size18_v1 = {RTW89_WDE_PG_64, 0, 640, 0,}, /* 8852C PCIE SCC */ .wde_size19 = {RTW89_WDE_PG_64, 3328, 0,}, .wde_size23 = {RTW89_WDE_PG_64, 1022, 2,}, @@ -1710,6 +1751,8 @@ const struct rtw89_mac_size_set rtw89_mac_size = { .ple_size18 = {RTW89_PLE_PG_128, 2544, 16,}, /* 8852C PCIE SCC */ .ple_size19 = {RTW89_PLE_PG_128, 1904, 16,}, + .ple_size20_v1 = {RTW89_PLE_PG_128, 2554, 182, 40960,}, + .ple_size22_v1 = {RTW89_PLE_PG_128, 2736, 0, 40960,}, /* 8852B USB2.0 SCC */ .ple_size32 = {RTW89_PLE_PG_128, 620, 20,}, /* 8852B USB3.0 SCC */ @@ -1721,6 +1764,7 @@ const struct rtw89_mac_size_set rtw89_mac_size = { .wde_qt0_v1 = {3302, 6, 0, 20,}, /* 8852A USB */ .wde_qt1 = {512, 196, 0, 60,}, + .wde_qt3 = {0, 0, 0, 0,}, /* DLFW */ .wde_qt4 = {0, 0, 0, 0,}, /* PCIE 64 */ @@ -1733,6 +1777,7 @@ const struct rtw89_mac_size_set rtw89_mac_size = { .wde_qt17 = {0, 0, 0, 0,}, /* 8852C PCIE SCC */ .wde_qt18 = {3228, 60, 0, 40,}, + .wde_qt19_v1 = {613, 6, 0, 20,}, .wde_qt23 = {958, 48, 0, 16,}, /* 8852B USB2.0/USB3.0 SCC */ .wde_qt25 = {152, 2, 0, 8,}, @@ -1744,6 +1789,7 @@ const struct rtw89_mac_size_set rtw89_mac_size = { .ple_qt4 = {264, 0, 16, 20, 26, 13, 356, 0, 32, 40, 8,}, /* PCIE SCC */ .ple_qt5 = {264, 0, 32, 20, 64, 13, 1101, 0, 64, 128, 120,}, + .ple_qt5_v2 = {0, 0, 32, 256, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,}, .ple_qt9 = {0, 0, 32, 256, 0, 0, 0, 0, 0, 0, 1, 0, 0,}, /* DLFW */ .ple_qt13 = {0, 0, 16, 48, 0, 0, 0, 0, 0, 0, 0,}, @@ -1754,8 +1800,10 @@ const struct rtw89_mac_size_set rtw89_mac_size = { .ple_qt26 = {2654, 0, 1134, 48, 64, 13, 1478, 0, 64, 128, 120, 0,}, /* USB 52C USB3.0 */ .ple_qt42 = {1068, 0, 16, 48, 4, 13, 178, 0, 16, 1, 8, 16, 0,}, + .ple_qt42_v2 = {91, 91, 32, 16, 19, 13, 91, 91, 44, 18, 1, 4, 0, 0,}, /* USB 52C USB3.0 */ .ple_qt43 = {3068, 0, 32, 48, 4, 13, 178, 0, 16, 1, 8, 16, 0,}, + .ple_qt43_v2 = {645, 645, 32, 16, 2062, 2056, 2134, 2134, 2087, 2061, 1, 2047, 0, 0,}, /* DLFW 52C */ .ple_qt44 = {0, 0, 16, 256, 0, 0, 0, 0, 0, 0, 0, 0,}, /* DLFW 52C */ @@ -1789,8 +1837,13 @@ const struct rtw89_mac_size_set rtw89_mac_size = { .ple_qt_51b_wow = {147, 0, 16, 20, 157, 13, 133, 0, 172, 14, 24, 0,}, .ple_rsvd_qt0 = {2, 107, 107, 6, 6, 6, 6, 0, 0, 0,}, .ple_rsvd_qt1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, + .ple_rsvd_qt9 = {1, 44, 44, 6, 6, 6, 6, 69, 0, 0,}, .rsvd0_size0 = {212992, 0,}, + .rsvd0_size6 = {40960, 0,}, .rsvd1_size0 = {587776, 2048,}, + .rsvd1_size2 = {391168, 2048,}, + .dle_input3 = {0, 0, 0, 16384, 0, 2048, 0, 0,}, + .dle_input18 = {128, 128, 11454, 2048, 0, 2048, 24, 24,}, }; EXPORT_SYMBOL(rtw89_mac_size); @@ -1811,6 +1864,7 @@ static const struct rtw89_dle_mem *get_dle_mem_cfg(struct rtw89_dev *rtwdev, } mac->dle_info.rsvd_qt = cfg->rsvd_qt; + mac->dle_info.dle_input = cfg->dle_input; mac->dle_info.ple_pg_size = cfg->ple_size->pge_size; mac->dle_info.ple_free_pg = cfg->ple_size->lnk_pge_num; mac->dle_info.qta_mode = mode; @@ -2231,8 +2285,8 @@ error: return ret; } -static int preload_init_set(struct rtw89_dev *rtwdev, enum rtw89_mac_idx mac_idx, - enum rtw89_qta_mode mode) +static int preload_init_set_ax(struct rtw89_dev *rtwdev, u8 mac_idx, + enum rtw89_qta_mode mode) { u32 reg, max_preld_size, min_rsvd_size; @@ -2260,13 +2314,14 @@ static bool is_qta_poh(struct rtw89_dev *rtwdev) int rtw89_mac_preload_init(struct rtw89_dev *rtwdev, enum rtw89_mac_idx mac_idx, enum rtw89_qta_mode mode) { + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; const struct rtw89_chip_info *chip = rtwdev->chip; if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev) || !is_qta_poh(rtwdev)) return 0; - return preload_init_set(rtwdev, mac_idx, mode); + return mac->preload_init(rtwdev, mac_idx, mode); } static bool dle_is_txq_empty(struct rtw89_dev *rtwdev) @@ -3061,6 +3116,7 @@ static int rtw89_mac_setup_phycap_part0(struct rtw89_dev *rtwdev) struct rtw89_efuse *efuse = &rtwdev->efuse; struct rtw89_mac_c2h_info c2h_info = {}; struct rtw89_hal *hal = &rtwdev->hal; + u8 protocol; u8 tx_nss; u8 rx_nss; u8 tx_ant; @@ -3108,6 +3164,10 @@ static int rtw89_mac_setup_phycap_part0(struct rtw89_dev *rtwdev) rtw89_debug(rtwdev, RTW89_DBG_FW, "TX path diversity=%d\n", hal->tx_path_diversity); rtw89_debug(rtwdev, RTW89_DBG_FW, "Antenna diversity=%d\n", hal->ant_diversity); + protocol = u32_get_bits(phycap->w1, RTW89_C2HREG_PHYCAP_W1_PROT); + if (protocol < RTW89_C2HREG_PHYCAP_W1_PROT_11BE) + hal->no_eht = true; + return 0; } @@ -3931,6 +3991,29 @@ static int rtw89_mac_feat_init(struct rtw89_dev *rtwdev) return 0; } +static int rtw89_mac_reset_pwr_state_ax(struct rtw89_dev *rtwdev) +{ + u8 val; + + val = rtw89_read32_mask(rtwdev, R_AX_IC_PWR_STATE, B_AX_WLMAC_PWR_STE_MASK); + if (val == MAC_AX_MAC_ON) { + /* + * A USB adapter might play as USB mass storage with driver and + * then switch to WiFi adapter, causing it stays on power-on + * state when doing WiFi USB probe. Return EAGAIN to caller to + * power-off and power-on again to reset the state. + */ + if (rtwdev->hci.type == RTW89_HCI_TYPE_USB && + !test_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags)) + return -EAGAIN; + + rtw89_err(rtwdev, "MAC has already powered on\n"); + return -EBUSY; + } + + return 0; +} + static void rtw89_disable_fw_watchdog(struct rtw89_dev *rtwdev) { u32 val32; @@ -4145,12 +4228,19 @@ int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb) int rtw89_mac_preinit(struct rtw89_dev *rtwdev) { + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; int ret; ret = rtw89_mac_pwr_on(rtwdev); if (ret) return ret; + if (mac->mac_func_en) { + ret = mac->mac_func_en(rtwdev); + if (ret) + return ret; + } + return 0; } @@ -4341,6 +4431,7 @@ static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev, #define BCN_HOLD_DEF 200 #define BCN_MASK_DEF 0 #define TBTT_ERLY_DEF 5 +#define TBTT_AGG_DEF 1 #define BCN_SET_UNIT 32 #define BCN_ERLY_SET_DLY (10 * 2) @@ -4644,6 +4735,16 @@ static void rtw89_mac_port_cfg_tbtt_early(struct rtw89_dev *rtwdev, B_AX_TBTTERLY_MASK, TBTT_ERLY_DEF); } +static void rtw89_mac_port_cfg_tbtt_agg(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_port_reg *p = mac->port_base; + + rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_agg, + B_AX_TBTT_AGG_NUM_MASK, TBTT_AGG_DEF); +} + static void rtw89_mac_port_cfg_bss_color(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { @@ -4904,6 +5005,7 @@ int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvi rtw89_mac_port_cfg_bcn_hold_time(rtwdev, rtwvif_link); rtw89_mac_port_cfg_bcn_mask_area(rtwdev, rtwvif_link); rtw89_mac_port_cfg_tbtt_early(rtwdev, rtwvif_link); + rtw89_mac_port_cfg_tbtt_agg(rtwdev, rtwvif_link); rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif_link); rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif_link); rtw89_mac_port_cfg_func_en(rtwdev, rtwvif_link, true); @@ -5198,10 +5300,10 @@ rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_l if (start_detect) return; - ieee80211_connection_loss(vif); - } else { - rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); + ieee80211_beacon_loss(vif); } + + rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); return; case RTW89_BCN_FLTR_NOTIFY: nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; @@ -6358,9 +6460,11 @@ int rtw89_mac_cfg_plt_ax(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt) void rtw89_mac_cfg_sb(struct rtw89_dev *rtwdev, u32 val) { + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 reg = chip->btc_sb.n[0].cfg; u32 fw_sb; - fw_sb = rtw89_read32(rtwdev, R_AX_SCOREBOARD); + fw_sb = rtw89_read32(rtwdev, reg); fw_sb = FIELD_GET(B_MAC_AX_SB_FW_MASK, fw_sb); fw_sb = fw_sb & ~B_MAC_AX_BTGS1_NOTIFY; if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) @@ -6371,13 +6475,16 @@ void rtw89_mac_cfg_sb(struct rtw89_dev *rtwdev, u32 val) val = B_AX_TOGGLE | FIELD_PREP(B_MAC_AX_SB_DRV_MASK, val) | FIELD_PREP(B_MAC_AX_SB_FW_MASK, fw_sb); - rtw89_write32(rtwdev, R_AX_SCOREBOARD, val); + rtw89_write32(rtwdev, reg, val); fsleep(1000); /* avoid BT FW loss information */ } u32 rtw89_mac_get_sb(struct rtw89_dev *rtwdev) { - return rtw89_read32(rtwdev, R_AX_SCOREBOARD); + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 reg = chip->btc_sb.n[0].get; + + return rtw89_read32(rtwdev, reg); } int rtw89_mac_cfg_ctrl_path(struct rtw89_dev *rtwdev, bool wl) @@ -6942,6 +7049,12 @@ int rtw89_mac_write_xtal_si_ax(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 m return ret; } + if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags) && + (u32_get_bits(val32, B_AX_WL_XTAL_SI_ADDR_MASK) != offset || + u32_get_bits(val32, B_AX_WL_XTAL_SI_DATA_MASK) != val)) + rtw89_warn(rtwdev, "xtal si write: offset=%x val=%x poll=%x\n", + offset, val, val32); + return 0; } @@ -6965,7 +7078,12 @@ int rtw89_mac_read_xtal_si_ax(struct rtw89_dev *rtwdev, u8 offset, u8 *val) return ret; } - *val = rtw89_read8(rtwdev, R_AX_WLAN_XTAL_SI_CTRL + 1); + if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags) && + u32_get_bits(val32, B_AX_WL_XTAL_SI_ADDR_MASK) != offset) + rtw89_warn(rtwdev, "xtal si read: offset=%x poll=%x\n", + offset, val32); + + *val = u32_get_bits(val32, B_AX_WL_XTAL_SI_DATA_MASK); return 0; } @@ -7184,6 +7302,9 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = { .check_mac_en = rtw89_mac_check_mac_en_ax, .sys_init = sys_init_ax, .trx_init = trx_init_ax, + .preload_init = preload_init_set_ax, + .err_imr_ctrl = err_imr_ctrl_ax, + .mac_func_en = NULL, .hci_func_en = rtw89_mac_hci_func_en_ax, .dmac_func_pre_en = rtw89_mac_dmac_func_pre_en_ax, .dle_func_en = dle_func_en_ax, @@ -7193,6 +7314,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = { .typ_fltr_opt = rtw89_mac_typ_fltr_opt_ax, .cfg_ppdu_status = rtw89_mac_cfg_ppdu_status_ax, .cfg_phy_rpt = NULL, + .set_edcca_mode = NULL, .dle_mix_cfg = dle_mix_cfg_ax, .chk_dle_rdy = chk_dle_rdy_ax, @@ -7206,6 +7328,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = { .set_cpuio = set_cpuio_ax, .dle_quota_change = dle_quota_change_ax, + .reset_pwr_state = rtw89_mac_reset_pwr_state_ax, .disable_cpu = rtw89_mac_disable_cpu_ax, .fwdl_enable_wcpu = rtw89_mac_enable_cpu_ax, .fwdl_get_status = rtw89_fw_get_rdy_ax, @@ -7215,6 +7338,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_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, + .efuse_read_ecv = NULL, .cfg_plt = rtw89_mac_cfg_plt_ax, .get_plt_cnt = rtw89_mac_get_plt_cnt_ax, diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index 0007229d6753..14fffb660a29 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -914,6 +914,9 @@ enum mac_ax_err_info { MAC_AX_ERR_L0_CFG_DIS_NOTIFY = 0x0011, MAC_AX_ERR_L0_CFG_HANDSHAKE = 0x0012, MAC_AX_ERR_L0_RCVY_EN = 0x0013, + MAC_AX_ERR_L0_RESET_FORCE = 0x0020, + MAC_AX_ERR_L0_RESET_FORCE_C1 = 0x0021, + MAC_AX_ERR_L1_RESET_FORCE = 0x0022, MAC_AX_SET_ERR_MAX, }; @@ -929,8 +932,10 @@ struct rtw89_mac_size_set { const struct rtw89_dle_size wde_size6; const struct rtw89_dle_size wde_size7; const struct rtw89_dle_size wde_size9; + const struct rtw89_dle_size wde_size16_v1; const struct rtw89_dle_size wde_size17; const struct rtw89_dle_size wde_size18; + const struct rtw89_dle_size wde_size18_v1; const struct rtw89_dle_size wde_size19; const struct rtw89_dle_size wde_size23; const struct rtw89_dle_size wde_size25; @@ -946,18 +951,22 @@ struct rtw89_mac_size_set { const struct rtw89_dle_size ple_size17; const struct rtw89_dle_size ple_size18; const struct rtw89_dle_size ple_size19; + const struct rtw89_dle_size ple_size20_v1; + const struct rtw89_dle_size ple_size22_v1; const struct rtw89_dle_size ple_size32; const struct rtw89_dle_size ple_size33; const struct rtw89_dle_size ple_size34; const struct rtw89_wde_quota wde_qt0; const struct rtw89_wde_quota wde_qt1; const struct rtw89_wde_quota wde_qt0_v1; + const struct rtw89_wde_quota wde_qt3; const struct rtw89_wde_quota wde_qt4; const struct rtw89_wde_quota wde_qt6; const struct rtw89_wde_quota wde_qt7; const struct rtw89_wde_quota wde_qt16; const struct rtw89_wde_quota wde_qt17; const struct rtw89_wde_quota wde_qt18; + const struct rtw89_wde_quota wde_qt19_v1; const struct rtw89_wde_quota wde_qt23; const struct rtw89_wde_quota wde_qt25; const struct rtw89_wde_quota wde_qt31; @@ -965,13 +974,16 @@ struct rtw89_mac_size_set { const struct rtw89_ple_quota ple_qt1; const struct rtw89_ple_quota ple_qt4; const struct rtw89_ple_quota ple_qt5; + const struct rtw89_ple_quota ple_qt5_v2; const struct rtw89_ple_quota ple_qt9; const struct rtw89_ple_quota ple_qt13; const struct rtw89_ple_quota ple_qt18; const struct rtw89_ple_quota ple_qt25; const struct rtw89_ple_quota ple_qt26; const struct rtw89_ple_quota ple_qt42; + const struct rtw89_ple_quota ple_qt42_v2; const struct rtw89_ple_quota ple_qt43; + const struct rtw89_ple_quota ple_qt43_v2; const struct rtw89_ple_quota ple_qt44; const struct rtw89_ple_quota ple_qt45; const struct rtw89_ple_quota ple_qt46; @@ -991,8 +1003,14 @@ struct rtw89_mac_size_set { const struct rtw89_ple_quota ple_qt_51b_wow; const struct rtw89_rsvd_quota ple_rsvd_qt0; const struct rtw89_rsvd_quota ple_rsvd_qt1; + const struct rtw89_rsvd_quota ple_rsvd_qt1_v1; + const struct rtw89_rsvd_quota ple_rsvd_qt9; const struct rtw89_dle_rsvd_size rsvd0_size0; + const struct rtw89_dle_rsvd_size rsvd0_size6; const struct rtw89_dle_rsvd_size rsvd1_size0; + const struct rtw89_dle_rsvd_size rsvd1_size2; + const struct rtw89_dle_input dle_input3; + const struct rtw89_dle_input dle_input18; }; extern const struct rtw89_mac_size_set rtw89_mac_size; @@ -1019,6 +1037,10 @@ struct rtw89_mac_gen_def { enum rtw89_mac_hwmod_sel sel); int (*sys_init)(struct rtw89_dev *rtwdev); int (*trx_init)(struct rtw89_dev *rtwdev); + int (*preload_init)(struct rtw89_dev *rtwdev, u8 mac_idx, + enum rtw89_qta_mode mode); + void (*err_imr_ctrl)(struct rtw89_dev *rtwdev, bool en); + int (*mac_func_en)(struct rtw89_dev *rtwdev); void (*hci_func_en)(struct rtw89_dev *rtwdev); void (*dmac_func_pre_en)(struct rtw89_dev *rtwdev); void (*dle_func_en)(struct rtw89_dev *rtwdev, bool enable); @@ -1033,6 +1055,7 @@ struct rtw89_mac_gen_def { u8 mac_idx); int (*cfg_ppdu_status)(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable); void (*cfg_phy_rpt)(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable); + void (*set_edcca_mode)(struct rtw89_dev *rtwdev, u8 mac_idx, bool normal); int (*dle_mix_cfg)(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg); int (*chk_dle_rdy)(struct rtw89_dev *rtwdev, bool wde_or_ple); @@ -1052,6 +1075,7 @@ struct rtw89_mac_gen_def { struct rtw89_cpuio_ctrl *ctrl_para, bool wd); int (*dle_quota_change)(struct rtw89_dev *rtwdev, bool band1_en); + int (*reset_pwr_state)(struct rtw89_dev *rtwdev); void (*disable_cpu)(struct rtw89_dev *rtwdev); int (*fwdl_enable_wcpu)(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw, bool include_bb); @@ -1062,6 +1086,7 @@ struct rtw89_mac_gen_def { 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 (*efuse_read_ecv)(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); @@ -1105,6 +1130,14 @@ u32 rtw89_mac_reg_by_idx(struct rtw89_dev *rtwdev, u32 reg_base, u8 band) return band == 0 ? reg_base : (reg_base + mac->band1_offset); } +static inline void +rtw89_write16_idx(struct rtw89_dev *rtwdev, u32 addr, u16 data, u8 band) +{ + addr = rtw89_mac_reg_by_idx(rtwdev, addr, band); + + rtw89_write16(rtwdev, addr, data); +} + static inline u32 rtw89_mac_reg_by_port(struct rtw89_dev *rtwdev, u32 base, u8 port, u8 mac_idx) { @@ -1340,6 +1373,24 @@ int rtw89_mac_cfg_ppdu_status_bands(struct rtw89_dev *rtwdev, bool enable) return rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_1, enable); } +static inline +void rtw89_mac_set_edcca_mode(struct rtw89_dev *rtwdev, u8 mac_idx, bool normal) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + if (!mac->set_edcca_mode) + return; + + mac->set_edcca_mode(rtwdev, mac_idx, normal); +} + +static inline +void rtw89_mac_set_edcca_mode_bands(struct rtw89_dev *rtwdev, bool normal) +{ + rtw89_mac_set_edcca_mode(rtwdev, RTW89_MAC_0, normal); + rtw89_mac_set_edcca_mode(rtwdev, RTW89_MAC_1, normal); +} + void rtw89_mac_set_rx_fltr(struct rtw89_dev *rtwdev, u8 mac_idx, u32 rx_fltr); void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev); void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop); @@ -1352,6 +1403,8 @@ int rtw89_mac_cfg_gnt_v1(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex_gnt *gnt_cfg); int rtw89_mac_cfg_gnt_v2(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex_gnt *gnt_cfg); +int rtw89_mac_cfg_gnt_v3(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex_gnt *gnt_cfg); static inline int rtw89_mac_cfg_plt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt) @@ -1567,6 +1620,8 @@ enum rtw89_mac_xtal_si_offset { XTAL_SI_APBT = 0xD1, XTAL_SI_PLL = 0xE0, XTAL_SI_PLL_1 = 0xE1, + XTAL_SI_CHIP_ID_L = 0xFD, + XTAL_SI_CHIP_ID_H = 0xFE, }; static inline @@ -1597,6 +1652,16 @@ 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 int rtw89_mac_efuse_read_ecv(struct rtw89_dev *rtwdev) +{ + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + if (!mac->efuse_read_ecv) + return -ENOENT; + + return mac->efuse_read_ecv(rtwdev); +} + static inline void rtw89_fwdl_secure_idmem_share_mode(struct rtw89_dev *rtwdev, u8 mode) { @@ -1605,7 +1670,7 @@ void rtw89_fwdl_secure_idmem_share_mode(struct rtw89_dev *rtwdev, u8 mode) if (!mac->fwdl_secure_idmem_share_mode) return; - return mac->fwdl_secure_idmem_share_mode(rtwdev, mode); + mac->fwdl_secure_idmem_share_mode(rtwdev, mode); } static inline @@ -1719,4 +1784,16 @@ void rtw89_tx_rpt_skbs_purge(struct rtw89_dev *rtwdev) rtw89_tx_rpt_tx_status(rtwdev, skbs[i], RTW89_TX_MACID_DROP); } + +static inline bool rtw89_mac_chk_preload_allow(struct rtw89_dev *rtwdev) +{ + if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE) + return false; + + if (rtwdev->chip->chip_id == RTL8922D && rtwdev->hal.cid == RTL8922D_CID7090) + return true; + + return false; +} + #endif diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index f39ca1c2ed10..ba71709a9bc9 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -127,6 +127,7 @@ static int __rtw89_ops_add_iface_link(struct rtw89_dev *rtwdev, rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; rtwvif_link->rand_tsf_done = false; rtwvif_link->detect_bcn_count = 0; + rtwvif_link->last_sync_bcn_tsf = 0; rcu_read_lock(); @@ -719,7 +720,8 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_MLD_VALID_LINKS) { struct rtw89_vif_link *cur = rtw89_get_designated_link(rtwvif); - rtw89_chip_rfk_channel(rtwdev, cur); + if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw)) + rtw89_chip_rfk_channel(rtwdev, cur); if (hweight16(vif->active_links) == 1) rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR; @@ -1612,12 +1614,23 @@ static int __rtw89_ops_set_vif_links(struct rtw89_dev *rtwdev, return 0; } -static void rtw89_vif_cfg_fw_links(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, - unsigned long links, bool en) +static void rtw89_vif_update_fw_links(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + u16 current_links, bool en) { + struct rtw89_vif_ml_trans *trans = &rtwvif->ml_trans; struct rtw89_vif_link *rtwvif_link; unsigned int link_id; + unsigned long links; + + /* Do follow-up when all updating links exist. */ + if (current_links != trans->mediate_links) + return; + + if (en) + links = trans->links_to_add; + else + links = trans->links_to_del; for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) { rtwvif_link = rtwvif->links[link_id]; @@ -1628,20 +1641,6 @@ static void rtw89_vif_cfg_fw_links(struct rtw89_dev *rtwdev, } } -static void rtw89_vif_update_fw_links(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif, - u16 current_links) -{ - struct rtw89_vif_ml_trans *trans = &rtwvif->ml_trans; - - /* Do follow-up when all updating links exist. */ - if (current_links != trans->mediate_links) - return; - - rtw89_vif_cfg_fw_links(rtwdev, rtwvif, trans->links_to_del, false); - rtw89_vif_cfg_fw_links(rtwdev, rtwvif, trans->links_to_add, true); -} - static int rtw89_ops_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -1683,7 +1682,7 @@ int rtw89_ops_change_vif_links(struct ieee80211_hw *hw, if (rtwdev->scanning) rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); - rtw89_vif_update_fw_links(rtwdev, rtwvif, old_links); + rtw89_vif_update_fw_links(rtwdev, rtwvif, old_links, true); if (!old_links) __rtw89_ops_clr_vif_links(rtwdev, rtwvif, @@ -1716,6 +1715,9 @@ int rtw89_ops_change_vif_links(struct ieee80211_hw *hw, BIT(RTW89_VIF_IDLE_LINK_ID)); } + if (!ret) + rtw89_vif_update_fw_links(rtwdev, rtwvif, new_links, false); + rtw89_enter_ips_by_hwflags(rtwdev); return ret; } diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c index 556e5f98e8d4..142e892f85c4 100644 --- a/drivers/net/wireless/realtek/rtw89/mac_be.c +++ b/drivers/net/wireless/realtek/rtw89/mac_be.c @@ -89,6 +89,7 @@ static void hfc_get_mix_info_be(struct rtw89_dev *rtwdev) struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; struct rtw89_hfc_pub_info *info = ¶m->pub_info; + const struct rtw89_chip_info *chip = rtwdev->chip; u32 val; val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_INFO1); @@ -116,14 +117,23 @@ static void hfc_get_mix_info_be(struct rtw89_dev *rtwdev) val = rtw89_read32(rtwdev, R_BE_CH_PAGE_CTRL); prec_cfg->ch011_prec = u32_get_bits(val, B_BE_PREC_PAGE_CH011_V1_MASK); + if (chip->chip_id == RTL8922D) + prec_cfg->ch011_full_page = u32_get_bits(val, B_BE_FULL_WD_PG_MASK); prec_cfg->h2c_prec = u32_get_bits(val, B_BE_PREC_PAGE_CH12_V1_MASK); val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_CTRL2); pub_cfg->pub_max = u32_get_bits(val, B_BE_PUBPG_ALL_MASK); val = rtw89_read32(rtwdev, R_BE_WP_PAGE_CTRL1); - prec_cfg->wp_ch07_prec = u32_get_bits(val, B_BE_PREC_PAGE_WP_CH07_MASK); - prec_cfg->wp_ch811_prec = u32_get_bits(val, B_BE_PREC_PAGE_WP_CH811_MASK); + if (chip->chip_id == RTL8922D) { + prec_cfg->wp_ch07_prec = u32_get_bits(val, B_BE_PREC_PAGE_WP_CH07_V1_MASK); + prec_cfg->wp_ch07_full_page = u32_get_bits(val, B_BE_FULL_PAGE_WP_CH07_MASK); + prec_cfg->wp_ch811_prec = u32_get_bits(val, B_BE_PREC_PAGE_WP_CH811_V1_MASK); + prec_cfg->wp_ch811_full_page = u32_get_bits(val, B_BE_FULL_PAGE_WP_CH811_MASK); + } else { + prec_cfg->wp_ch07_prec = u32_get_bits(val, B_BE_PREC_PAGE_WP_CH07_MASK); + prec_cfg->wp_ch811_prec = u32_get_bits(val, B_BE_PREC_PAGE_WP_CH811_MASK); + } val = rtw89_read32(rtwdev, R_BE_WP_PAGE_CTRL2); pub_cfg->wp_thrd = u32_get_bits(val, B_BE_WP_THRD_MASK); @@ -148,17 +158,26 @@ static void hfc_mix_cfg_be(struct rtw89_dev *rtwdev) struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; const struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; const struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; + const struct rtw89_chip_info *chip = rtwdev->chip; u32 val; val = u32_encode_bits(prec_cfg->ch011_prec, B_BE_PREC_PAGE_CH011_V1_MASK) | u32_encode_bits(prec_cfg->h2c_prec, B_BE_PREC_PAGE_CH12_V1_MASK); + if (chip->chip_id == RTL8922D) + val = u32_replace_bits(val, prec_cfg->ch011_full_page, B_BE_FULL_WD_PG_MASK); rtw89_write32(rtwdev, R_BE_CH_PAGE_CTRL, val); val = u32_encode_bits(pub_cfg->pub_max, B_BE_PUBPG_ALL_MASK); rtw89_write32(rtwdev, R_BE_PUB_PAGE_CTRL2, val); - val = u32_encode_bits(prec_cfg->wp_ch07_prec, B_BE_PREC_PAGE_WP_CH07_MASK) | - u32_encode_bits(prec_cfg->wp_ch811_prec, B_BE_PREC_PAGE_WP_CH811_MASK); + if (chip->chip_id == RTL8922D) + val = u32_encode_bits(prec_cfg->wp_ch07_prec, B_BE_PREC_PAGE_WP_CH07_V1_MASK) | + u32_encode_bits(prec_cfg->wp_ch07_full_page, B_BE_FULL_PAGE_WP_CH07_MASK) | + u32_encode_bits(prec_cfg->wp_ch811_prec, B_BE_PREC_PAGE_WP_CH811_V1_MASK) | + u32_encode_bits(prec_cfg->wp_ch811_full_page, B_BE_FULL_PAGE_WP_CH811_MASK); + else + val = u32_encode_bits(prec_cfg->wp_ch07_prec, B_BE_PREC_PAGE_WP_CH07_MASK) | + u32_encode_bits(prec_cfg->wp_ch811_prec, B_BE_PREC_PAGE_WP_CH811_MASK); rtw89_write32(rtwdev, R_BE_WP_PAGE_CTRL1, val); val = u32_replace_bits(rtw89_read32(rtwdev, R_BE_HCI_FC_CTRL), @@ -200,6 +219,9 @@ static void dle_func_en_be(struct rtw89_dev *rtwdev, bool enable) static void dle_clk_en_be(struct rtw89_dev *rtwdev, bool enable) { + if (rtwdev->chip->chip_id != RTL8922A) + return; + if (enable) rtw89_write32_set(rtwdev, R_BE_DMAC_CLK_EN, B_BE_DLE_WDE_CLK_EN | B_BE_DLE_PLE_CLK_EN); @@ -331,6 +353,11 @@ static void ple_quota_cfg_be(struct rtw89_dev *rtwdev, SET_QUOTA(cpu_io, PLE, 10); SET_QUOTA(tx_rpt, PLE, 11); SET_QUOTA(h2d, PLE, 12); + + if (rtwdev->chip->chip_id == RTL8922A) + return; + + SET_QUOTA(snrpt, PLE, 13); } static void rtw89_mac_hci_func_en_be(struct rtw89_dev *rtwdev) @@ -341,6 +368,8 @@ static void rtw89_mac_hci_func_en_be(struct rtw89_dev *rtwdev) static void rtw89_mac_dmac_func_pre_en_be(struct rtw89_dev *rtwdev) { + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 mask; u32 val; val = rtw89_read32(rtwdev, R_BE_HAXI_INIT_CFG1); @@ -364,12 +393,12 @@ static void rtw89_mac_dmac_func_pre_en_be(struct rtw89_dev *rtwdev) rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val); - rtw89_write32_clr(rtwdev, R_BE_HAXI_DMA_STOP1, - B_BE_STOP_CH0 | B_BE_STOP_CH1 | B_BE_STOP_CH2 | - B_BE_STOP_CH3 | B_BE_STOP_CH4 | B_BE_STOP_CH5 | - B_BE_STOP_CH6 | B_BE_STOP_CH7 | B_BE_STOP_CH8 | - B_BE_STOP_CH9 | B_BE_STOP_CH10 | B_BE_STOP_CH11 | - B_BE_STOP_CH12 | B_BE_STOP_CH13 | B_BE_STOP_CH14); + if (chip->chip_id == RTL8922A) + mask = B_BE_TX_STOP1_MASK; + else + mask = B_BE_TX_STOP1_MASK_V1; + + rtw89_write32_clr(rtwdev, R_BE_HAXI_DMA_STOP1, mask); rtw89_write32_set(rtwdev, R_BE_DMAC_TABLE_CTRL, B_BE_DMAC_ADDR_MODE); } @@ -396,6 +425,12 @@ int rtw89_mac_write_xtal_si_be(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 m return ret; } + if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags) && + (u32_get_bits(val32, B_BE_WL_XTAL_SI_ADDR_MASK) != offset || + u32_get_bits(val32, B_BE_WL_XTAL_SI_DATA_MASK) != val)) + rtw89_warn(rtwdev, "xtal si write: offset=%x val=%x poll=%x\n", + offset, val, val32); + return 0; } @@ -420,7 +455,141 @@ int rtw89_mac_read_xtal_si_be(struct rtw89_dev *rtwdev, u8 offset, u8 *val) return ret; } - *val = rtw89_read8(rtwdev, R_BE_WLAN_XTAL_SI_CTRL + 1); + if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags) && + u32_get_bits(val32, B_BE_WL_XTAL_SI_ADDR_MASK) != offset) + rtw89_warn(rtwdev, "xtal si read: offset=%x poll=%x\n", + offset, val32); + + *val = u32_get_bits(val32, B_BE_WL_XTAL_SI_DATA_MASK); + + return 0; +} + +static int rtw89_mac_reset_pwr_state_be(struct rtw89_dev *rtwdev) +{ + u32 val32; + int ret; + + val32 = rtw89_read32(rtwdev, R_BE_SYSON_FSM_MON); + val32 &= WLAN_FSM_MASK; + val32 |= WLAN_FSM_SET; + rtw89_write32(rtwdev, R_BE_SYSON_FSM_MON, val32); + + ret = read_poll_timeout(rtw89_read32_mask, val32, val32 == WLAN_FSM_IDLE, + 1000, 2000000, false, + rtwdev, R_BE_SYSON_FSM_MON, WLAN_FSM_STATE_MASK); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling WLAN PMC timeout= %X\n", val32); + return ret; + } + + val32 = rtw89_read32_mask(rtwdev, R_BE_IC_PWR_STATE, B_BE_WLMAC_PWR_STE_MASK); + if (val32 == MAC_AX_MAC_OFF) { + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN); + + ret = read_poll_timeout(rtw89_read32_mask, val32, !val32, + 1000, 2000000, false, + rtwdev, R_BE_HCI_OPT_CTRL, + B_BE_HAXIDMA_IO_ST | B_BE_HAXIDMA_BACKUP_RESTORE_ST); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling HAXI IO timeout= %X\n", val32); + return ret; + } + + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN); + + ret = read_poll_timeout(rtw89_read32_mask, val32, !val32, + 1000, 2000000, false, + rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_ST); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling WLAN IO timeout= %X\n", val32); + return ret; + } + + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON); + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS); + } else if (val32 == MAC_AX_MAC_ON) { + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN); + + ret = read_poll_timeout(rtw89_read32_mask, val32, !val32, + 1000, 2000000, false, + rtwdev, R_BE_HCI_OPT_CTRL, + B_BE_HAXIDMA_IO_ST | B_BE_HAXIDMA_BACKUP_RESTORE_ST); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling HAXI IO timeout= %X\n", val32); + return ret; + } + + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN); + + ret = read_poll_timeout(rtw89_read32_mask, val32, !val32, + 1000, 2000000, false, + rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_ST); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling WLAN IO timeout= %X\n", val32); + return ret; + } + + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON); + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_OFFMAC); + + ret = read_poll_timeout(rtw89_read32_mask, val32, val32 == MAC_AX_MAC_OFF, + 1000, 2000000, false, + rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_OFFMAC); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling MAC state timeout= %X\n", val32); + return ret; + } + + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON); + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS); + } else if (val32 == MAC_AX_MAC_LPS) { + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN); + + ret = read_poll_timeout(rtw89_read32_mask, val32, !val32, + 1000, 2000000, false, + rtwdev, R_BE_HCI_OPT_CTRL, + B_BE_HAXIDMA_IO_ST | B_BE_HAXIDMA_BACKUP_RESTORE_ST); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling HAXI IO timeout= %X\n", val32); + return ret; + } + + rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN); + + ret = read_poll_timeout(rtw89_read32_mask, val32, !val32, + 1000, 2000000, false, + rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_ST); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling WLAN IO timeout= %X\n", val32); + return ret; + } + + rtw89_write32_set(rtwdev, R_BE_WLLPS_CTRL, B_BE_FORCE_LEAVE_LPS); + + ret = read_poll_timeout(rtw89_read32_mask, val32, val32 == MAC_AX_MAC_ON, + 1000, 2000000, false, + rtwdev, R_BE_IC_PWR_STATE, B_BE_WLMAC_PWR_STE_MASK); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling MAC STS timeout= %X\n", val32); + return ret; + } + + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON); + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_OFFMAC); + + ret = read_poll_timeout(rtw89_read32_mask, val32, val32 == MAC_AX_MAC_OFF, + 1000, 2000000, false, + rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_OFFMAC); + if (ret) { + rtw89_err(rtwdev, "[ERR]Polling MAC state timeout= %X\n", val32); + return ret; + } + + rtw89_write32_clr(rtwdev, R_BE_WLLPS_CTRL, B_BE_FORCE_LEAVE_LPS); + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON); + rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS); + } return 0; } @@ -439,7 +608,8 @@ static void rtw89_mac_disable_cpu_be(struct rtw89_dev *rtwdev) val32 &= B_BE_RUN_ENV_MASK; rtw89_write32(rtwdev, R_BE_WCPU_FW_CTRL, val32); - rtw89_write32_set(rtwdev, R_BE_DCPU_PLATFORM_ENABLE, B_BE_DCPU_PLATFORM_EN); + if (rtwdev->chip->chip_id == RTL8922A) + rtw89_write32_set(rtwdev, R_BE_DCPU_PLATFORM_ENABLE, B_BE_DCPU_PLATFORM_EN); rtw89_write32(rtwdev, R_BE_UDM0, 0); rtw89_write32(rtwdev, R_BE_HALT_C2H, 0); @@ -585,31 +755,125 @@ static int rtw89_fwdl_check_path_ready_be(struct rtw89_dev *rtwdev, static int dmac_func_en_be(struct rtw89_dev *rtwdev) { + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->chip_id == RTL8922A) + return 0; + + rtw89_write32_set(rtwdev, R_BE_DMAC_FUNC_EN, + B_BE_MAC_FUNC_EN | B_BE_DMAC_FUNC_EN | + B_BE_MPDU_PROC_EN | B_BE_WD_RLS_EN | + B_BE_DLE_WDE_EN | B_BE_TXPKT_CTRL_EN | + B_BE_STA_SCH_EN | B_BE_DLE_PLE_EN | + B_BE_PKT_BUF_EN | B_BE_DMAC_TBL_EN | + B_BE_PKT_IN_EN | B_BE_DLE_CPUIO_EN | + B_BE_DISPATCHER_EN | B_BE_BBRPT_EN | + B_BE_MAC_SEC_EN | B_BE_H_AXIDMA_EN | + B_BE_DMAC_MLO_EN | B_BE_PLRLS_EN | + B_BE_P_AXIDMA_EN | B_BE_DLE_DATACPUIO_EN); + + return 0; +} + +static int cmac_share_func_en_be(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + if (chip->chip_id == RTL8922A) + return 0; + + rtw89_write32_set(rtwdev, R_BE_CMAC_SHARE_FUNC_EN, + B_BE_CMAC_SHARE_EN | B_BE_RESPBA_EN | + B_BE_ADDRSRCH_EN | B_BE_BTCOEX_EN); + + return 0; +} + +static int cmac_pwr_en_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool en) +{ + if (mac_idx > RTW89_MAC_1) + return -EINVAL; + + if (mac_idx == RTW89_MAC_0) { + if (en == test_bit(RTW89_FLAG_CMAC0_PWR, rtwdev->flags)) + return 0; + + if (en) { + rtw89_write32_set(rtwdev, R_BE_AFE_CTRL1, + B_BE_R_SYM_WLCMAC0_ALL_EN); + rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_R_SYM_ISO_CMAC02PP); + rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_CMAC0_FEN); + + set_bit(RTW89_FLAG_CMAC0_PWR, rtwdev->flags); + } else { + rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_CMAC0_FEN); + rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_R_SYM_ISO_CMAC02PP); + rtw89_write32_clr(rtwdev, R_BE_AFE_CTRL1, + B_BE_R_SYM_WLCMAC0_ALL_EN); + + clear_bit(RTW89_FLAG_CMAC0_PWR, rtwdev->flags); + } + } else { + if (en == test_bit(RTW89_FLAG_CMAC1_PWR, rtwdev->flags)) + return 0; + + if (en) { + rtw89_write32_set(rtwdev, R_BE_AFE_CTRL1, + B_BE_R_SYM_WLCMAC1_ALL_EN); + rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_R_SYM_ISO_CMAC12PP); + rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_CMAC1_FEN); + + set_bit(RTW89_FLAG_CMAC1_PWR, rtwdev->flags); + } else { + rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_CMAC1_FEN); + rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, + B_BE_R_SYM_ISO_CMAC12PP); + rtw89_write32_clr(rtwdev, R_BE_AFE_CTRL1, + B_BE_R_SYM_WLCMAC1_ALL_EN); + + clear_bit(RTW89_FLAG_CMAC1_PWR, rtwdev->flags); + } + } + return 0; } static int cmac_func_en_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool en) { + enum rtw89_flags pwr_flag, func_flag; u32 reg; if (mac_idx > RTW89_MAC_1) return -EINVAL; - if (mac_idx == RTW89_MAC_0) + if (mac_idx == RTW89_MAC_0) { + pwr_flag = RTW89_FLAG_CMAC0_PWR; + func_flag = RTW89_FLAG_CMAC0_FUNC; + } else { + pwr_flag = RTW89_FLAG_CMAC1_PWR; + func_flag = RTW89_FLAG_CMAC1_FUNC; + } + + if (!test_bit(pwr_flag, rtwdev->flags)) { + rtw89_warn(rtwdev, "CMAC %u power cut did not release\n", mac_idx); return 0; + } if (en) { - rtw89_write32_set(rtwdev, R_BE_AFE_CTRL1, B_BE_AFE_CTRL1_SET); - rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL_EXTEND, B_BE_R_SYM_ISO_CMAC12PP); - rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_CMAC1_FEN); - reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CK_EN, mac_idx); rtw89_write32_set(rtwdev, reg, B_BE_CK_EN_SET); reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CMAC_FUNC_EN, mac_idx); rtw89_write32_set(rtwdev, reg, B_BE_CMAC_FUNC_EN_SET); - set_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags); + set_bit(func_flag, rtwdev->flags); } else { reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CMAC_FUNC_EN, mac_idx); rtw89_write32_clr(rtwdev, reg, B_BE_CMAC_FUNC_EN_SET); @@ -617,11 +881,7 @@ static int cmac_func_en_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool en) reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CK_EN, mac_idx); rtw89_write32_clr(rtwdev, reg, B_BE_CK_EN_SET); - rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_CMAC1_FEN); - rtw89_write32_set(rtwdev, R_BE_SYS_ISO_CTRL_EXTEND, B_BE_R_SYM_ISO_CMAC12PP); - rtw89_write32_clr(rtwdev, R_BE_AFE_CTRL1, B_BE_AFE_CTRL1_SET); - - clear_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags); + clear_bit(func_flag, rtwdev->flags); } return 0; @@ -640,6 +900,14 @@ static int sys_init_be(struct rtw89_dev *rtwdev) if (ret) return ret; + ret = cmac_share_func_en_be(rtwdev); + if (ret) + return ret; + + ret = cmac_pwr_en_be(rtwdev, RTW89_MAC_0, true); + if (ret) + return ret; + ret = cmac_func_en_be(rtwdev, RTW89_MAC_0, true); if (ret) return ret; @@ -651,11 +919,53 @@ static int sys_init_be(struct rtw89_dev *rtwdev) return ret; } +static int mac_func_en_be(struct rtw89_dev *rtwdev) +{ + u32 val; + int ret; + + ret = dmac_func_en_be(rtwdev); + if (ret) + return ret; + + ret = cmac_share_func_en_be(rtwdev); + if (ret) + return ret; + + val = rtw89_read32(rtwdev, R_BE_FEN_RST_ENABLE); + if (val & B_BE_CMAC0_FEN) { + ret = cmac_pwr_en_be(rtwdev, RTW89_MAC_0, true); + if (ret) + return ret; + + ret = cmac_func_en_be(rtwdev, RTW89_MAC_0, true); + if (ret) + return ret; + } + + if (val & B_BE_CMAC1_FEN) { + ret = cmac_pwr_en_be(rtwdev, RTW89_MAC_1, true); + if (ret) + return ret; + + ret = cmac_func_en_be(rtwdev, RTW89_MAC_1, true); + if (ret) + return ret; + } + + return 0; +} + static int sta_sch_init_be(struct rtw89_dev *rtwdev) { u32 p_val; int ret; + if (rtwdev->chip->chip_id == RTL8922D) { + rtw89_write32_set(rtwdev, R_BE_SS_LITE_TXL_MACID, B_BE_RPT_OTHER_BAND_EN); + return 0; + } + ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); if (ret) return ret; @@ -685,14 +995,16 @@ static int mpdu_proc_init_be(struct rtw89_dev *rtwdev) return ret; rtw89_write32_set(rtwdev, R_BE_MPDU_PROC, B_BE_APPEND_FCS); - rtw89_write32(rtwdev, R_BE_CUT_AMSDU_CTRL, TRXCFG_MPDU_PROC_CUT_CTRL); + rtw89_write32(rtwdev, R_BE_CUT_AMSDU_CTRL, TRXCFG_MPDU_PROC_CUT_CTRL | + B_BE_CA_CHK_ADDRCAM_EN); val32 = rtw89_read32(rtwdev, R_BE_HDR_SHCUT_SETTING); val32 |= (B_BE_TX_HW_SEQ_EN | B_BE_TX_HW_ACK_POLICY_EN | B_BE_TX_MAC_MPDU_PROC_EN); val32 &= ~B_BE_TX_ADDR_MLD_TO_LIK; rtw89_write32_set(rtwdev, R_BE_HDR_SHCUT_SETTING, val32); - rtw89_write32(rtwdev, R_BE_RX_HDRTRNS, TRXCFG_MPDU_PROC_RX_HDR_CONV); + rtw89_write32(rtwdev, R_BE_RX_HDRTRNS, TRXCFG_MPDU_PROC_RX_HDR_CONV | + B_BE_HC_ADDR_HIT_EN); val32 = rtw89_read32(rtwdev, R_BE_DISP_FWD_WLAN_0); val32 = u32_replace_bits(val32, 1, B_BE_FWD_WLAN_CPU_TYPE_0_DATA_MASK); @@ -728,7 +1040,10 @@ static int sec_eng_init_be(struct rtw89_dev *rtwdev) static int txpktctrl_init_be(struct rtw89_dev *rtwdev) { + struct rtw89_mac_info *mac = &rtwdev->mac; struct rtw89_mac_dle_rsvd_qt_cfg qt_cfg; + const struct rtw89_dle_input *dle_input; + u32 mpdu_info_b1_ofst; u32 val32; int ret; @@ -739,9 +1054,16 @@ static int txpktctrl_init_be(struct rtw89_dev *rtwdev) return ret; } + dle_input = mac->dle_info.dle_input; + if (dle_input) + mpdu_info_b1_ofst = DIV_ROUND_UP(dle_input->mpdu_info_tbl_b0, + BIT(MPDU_INFO_TBL_FACTOR)); + else + mpdu_info_b1_ofst = MPDU_INFO_B1_OFST; + val32 = rtw89_read32(rtwdev, R_BE_TXPKTCTL_MPDUINFO_CFG); val32 = u32_replace_bits(val32, qt_cfg.pktid, B_BE_MPDUINFO_PKTID_MASK); - val32 = u32_replace_bits(val32, MPDU_INFO_B1_OFST, B_BE_MPDUINFO_B1_BADDR_MASK); + val32 = u32_replace_bits(val32, mpdu_info_b1_ofst, B_BE_MPDUINFO_B1_BADDR_MASK); val32 |= B_BE_MPDUINFO_FEN; rtw89_write32(rtwdev, R_BE_TXPKTCTL_MPDUINFO_CFG, val32); @@ -750,7 +1072,9 @@ static int txpktctrl_init_be(struct rtw89_dev *rtwdev) static int mlo_init_be(struct rtw89_dev *rtwdev) { + const struct rtw89_chip_info *chip = rtwdev->chip; u32 val32; + u32 reg; int ret; val32 = rtw89_read32(rtwdev, R_BE_MLO_INIT_CTL); @@ -766,7 +1090,12 @@ static int mlo_init_be(struct rtw89_dev *rtwdev) if (ret) rtw89_err(rtwdev, "[MLO]%s: MLO init polling timeout\n", __func__); - rtw89_write32_set(rtwdev, R_BE_SS_CTRL, B_BE_MLO_HW_CHGLINK_EN); + if (chip->chip_id == RTL8922A) + reg = R_BE_SS_CTRL; + else + reg = R_BE_SS_CTRL_V1; + + rtw89_write32_set(rtwdev, reg, B_BE_MLO_HW_CHGLINK_EN); rtw89_write32_set(rtwdev, R_BE_CMAC_SHARE_ACQCHK_CFG_0, B_BE_R_MACID_ACQ_CHK_EN); return ret; @@ -829,6 +1158,7 @@ static int dmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) static int scheduler_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) { + const struct rtw89_chip_info *chip = rtwdev->chip; u32 val32; u32 reg; int ret; @@ -837,6 +1167,11 @@ static int scheduler_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) if (ret) return ret; + if (chip->chip_id == RTL8922D) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_SCH_EXT_CTRL, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_CWCNT_PLUS_MODE); + } + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_HE_CTN_CHK_CCA_NAV, mac_idx); val32 = B_BE_HE_CTN_CHK_CCA_P20 | B_BE_HE_CTN_CHK_EDCCA_P20 | B_BE_HE_CTN_CHK_CCA_BITMAP | B_BE_HE_CTN_CHK_EDCCA_BITMAP | @@ -870,6 +1205,11 @@ static int scheduler_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) rtw89_write32_mask(rtwdev, reg, B_BE_BCNQ_CW_MASK, 0x32); rtw89_write32_mask(rtwdev, reg, B_BE_BCNQ_AIFS_MASK, BCN_IFS_25US); + if (chip->chip_id == RTL8922D) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_SCH_EDCA_RST_CFG, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_TX_NAV_RST_EDCA_EN); + } + return 0; } @@ -985,6 +1325,9 @@ static int nav_ctrl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) rtw89_write32(rtwdev, reg, val32); + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_SPECIAL_TX_SETTING, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_BE_BMC_NAV_PROTECT); + return 0; } @@ -1008,14 +1351,22 @@ static int spatial_reuse_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) static int tmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) { + const struct rtw89_chip_info *chip = rtwdev->chip; u32 reg; reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TB_PPDU_CTRL, mac_idx); rtw89_write32_clr(rtwdev, reg, B_BE_QOSNULL_UPD_MUEDCA_EN); - reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMTX_TCR_BE_4, mac_idx); - rtw89_write32_mask(rtwdev, reg, B_BE_EHT_HE_PPDU_4XLTF_ZLD_USTIMER_MASK, 0x12); - rtw89_write32_mask(rtwdev, reg, B_BE_EHT_HE_PPDU_2XLTF_ZLD_USTIMER_MASK, 0xe); + if (chip->chip_id == RTL8922A) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMTX_TCR_BE_4, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_EHT_HE_PPDU_4XLTF_ZLD_USTIMER_MASK, 0x12); + rtw89_write32_mask(rtwdev, reg, B_BE_EHT_HE_PPDU_2XLTF_ZLD_USTIMER_MASK, 0xe); + } + + if (chip->chip_id == RTL8922D) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_COMMON_PHYINTF_CTRL_0, mac_idx); + rtw89_write32_clr(rtwdev, reg, CLEAR_DTOP_DIS); + } return 0; } @@ -1040,6 +1391,15 @@ static int trxptcl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) val32 &= ~B_BE_MACLBK_EN; rtw89_write32(rtwdev, reg, val32); + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CMAC_FUNC_EN, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_PHYINTF_EN); + + if (chip->chip_id == RTL8922D) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_PLCP_EXT_OPTION_2, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_PLCP_PHASE_B_CRC_CHK_EN | + B_BE_PLCP_PHASE_A_CRC_CHK_EN); + } + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_0, mac_idx); val32 = rtw89_read32(rtwdev, reg); val32 = u32_replace_bits(val32, WMAC_SPEC_SIFS_CCK, @@ -1109,6 +1469,7 @@ static int rst_bacam_be(struct rtw89_dev *rtwdev) static int rmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) { + const struct rtw89_chip_info *chip = rtwdev->chip; u32 rx_min_qta, rx_max_len, rx_max_pg; u16 val16; u32 reg; @@ -1152,6 +1513,17 @@ static int rmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_PLCP_EXT_OPTION_1, mac_idx); rtw89_write16_set(rtwdev, reg, B_BE_PLCP_SU_PSDU_LEN_SRC); + if (chip->chip_id == RTL8922D) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_BSR_UPD_CTRL, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_QSIZE_RULE); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RXGCK_CTRL, mac_idx); + rtw89_write16_mask(rtwdev, reg, B_BE_RXGCK_GCK_RATE_LIMIT_MASK, RX_GCK_LEGACY); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PLCP_HDR_FLTR, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_DIS_CHK_MIN_LEN); + } + return 0; } @@ -1175,7 +1547,7 @@ static int resp_pktctl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RESP_CSI_RESERVED_PAGE, mac_idx); rtw89_write32_mask(rtwdev, reg, B_BE_CSI_RESERVED_START_PAGE_MASK, qt_cfg.pktid); - rtw89_write32_mask(rtwdev, reg, B_BE_CSI_RESERVED_PAGE_NUM_MASK, qt_cfg.pg_num); + rtw89_write32_mask(rtwdev, reg, B_BE_CSI_RESERVED_PAGE_NUM_MASK, qt_cfg.pg_num + 1); return 0; } @@ -1210,6 +1582,7 @@ static int cmac_com_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) static int ptcl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) { + const struct rtw89_chip_info *chip = rtwdev->chip; u32 val32; u8 val8; u32 reg; @@ -1224,8 +1597,9 @@ static int ptcl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) val32 = rtw89_read32(rtwdev, reg); val32 = u32_replace_bits(val32, S_AX_CTS2S_TH_1K, B_BE_HW_CTS2SELF_PKT_LEN_TH_MASK); - val32 = u32_replace_bits(val32, S_AX_CTS2S_TH_SEC_256B, - B_BE_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK); + if (chip->chip_id == RTL8922A) + val32 = u32_replace_bits(val32, S_AX_CTS2S_TH_SEC_256B, + B_BE_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK); val32 |= B_BE_HW_CTS2SELF_EN; rtw89_write32(rtwdev, reg, val32); @@ -1246,7 +1620,46 @@ static int ptcl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) rtw89_write8(rtwdev, reg, val8); reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_AMPDU_AGG_LIMIT, mac_idx); - rtw89_write32_mask(rtwdev, reg, B_BE_AMPDU_MAX_TIME_MASK, AMPDU_MAX_TIME); + if (chip->chip_id == RTL8922A) + val32 = AMPDU_MAX_TIME; + else + val32 = AMPDU_MAX_TIME_V1; + rtw89_write32_mask(rtwdev, reg, B_BE_AMPDU_MAX_TIME_MASK, val32); + + if (chip->chip_id == RTL8922D) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_AGG_BK_0, mac_idx); + rtw89_write32_clr(rtwdev, reg, B_BE_WDBK_CFG | B_BE_EN_RTY_BK | + B_BE_EN_RTY_BK_COD); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_AMPDU_AGG_LIMIT, mac_idx); + rtw89_write32_mask(rtwdev, reg, B_BE_MAX_AGG_NUM_MASK, + MAX_TX_AMPDU_NUM_V1 - 1); + } + + if (rtw89_mac_chk_preload_allow(rtwdev)) { + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_AGG_BK_0, mac_idx); + rtw89_write32_set(rtwdev, reg, B_BE_PRELD_MGQ0_EN | + B_BE_PRELD_HIQ_P4_EN | + B_BE_PRELD_HIQ_P3_EN | + B_BE_PRELD_HIQ_P2_EN | + B_BE_PRELD_HIQ_P1_EN | + B_BE_PRELD_HIQ_P0MB15_EN | + B_BE_PRELD_HIQ_P0MB14_EN | + B_BE_PRELD_HIQ_P0MB13_EN | + B_BE_PRELD_HIQ_P0MB12_EN | + B_BE_PRELD_HIQ_P0MB11_EN | + B_BE_PRELD_HIQ_P0MB10_EN | + B_BE_PRELD_HIQ_P0MB9_EN | + B_BE_PRELD_HIQ_P0MB8_EN | + B_BE_PRELD_HIQ_P0MB7_EN | + B_BE_PRELD_HIQ_P0MB6_EN | + B_BE_PRELD_HIQ_P0MB5_EN | + B_BE_PRELD_HIQ_P0MB4_EN | + B_BE_PRELD_HIQ_P0MB3_EN | + B_BE_PRELD_HIQ_P0MB2_EN | + B_BE_PRELD_HIQ_P0MB1_EN | + B_BE_PRELD_HIQ_P0_EN); + } return 0; } @@ -1533,22 +1946,22 @@ static int dle_quota_change_be(struct rtw89_dev *rtwdev, bool band1_en) static int preload_init_be(struct rtw89_dev *rtwdev, u8 mac_idx, enum rtw89_qta_mode mode) { + const struct rtw89_chip_info *chip = rtwdev->chip; u32 max_preld_size, min_rsvd_size; + u8 preld_acq, preld_miscq; u32 val32; u32 reg; + if (!(chip->chip_id == RTL8922A || rtw89_mac_chk_preload_allow(rtwdev))) + return 0; + max_preld_size = mac_idx == RTW89_MAC_0 ? PRELD_B0_ENT_NUM : PRELD_B1_ENT_NUM; + if (chip->chip_id == RTL8922D) + max_preld_size = PRELD_B01_ENT_NUM_8922D; max_preld_size *= PRELD_AMSDU_SIZE; + min_rsvd_size = PRELD_NEXT_MIN_SIZE; - reg = mac_idx == RTW89_MAC_0 ? R_BE_TXPKTCTL_B0_PRELD_CFG0 : - R_BE_TXPKTCTL_B1_PRELD_CFG0; - val32 = rtw89_read32(rtwdev, reg); - val32 = u32_replace_bits(val32, max_preld_size, B_BE_B0_PRELD_USEMAXSZ_MASK); - val32 |= B_BE_B0_PRELD_FEN; - rtw89_write32(rtwdev, reg, val32); - - min_rsvd_size = PRELD_AMSDU_SIZE; reg = mac_idx == RTW89_MAC_0 ? R_BE_TXPKTCTL_B0_PRELD_CFG1 : R_BE_TXPKTCTL_B1_PRELD_CFG1; val32 = rtw89_read32(rtwdev, reg); @@ -1556,6 +1969,24 @@ static int preload_init_be(struct rtw89_dev *rtwdev, u8 mac_idx, val32 = u32_replace_bits(val32, min_rsvd_size, B_BE_B0_PRELD_NXT_RSVMINSZ_MASK); rtw89_write32(rtwdev, reg, val32); + reg = mac_idx == RTW89_MAC_0 ? R_BE_TXPKTCTL_B0_PRELD_CFG0 : + R_BE_TXPKTCTL_B1_PRELD_CFG0; + if (chip->chip_id == RTL8922D) { + preld_acq = PRELD_ACQ_ENT_NUM_8922D; + preld_miscq = PRELD_MISCQ_ENT_NUM_8922D; + } else { + preld_acq = mac_idx == RTW89_MAC_0 ? PRELD_B0_ACQ_ENT_NUM_8922A : + PRELD_B1_ACQ_ENT_NUM_8922A; + preld_miscq = PRELD_MISCQ_ENT_NUM_8922A; + } + + val32 = rtw89_read32(rtwdev, reg); + val32 = u32_replace_bits(val32, preld_acq, B_BE_B0_PRELD_CAM_G0ENTNUM_MASK); + val32 = u32_replace_bits(val32, preld_miscq, B_BE_B0_PRELD_CAM_G1ENTNUM_MASK); + val32 = u32_replace_bits(val32, max_preld_size, B_BE_B0_PRELD_USEMAXSZ_MASK); + val32 |= B_BE_B0_PRELD_FEN; + rtw89_write32(rtwdev, reg, val32); + return 0; } @@ -1588,6 +2019,10 @@ static int enable_imr_be(struct rtw89_dev *rtwdev, u8 mac_idx, else return -EINVAL; + if (chip->chip_id == RTL8922D) + rtw89_write32_mask(rtwdev, R_BE_NO_RX_ERR_CFG, + B_BE_NO_RX_ERR_TO_MASK, 0); + for (i = 0; i < table->n_regs; i++) { reg = &table->regs[i]; addr = rtw89_mac_reg_by_idx(rtwdev, reg->addr, mac_idx); @@ -1638,6 +2073,12 @@ static int band1_enable_be(struct rtw89_dev *rtwdev) return ret; } + ret = cmac_pwr_en_be(rtwdev, RTW89_MAC_1, true); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d pwr en %d\n", RTW89_MAC_1, ret); + return ret; + } + ret = cmac_func_en_be(rtwdev, RTW89_MAC_1, true); if (ret) { rtw89_err(rtwdev, "[ERR]CMAC%d func en %d\n", RTW89_MAC_1, ret); @@ -1681,6 +2122,12 @@ static int band1_disable_be(struct rtw89_dev *rtwdev) return ret; } + ret = cmac_pwr_en_be(rtwdev, RTW89_MAC_1, false); + if (ret) { + rtw89_err(rtwdev, "[ERR]CMAC%d pwr dis %d\n", RTW89_MAC_1, ret); + return ret; + } + ret = rtw89_mac_dle_quota_change(rtwdev, rtwdev->mac.qta_mode, false); if (ret) { rtw89_err(rtwdev, "[ERR]DLE quota change %d\n", ret); @@ -1731,26 +2178,40 @@ static int dbcc_enable_be(struct rtw89_dev *rtwdev, bool enable) static int set_host_rpr_be(struct rtw89_dev *rtwdev) { + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; u32 val32; u32 mode; u32 fltr; + u32 qid; bool poh; poh = is_qta_poh(rtwdev); if (poh) { mode = RTW89_RPR_MODE_POH; - fltr = S_BE_WDRLS_FLTR_TXOK | S_BE_WDRLS_FLTR_RTYLMT | - S_BE_WDRLS_FLTR_LIFTIM | S_BE_WDRLS_FLTR_MACID; + qid = WDRLS_DEST_QID_POH; } else { mode = RTW89_RPR_MODE_STF; fltr = 0; + qid = WDRLS_DEST_QID_STF; + } + + if (chip_id == RTL8922A) { + fltr = S_BE_WDRLS_FLTR_TXOK | S_BE_WDRLS_FLTR_RTYLMT | + S_BE_WDRLS_FLTR_LIFTIM | S_BE_WDRLS_FLTR_MACID; + } else { + fltr = S_BE_WDRLS_FLTR_TXOK_V1 | S_BE_WDRLS_FLTR_RTYLMT_V1 | + S_BE_WDRLS_FLTR_LIFTIM_V1 | S_BE_WDRLS_FLTR_MACID_V1; } rtw89_write32_mask(rtwdev, R_BE_WDRLS_CFG, B_BE_WDRLS_MODE_MASK, mode); + rtw89_write32_mask(rtwdev, R_BE_RLSRPT0_CFG0, B_BE_RLSRPT0_QID_MASK, qid); val32 = rtw89_read32(rtwdev, R_BE_RLSRPT0_CFG1); - val32 = u32_replace_bits(val32, fltr, B_BE_RLSRPT0_FLTR_MAP_MASK); + if (chip_id == RTL8922A) + val32 = u32_replace_bits(val32, fltr, B_BE_RLSRPT0_FLTR_MAP_MASK); + else + val32 = u32_replace_bits(val32, fltr, B_BE_RLSRPT0_FLTR_MAP_V1_MASK); val32 = u32_replace_bits(val32, 30, B_BE_RLSRPT0_AGGNUM_MASK); val32 = u32_replace_bits(val32, 255, B_BE_RLSRPT0_TO_MASK); rtw89_write32(rtwdev, R_BE_RLSRPT0_CFG1, val32); @@ -1863,12 +2324,65 @@ int rtw89_mac_cfg_gnt_v2(struct rtw89_dev *rtwdev, } EXPORT_SYMBOL(rtw89_mac_cfg_gnt_v2); +int rtw89_mac_cfg_gnt_v3(struct rtw89_dev *rtwdev, + const struct rtw89_mac_ax_coex_gnt *gnt_cfg) +{ + u32 val = 0; + + if (gnt_cfg->band[0].gnt_bt) + val |= B_BE_PTA_GNT_BT0_BB_VAL | B_BE_PTA_GNT_BT0_RX_BB0_VAL | + B_BE_PTA_GNT_BT0_TX_BB0_VAL; + + if (gnt_cfg->band[0].gnt_bt_sw_en) + val |= B_BE_PTA_GNT_BT0_BB_SWCTRL | B_BE_PTA_GNT_BT0_RX_BB0_SWCTRL | + B_BE_PTA_GNT_BT0_TX_BB0_SWCTRL; + + if (gnt_cfg->band[0].gnt_wl) + val |= B_BE_PTA_GNT_WL_BB0_VAL; + + if (gnt_cfg->band[0].gnt_wl_sw_en) + val |= B_BE_PTA_GNT_WL_BB0_SWCTRL; + + if (gnt_cfg->band[1].gnt_bt) + val |= B_BE_PTA_GNT_BT0_BB_VAL | B_BE_PTA_GNT_BT0_RX_BB1_VAL | + B_BE_PTA_GNT_BT0_TX_BB1_VAL; + + if (gnt_cfg->band[1].gnt_bt_sw_en) + val |= B_BE_PTA_GNT_BT0_BB_SWCTRL | B_BE_PTA_GNT_BT0_RX_BB1_SWCTRL | + B_BE_PTA_GNT_BT0_TX_BB1_SWCTRL; + + if (gnt_cfg->band[1].gnt_wl) + val |= B_BE_PTA_GNT_WL_BB1_VAL; + + if (gnt_cfg->band[1].gnt_wl_sw_en) + val |= B_BE_PTA_GNT_WL_BB1_SWCTRL; + + if (gnt_cfg->bt[0].wlan_act_en) + val |= B_BE_PTA_WL_ACT0_SWCTRL | B_BE_PTA_WL_ACT_RX_BT0_SWCTRL | + B_BE_PTA_WL_ACT_TX_BT0_SWCTRL; + if (gnt_cfg->bt[0].wlan_act) + val |= B_BE_PTA_WL_ACT0_VAL | B_BE_PTA_WL_ACT_RX_BT0_VAL | + B_BE_PTA_WL_ACT_TX_BT0_VAL; + if (gnt_cfg->bt[1].wlan_act_en) + val |= B_BE_PTA_WL_ACT1_SWCTRL | B_BE_PTA_WL_ACT_RX_BT1_SWCTRL | + B_BE_PTA_WL_ACT_TX_BT1_SWCTRL; + if (gnt_cfg->bt[1].wlan_act) + val |= B_BE_PTA_WL_ACT1_VAL | B_BE_PTA_WL_ACT_RX_BT1_VAL | + B_BE_PTA_WL_ACT_TX_BT1_VAL; + + rtw89_write32(rtwdev, R_BE_PTA_GNT_SW_CTRL, val); + + return 0; +} +EXPORT_SYMBOL(rtw89_mac_cfg_gnt_v3); + int rtw89_mac_cfg_ctrl_path_v2(struct rtw89_dev *rtwdev, bool wl) { struct rtw89_btc *btc = &rtwdev->btc; struct rtw89_btc_dm *dm = &btc->dm; struct rtw89_mac_ax_gnt *g = dm->gnt.band; struct rtw89_mac_ax_wl_act *gbt = dm->gnt.bt; + const struct rtw89_chip_info *chip = rtwdev->chip; int i; if (wl) @@ -1883,7 +2397,11 @@ int rtw89_mac_cfg_ctrl_path_v2(struct rtw89_dev *rtwdev, bool wl) gbt[i].wlan_act_en = 0; } - return rtw89_mac_cfg_gnt_v2(rtwdev, &dm->gnt); + if (chip->chip_id == RTL8922A) + return rtw89_mac_cfg_gnt_v2(rtwdev, &dm->gnt); + else + return rtw89_mac_cfg_gnt_v3(rtwdev, &dm->gnt); + } EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path_v2); @@ -2012,6 +2530,65 @@ void rtw89_mac_cfg_phy_rpt_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) EXPORT_SYMBOL(rtw89_mac_cfg_phy_rpt_be); static +void rtw89_mac_set_edcca_mode_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool normal) +{ + u16 resp_ack, resp_rts, resp_rts_punc, resp_normal, resp_normal_punc; + + if (rtwdev->chip->chip_id == RTL8922A) + return; + + resp_ack = RESP_ACK_CFG_BE; + resp_rts = RESP_RTS_CFG_BE; + resp_rts_punc = RESP_RTS_PUNC_CFG_BE; + resp_normal = RESP_NORMAL_CFG_BE; + resp_normal_punc = RESP_NORMAL_PUNC_CFG_BE; + + if (normal) { + rtw89_write16_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_LEGACY, + resp_ack, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_HE, + resp_ack, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_EHT_LEG_PUNC, + resp_ack, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_RTS_RESP_LEGACY, + resp_rts, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_RTS_RESP_LEGACY_PUNC, + resp_rts_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_MURTS_RESP_LEGACY, + resp_normal, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_MURTS_RESP_LEGACY_PUNC, + resp_normal_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_OTHERS_RESP_LEGACY, + resp_normal, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_OTHERS_RESP_HE, + resp_normal_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_OTHERS_RESP_EHT_LEG_PUNC, + resp_normal_punc, mac_idx); + } else { + rtw89_write16_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_LEGACY, + resp_normal, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_HE, + resp_normal_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_EHT_LEG_PUNC, + resp_normal_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_RTS_RESP_LEGACY, + resp_rts, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_RTS_RESP_LEGACY_PUNC, + resp_rts_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_MURTS_RESP_LEGACY, + resp_normal, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_RX_MURTS_RESP_LEGACY_PUNC, + resp_normal_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_OTHERS_RESP_LEGACY, + resp_normal, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_OTHERS_RESP_HE, + resp_normal_punc, mac_idx); + rtw89_write16_idx(rtwdev, R_BE_WMAC_OTHERS_RESP_EHT_LEG_PUNC, + resp_normal_punc, mac_idx); + } +} + +static int rtw89_mac_cfg_ppdu_status_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) { u32 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PPDU_STAT, mac_idx); @@ -2601,6 +3178,9 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = { .check_mac_en = rtw89_mac_check_mac_en_be, .sys_init = sys_init_be, .trx_init = trx_init_be, + .preload_init = preload_init_be, + .err_imr_ctrl = err_imr_ctrl_be, + .mac_func_en = mac_func_en_be, .hci_func_en = rtw89_mac_hci_func_en_be, .dmac_func_pre_en = rtw89_mac_dmac_func_pre_en_be, .dle_func_en = dle_func_en_be, @@ -2610,6 +3190,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = { .typ_fltr_opt = rtw89_mac_typ_fltr_opt_be, .cfg_ppdu_status = rtw89_mac_cfg_ppdu_status_be, .cfg_phy_rpt = rtw89_mac_cfg_phy_rpt_be, + .set_edcca_mode = rtw89_mac_set_edcca_mode_be, .dle_mix_cfg = dle_mix_cfg_be, .chk_dle_rdy = chk_dle_rdy_be, @@ -2623,6 +3204,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = { .set_cpuio = set_cpuio_be, .dle_quota_change = dle_quota_change_be, + .reset_pwr_state = rtw89_mac_reset_pwr_state_be, .disable_cpu = rtw89_mac_disable_cpu_be, .fwdl_enable_wcpu = rtw89_mac_fwdl_enable_wcpu_be, .fwdl_get_status = fwdl_get_status_be, @@ -2632,6 +3214,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_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, + .efuse_read_ecv = rtw89_efuse_read_ecv_be, .cfg_plt = rtw89_mac_cfg_plt_be, .get_plt_cnt = rtw89_mac_get_plt_cnt_be, diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index a66fcdb0293b..093960d7279f 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -604,11 +604,16 @@ static void rtw89_pci_release_rpp(struct rtw89_dev *rtwdev, void *rpp) info->parse_rpp(rtwdev, rpp, &rpp_info); - if (rpp_info.txch == RTW89_TXCH_CH12) { + if (unlikely(rpp_info.txch == RTW89_TXCH_CH12)) { rtw89_warn(rtwdev, "should no fwcmd release report\n"); return; } + if (unlikely(rpp_info.seq >= RTW89_PCI_TXWD_NUM_MAX)) { + rtw89_warn(rtwdev, "invalid seq %d\n", rpp_info.seq); + return; + } + tx_ring = &rtwpci->tx.rings[rpp_info.txch]; wd_ring = &tx_ring->wd_ring; txwd = &wd_ring->pages[rpp_info.seq]; diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index 16dfb0e79d77..b0081b694046 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -55,6 +55,8 @@ #define B_AX_CALIB_EN BIT(13) #define B_AX_DIV GENMASK(15, 14) #define RAC_SET_PPR_V1 0x31 +#define RAC_ANA41 0x41 +#define PHY_ERR_FLAG_EN BIT(6) #define R_AX_DBI_FLAG 0x1090 #define B_AX_DBI_RFLAG BIT(17) @@ -145,6 +147,11 @@ #define R_RAC_DIRECT_OFFSET_BE_LANE0_G2 0x3900 #define R_RAC_DIRECT_OFFSET_BE_LANE1_G2 0x3980 +#define RAC_DIRECT_OFFESET_L0_G1 0x3800 +#define RAC_DIRECT_OFFESET_L1_G1 0x3900 +#define RAC_DIRECT_OFFESET_L0_G2 0x3A00 +#define RAC_DIRECT_OFFESET_L1_G2 0x3B00 + #define RTW89_PCI_WR_RETRY_CNT 20 /* Interrupts */ @@ -296,6 +303,10 @@ #define B_BE_PCIE_EN_AUX_CLK BIT(0) #define R_BE_PCIE_PS_CTRL 0x3008 +#define B_BE_ASPM_L11_EN BIT(19) +#define B_BE_ASPM_L12_EN BIT(18) +#define B_BE_PCIPM_L11_EN BIT(17) +#define B_BE_PCIPM_L12_EN BIT(16) #define B_BE_RSM_L0S_EN BIT(8) #define B_BE_CMAC_EXIT_L1_EN BIT(7) #define B_BE_DMAC0_EXIT_L1_EN BIT(6) @@ -767,31 +778,6 @@ #define R_AX_WP_ADDR_H_SEL8_11 0x133C #define R_AX_WP_ADDR_H_SEL12_15 0x1340 -#define R_BE_HAXI_DMA_STOP1 0xB010 -#define B_BE_STOP_WPDMA BIT(31) -#define B_BE_STOP_CH14 BIT(14) -#define B_BE_STOP_CH13 BIT(13) -#define B_BE_STOP_CH12 BIT(12) -#define B_BE_STOP_CH11 BIT(11) -#define B_BE_STOP_CH10 BIT(10) -#define B_BE_STOP_CH9 BIT(9) -#define B_BE_STOP_CH8 BIT(8) -#define B_BE_STOP_CH7 BIT(7) -#define B_BE_STOP_CH6 BIT(6) -#define B_BE_STOP_CH5 BIT(5) -#define B_BE_STOP_CH4 BIT(4) -#define B_BE_STOP_CH3 BIT(3) -#define B_BE_STOP_CH2 BIT(2) -#define B_BE_STOP_CH1 BIT(1) -#define B_BE_STOP_CH0 BIT(0) -#define B_BE_TX_STOP1_MASK (B_BE_STOP_CH0 | B_BE_STOP_CH1 | \ - B_BE_STOP_CH2 | B_BE_STOP_CH3 | \ - B_BE_STOP_CH4 | B_BE_STOP_CH5 | \ - B_BE_STOP_CH6 | B_BE_STOP_CH7 | \ - B_BE_STOP_CH8 | B_BE_STOP_CH9 | \ - B_BE_STOP_CH10 | B_BE_STOP_CH11 | \ - B_BE_STOP_CH12) - #define R_BE_CH0_TXBD_NUM_V1 0xB030 #define R_BE_CH1_TXBD_NUM_V1 0xB032 #define R_BE_CH2_TXBD_NUM_V1 0xB034 @@ -974,6 +960,12 @@ #define R_BE_PCIE_CRPWM 0x30C4 #define R_BE_L1_2_CTRL_HCILDO 0x3110 +#define B_BE_PM_CLKREQ_EXT_RB BIT(11) +#define B_BE_PCIE_DIS_RTK_PRST_N_L1_2 BIT(10) +#define B_BE_PCIE_PRST_IN_L1_2_RB BIT(9) +#define B_BE_PCIE_PRST_SEL_RB_V1 BIT(8) +#define B_BE_PCIE_DIS_L2_CTRL_APHY_SUSB BIT(7) +#define B_BE_PCIE_DIS_L1_2_CTRL_APHY_SUSB BIT(6) #define B_BE_PCIE_DIS_L1_2_CTRL_HCILDO BIT(0) #define R_BE_PL1_DBG_INFO 0x3120 @@ -1023,9 +1015,11 @@ #define B_BE_PL1_SER_PL1_EN BIT(31) #define B_BE_PL1_IGNORE_HOT_RST BIT(30) #define B_BE_PL1_TIMER_UNIT_MASK GENMASK(19, 17) +#define PCIE_SER_TIMER_UNIT 0x2 #define B_BE_PL1_TIMER_CLEAR BIT(0) #define R_BE_REG_PL1_MASK 0x34B0 +#define B_BE_SER_LTSSM_UNSTABLE_MASK BIT(6) #define B_BE_SER_PCLKREQ_ACK_MASK BIT(5) #define B_BE_SER_PM_CLK_MASK BIT(4) #define B_BE_SER_LTSSM_IMR BIT(3) @@ -1055,6 +1049,18 @@ #define B_BE_CLR_CH2_IDX BIT(2) #define B_BE_CLR_CH1_IDX BIT(1) #define B_BE_CLR_CH0_IDX BIT(0) +#define B_BE_CLR_ALL_IDX_MASK (B_BE_CLR_CH0_IDX | B_BE_CLR_CH1_IDX | \ + B_BE_CLR_CH2_IDX | B_BE_CLR_CH3_IDX | \ + B_BE_CLR_CH4_IDX | B_BE_CLR_CH5_IDX | \ + B_BE_CLR_CH6_IDX | B_BE_CLR_CH7_IDX | \ + B_BE_CLR_CH8_IDX | B_BE_CLR_CH9_IDX | \ + B_BE_CLR_CH10_IDX | B_BE_CLR_CH11_IDX | \ + B_BE_CLR_CH12_IDX | B_BE_CLR_CH13_IDX | \ + B_BE_CLR_CH14_IDX) +#define B_BE_CLR_ALL_IDX_MASK_V1 (B_BE_CLR_CH0_IDX | B_BE_CLR_CH2_IDX | \ + B_BE_CLR_CH4_IDX | B_BE_CLR_CH6_IDX | \ + B_BE_CLR_CH8_IDX | B_BE_CLR_CH10_IDX | \ + B_BE_CLR_CH12_IDX) #define R_BE_RXBD_RWPTR_CLR1_V1 0xB018 #define B_BE_CLR_ROQ1_IDX_V1 BIT(5) diff --git a/drivers/net/wireless/realtek/rtw89/pci_be.c b/drivers/net/wireless/realtek/rtw89/pci_be.c index e4590879b800..33bdd3e66bf6 100644 --- a/drivers/net/wireless/realtek/rtw89/pci_be.c +++ b/drivers/net/wireless/realtek/rtw89/pci_be.c @@ -46,6 +46,14 @@ static void rtw89_pci_aspm_set_be(struct rtw89_dev *rtwdev, bool enable) static void rtw89_pci_l1ss_set_be(struct rtw89_dev *rtwdev, bool enable) { + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + struct rtw89_hal *hal = &rtwdev->hal; + + if (enable && chip_id == RTL8922D && hal->cid == RTL8922D_CID7090) + rtw89_write32_set(rtwdev, R_BE_PCIE_PS_CTRL, + B_BE_ASPM_L11_EN | B_BE_ASPM_L12_EN | + B_BE_PCIPM_L11_EN | B_BE_PCIPM_L12_EN); + if (enable) rtw89_write32_set(rtwdev, R_BE_PCIE_MIX_CFG, B_BE_L1SUB_ENABLE); @@ -154,7 +162,7 @@ static void rtw89_pci_ctrl_trxdma_pcie_be(struct rtw89_dev *rtwdev, rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val); - if (io_en == MAC_AX_PCIE_ENABLE) + if (io_en == MAC_AX_PCIE_ENABLE && rtwdev->chip->chip_id == RTL8922A) rtw89_write32_mask(rtwdev, R_BE_HAXI_MST_WDT_TIMEOUT_SEL_V1, B_BE_HAXI_MST_WDT_TIMEOUT_SEL_MASK, 4); } @@ -162,14 +170,15 @@ static void rtw89_pci_ctrl_trxdma_pcie_be(struct rtw89_dev *rtwdev, static void rtw89_pci_clr_idx_all_be(struct rtw89_dev *rtwdev) { struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_pci_rx_ring *rx_ring; u32 val; - val = B_BE_CLR_CH0_IDX | B_BE_CLR_CH1_IDX | B_BE_CLR_CH2_IDX | - B_BE_CLR_CH3_IDX | B_BE_CLR_CH4_IDX | B_BE_CLR_CH5_IDX | - B_BE_CLR_CH6_IDX | B_BE_CLR_CH7_IDX | B_BE_CLR_CH8_IDX | - B_BE_CLR_CH9_IDX | B_BE_CLR_CH10_IDX | B_BE_CLR_CH11_IDX | - B_BE_CLR_CH12_IDX | B_BE_CLR_CH13_IDX | B_BE_CLR_CH14_IDX; + if (chip->chip_id == RTL8922A) + val = B_BE_CLR_ALL_IDX_MASK; + else + val = B_BE_CLR_ALL_IDX_MASK_V1; + rtw89_write32(rtwdev, R_BE_TXBD_RWPTR_CLR1, val); rtw89_write32(rtwdev, R_BE_RXBD_RWPTR_CLR1_V1, @@ -184,10 +193,13 @@ static void rtw89_pci_clr_idx_all_be(struct rtw89_dev *rtwdev) static int rtw89_pci_poll_txdma_ch_idle_be(struct rtw89_dev *rtwdev) { + const struct rtw89_pci_info *info = rtwdev->pci_info; + u32 dma_busy1 = info->dma_busy1.addr; + u32 check = info->dma_busy1.mask; u32 val; - return read_poll_timeout(rtw89_read32, val, (val & DMA_BUSY1_CHECK_BE) == 0, - 10, 1000, false, rtwdev, R_BE_HAXI_DMA_BUSY1); + return read_poll_timeout(rtw89_read32, val, (val & check) == 0, + 10, 1000, false, rtwdev, dma_busy1); } static int rtw89_pci_poll_rxdma_ch_idle_be(struct rtw89_dev *rtwdev) @@ -223,20 +235,24 @@ static int rtw89_pci_poll_dma_all_idle_be(struct rtw89_dev *rtwdev) static void rtw89_pci_mode_op_be(struct rtw89_dev *rtwdev) { const struct rtw89_pci_info *info = rtwdev->pci_info; + const struct rtw89_chip_info *chip = rtwdev->chip; u32 val32_init1, val32_rxapp, val32_exp; val32_init1 = rtw89_read32(rtwdev, R_BE_HAXI_INIT_CFG1); - val32_rxapp = rtw89_read32(rtwdev, R_BE_RX_APPEND_MODE); + if (chip->chip_id == RTL8922A) + val32_rxapp = rtw89_read32(rtwdev, R_BE_RX_APPEND_MODE); val32_exp = rtw89_read32(rtwdev, R_BE_HAXI_EXP_CTRL_V1); - if (info->rxbd_mode == MAC_AX_RXBD_PKT) { - val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_NORM, - B_BE_RXQ_RXBD_MODE_MASK); - } else if (info->rxbd_mode == MAC_AX_RXBD_SEP) { - val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_SEP, - B_BE_RXQ_RXBD_MODE_MASK); - val32_rxapp = u32_replace_bits(val32_rxapp, 0, - B_BE_APPEND_LEN_MASK); + if (chip->chip_id == RTL8922A) { + if (info->rxbd_mode == MAC_AX_RXBD_PKT) { + val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_NORM, + B_BE_RXQ_RXBD_MODE_MASK); + } else if (info->rxbd_mode == MAC_AX_RXBD_SEP) { + val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_SEP, + B_BE_RXQ_RXBD_MODE_MASK); + val32_rxapp = u32_replace_bits(val32_rxapp, 0, + B_BE_APPEND_LEN_MASK); + } } val32_init1 = u32_replace_bits(val32_init1, info->tx_burst, @@ -251,7 +267,8 @@ static void rtw89_pci_mode_op_be(struct rtw89_dev *rtwdev) B_BE_CFG_WD_PERIOD_ACTIVE_MASK); rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val32_init1); - rtw89_write32(rtwdev, R_BE_RX_APPEND_MODE, val32_rxapp); + if (chip->chip_id == RTL8922A) + rtw89_write32(rtwdev, R_BE_RX_APPEND_MODE, val32_rxapp); rtw89_write32(rtwdev, R_BE_HAXI_EXP_CTRL_V1, val32_exp); } @@ -277,6 +294,10 @@ static void rtw89_pci_debounce_be(struct rtw89_dev *rtwdev) static void rtw89_pci_ldo_low_pwr_be(struct rtw89_dev *rtwdev) { + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + struct rtw89_hal *hal = &rtwdev->hal; + u32 clr; + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_PSUS_OFF_CAPC_EN); rtw89_write32_set(rtwdev, R_BE_SYS_PAGE_CLK_GATED, B_BE_SOP_OFFPOOBS_PC | B_BE_CPHY_AUXCLK_OP | @@ -284,7 +305,16 @@ static void rtw89_pci_ldo_low_pwr_be(struct rtw89_dev *rtwdev) rtw89_write32_clr(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_PCIE_FORCE_IBX_EN | B_BE_PCIE_DIS_L2_RTK_PERST | B_BE_PCIE_DIS_L2__CTRL_LDO_HCI); - rtw89_write32_clr(rtwdev, R_BE_L1_2_CTRL_HCILDO, B_BE_PCIE_DIS_L1_2_CTRL_HCILDO); + + if (chip_id == RTL8922D && hal->cid == RTL8922D_CID7090) + clr = B_BE_PCIE_DIS_L1_2_CTRL_HCILDO | + B_BE_PCIE_DIS_L1_2_CTRL_APHY_SUSB | + B_BE_PCIE_DIS_RTK_PRST_N_L1_2 | + B_BE_PCIE_DIS_L2_CTRL_APHY_SUSB; + else + clr = B_BE_PCIE_DIS_L1_2_CTRL_HCILDO; + + rtw89_write32_clr(rtwdev, R_BE_L1_2_CTRL_HCILDO, clr); } static void rtw89_pci_pcie_setting_be(struct rtw89_dev *rtwdev) @@ -300,11 +330,25 @@ static void rtw89_pci_pcie_setting_be(struct rtw89_dev *rtwdev) rtw89_write32_set(rtwdev, R_BE_EFUSE_CTRL_2_V1, B_BE_R_SYM_AUTOLOAD_WITH_PMC_SEL); rtw89_write32_set(rtwdev, R_BE_PCIE_LAT_CTRL, B_BE_SYM_AUX_CLK_SEL); + + if (chip->chip_id != RTL8922D) + return; + + rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_R_SYM_PRST_CPHY_RST); + rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_USUS_OFFCAPC_EN); } static void rtw89_pci_ser_setting_be(struct rtw89_dev *rtwdev) { + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; + struct rtw89_hal *hal = &rtwdev->hal; u32 val32; + int ret; + + if (chip_id == RTL8922D) + goto be2_chips; + else if (chip_id != RTL8922A) + return; rtw89_write32(rtwdev, R_BE_PL1_DBG_INFO, 0x0); rtw89_write32_set(rtwdev, R_BE_FWS1IMR, B_BE_PCIE_SER_TIMEOUT_INDIC_EN); @@ -315,10 +359,48 @@ static void rtw89_pci_ser_setting_be(struct rtw89_dev *rtwdev) val32 |= B_BE_SER_PMU_IMR | B_BE_SER_L1SUB_IMR | B_BE_SER_PM_MASTER_IMR | B_BE_SER_LTSSM_IMR | B_BE_SER_PM_CLK_MASK | B_BE_SER_PCLKREQ_ACK_MASK; rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32); + + return; + +be2_chips: + rtw89_write32_clr(rtwdev, R_BE_PCIE_SER_DBG, B_BE_PCIE_SER_FLUSH_RSTB); + rtw89_write32_set(rtwdev, R_BE_PCIE_SER_DBG, B_BE_PCIE_SER_FLUSH_RSTB); + + rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G1 + + RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN); + rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G2 + + RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN); + rtw89_write16_set(rtwdev, RAC_DIRECT_OFFESET_L0_G1 + + RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN); + rtw89_write16_set(rtwdev, RAC_DIRECT_OFFESET_L0_G2 + + RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN); + + val32 = rtw89_read32(rtwdev, R_BE_SER_PL1_CTRL); + val32 &= ~B_BE_PL1_SER_PL1_EN; + rtw89_write32(rtwdev, R_BE_SER_PL1_CTRL, val32); + + ret = read_poll_timeout_atomic(rtw89_read32, val32, !val32, + 1, 1000, false, rtwdev, R_BE_REG_PL1_ISR); + if (ret) + rtw89_warn(rtwdev, "[ERR] PCIE SER clear poll fail\n"); + + val32 = rtw89_read32(rtwdev, R_BE_REG_PL1_MASK); + val32 |= B_BE_SER_PMU_IMR | B_BE_SER_L1SUB_IMR | B_BE_SER_PM_MASTER_IMR | + B_BE_SER_LTSSM_IMR | B_BE_SER_PM_CLK_MASK | B_BE_SER_PCLKREQ_ACK_MASK | + B_BE_SER_LTSSM_UNSTABLE_MASK; + rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32); + + rtw89_write32_mask(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_TIMER_UNIT_MASK, + PCIE_SER_TIMER_UNIT); + rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN); + + if (hal->cid == RTL8922D_CID7090) + rtw89_write32_set(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_SER_DETECT_EN); } static void rtw89_pci_ctrl_txdma_ch_be(struct rtw89_dev *rtwdev, bool enable) { + const struct rtw89_pci_info *info = rtwdev->pci_info; u32 mask_all; u32 val; @@ -327,6 +409,9 @@ static void rtw89_pci_ctrl_txdma_ch_be(struct rtw89_dev *rtwdev, bool enable) B_BE_STOP_CH6 | B_BE_STOP_CH7 | B_BE_STOP_CH8 | B_BE_STOP_CH9 | B_BE_STOP_CH10 | B_BE_STOP_CH11; + /* mask out unsupported channels for certains chips */ + mask_all &= info->dma_stop1.mask; + val = rtw89_read32(rtwdev, R_BE_HAXI_DMA_STOP1); val |= B_BE_STOP_CH13 | B_BE_STOP_CH14; @@ -409,6 +494,7 @@ static int rtw89_pci_ops_mac_pre_deinit_be(struct rtw89_dev *rtwdev) int rtw89_pci_ltr_set_v2(struct rtw89_dev *rtwdev, bool en) { u32 ctrl0, cfg0, cfg1, dec_ctrl, idle_ltcy, act_ltcy, dis_ltcy; + u32 ltr_idle_lat_ctrl, ltr_act_lat_ctrl; ctrl0 = rtw89_read32(rtwdev, R_BE_LTR_CTRL_0); if (rtw89_pci_ltr_is_err_reg_val(ctrl0)) @@ -451,8 +537,16 @@ int rtw89_pci_ltr_set_v2(struct rtw89_dev *rtwdev, bool en) cfg0 = u32_replace_bits(cfg0, 3, B_BE_LTR_IDX_IDLE_MASK); dec_ctrl = u32_replace_bits(dec_ctrl, 0, B_BE_LTR_IDX_DISABLE_V1_MASK); - rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX3_V1, 0x90039003); - rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX1_V1, 0x880b880b); + if (rtwdev->chip->chip_id == RTL8922A) { + ltr_idle_lat_ctrl = 0x90039003; + ltr_act_lat_ctrl = 0x880b880b; + } else { + ltr_idle_lat_ctrl = 0x90019001; + ltr_act_lat_ctrl = 0x88018801; + } + + rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX3_V1, ltr_idle_lat_ctrl); + rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX1_V1, ltr_act_lat_ctrl); rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX0_V1, 0); rtw89_write32(rtwdev, R_BE_LTR_DECISION_CTRL_V1, dec_ctrl); rtw89_write32(rtwdev, R_BE_LTR_CFG_0, cfg0); diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 9f418b1fb7ed..0b72d3dcf666 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -281,8 +281,7 @@ static void rtw89_phy_ra_gi_ltf(struct rtw89_dev *rtwdev, struct cfg80211_bitrate_mask *mask = &rtwsta_link->mask; u8 band = chan->band_type; enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band); - u8 he_ltf = mask->control[nl_band].he_ltf; - u8 he_gi = mask->control[nl_band].he_gi; + u8 ltf, gi; *fix_giltf_en = true; @@ -293,22 +292,31 @@ static void rtw89_phy_ra_gi_ltf(struct rtw89_dev *rtwdev, else *fix_giltf = RTW89_GILTF_2XHE08; - if (!(rtwsta_link->use_cfg_mask && link_sta->he_cap.has_he)) + if (!rtwsta_link->use_cfg_mask) return; - if (he_ltf == 2 && he_gi == 2) { + if (link_sta->eht_cap.has_eht) { + ltf = mask->control[nl_band].eht_ltf; + gi = mask->control[nl_band].eht_gi; + } else if (link_sta->he_cap.has_he) { + ltf = mask->control[nl_band].he_ltf; + gi = mask->control[nl_band].he_gi; + } else { + return; + } + + if (ltf == 2 && gi == 2) *fix_giltf = RTW89_GILTF_LGI_4XHE32; - } else if (he_ltf == 2 && he_gi == 0) { + else if (ltf == 2 && gi == 0) *fix_giltf = RTW89_GILTF_SGI_4XHE08; - } else if (he_ltf == 1 && he_gi == 1) { + else if (ltf == 1 && gi == 1) *fix_giltf = RTW89_GILTF_2XHE16; - } else if (he_ltf == 1 && he_gi == 0) { + else if (ltf == 1 && gi == 0) *fix_giltf = RTW89_GILTF_2XHE08; - } else if (he_ltf == 0 && he_gi == 1) { + else if (ltf == 0 && gi == 1) *fix_giltf = RTW89_GILTF_1XHE16; - } else if (he_ltf == 0 && he_gi == 0) { + else if (ltf == 0 && gi == 0) *fix_giltf = RTW89_GILTF_1XHE08; - } } static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, @@ -3808,13 +3816,22 @@ int rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev *rtwdev, { int ret; - rtw89_phy_rfk_report_prep(rtwdev); + if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw)) { + rtw89_phy_rfk_report_prep(rtwdev); + rtw89_fw_h2c_rf_pre_ntfy(rtwdev, phy_idx); + ret = rtw89_phy_rfk_report_wait(rtwdev, "PRE_NTFY", ms); + if (ret) + return ret; + } - ret = rtw89_fw_h2c_rf_pre_ntfy(rtwdev, phy_idx); - if (ret) - return ret; + if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY_MCC, &rtwdev->fw)) { + ret = rtw89_fw_h2c_rf_pre_ntfy_mcc(rtwdev, phy_idx); + if (ret) + return ret; + } + + return 0; - return rtw89_phy_rfk_report_wait(rtwdev, "PRE_NTFY", ms); } EXPORT_SYMBOL(rtw89_phy_rfk_pre_ntfy_and_wait); diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c index 3f69dd4361c3..abd8aee02b47 100644 --- a/drivers/net/wireless/realtek/rtw89/ps.c +++ b/drivers/net/wireless/realtek/rtw89/ps.c @@ -16,7 +16,7 @@ static int rtw89_fw_receive_lps_h2c_check(struct rtw89_dev *rtwdev, u8 macid) { - struct rtw89_mac_c2h_info c2h_info = {}; + struct rtw89_mac_c2h_info c2h_info = {.timeout = 5000}; u16 c2hreg_macid; u32 c2hreg_ret; int ret; diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 5b4a459cf29c..efeb4507b1a9 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -149,6 +149,7 @@ #define R_AX_WLLPS_CTRL 0x0090 #define B_AX_LPSOP_ASWRM BIT(17) #define B_AX_LPSOP_DSWRM BIT(9) +#define B_AX_FORCE_LEAVE_LPS BIT(3) #define B_AX_DIS_WLBT_LPSEN_LOPC BIT(1) #define SW_LPS_OPTION 0x0001A0B2 @@ -313,13 +314,18 @@ #define R_AX_IC_PWR_STATE 0x03F0 #define B_AX_WHOLE_SYS_PWR_STE_MASK GENMASK(25, 16) #define B_AX_WLMAC_PWR_STE_MASK GENMASK(9, 8) +#define MAC_AX_MAC_OFF 0 +#define MAC_AX_MAC_ON 1 +#define MAC_AX_MAC_LPS 2 #define B_AX_UART_HCISYS_PWR_STE_MASK GENMASK(7, 6) #define B_AX_SDIO_HCISYS_PWR_STE_MASK GENMASK(5, 4) #define B_AX_USB_HCISYS_PWR_STE_MASK GENMASK(3, 2) #define B_AX_PCIE_HCISYS_PWR_STE_MASK GENMASK(1, 0) #define R_AX_SPS_DIG_OFF_CTRL0 0x0400 +#define B_AX_R1_L1_MASK GENMASK(7, 6) #define B_AX_C3_L1_MASK GENMASK(5, 4) +#define B_AX_C2_L1_MASK GENMASK(3, 2) #define B_AX_C1_L1_MASK GENMASK(1, 0) #define R_AX_AFE_OFF_CTRL1 0x0444 @@ -603,6 +609,9 @@ #define R_AX_SER_DBG_INFO 0x8424 #define B_AX_L0_TO_L1_EVENT_MASK GENMASK(31, 28) +#define B_AX_SER_L1_COUNTER_MASK GENMASK(27, 24) +#define B_AX_RMAC_PPDU_HANG_CNT_MASK GENMASK(23, 16) +#define B_AX_SER_L0_COUNTER_MASK GENMASK(7, 0) #define R_AX_DLE_EMPTY0 0x8430 #define B_AX_PLE_EMPTY_QTA_DMAC_CPUIO BIT(26) @@ -1958,7 +1967,9 @@ #define B_AX_B0_PRELD_FEN BIT(31) #define B_AX_B0_PRELD_USEMAXSZ_MASK GENMASK(25, 16) #define PRELD_B0_ENT_NUM 10 +#define PRELD_B01_ENT_NUM_8922D 2 #define PRELD_AMSDU_SIZE 52 +#define PRELD_NEXT_MIN_SIZE 255 #define B_AX_B0_PRELD_CAM_G1ENTNUM_MASK GENMASK(12, 8) #define B_AX_B0_PRELD_CAM_G0ENTNUM_MASK GENMASK(4, 0) @@ -2094,6 +2105,7 @@ #define B_AX_B1_ISR_ERR_USRCTL_REINIT BIT(0) #define R_AX_AFE_CTRL1 0x0024 +#define B_AX_CMAC_CLK_SEL BIT(21) #define B_AX_R_SYM_WLCMAC1_P4_PC_EN BIT(4) #define B_AX_R_SYM_WLCMAC1_P3_PC_EN BIT(3) @@ -2107,6 +2119,12 @@ #define B_AX_R_SYM_FEN_WLBBFUN_1 BIT(16) #define B_AX_R_SYM_ISO_CMAC12PP BIT(5) +#define R_AX_SYSON_FSM_MON 0x00A0 +#define B_AX_FSM_MON_SEL_MASK GENMASK(26, 24) +#define B_AX_DOP_ELDO BIT(23) +#define B_AX_FSM_MON_UPD BIT(15) +#define B_AX_FSM_PAR_MASK GENMASK(14, 0) + #define R_AX_CMAC_REG_START 0xC000 #define R_AX_CMAC_FUNC_EN 0xC000 @@ -3813,6 +3831,7 @@ #define B_BE_EN_WLON BIT(16) #define B_BE_APDM_HPDN BIT(15) #define B_BE_PSUS_OFF_CAPC_EN BIT(14) +#define B_BE_USUS_OFFCAPC_EN BIT(13) #define B_BE_AFSM_PCIE_SUS_EN BIT(12) #define B_BE_AFSM_WLSUS_EN BIT(11) #define B_BE_APFM_SWLPS BIT(10) @@ -3881,6 +3900,8 @@ #define B_BE_SYM_PADPDN_WL_RFC0_1P3 BIT(5) #define R_BE_RSV_CTRL 0x001C +#define B_BE_R_SYM_PRST_CPHY_RST BIT(25) +#define B_BE_R_SYM_PRST_PDN_EN BIT(24) #define B_BE_HR_BE_DBG GENMASK(23, 12) #define B_BE_R_SYM_DIS_PCIE_FLR BIT(9) #define B_BE_R_EN_HRST_PWRON BIT(8) @@ -3927,6 +3948,11 @@ #define B_BE_R_SYM_WLCMAC0_P2_PC_EN BIT(26) #define B_BE_R_SYM_WLCMAC0_P1_PC_EN BIT(25) #define B_BE_R_SYM_WLCMAC0_PC_EN BIT(24) +#define B_BE_R_SYM_WLCMAC0_ALL_EN (B_BE_R_SYM_WLCMAC0_PC_EN | \ + B_BE_R_SYM_WLCMAC0_P1_PC_EN | \ + B_BE_R_SYM_WLCMAC0_P2_PC_EN | \ + B_BE_R_SYM_WLCMAC0_P3_PC_EN | \ + B_BE_R_SYM_WLCMAC0_P4_PC_EN) #define B_BE_DATAMEM_PC3_EN BIT(23) #define B_BE_DATAMEM_PC2_EN BIT(22) #define B_BE_DATAMEM_PC1_EN BIT(21) @@ -3948,11 +3974,11 @@ #define B_BE_R_SYM_WLCMAC1_P2_PC_EN BIT(2) #define B_BE_R_SYM_WLCMAC1_P1_PC_EN BIT(1) #define B_BE_R_SYM_WLCMAC1_PC_EN BIT(0) -#define B_BE_AFE_CTRL1_SET (B_BE_R_SYM_WLCMAC1_PC_EN | \ - B_BE_R_SYM_WLCMAC1_P1_PC_EN | \ - B_BE_R_SYM_WLCMAC1_P2_PC_EN | \ - B_BE_R_SYM_WLCMAC1_P3_PC_EN | \ - B_BE_R_SYM_WLCMAC1_P4_PC_EN) +#define B_BE_R_SYM_WLCMAC1_ALL_EN (B_BE_R_SYM_WLCMAC1_PC_EN | \ + B_BE_R_SYM_WLCMAC1_P1_PC_EN | \ + B_BE_R_SYM_WLCMAC1_P2_PC_EN | \ + B_BE_R_SYM_WLCMAC1_P3_PC_EN | \ + B_BE_R_SYM_WLCMAC1_P4_PC_EN) #define R_BE_EFUSE_CTRL 0x0030 #define B_BE_EF_MODE_SEL_MASK GENMASK(31, 30) @@ -4015,6 +4041,7 @@ #define R_BE_SYS_SDIO_CTRL 0x0070 #define B_BE_MCM_FLASH_EN BIT(28) +#define B_BE_SER_DETECT_EN BIT(26) #define B_BE_PCIE_SEC_LOAD BIT(26) #define B_BE_PCIE_SER_RSTB BIT(25) #define B_BE_PCIE_SEC_LOAD_CLR BIT(24) @@ -4172,6 +4199,22 @@ #define B_BE_LPSROP_LOWPWRPLL BIT(7) #define B_BE_LPSROP_DSWRSD_SEL_MASK GENMASK(5, 4) +#define R_BE_SYSON_FSM_MON 0x00A0 +#define B_BE_FSM_MON_SEL_MASK GENMASK(26, 24) +#define B_BE_DOP_ELDO BIT(23) +#define B_BE_AFE_PLL_BYPASS BIT(22) +#define B_BE_PON_SWR_BYPASS BIT(21) +#define B_BE_PON_ADIE_BYPASS BIT(20) +#define B_BE_AFE_LS_BYPASS BIT(19) +#define B_BE_BTPMC_XTAL_SI_BYPASS BIT(17) +#define B_BE_WLPMC_XTAL_SI_BYPASS BIT(16) +#define B_BE_FSM_MON_UPD BIT(15) +#define B_BE_FSM_PAR_MASK GENMASK(14, 0) +#define WLAN_FSM_MASK 0xFFFFFF +#define WLAN_FSM_SET 0x4000000 +#define WLAN_FSM_STATE_MASK 0x1FF +#define WLAN_FSM_IDLE 0 + #define R_BE_EFUSE_CTRL_2_V1 0x00A4 #define B_BE_EF_ENT BIT(31) #define B_BE_EF_TCOLUMN_EN BIT(29) @@ -4188,6 +4231,10 @@ #define B_BE_EF_DSB_EN BIT(11) #define B_BE_EF_DLY_SEL_MASK GENMASK(3, 0) +#define R_BE_SCOREBOARD 0x00AC +#define B_BE_TOGGLE BIT(31) +#define B_BE_DATA_LINE_MASK GENMASK(30, 0) + #define R_BE_PMC_DBG_CTRL2 0x00CC #define B_BE_EFUSE_BURN_GNT_MASK GENMASK(31, 24) #define B_BE_DIS_IOWRAP_TIMEOUT BIT(16) @@ -4237,6 +4284,13 @@ #define R_BE_PCIE_MIO_INTD 0x00E8 #define B_BE_PCIE_MIO_DATA_MASK GENMASK(31, 0) +#define R_BE_SYS_CHIPINFO 0x00FC +#define B_BE_USB2_SEL BIT(31) +#define B_BE_U3PHY_RST_V1 BIT(30) +#define B_BE_U3_TERM_DETECT BIT(29) +#define B_BE_VERIFY_ENV_MASK GENMASK(9, 8) +#define B_BE_HW_ID_MASK GENMASK(7, 0) + #define R_BE_HALT_H2C_CTRL 0x0160 #define B_BE_HALT_H2C_TRIGGER BIT(0) @@ -4447,6 +4501,16 @@ #define B_BE_WL_XTAL_SI_DATA_MASK GENMASK(15, 8) #define B_BE_WL_XTAL_SI_ADDR_MASK GENMASK(7, 0) +#define R_BE_PCIE_SER_DBG 0x02FC +#define B_BE_PCIE_SER_DBG_MASK GENMASK(31, 10) +#define B_BE_PCIE_SER_PHY_PROTECT BIT(9) +#define B_BE_PCIE_SER_MAC_PROTECT BIT(8) +#define B_BE_PCIE_SER_FLUSH_RSTB BIT(4) +#define B_BE_PCIE_AXI_BRG_FLUSH_EN BIT(3) +#define B_BE_PCIE_SER_AUXCLK_RDY BIT(2) +#define B_BE_PCIE_SER_FRZ_REG_RST BIT(1) +#define B_BE_PCIE_SER_FRZ_CFG_SPC_RST BIT(0) + #define R_BE_IC_PWR_STATE 0x03F0 #define B_BE_WHOLE_SYS_PWR_STE_MASK GENMASK(25, 16) #define MAC_AX_SYS_ACT 0x220 @@ -4599,6 +4663,10 @@ #define R_BE_LTR_LATENCY_IDX2_V1 0x361C #define R_BE_LTR_LATENCY_IDX3_V1 0x3620 +#define R_BE_HCI_BUF_IMR 0x6018 +#define B_BE_HCI_BUF_IMR_CLR 0xC0000303 +#define B_BE_HCI_BUF_IMR_SET 0xC0000301 + #define R_BE_H2CREG_DATA0 0x7140 #define R_BE_H2CREG_DATA1 0x7144 #define R_BE_H2CREG_DATA2 0x7148 @@ -4693,6 +4761,9 @@ #define B_BE_LTR_CMAC1_RX_USE_PG_TH_MASK GENMASK(27, 16) #define B_BE_LTR_CMAC0_RX_USE_PG_TH_MASK GENMASK(11, 0) +#define R_BE_NO_RX_ERR_CFG 0x841C +#define B_BE_NO_RX_ERR_TO_MASK GENMASK(31, 29) + #define R_BE_DMAC_TABLE_CTRL 0x8420 #define B_BE_HWAMSDU_PADDING_MODE BIT(31) #define B_BE_MACID_MPDU_PROCESSOR_OFFSET_MASK GENMASK(26, 16) @@ -4704,7 +4775,7 @@ #define B_BE_SER_L0_PROMOTE_L1_EVENT_MASK GENMASK(31, 28) #define B_BE_SER_L1_COUNTER_MASK GENMASK(27, 24) #define B_BE_RMAC_PPDU_HANG_CNT_MASK GENMASK(23, 16) -#define B_BE_SER_L0_COUNTER_MASK GENMASK(8, 0) +#define B_BE_SER_L0_COUNTER_MASK GENMASK(7, 0) #define R_BE_DMAC_SYS_CR32B 0x842C #define B_BE_DMAC_BB_PHY1_MASK GENMASK(31, 16) @@ -5026,6 +5097,8 @@ B_BE_STF_WRFF_UNDERFLOW_ERR_INT_EN | \ B_BE_STF_OQT_OVERFLOW_ERR_INT_EN | \ B_BE_STF_OQT_UNDERFLOW_ERR_INT_EN) +#define B_BE_DISP_OTHER_IMR_CLR_V1 0xFFFFFFFF +#define B_BE_DISP_OTHER_IMR_SET_V1 0x3F002000 #define R_BE_DISP_HOST_IMR 0x8874 #define B_BE_HR_WRFF_UNDERFLOW_ERR_INT_EN BIT(31) @@ -5103,6 +5176,8 @@ B_BE_HR_DMA_PROCESS_ERR_INT_EN | \ B_BE_HR_WRFF_OVERFLOW_ERR_INT_EN | \ B_BE_HR_WRFF_UNDERFLOW_ERR_INT_EN) +#define B_BE_DISP_HOST_IMR_CLR_V1 0xFBFFFFFF +#define B_BE_DISP_HOST_IMR_SET_V1 0xC8B3E579 #define R_BE_DISP_CPU_IMR 0x8878 #define B_BE_CR_PLD_LEN_ERR_INT_EN BIT(30) @@ -5177,6 +5252,8 @@ B_BE_CR_DMA_PROCESS_ERR_INT_EN | \ B_BE_CR_WRFF_OVERFLOW_ERR_INT_EN | \ B_BE_CR_WRFF_UNDERFLOW_ERR_INT_EN) +#define B_BE_DISP_CPU_IMR_CLR_V1 0x7DFFFFFD +#define B_BE_DISP_CPU_IMR_SET_V1 0x34F938FD #define R_BE_RX_STOP 0x8914 #define B_BE_CPU_RX_STOP BIT(17) @@ -5471,6 +5548,10 @@ #define B_BE_PLE_Q12_MAX_SIZE_MASK GENMASK(27, 16) #define B_BE_PLE_Q12_MIN_SIZE_MASK GENMASK(11, 0) +#define R_BE_PLE_QTA13_CFG 0x9074 +#define B_BE_PLE_Q13_MAX_SIZE_MASK GENMASK(27, 16) +#define B_BE_PLE_Q13_MIN_SIZE_MASK GENMASK(11, 0) + #define R_BE_PLE_ERRFLAG1_IMR 0x90C0 #define B_BE_PLE_SRCHPG_PGOFST_IMR BIT(26) #define B_BE_PLE_SRCHPG_STRPG_IMR BIT(25) @@ -5528,7 +5609,21 @@ B_BE_WDRLS_RPT1_AGGNUM0_ERR_INT_EN | \ B_BE_WDRLS_RPT1_FRZTO_ERR_INT_EN) +#define R_BE_RLSRPT0_CFG0 0x9440 +#define B_BE_RLSRPT0_FWRLS BIT(31) +#define B_BE_RLSRPT0_FWD_TRGT_MASK GENMASK(23, 16) +#define B_BE_RLSRPT0_PID_MASK GENMASK(10, 8) +#define B_BE_RLSRPT0_QID_MASK GENMASK(5, 0) +#define WDRLS_DEST_QID_POH 1 +#define WDRLS_DEST_QID_STF 0 + #define R_BE_RLSRPT0_CFG1 0x9444 +#define B_BE_RLSRPT0_FLTR_MAP_V1_MASK GENMASK(28, 24) +#define S_BE_WDRLS_FLTR_TXOK_V1 BIT(0) +#define S_BE_WDRLS_FLTR_RTYLMT_V1 BIT(1) +#define S_BE_WDRLS_FLTR_LIFTIM_V1 BIT(2) +#define S_BE_WDRLS_FLTR_MACID_V1 BIT(3) +#define S_BE_WDRLS_FLTR_RELINK_V1 BIT(4) #define B_BE_RLSRPT0_FLTR_MAP_MASK GENMASK(27, 24) #define S_BE_WDRLS_FLTR_TXOK 1 #define S_BE_WDRLS_FLTR_RTYLMT 2 @@ -5822,12 +5917,18 @@ #define B_BE_MPDUINFO_PKTID_MASK GENMASK(27, 16) #define B_BE_MPDUINFO_B1_BADDR_MASK GENMASK(5, 0) #define MPDU_INFO_B1_OFST 18 +#define MPDU_INFO_TBL_FACTOR 3 #define R_BE_TXPKTCTL_B0_PRELD_CFG0 0x9F48 #define B_BE_B0_PRELD_FEN BIT(31) #define B_BE_B0_PRELD_USEMAXSZ_MASK GENMASK(25, 16) #define B_BE_B0_PRELD_CAM_G1ENTNUM_MASK GENMASK(12, 8) +#define PRELD_MISCQ_ENT_NUM_8922A 2 +#define PRELD_MISCQ_ENT_NUM_8922D 1 #define B_BE_B0_PRELD_CAM_G0ENTNUM_MASK GENMASK(4, 0) +#define PRELD_B0_ACQ_ENT_NUM_8922A 8 +#define PRELD_B1_ACQ_ENT_NUM_8922A 2 +#define PRELD_ACQ_ENT_NUM_8922D 1 #define R_BE_TXPKTCTL_B0_PRELD_CFG1 0x9F4C #define B_BE_B0_PRELD_NXT_TXENDWIN_MASK GENMASK(11, 8) @@ -5939,6 +6040,7 @@ #define B_BE_PLRLS_CTL_FRZTO_ISR BIT(0) #define R_BE_SS_CTRL 0xA310 +#define R_BE_SS_CTRL_V1 0xA610 #define B_BE_SS_INIT_DONE BIT(31) #define B_BE_WDE_STA_DIS BIT(30) #define B_BE_WARM_INIT BIT(29) @@ -5978,6 +6080,24 @@ #define B_BE_RPT_TIMEOUT_ISR BIT(1) #define B_BE_SEARCH_TIMEOUT_ISR BIT(0) +#define R_BE_PLRLS_ERR_IMR_V1 0xA518 +#define B_BE_PLRLS_DUMMY_ISR6 BIT(7) +#define B_BE_PLRLS_DUMMY_ISR5 BIT(6) +#define B_BE_PLRLS_DUMMY_ISR4 BIT(5) +#define B_BE_PLRLS_DUMMY_ISR3 BIT(4) +#define B_BE_PLRLS_DUMMY_ISR2 BIT(3) +#define B_BE_PLRLS_DUMMY_ISR1 BIT(2) +#define B_BE_PLRLS_DUMMY_ISR0 BIT(1) +#define B_BE_PLRLS_ERR_IMR_V1_CLR 0x1 +#define B_BE_PLRLS_ERR_IMR_V1_SET 0x1 + +#define R_BE_SS_LITE_TXL_MACID 0xA790 +#define B_BE_RPT_OTHER_BAND_EN BIT(31) +#define B_BE_TXL_CMD_EN BIT(30) +#define B_BE_TXL_READ_MACID_MASK GENMASK(29, 20) +#define B_BE_TXL_MACID_1_MASK GENMASK(19, 10) +#define B_BE_TXL_MACID_0_MASK GENMASK(9, 0) + #define R_BE_HAXI_INIT_CFG1 0xB000 #define B_BE_CFG_WD_PERIOD_IDLE_MASK GENMASK(31, 28) #define B_BE_CFG_WD_PERIOD_ACTIVE_MASK GENMASK(27, 24) @@ -6017,6 +6137,18 @@ #define B_BE_STOP_CH2 BIT(2) #define B_BE_STOP_CH1 BIT(1) #define B_BE_STOP_CH0 BIT(0) +#define B_BE_TX_STOP1_MASK (B_BE_STOP_CH0 | B_BE_STOP_CH1 | \ + B_BE_STOP_CH2 | B_BE_STOP_CH3 | \ + B_BE_STOP_CH4 | B_BE_STOP_CH5 | \ + B_BE_STOP_CH6 | B_BE_STOP_CH7 | \ + B_BE_STOP_CH8 | B_BE_STOP_CH9 | \ + B_BE_STOP_CH10 | B_BE_STOP_CH11 | \ + B_BE_STOP_CH12 | B_BE_STOP_CH13 | \ + B_BE_STOP_CH14) +#define B_BE_TX_STOP1_MASK_V1 (B_BE_STOP_CH0 | B_BE_STOP_CH2 | \ + B_BE_STOP_CH4 | B_BE_STOP_CH6 | \ + B_BE_STOP_CH8 | B_BE_STOP_CH10 | \ + B_BE_STOP_CH12) #define R_BE_HAXI_MST_WDT_TIMEOUT_SEL_V1 0xB02C #define B_BE_HAXI_MST_WDT_TIMEOUT_SEL_MASK GENMASK(4, 0) @@ -6069,6 +6201,7 @@ #define R_BE_CH_PAGE_CTRL 0xB704 #define B_BE_PREC_PAGE_CH12_V1_MASK GENMASK(21, 16) +#define B_BE_FULL_WD_PG_MASK GENMASK(15, 8) #define B_BE_PREC_PAGE_CH011_V1_MASK GENMASK(5, 0) #define R_BE_CH0_PAGE_CTRL 0xB718 @@ -6101,6 +6234,10 @@ #define R_BE_WP_PAGE_CTRL1 0xB7A4 #define B_BE_PREC_PAGE_WP_CH811_MASK GENMASK(24, 16) #define B_BE_PREC_PAGE_WP_CH07_MASK GENMASK(8, 0) +#define B_BE_FULL_PAGE_WP_CH811_MASK GENMASK(31, 24) +#define B_BE_PREC_PAGE_WP_CH811_V1_MASK GENMASK(23, 16) +#define B_BE_FULL_PAGE_WP_CH07_MASK GENMASK(15, 8) +#define B_BE_PREC_PAGE_WP_CH07_V1_MASK GENMASK(7, 0) #define R_BE_WP_PAGE_CTRL2 0xB7A8 #define B_BE_WP_THRD_MASK GENMASK(12, 0) @@ -6159,6 +6296,75 @@ #define B_BE_GNT_WL_BB_PWR_VAL BIT(1) #define B_BE_GNT_WL_BB_PWR_SWCTRL BIT(0) +#define R_BE_PTA_GNT_SW_CTRL 0x0E348 +#define B_BE_PTA_WL_ACT0_VAL BIT(19) +#define B_BE_PTA_WL_ACT0_SWCTRL BIT(18) +#define B_BE_PTA_GNT_BT0_RX_BB1_VAL BIT(17) +#define B_BE_PTA_GNT_BT0_RX_BB1_SWCTRL BIT(16) +#define B_BE_PTA_GNT_BT0_TX_BB1_VAL BIT(15) +#define B_BE_PTA_GNT_BT0_TX_BB1_SWCTRL BIT(14) +#define B_BE_PTA_GNT_BT0_RX_BB0_VAL BIT(13) +#define B_BE_PTA_GNT_BT0_RX_BB0_SWCTRL BIT(12) +#define B_BE_PTA_GNT_BT0_TX_BB0_VAL BIT(11) +#define B_BE_PTA_GNT_BT0_TX_BB0_SWCTRL BIT(10) +#define B_BE_PTA_GNT_BT0_BB_VAL BIT(9) +#define B_BE_PTA_GNT_BT0_BB_SWCTRL BIT(8) +#define B_BE_PTA_WL_ACT_RX_BT0_VAL BIT(7) +#define B_BE_PTA_WL_ACT_RX_BT0_SWCTRL BIT(6) +#define B_BE_PTA_WL_ACT_TX_BT0_VAL BIT(5) +#define B_BE_PTA_WL_ACT_TX_BT0_SWCTRL BIT(4) +#define B_BE_PTA_GNT_WL_BB1_VAL BIT(3) +#define B_BE_PTA_GNT_WL_BB1_SWCTRL BIT(2) +#define B_BE_PTA_GNT_WL_BB0_VAL BIT(1) +#define B_BE_PTA_GNT_WL_BB0_SWCTRL BIT(0) + +#define R_BE_PTA_GNT_VAL 0x0E34C +#define B_BE_PTA_WL_ACT2 BIT(20) +#define B_BE_PTA_GNT_ZB_TX_BB1 BIT(19) +#define B_BE_PTA_GNT_ZB_TX_BB0 BIT(18) +#define B_BE_PTA_WL_ACT1 BIT(17) +#define B_BE_PTA_GNT_BT1_RX_BB1 BIT(16) +#define B_BE_PTA_GNT_BT1_RX_BB0 BIT(15) +#define B_BE_PTA_GNT_BT1_TX_BB1 BIT(14) +#define B_BE_PTA_GNT_BT1_TX_BB0 BIT(13) +#define B_BE_PTA_WL_ACT_RX_BT1 BIT(12) +#define B_BE_PTA_WL_ACT_TX_BT1 BIT(11) +#define B_BE_PTA_GNT_BT1_BB BIT(10) +#define B_BE_PTA_WL_ACT0 BIT(9) +#define B_BE_PTA_GNT_BT0_RX_BB1 BIT(8) +#define B_BE_PTA_GNT_BT0_TX_BB1 BIT(7) +#define B_BE_PTA_GNT_BT0_RX_BB0 BIT(6) +#define B_BE_PTA_GNT_BT0_TX_BB0 BIT(5) +#define B_BE_PTA_GNT_BT0_BB BIT(4) +#define B_BE_PTA_WL_ACT_RX_BT0 BIT(3) +#define B_BE_PTA_WL_ACT_TX_BT0 BIT(2) +#define B_BE_PTA_GNT_WL_BB1 BIT(1) +#define B_BE_PTA_GNT_WL_BB0 BIT(0) + +#define R_BE_PTA_GNT_ZL_SW_CTRL 0x0E350 +#define B_BE_PTA_WL_ACT2_VAL BIT(21) +#define B_BE_PTA_WL_ACT2_SWCTRL BIT(20) +#define B_BE_PTA_GNT_ZB_TX_BB1_VAL BIT(19) +#define B_BE_PTA_GNT_ZB_TX_BB1_SWCTRL BIT(18) +#define B_BE_PTA_GNT_ZB_TX_BB0_VAL BIT(17) +#define B_BE_PTA_GNT_ZB_TX_BB0_SWCTRL BIT(16) +#define B_BE_PTA_WL_ACT1_VAL BIT(15) +#define B_BE_PTA_WL_ACT1_SWCTRL BIT(14) +#define B_BE_PTA_GNT_BT1_RX_BB1_VAL BIT(13) +#define B_BE_PTA_GNT_BT1_RX_BB1_SWCTRL BIT(12) +#define B_BE_PTA_GNT_BT1_RX_BB0_VAL BIT(11) +#define B_BE_PTA_GNT_BT1_RX_BB0_SWCTRL BIT(10) +#define B_BE_PTA_GNT_BT1_TX_BB1_VAL BIT(9) +#define B_BE_PTA_GNT_BT1_TX_BB1_SWCTRL BIT(8) +#define B_BE_PTA_GNT_BT1_TX_BB0_VAL BIT(7) +#define B_BE_PTA_GNT_BT1_TX_BB0_SWCTRL BIT(6) +#define B_BE_PTA_WL_ACT_RX_BT1_VAL BIT(5) +#define B_BE_PTA_WL_ACT_RX_BT1_SWCTRL BIT(4) +#define B_BE_PTA_WL_ACT_TX_BT1_VAL BIT(3) +#define B_BE_PTA_WL_ACT_TX_BT1_SWCTRL BIT(2) +#define B_BE_PTA_GNT_BT1_BB_VAL BIT(1) +#define B_BE_PTA_GNT_BT1_BB_SWCTRL BIT(0) + #define R_BE_PWR_MACID_PATH_BASE 0x0E500 #define R_BE_PWR_MACID_LMT_BASE 0x0ED00 @@ -6257,6 +6463,21 @@ #define B_BE_RSC_MASK GENMASK(7, 6) #define B_BE_RRSR_CCK_MASK GENMASK(3, 0) +#define R_BE_COMMON_PHYINTF_CTRL_0 0x100B8 +#define R_BE_COMMON_PHYINTF_CTRL_0_C1 0x140B8 +#define B_BE_SEQ_EN_GUARD_CYE_MASK GENMASK(23, 20) +#define B_BE_PARA_FIFO_CRC_EN BIT(18) +#define B_BE_SEQ_FIFO_TO_EN BIT(17) +#define B_BE_PARA_FIFO_TO_EN BIT(16) +#define B_BE_SEQ_FIFO_CLR_EN BIT(6) +#define B_BE_PARA_FIFO_CLR_EN_V1 BIT(5) +#define B_BE_CSI_FIFO_CLR_EN_V1 BIT(4) +#define B_BE_FTM_FIFO_CLR_EN_V1 BIT(3) +#define B_BE_RXD_FIFO_CLR_EN_V1 BIT(2) +#define B_BE_TXD_FIFO_CLR_EN_V1 BIT(1) +#define B_BE_TXUID_FIFO_CLR_EN_V1 BIT(0) +#define CLEAR_DTOP_DIS (BIT(1) | BIT(5) | BIT(6)) + #define R_BE_CMAC_ERR_IMR 0x10160 #define R_BE_CMAC_ERR_IMR_C1 0x14160 #define B_BE_CMAC_FW_ERR_IDCT_EN BIT(16) @@ -6349,6 +6570,25 @@ #define B_BE_P0_SYNC_PORT_SRC_SEL_MASK GENMASK(26, 24) #define B_BE_P0_TSFTR_SYNC_OFFSET_MASK GENMASK(18, 0) +#define R_BE_SCH_EDCA_RST_CFG 0x102E4 +#define R_BE_SCH_EDCA_RST_CFG_C1 0x142E4 +#define B_BE_EDCCA_S160_RST_EDCA_EN BIT(23) +#define B_BE_EDCCA_S80_RST_EDCA_EN BIT(22) +#define B_BE_EDCCA_S40_RST_EDCA_EN BIT(21) +#define B_BE_EDCCA_S20_RST_EDCA_EN BIT(20) +#define B_BE_OFDM_CCA_S160_RST_EDCA_EN BIT(19) +#define B_BE_CCA_PEB_BE_BITMAP_RST_EDCA_EN BIT(18) +#define B_BE_RX_INTRA_NAV_RST_EDCA_EN BIT(15) +#define B_BE_RX_BASIC_NAV_RST_EDCA_EN BIT(14) +#define B_BE_EDCCA_PER20_BITMAP_SIFS_RST_EDCA_EN BIT(10) +#define B_BE_TX_NAV_RST_EDCA_EN BIT(7) +#define B_BE_NO_GNT_WL_RST_EDCA_EN BIT(5) +#define B_BE_EDCCA_P20_RST_EDCA_EN BIT(4) +#define B_BE_OFDM_CCA_S80_RST_EDCA_EN BIT(3) +#define B_BE_OFDM_CCA_S40_RST_EDCA_EN BIT(2) +#define B_BE_OFDM_CCA_S20_RST_EDCA_EN BIT(1) +#define B_BE_CCA_P20_RST_EDCA_EN BIT(0) + #define R_BE_EDCA_BCNQ_PARAM 0x10324 #define R_BE_EDCA_BCNQ_PARAM_C1 0x14324 #define B_BE_BCNQ_CW_MASK GENMASK(31, 24) @@ -6639,6 +6879,34 @@ #define B_BE_CMAC_TX_MODE_1 BIT(1) #define B_BE_CMAC_TX_MODE_0 BIT(0) +#define R_BE_AGG_BK_0 0x10804 +#define R_BE_AGG_BK_0_C1 0x14804 +#define B_BE_DIS_SAMPDU_TXIME_SR_CHECK BIT(24) +#define B_BE_TX_PAIR_MACID_LEN_EN BIT(23) +#define B_BE_DIS_SND_STS_CHECK_SU BIT(22) +#define B_BE_MAX_AGG_NUM_FIX_MODE_EN_V1 BIT(21) +#define B_BE_DIS_SIFS_BK_AGG_AMPDU BIT(20) +#define B_BE_EN_MU2SU_CHK_PROTECT_PPDU BIT(19) +#define B_BE_RPT_TXOP_START_PROTECT BIT(18) +#define B_BE_RANDOM_GEN_CMD_ABORT_EN BIT(17) +#define B_BE_PHYTXON_ENDPS_RESP_CHK BIT(16) +#define B_BE_CTN_CHK_SEQ_REQ_EN BIT(15) +#define B_BE_PTCL_RLS_ALLFAIL_EN BIT(14) +#define B_BE_DIS_MURU_PRI_Q_EMPTY_CHK BIT(13) +#define B_BE_DIS_MURU_SEC_Q_EMPTY_CHK BIT(12) +#define B_BE_EN_SAMPDU_TXIME_TWT_CHECK BIT(11) +#define B_BE_DIS_SAMPDU_TXIME_P2P_CHECK BIT(10) +#define B_BE_DIS_SAMPDU_TXIME_BCN_CHECK BIT(9) +#define B_BE_DIS_UL_SEQ_ABORT_CHECK BIT(8) +#define B_BE_DIS_SND_STS_CHECK BIT(7) +#define B_BE_NAV_PAUS_PHB_EN BIT(6) +#define B_BE_TXOP_SHT_PHB_EN BIT(5) +#define B_BE_AGG_BRK_PHB_EN BIT(4) +#define B_BE_DIS_SSN_CHK BIT(3) +#define B_BE_WDBK_CFG BIT(2) +#define B_BE_EN_RTY_BK BIT(1) +#define B_BE_EN_RTY_BK_COD BIT(0) + #define R_BE_TB_PPDU_CTRL 0x1080C #define R_BE_TB_PPDU_CTRL_C1 0x1480C #define B_BE_TB_PPDU_BK_DIS BIT(15) @@ -6653,9 +6921,11 @@ #define R_BE_AMPDU_AGG_LIMIT_C1 0x14810 #define B_BE_AMPDU_MAX_TIME_MASK GENMASK(31, 24) #define AMPDU_MAX_TIME 0x9E +#define AMPDU_MAX_TIME_V1 0xA4 #define B_BE_RA_TRY_RATE_AGG_LMT_MASK GENMASK(23, 16) #define B_BE_RTS_MAX_AGG_NUM_MASK GENMASK(15, 8) #define B_BE_MAX_AGG_NUM_MASK GENMASK(7, 0) +#define MAX_TX_AMPDU_NUM_V1 128 #define R_BE_AGG_LEN_HT_0 0x10814 #define R_BE_AGG_LEN_HT_0_C1 0x14814 @@ -6663,6 +6933,20 @@ #define B_BE_RTS_TXTIME_TH_MASK GENMASK(15, 8) #define B_BE_RTS_LEN_TH_MASK GENMASK(7, 0) +#define R_BE_SPECIAL_TX_SETTING 0x10820 +#define R_BE_SPECIAL_TX_SETTING_C1 0x14820 +#define B_BE_TRI_PADDING_EXTEND BIT(31) +#define B_BE_TX_SN_BYPASS_EN BIT(30) +#define B_BE_USE_DATA_BW BIT(29) +#define B_BE_BW_SIGTA_MASK GENMASK(28, 27) +#define B_BE_BMC_NAV_PROTECT BIT(26) +#define B_BE_F2P_KEEP_NON_SR_CMD BIT(25) +#define B_BE_F2P_SU_FIXRATE_OVER_WD BIT(24) +#define B_BE_BAR_TXRATE_FOR_NULL_WD_MASK GENMASK(23, 20) +#define B_BE_STBC_CFEND_MASK GENMASK(19, 18) +#define B_BE_STBC_CFEND_RATE_MASK GENMASK(17, 9) +#define B_BE_BASIC_CFEND_RATE_MASK GENMASK(8, 0) + #define R_BE_SIFS_SETTING 0x10824 #define R_BE_SIFS_SETTING_C1 0x14824 #define B_BE_HW_CTS2SELF_PKT_LEN_TH_MASK GENMASK(31, 24) @@ -6696,6 +6980,44 @@ #define B_BE_PORT_DROP_4_0_MASK GENMASK(20, 16) #define B_BE_MBSSID_DROP_15_0_MASK GENMASK(15, 0) +#define R_BE_PTCL_PRELD_CTRL 0x10868 +#define R_BE_PTCL_PRELD_CTRL_C1 0x14868 +#define B_BE_PRELD_MGQ2_EN BIT(22) +#define B_BE_PRELD_MGQ1_EN BIT(21) +#define B_BE_PRELD_MGQ0_EN BIT(20) +#define B_BE_PRELD_HIQ_P4_EN BIT(19) +#define B_BE_PRELD_HIQ_P3_EN BIT(18) +#define B_BE_PRELD_HIQ_P2_EN BIT(17) +#define B_BE_PRELD_HIQ_P1_EN BIT(16) +#define B_BE_PRELD_HIQ_P0MB15_EN BIT(15) +#define B_BE_PRELD_HIQ_P0MB14_EN BIT(14) +#define B_BE_PRELD_HIQ_P0MB13_EN BIT(13) +#define B_BE_PRELD_HIQ_P0MB12_EN BIT(12) +#define B_BE_PRELD_HIQ_P0MB11_EN BIT(11) +#define B_BE_PRELD_HIQ_P0MB10_EN BIT(10) +#define B_BE_PRELD_HIQ_P0MB9_EN BIT(9) +#define B_BE_PRELD_HIQ_P0MB8_EN BIT(8) +#define B_BE_PRELD_HIQ_P0MB7_EN BIT(7) +#define B_BE_PRELD_HIQ_P0MB6_EN BIT(6) +#define B_BE_PRELD_HIQ_P0MB5_EN BIT(5) +#define B_BE_PRELD_HIQ_P0MB4_EN BIT(4) +#define B_BE_PRELD_HIQ_P0MB3_EN BIT(3) +#define B_BE_PRELD_HIQ_P0MB2_EN BIT(2) +#define B_BE_PRELD_HIQ_P0MB1_EN BIT(1) +#define B_BE_PRELD_HIQ_P0_EN BIT(0) +#define B_BE_PRELD_HIQ_ALL_EN (B_BE_PRELD_HIQ_P0_EN | B_BE_PRELD_HIQ_P1_EN | \ + B_BE_PRELD_HIQ_P2_EN | B_BE_PRELD_HIQ_P3_EN | \ + B_BE_PRELD_HIQ_P4_EN) +#define B_BE_PRELD_HIQ_P0MB_ALL_EN \ + (B_BE_PRELD_HIQ_P0_EN | B_BE_PRELD_HIQ_P0MB1_EN | \ + B_BE_PRELD_HIQ_P0MB2_EN | B_BE_PRELD_HIQ_P0MB3_EN | \ + B_BE_PRELD_HIQ_P0MB4_EN | B_BE_PRELD_HIQ_P0MB5_EN | \ + B_BE_PRELD_HIQ_P0MB6_EN | B_BE_PRELD_HIQ_P0MB7_EN | \ + B_BE_PRELD_HIQ_P0MB8_EN | B_BE_PRELD_HIQ_P0MB9_EN | \ + B_BE_PRELD_HIQ_P0MB10_EN | B_BE_PRELD_HIQ_P0MB11_EN | \ + B_BE_PRELD_HIQ_P0MB12_EN | B_BE_PRELD_HIQ_P0MB13_EN | \ + B_BE_PRELD_HIQ_P0MB14_EN | B_BE_PRELD_HIQ_P0MB15_EN) + #define R_BE_BT_PLT 0x1087C #define R_BE_BT_PLT_C1 0x1487C #define B_BE_BT_PLT_PKT_CNT_MASK GENMASK(31, 16) @@ -6936,6 +7258,8 @@ B_BE_RX_RU1_FSM_HANG_ERROR_IMR | \ B_BE_RX_RU0_FSM_HANG_ERROR_IMR | \ B_BE_RX_GET_NULL_PKT_ERROR_IMR) +#define B_BE_RX_ERROR_FLAG_IMR_CLR_V1 0x7FFFFFF8 +#define B_BE_RX_ERROR_FLAG_IMR_SET_V1 0x7FFFFF38 #define R_BE_RX_CTRL_1 0x10C0C #define R_BE_RX_CTRL_1_C1 0x14C0C @@ -7349,6 +7673,8 @@ #define B_BE_ACK_BA_RESP_LEGACY_CHK_SEC_CCA20 BIT(2) #define B_BE_ACK_BA_RESP_LEGACY_CHK_EDCCA BIT(1) #define B_BE_ACK_BA_RESP_LEGACY_CHK_CCA BIT(0) +#define RESP_ACK_CFG_BE (B_BE_ACK_BA_RESP_LEGACY_CHK_BTCCA | \ + B_BE_ACK_BA_RESP_LEGACY_CHK_TX_NAV) #define R_BE_WMAC_ACK_BA_RESP_HE 0x11204 #define R_BE_WMAC_ACK_BA_RESP_HE_C1 0x15204 @@ -7390,6 +7716,188 @@ #define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_EDCCA BIT(1) #define B_BE_ACK_BA_EHT_LEG_PUNC_CHK_CCA BIT(0) +#define R_BE_WMAC_RX_RTS_RESP_LEGACY 0x1120C +#define R_BE_WMAC_RX_RTS_RESP_LEGACY_C1 0x1520C +#define B_BE_RX_RTS_RESP_LEGACY_CHK_NSTR BIT(16) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_TX_NAV BIT(15) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_INTRA_NAV BIT(14) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_BASIC_NAV BIT(13) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_BTCCA BIT(12) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA160 BIT(5) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA80 BIT(4) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA40 BIT(3) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA20 BIT(2) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA BIT(1) +#define B_BE_RX_RTS_RESP_LEGACY_CHK_CCA BIT(0) +#define RESP_RTS_CFG_BE (B_BE_RX_RTS_RESP_LEGACY_CHK_CCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA20 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA40 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA80 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA160 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA20 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA40 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA80 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA160 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BTCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BASIC_NAV | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_INTRA_NAV | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_TX_NAV) +#define RESP_RTS_PUNC_CFG_BE (B_BE_RX_RTS_RESP_LEGACY_CHK_CCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_CCA_PER20_BMP | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA_PER20_BMP | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BTCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BASIC_NAV | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_INTRA_NAV | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_TX_NAV) +#define RESP_NORMAL_CFG_BE (B_BE_RX_RTS_RESP_LEGACY_CHK_CCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA20 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA40 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA80 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_CCA160 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA20 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA40 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA80 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_SEC_EDCCA160 | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BTCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BASIC_NAV | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_TX_NAV) +#define RESP_NORMAL_PUNC_CFG_BE (B_BE_RX_RTS_RESP_LEGACY_CHK_CCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_CCA_PER20_BMP | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_EDCCA_PER20_BMP | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BTCCA | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_BASIC_NAV | \ + B_BE_RX_RTS_RESP_LEGACY_CHK_TX_NAV) + +#define R_BE_WMAC_RX_RTS_RESP_LEGACY_PUNC 0x11210 +#define R_BE_WMAC_RX_RTS_RESP_LEGACY_PUNC_C1 0x15210 +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_NSTR BIT(16) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_TX_NAV BIT(15) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_INTRA_NAV BIT(14) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_BASIC_NAV BIT(13) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_BTCCA BIT(12) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_CCA160 BIT(5) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_CCA80 BIT(4) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_CCA40 BIT(3) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_SEC_CCA20 BIT(2) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_EDCCA BIT(1) +#define B_BE_RX_RTS_RESP_LEGACY_PUNC_CHK_CCA BIT(0) + +#define R_BE_WMAC_RX_MURTS_RESP_LEGACY 0x11214 +#define R_BE_WMAC_RX_MURTS_RESP_LEGACY_C1 0x15214 +#define B_BE_MURTS_RESP_LEGACY_CHK_NSTR BIT(16) +#define B_BE_MURTS_RESP_LEGACY_CHK_TX_NAV BIT(15) +#define B_BE_MURTS_RESP_LEGACY_CHK_INTRA_NAV BIT(14) +#define B_BE_MURTS_RESP_LEGACY_CHK_BASIC_NAV BIT(13) +#define B_BE_MURTS_RESP_LEGACY_CHK_BTCCA BIT(12) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_MURTS_RESP_LEGACY_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_MURTS_RESP_LEGACY_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_CCA160 BIT(5) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_CCA80 BIT(4) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_CCA40 BIT(3) +#define B_BE_MURTS_RESP_LEGACY_CHK_SEC_CCA20 BIT(2) +#define B_BE_MURTS_RESP_LEGACY_CHK_EDCCA BIT(1) +#define B_BE_MURTS_RESP_LEGACY_CHK_CCA BIT(0) + +#define R_BE_WMAC_RX_MURTS_RESP_LEGACY_PUNC 0x11218 +#define R_BE_WMAC_RX_MURTS_RESP_LEGACY_PUNC_C1 0x15218 +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_NSTR BIT(16) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_TX_NAV BIT(15) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_INTRA_NAV BIT(14) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_BASIC_NAV BIT(13) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_BTCCA BIT(12) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_CCA160 BIT(5) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_CCA80 BIT(4) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_CCA40 BIT(3) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_SEC_CCA20 BIT(2) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_EDCCA BIT(1) +#define B_BE_MURTS_RESP_LEGACY_PUNC_CHK_CCA BIT(0) + +#define R_BE_WMAC_OTHERS_RESP_LEGACY 0x1121C +#define R_BE_WMAC_OTHERS_RESP_LEGACY_C1 0x1521C +#define B_BE_OTHERS_RESP_LEGACY_CHK_NSTR BIT(16) +#define B_BE_OTHERS_RESP_LEGACY_CHK_TX_NAV BIT(15) +#define B_BE_OTHERS_RESP_LEGACY_CHK_INTRA_NAV BIT(14) +#define B_BE_OTHERS_RESP_LEGACY_CHK_BASIC_NAV BIT(13) +#define B_BE_OTHERS_RESP_LEGACY_CHK_BTCCA BIT(12) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_OTHERS_RESP_LEGACY_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_OTHERS_RESP_LEGACY_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_CCA160 BIT(5) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_CCA80 BIT(4) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_CCA40 BIT(3) +#define B_BE_OTHERS_RESP_LEGACY_CHK_SEC_CCA20 BIT(2) +#define B_BE_OTHERS_RESP_LEGACY_CHK_EDCCA BIT(1) +#define B_BE_OTHERS_RESP_LEGACY_CHK_CCA BIT(0) + +#define R_BE_WMAC_OTHERS_RESP_HE 0x11220 +#define R_BE_WMAC_OTHERS_RESP_HE_C1 0x15220 +#define B_BE_OTHERS_RESP_HE_CHK_NSTR BIT(16) +#define B_BE_OTHERS_RESP_HE_CHK_TX_NAV BIT(15) +#define B_BE_OTHERS_RESP_HE_CHK_INTRA_NAV BIT(14) +#define B_BE_OTHERS_RESP_HE_CHK_BASIC_NAV BIT(13) +#define B_BE_OTHERS_RESP_HE_CHK_BTCCA BIT(12) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_OTHERS_RESP_HE_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_OTHERS_RESP_HE_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_CCA160 BIT(5) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_CCA80 BIT(4) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_CCA40 BIT(3) +#define B_BE_OTHERS_RESP_HE_CHK_SEC_CCA20 BIT(2) +#define B_BE_OTHERS_RESP_HE_CHK_EDCCA BIT(1) +#define B_BE_OTHERS_RESP_HE_CHK_CCA BIT(0) + +#define R_BE_WMAC_OTHERS_RESP_EHT_LEG_PUNC 0x11224 +#define R_BE_WMAC_OTHERS_RESP_EHT_LEG_PUNC_C1 0x15224 +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_NSTR BIT(16) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_TX_NAV BIT(15) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_INTRA_NAV BIT(14) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_BASIC_NAV BIT(13) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_BTCCA BIT(12) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_EDCCA160 BIT(11) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_EDCCA80 BIT(10) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_EDCCA40 BIT(9) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_EDCCA20 BIT(8) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_EDCCA_PER20_BMP BIT(7) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_CCA_PER20_BMP BIT(6) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_CCA160 BIT(5) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_CCA80 BIT(4) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_CCA40 BIT(3) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_SEC_CCA20 BIT(2) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_EDCCA BIT(1) +#define B_BE_OTHERS_RESP_EHT_LEG_PUNC_CHK_CCA BIT(0) + #define R_BE_RCR 0x11400 #define R_BE_RCR_C1 0x15400 #define B_BE_BUSY_CHKSN BIT(15) @@ -7427,6 +7935,17 @@ #define B_BE_CCK_SIG_CHK BIT(1) #define B_BE_CCK_CRC_CHK BIT(0) +#define R_BE_RXGCK_CTRL 0x11406 +#define R_BE_RXGCK_CTRL_C1 0x15406 +#define B_BE_RXGCK_BCNPRS_DISGCLK BIT(12) +#define B_BE_RXGCK_GCK_RATE_LIMIT_MASK GENMASK(9, 8) +#define RX_GCK_LEGACY 2 +#define B_BE_RXGCK_DISREG_GCLK BIT(7) +#define B_BE_RXGCK_ENTRY_DELAY_MASK GENMASK(6, 4) +#define B_BE_RXGCK_GCK_CYCLE_MASK GENMASK(3, 2) +#define B_BE_RXGCK_CCA_EN BIT(1) +#define B_BE_DISGCLK BIT(0) + #define R_BE_RX_FLTR_OPT 0x11420 #define R_BE_RX_FLTR_OPT_C1 0x15420 #define B_BE_UID_FILTER_MASK GENMASK(31, 24) @@ -7521,6 +8040,11 @@ #define B_BE_CSIPRT_HESU_AID_EN BIT(25) #define B_BE_CSIPRT_VHTSU_AID_EN BIT(24) +#define R_BE_BSR_UPD_CTRL 0x11468 +#define R_BE_BSR_UPD_CTRL_C1 0x15468 +#define B_BE_QSIZE_RULE BIT(1) +#define B_BE_QSIZE_UPD BIT(0) + #define R_BE_DRV_INFO_OPTION 0x11470 #define R_BE_DRV_INFO_OPTION_C1 0x15470 #define B_BE_DRV_INFO_PHYRPT_EN BIT(0) @@ -7586,11 +8110,35 @@ #define B_BE_PLCP_CH20_WIDATA_SRC BIT(1) #define B_BE_PLCP_PPDU_TYPE_SRC BIT(0) +#define R_BE_RX_PLCP_EXT_OPTION_2 0x11518 +#define R_BE_RX_PLCP_EXT_OPTION_2_C1 0x15518 +#define B_BE_PLCP_PHASE_B_CRC_CHK_EN BIT(17) +#define B_BE_PLCP_PHASE_A_CRC_CHK_EN BIT(16) +#define B_BE_EHTTB_EHTSIG_CRC_CHK_EN BIT(3) +#define B_BE_EHTTB_USIG_CRC_CHK_EN BIT(2) +#define B_BE_EHTMU_EHTSIG_CRC_CHK_EN BIT(1) +#define B_BE_EHTMU_USIG_CRC_CHK_EN BIT(0) + #define R_BE_RESP_CSI_RESERVED_PAGE 0x11810 #define R_BE_RESP_CSI_RESERVED_PAGE_C1 0x15810 #define B_BE_CSI_RESERVED_PAGE_NUM_MASK GENMASK(27, 16) #define B_BE_CSI_RESERVED_START_PAGE_MASK GENMASK(11, 0) +#define R_BE_RESP_IMR1 0x11878 +#define R_BE_RESP_IMR1_C1 0x15878 +#define B_BE_RESP_IMR_1_MASK GENMASK(31, 9) +#define B_BE_FSM_TIMEOUT_ERR_IMR BIT(8) +#define B_BE_SEC_DOUBLE_HIT_ERR_IMR BIT(7) +#define B_BE_WRPTR_ERR_IMR BIT(6) +#define B_BE_SMR_TOO_MANY_PLD_ERR_IMR BIT(5) +#define B_BE_LMR_TOO_MANY_PLD_ERR_IMR BIT(4) +#define B_BE_CSI_TOO_MANY_PLD_ERR_IMR BIT(3) +#define B_BE_FTM_LMR_PLDID_READY_ERR_IMR BIT(2) +#define B_BE_SMR_PLDID_READY_ERR_IMR BIT(1) +#define B_BE_CSI_PLDID_READY_ERR_IMR BIT(0) +#define B_BE_RESP_IMR1_CLR 0x1FF +#define B_BE_RESP_IMR1_SET 0xFF + #define R_BE_RESP_IMR 0x11884 #define R_BE_RESP_IMR_C1 0x15884 #define B_BE_RESP_TBL_FLAG_ERR_ISR_EN BIT(17) @@ -7635,6 +8183,8 @@ B_BE_RESP_PLDID_RDY_ERR_ISR_EN | \ B_BE_RESP_WRPTR_CROSS_ERR_ISR_EN | \ B_BE_RESP_SEC_DOUBLE_HIT_ERR_ISR_EN) +#define B_BE_RESP_IMR_CLR_V1 0xFFFFFFFF +#define B_BE_RESP_IMR_SET_V1 0xFFFFFFFF #define R_BE_PWR_MODULE 0x11900 #define R_BE_PWR_MODULE_C1 0x15900 @@ -7713,6 +8263,10 @@ #define R_BE_TXPWR_ERR_FLAG_C1 0x158E4 #define R_BE_TXPWR_ERR_IMR_C1 0x158E0 +#define R_BE_SCH_EXT_CTRL 0x103FC +#define R_BE_SCH_EXT_CTRL_C1 0x143FC +#define B_BE_CWCNT_PLUS_MODE BIT(31) + #define CMAC1_START_ADDR_BE 0x14000 #define CMAC1_END_ADDR_BE 0x17FFF diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c index 209d84909f88..c3425ed44732 100644 --- a/drivers/net/wireless/realtek/rtw89/regd.c +++ b/drivers/net/wireless/realtek/rtw89/regd.c @@ -1142,6 +1142,7 @@ static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev, } } else { rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT; + dflt = true; } rcu_read_unlock(); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c index 84b628d23882..0383d3b5c7bc 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c @@ -633,8 +633,6 @@ static int rtw8851b_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map, efuse->rfe_type = map->rfe_type; efuse->xtal_cap = map->xtal_k; - rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type); - return 0; } @@ -2553,6 +2551,7 @@ static const struct rtw89_chip_ops rtw8851b_chip_ops = { .h2c_default_dmac_tbl = NULL, .h2c_update_beacon = rtw89_fw_h2c_update_beacon, .h2c_ba_cam = rtw89_fw_h2c_ba_cam, + .h2c_wow_cam_update = rtw89_fw_h2c_wow_cam_update, .btc_set_rfe = rtw8851b_btc_set_rfe, .btc_init_cfg = rtw8851b_btc_init_cfg, @@ -2590,6 +2589,10 @@ const struct rtw89_chip_info rtw8851b_chip_info = { .small_fifo_size = true, .dle_scc_rsvd_size = 98304, .max_amsdu_limit = 3500, + .max_vht_mpdu_cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454, + .max_eht_mpdu_cap = 0, + .max_tx_agg_num = 128, + .max_rx_agg_num = 64, .dis_2g_40m_ul_ofdma = true, .rsvd_ple_ofst = 0x2f800, .hfc_param_ini = {rtw8851b_hfc_param_ini_pcie, @@ -2704,6 +2707,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = { .bss_clr_map_reg = R_BSS_CLR_MAP_V1, .rfkill_init = &rtw8851b_rfkill_regs, .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9}, + .btc_sb = {{{R_AX_SCOREBOARD, R_AX_SCOREBOARD},}}, .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), @@ -2712,6 +2716,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = { .wowlan_stub = &rtw_wowlan_stub_8851b, #endif .xtal_info = &rtw8851b_xtal_info, + .default_quirks = 0, }; EXPORT_SYMBOL(rtw8851b_chip_info); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 8677723e3561..329fc0a7b07b 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -678,8 +678,6 @@ static int rtw8852a_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map, efuse->rfe_type = map->rfe_type; efuse->xtal_cap = map->xtal_k; - rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type); - return 0; } @@ -2247,6 +2245,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = { .h2c_default_dmac_tbl = NULL, .h2c_update_beacon = rtw89_fw_h2c_update_beacon, .h2c_ba_cam = rtw89_fw_h2c_ba_cam, + .h2c_wow_cam_update = rtw89_fw_h2c_wow_cam_update, .btc_set_rfe = rtw8852a_btc_set_rfe, .btc_init_cfg = rtw8852a_btc_init_cfg, @@ -2275,6 +2274,10 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .small_fifo_size = false, .dle_scc_rsvd_size = 0, .max_amsdu_limit = 3500, + .max_vht_mpdu_cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454, + .max_eht_mpdu_cap = 0, + .max_tx_agg_num = 128, + .max_rx_agg_num = 64, .dis_2g_40m_ul_ofdma = true, .rsvd_ple_ofst = 0x6f800, .hfc_param_ini = {rtw8852a_hfc_param_ini_pcie, @@ -2391,12 +2394,14 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .bss_clr_map_reg = R_BSS_CLR_MAP, .rfkill_init = &rtw8852a_rfkill_regs, .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9}, + .btc_sb = {{{R_AX_SCOREBOARD, R_AX_SCOREBOARD},}}, .dma_ch_mask = 0, .edcca_regs = &rtw8852a_edcca_regs, #ifdef CONFIG_PM .wowlan_stub = &rtw_wowlan_stub_8852a, #endif .xtal_info = &rtw8852a_xtal_info, + .default_quirks = 0, }; EXPORT_SYMBOL(rtw8852a_chip_info); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852au.c b/drivers/net/wireless/realtek/rtw89/rtw8852au.c index ca782469c455..ccdbcc178c2a 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852au.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852au.c @@ -52,6 +52,8 @@ static const struct usb_device_id rtw_8852au_id_table[] = { .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3321, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3323, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x332c, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x013f, 0xff, 0xff, 0xff), @@ -60,6 +62,8 @@ static const struct usb_device_id rtw_8852au_id_table[] = { .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0141, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x3625, 0x010d, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, { USB_DEVICE_AND_INTERFACE_INFO(0x3625, 0x010f, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, {}, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index 70fb05bc5e98..f44674a39e30 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -313,6 +313,27 @@ static void rtw8852b_pwr_sps_ana(struct rtw89_dev *rtwdev) rtw89_write16(rtwdev, R_AX_SPS_ANA_ON_CTRL2, RTL8852B_RFE_05_SPS_ANA); } +static void rtw8852b_pwr_sps_dig_off(struct rtw89_dev *rtwdev) +{ + struct rtw89_efuse *efuse = &rtwdev->efuse; + + if (efuse->rfe_type == 0x5) { + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, + B_AX_C1_L1_MASK, 0x1); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, + B_AX_C2_L1_MASK, 0x1); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, + B_AX_C3_L1_MASK, 0x2); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, + B_AX_R1_L1_MASK, 0x1); + } else { + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, + B_AX_C1_L1_MASK, 0x1); + rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, + B_AX_C3_L1_MASK, 0x3); + } +} + static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev) { u32 val32; @@ -338,8 +359,7 @@ static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev) if (ret) return ret; - rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, B_AX_C1_L1_MASK, 0x1); - rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, B_AX_C3_L1_MASK, 0x3); + rtw8852b_pwr_sps_dig_off(rtwdev); rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON); rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC); @@ -858,6 +878,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = { .h2c_default_dmac_tbl = NULL, .h2c_update_beacon = rtw89_fw_h2c_update_beacon, .h2c_ba_cam = rtw89_fw_h2c_ba_cam, + .h2c_wow_cam_update = rtw89_fw_h2c_wow_cam_update, .btc_set_rfe = rtw8852b_btc_set_rfe, .btc_init_cfg = rtw8852bx_btc_init_cfg, @@ -899,6 +920,10 @@ const struct rtw89_chip_info rtw8852b_chip_info = { .small_fifo_size = true, .dle_scc_rsvd_size = 98304, .max_amsdu_limit = 5000, + .max_vht_mpdu_cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454, + .max_eht_mpdu_cap = 0, + .max_tx_agg_num = 128, + .max_rx_agg_num = 64, .dis_2g_40m_ul_ofdma = true, .rsvd_ple_ofst = 0x2f800, .hfc_param_ini = {rtw8852b_hfc_param_ini_pcie, @@ -1016,6 +1041,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { .bss_clr_map_reg = R_BSS_CLR_MAP_V1, .rfkill_init = &rtw8852b_rfkill_regs, .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9}, + .btc_sb = {{{R_AX_SCOREBOARD, R_AX_SCOREBOARD},}}, .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), @@ -1024,6 +1050,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { .wowlan_stub = &rtw_wowlan_stub_8852b, #endif .xtal_info = NULL, + .default_quirks = 0, }; EXPORT_SYMBOL(rtw8852b_chip_info); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c index 4e72f4961837..65b839323e3e 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c @@ -265,8 +265,6 @@ static int __rtw8852bx_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map, efuse->rfe_type = map->rfe_type; efuse->xtal_cap = map->xtal_k; - rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type); - return 0; } diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c index f956474c3b72..ab60ed389ff7 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c @@ -724,6 +724,7 @@ static const struct rtw89_chip_ops rtw8852bt_chip_ops = { .h2c_default_dmac_tbl = NULL, .h2c_update_beacon = rtw89_fw_h2c_update_beacon, .h2c_ba_cam = rtw89_fw_h2c_ba_cam, + .h2c_wow_cam_update = rtw89_fw_h2c_wow_cam_update, .btc_set_rfe = rtw8852bt_btc_set_rfe, .btc_init_cfg = rtw8852bx_btc_init_cfg, @@ -765,6 +766,10 @@ const struct rtw89_chip_info rtw8852bt_chip_info = { .small_fifo_size = true, .dle_scc_rsvd_size = 98304, .max_amsdu_limit = 5000, + .max_vht_mpdu_cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454, + .max_eht_mpdu_cap = 0, + .max_tx_agg_num = 128, + .max_rx_agg_num = 64, .dis_2g_40m_ul_ofdma = true, .rsvd_ple_ofst = 0x6f800, .hfc_param_ini = {rtw8852bt_hfc_param_ini_pcie, NULL, NULL}, @@ -873,6 +878,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = { .bss_clr_map_reg = R_BSS_CLR_MAP_V1, .rfkill_init = &rtw8852bt_rfkill_regs, .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9}, + .btc_sb = {{{R_AX_SCOREBOARD, R_AX_SCOREBOARD},}}, .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), @@ -881,6 +887,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = { .wowlan_stub = &rtw_wowlan_stub_8852bt, #endif .xtal_info = NULL, + .default_quirks = 0, }; EXPORT_SYMBOL(rtw8852bt_chip_info); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bu.c b/drivers/net/wireless/realtek/rtw89/rtw8852bu.c index 980d17ef68d0..84cd3ec971f9 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852bu.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bu.c @@ -54,6 +54,8 @@ static const struct usb_device_id rtw_8852bu_id_table[] = { .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, { USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0x6931, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0xf0c8, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3327, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, { USB_DEVICE_AND_INTERFACE_INFO(0x3574, 0x6121, 0xff, 0xff, 0xff), diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index db99450e9158..d2138be3640d 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -600,8 +600,6 @@ static int rtw8852c_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map, efuse->rfe_type = map->rfe_type; efuse->xtal_cap = map->xtal_k; - rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type); - return 0; } @@ -3088,6 +3086,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { .h2c_default_dmac_tbl = NULL, .h2c_update_beacon = rtw89_fw_h2c_update_beacon, .h2c_ba_cam = rtw89_fw_h2c_ba_cam, + .h2c_wow_cam_update = rtw89_fw_h2c_wow_cam_update, .btc_set_rfe = rtw8852c_btc_set_rfe, .btc_init_cfg = rtw8852c_btc_init_cfg, @@ -3116,6 +3115,10 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .small_fifo_size = false, .dle_scc_rsvd_size = 0, .max_amsdu_limit = 8000, + .max_vht_mpdu_cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454, + .max_eht_mpdu_cap = 0, + .max_tx_agg_num = 128, + .max_rx_agg_num = 64, .dis_2g_40m_ul_ofdma = false, .rsvd_ple_ofst = 0x6f800, .hfc_param_ini = {rtw8852c_hfc_param_ini_pcie, @@ -3236,12 +3239,14 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .bss_clr_map_reg = R_BSS_CLR_MAP, .rfkill_init = &rtw8852c_rfkill_regs, .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9}, + .btc_sb = {{{R_AX_SCOREBOARD, R_AX_SCOREBOARD},}}, .dma_ch_mask = 0, .edcca_regs = &rtw8852c_edcca_regs, #ifdef CONFIG_PM .wowlan_stub = &rtw_wowlan_stub_8852c, #endif .xtal_info = NULL, + .default_quirks = 0, }; EXPORT_SYMBOL(rtw8852c_chip_info); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c index 4437279c554b..6d2cd914e16e 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -628,24 +628,36 @@ static int rtw8922a_read_efuse_rf(struct rtw89_dev *rtwdev, u8 *log_map) rtw8922a_efuse_parsing_tssi(rtwdev, map); rtw8922a_efuse_parsing_gain_offset(rtwdev, map); - rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type); - return 0; } static int rtw8922a_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map, enum rtw89_efuse_block block) { + struct rtw89_efuse *efuse = &rtwdev->efuse; + int ret; + switch (block) { case RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO: - return rtw8922a_read_efuse_pci_sdio(rtwdev, log_map); + ret = rtw8922a_read_efuse_pci_sdio(rtwdev, log_map); + break; case RTW89_EFUSE_BLOCK_HCI_DIG_USB: - return rtw8922a_read_efuse_usb(rtwdev, log_map); + ret = rtw8922a_read_efuse_usb(rtwdev, log_map); + break; case RTW89_EFUSE_BLOCK_RF: - return rtw8922a_read_efuse_rf(rtwdev, log_map); + ret = rtw8922a_read_efuse_rf(rtwdev, log_map); + break; default: - return 0; + ret = 0; + break; + } + + if (!ret && is_zero_ether_addr(efuse->addr)) { + rtw89_info(rtwdev, "efuse mac address is zero, using random mac\n"); + eth_random_addr(efuse->addr); } + + return ret; } #define THM_TRIM_POSITIVE_MASK BIT(6) @@ -2847,6 +2859,7 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = { .h2c_default_dmac_tbl = rtw89_fw_h2c_default_dmac_tbl_v2, .h2c_update_beacon = rtw89_fw_h2c_update_beacon_be, .h2c_ba_cam = rtw89_fw_h2c_ba_cam_v1, + .h2c_wow_cam_update = rtw89_fw_h2c_wow_cam_update, .btc_set_rfe = rtw8922a_btc_set_rfe, .btc_init_cfg = rtw8922a_btc_init_cfg, @@ -2875,6 +2888,10 @@ const struct rtw89_chip_info rtw8922a_chip_info = { .small_fifo_size = false, .dle_scc_rsvd_size = 0, .max_amsdu_limit = 8000, + .max_vht_mpdu_cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454, + .max_eht_mpdu_cap = IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_7991, + .max_tx_agg_num = 128, + .max_rx_agg_num = 64, .dis_2g_40m_ul_ofdma = false, .rsvd_ple_ofst = 0x8f800, .hfc_param_ini = {rtw8922a_hfc_param_ini_pcie, NULL, NULL}, @@ -2988,12 +3005,14 @@ const struct rtw89_chip_info rtw8922a_chip_info = { .bss_clr_map_reg = R_BSS_CLR_MAP_V2, .rfkill_init = &rtw8922a_rfkill_regs, .rfkill_get = {R_BE_GPIO_EXT_CTRL, B_BE_GPIO_IN_9}, + .btc_sb = {{{R_BE_SCOREBOARD, R_BE_SCOREBOARD},}}, .dma_ch_mask = 0, .edcca_regs = &rtw8922a_edcca_regs, #ifdef CONFIG_PM .wowlan_stub = &rtw_wowlan_stub_8922a, #endif .xtal_info = NULL, + .default_quirks = 0, }; EXPORT_SYMBOL(rtw8922a_chip_info); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c index fce094c7ce93..98f14b31cf52 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c @@ -205,11 +205,11 @@ static void rtw8922a_chlk_ktbl_sel(struct rtw89_dev *rtwdev, u8 kpath, u8 idx) } } -static u8 rtw8922a_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev, - const struct rtw89_chan *chan, u8 path) +static u8 rtw8922a_chlk_reload_sel_tbl_v0(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] = {}; + struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; u8 tbl_sel; for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) { @@ -229,11 +229,53 @@ static u8 rtw8922a_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev, rfk_mcc->data[path].ch[tbl_sel] = chan->channel; rfk_mcc->data[path].band[tbl_sel] = chan->band_type; rfk_mcc->data[path].bw[tbl_sel] = chan->band_width; + rfk_mcc->data[path].rf18[tbl_sel] = rtw89_chip_chan_to_rf18_val(rtwdev, chan); rfk_mcc->data[path].table_idx = tbl_sel; return tbl_sel; } +static u8 rtw8922a_chlk_reload_sel_tbl_v1(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, u8 path) +{ + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; + struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {}; + u8 tbl_sel; + + for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) { + struct rtw89_rfk_chan_desc *p = &desc[tbl_sel]; + + p->ch = rfk_mcc->ch[tbl_sel]; + + p->has_band = true; + p->band = rfk_mcc->band[tbl_sel]; + + p->has_bw = true; + p->bw = rfk_mcc->bw[tbl_sel]; + } + + tbl_sel = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan); + + rfk_mcc->ch[tbl_sel] = chan->channel; + rfk_mcc->band[tbl_sel] = chan->band_type; + rfk_mcc->bw[tbl_sel] = chan->band_width; + rfk_mcc->rf18[tbl_sel] = rtw89_chip_chan_to_rf18_val(rtwdev, chan); + + /* shared table array, but tbl_sel can be independent by path */ + rfk_mcc[path].table_idx = tbl_sel; + + return tbl_sel; +} + +static u8 rtw8922a_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, u8 path) +{ + if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V1, &rtwdev->fw)) + return rtw8922a_chlk_reload_sel_tbl_v1(rtwdev, chan, path); + else + return rtw8922a_chlk_reload_sel_tbl_v0(rtwdev, chan, path); +} + static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev) { const struct rtw89_chan *chan0, *chan1; diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index f99e179f7ff9..7fdc69578da3 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -431,6 +431,14 @@ static void hal_send_m4_event(struct rtw89_ser *ser) rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_RCVY_EN); } +static void hal_enable_err_imr(struct rtw89_ser *ser) +{ + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + + mac->err_imr_ctrl(rtwdev, true); +} + /* state handler */ static void ser_idle_st_hdl(struct rtw89_ser *ser, u8 evt) { @@ -552,6 +560,8 @@ static void ser_do_hci_st_hdl(struct rtw89_ser *ser, u8 evt) break; case SER_EV_MAC_RESET_DONE: + hal_enable_err_imr(ser); + ser_state_goto(ser, SER_IDLE_ST); break; diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h index fa324b4a1dde..b69a2529aefc 100644 --- a/drivers/net/wireless/realtek/rtw89/txrx.h +++ b/drivers/net/wireless/realtek/rtw89/txrx.h @@ -188,12 +188,16 @@ static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate) #define BE_TXD_BODY2_QSEL GENMASK(22, 17) #define BE_TXD_BODY2_TID_IND BIT(23) #define BE_TXD_BODY2_MACID GENMASK(31, 24) +#define BE_TXD_BODY2_QSEL_V1 GENMASK(20, 15) +#define BE_TXD_BODY2_TID_IND_V1 BIT(21) +#define BE_TXD_BODY2_MACID_V1 GENMASK(31, 22) /* TX WD BODY DWORD 3 */ #define BE_TXD_BODY3_WIFI_SEQ GENMASK(11, 0) #define BE_TXD_BODY3_MLO_FLAG BIT(12) #define BE_TXD_BODY3_IS_MLD_SW_EN BIT(13) #define BE_TXD_BODY3_TRY_RATE BIT(14) +#define BE_TXD_BODY3_BK_V1 BIT(14) #define BE_TXD_BODY3_RELINK_FLAG_V1 BIT(15) #define BE_TXD_BODY3_BAND0_SU_TC_V1 GENMASK(21, 16) #define BE_TXD_BODY3_TOTAL_TC GENMASK(27, 22) @@ -201,6 +205,7 @@ static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate) #define BE_TXD_BODY3_MU_PRI_RTY BIT(29) #define BE_TXD_BODY3_MU_2ND_RTY BIT(30) #define BE_TXD_BODY3_BAND1_SU_RTY_V1 BIT(31) +#define BE_TXD_BODY3_DRIVER_QUEUE_TIME GENMASK(31, 16) /* TX WD BODY DWORD 4 */ #define BE_TXD_BODY4_TXDESC_CHECKSUM GENMASK(15, 0) @@ -224,6 +229,10 @@ static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate) #define BE_TXD_BODY6_EOSP_BIT BIT(15) #define BE_TXD_BODY6_S_IDX GENMASK(23, 16) #define BE_TXD_BODY6_RU_POS GENMASK(31, 24) +#define BE_TXD_BODY6_MU_TC_V1 GENMASK(3, 0) +#define BE_TXD_BODY6_RU_TC_V1 GENMASK(8, 5) +#define BE_TXD_BODY6_RELINK_EN BIT(9) +#define BE_TXD_BODY6_RELINK_LAST BIT(10) /* TX WD BODY DWORD 7 */ #define BE_TXD_BODY7_RTS_TC GENMASK(5, 0) @@ -262,6 +271,8 @@ static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate) /* TX WD INFO DWORD 2 */ #define BE_TXD_INFO2_SEC_CAM_IDX GENMASK(7, 0) #define BE_TXD_INFO2_FORCE_KEY_EN BIT(8) +#define BE_TXD_INFO2_SEC_CAM_IDX_V1 GENMASK(9, 0) +#define BE_TXD_INFO2_FORCE_KEY_EN_V1 BIT(10) #define BE_TXD_INFO2_LIFETIME_SEL GENMASK(15, 13) #define BE_TXD_INFO2_FORCE_TXOP BIT(17) #define BE_TXD_INFO2_AMPDU_DENSITY GENMASK(20, 18) @@ -277,6 +288,7 @@ static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate) #define BE_TXD_INFO3_RTT_EN BIT(9) #define BE_TXD_INFO3_HT_DATA_SND_V1 BIT(10) #define BE_TXD_INFO3_BT_NULL BIT(11) +#define BE_TXD_INFO3_DISABLE_TXBF BIT(11) #define BE_TXD_INFO3_TRI_FRAME BIT(12) #define BE_TXD_INFO3_NULL_0 BIT(13) #define BE_TXD_INFO3_NULL_1 BIT(14) @@ -292,6 +304,8 @@ static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate) #define BE_TXD_INFO4_PUNC_MODE GENMASK(17, 16) #define BE_TXD_INFO4_SW_TX_OK_0 BIT(18) #define BE_TXD_INFO4_SW_TX_OK_1 BIT(19) +#define BE_TXD_INFO4_SW_EHT_NLTF_SWITCH BIT(20) +#define BE_TXD_INFO4_SW_EHT_NLTF GENMASK(22, 21) #define BE_TXD_INFO4_SW_TX_PWR_DBM GENMASK(26, 23) #define BE_TXD_INFO4_RTS_EN BIT(27) #define BE_TXD_INFO4_CTS2SELF BIT(28) @@ -308,6 +322,7 @@ static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate) #define BE_TXD_INFO6_UL_GI_LTF GENMASK(14, 12) #define BE_TXD_INFO6_UL_DOPPLER BIT(15) #define BE_TXD_INFO6_UL_STBC BIT(16) +#define BE_TXD_INFO6_UL_MU_MIMO_EN BIT(17) #define BE_TXD_INFO6_UL_LENGTH_REF GENMASK(21, 18) #define BE_TXD_INFO6_UL_RF_GAIN_IDX GENMASK(31, 22) @@ -322,6 +337,7 @@ static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate) #define BE_TXD_INFO7_UL_HELTF_SYMBOL_NUM GENMASK(19, 17) #define BE_TXD_INFO7_ULBW GENMASK(21, 20) #define BE_TXD_INFO7_ULBW_EXT GENMASK(23, 22) +#define BE_TXD_INFO7_UL_TRI_PAD_TSF BIT(24) #define BE_TXD_INFO7_USE_WD_UL GENMASK(25, 24) #define BE_TXD_INFO7_EXTEND_MODE_SEL GENMASK(31, 28) @@ -488,6 +504,7 @@ struct rtw89_phy_sts_iehdr { /* BE RXD dword2 */ #define BE_RXD_MAC_ID_MASK GENMASK(7, 0) +#define BE_RXD_MAC_ID_V1 GENMASK(9, 0) #define BE_RXD_TYPE_MASK GENMASK(11, 10) #define BE_RXD_LAST_MSDU BIT(12) #define BE_RXD_AMSDU_CUT BIT(13) @@ -519,6 +536,7 @@ struct rtw89_phy_sts_iehdr { #define BE_RXD_QNULL BIT(22) #define BE_RXD_A4_FRAME BIT(23) #define BE_RXD_FRAG_MASK GENMASK(27, 24) +#define BE_RXD_GET_CH_INFO_V2 GENMASK(31, 29) #define BE_RXD_GET_CH_INFO_V1_MASK GENMASK(31, 30) /* BE RXD dword4 */ @@ -534,10 +552,14 @@ struct rtw89_phy_sts_iehdr { /* BE RXD dword6 */ #define BE_RXD_ADDR_CAM_MASK GENMASK(7, 0) +#define BE_RXD_ADDR_CAM_V1 GENMASK(9, 0) +#define BE_RXD_RX_STATISTICS_V1 BIT(11) +#define BE_RXD_SMART_ANT_V1 BIT(12) #define BE_RXD_SR_EN BIT(13) #define BE_RXD_NON_SRG_PPDU BIT(14) #define BE_RXD_INTER_PPDU BIT(15) #define BE_RXD_USER_ID_MASK GENMASK(21, 16) +#define BE_RXD_SEC_CAM_IDX_V1 GENMASK(31, 22) #define BE_RXD_RX_STATISTICS BIT(22) #define BE_RXD_SMART_ANT BIT(23) #define BE_RXD_SEC_CAM_IDX_MASK GENMASK(31, 24) diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireless/realtek/rtw89/usb.c index d7d968207a39..e77561a4d971 100644 --- a/drivers/net/wireless/realtek/rtw89/usb.c +++ b/drivers/net/wireless/realtek/rtw89/usb.c @@ -620,7 +620,7 @@ static int rtw89_usb_init_rx(struct rtw89_dev *rtwdev) struct sk_buff *rx_skb; int i; - rtwusb->rxwq = alloc_workqueue("rtw89_usb: rx wq", WQ_BH, 0); + rtwusb->rxwq = alloc_workqueue("rtw89_usb: rx wq", WQ_BH | WQ_PERCPU, 0); if (!rtwusb->rxwq) { rtw89_err(rtwdev, "failed to create RX work queue\n"); return -ENOMEM; diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index 46aba4cb2ee9..5d3227e2b3e4 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -809,6 +809,10 @@ static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev) reason = rtw89_read8(rtwdev, wow_reason_reg); switch (reason) { + case RTW89_WOW_RSN_RX_DISASSOC: + wakeup.disconnect = true; + rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx disassoc\n"); + break; case RTW89_WOW_RSN_RX_DEAUTH: wakeup.disconnect = true; rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx deauth\n"); @@ -1070,7 +1074,7 @@ static void rtw89_wow_pattern_clear_cam(struct rtw89_dev *rtwdev) for (i = 0; i < rtw_wow->pattern_cnt; i++) { rtw_pattern = &rtw_wow->patterns[i]; rtw_pattern->valid = false; - rtw89_fw_wow_cam_update(rtwdev, rtw_pattern); + rtw89_chip_h2c_wow_cam_update(rtwdev, rtw_pattern); } } @@ -1081,7 +1085,7 @@ static void rtw89_wow_pattern_write(struct rtw89_dev *rtwdev) int i; for (i = 0; i < rtw_wow->pattern_cnt; i++) - rtw89_fw_wow_cam_update(rtwdev, rtw_pattern + i); + rtw89_chip_h2c_wow_cam_update(rtwdev, rtw_pattern + i); } static void rtw89_wow_pattern_clear(struct rtw89_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw89/wow.h b/drivers/net/wireless/realtek/rtw89/wow.h index d2ba6cebc2a6..71e07f482174 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.h +++ b/drivers/net/wireless/realtek/rtw89/wow.h @@ -33,6 +33,7 @@ enum rtw89_wake_reason { RTW89_WOW_RSN_RX_PTK_REKEY = 0x1, RTW89_WOW_RSN_RX_GTK_REKEY = 0x2, + RTW89_WOW_RSN_RX_DISASSOC = 0x4, RTW89_WOW_RSN_RX_DEAUTH = 0x8, RTW89_WOW_RSN_DISCONNECT = 0x10, RTW89_WOW_RSN_RX_MAGIC_PKT = 0x21, |
