rtw-next patches for v6.17

Regular development, refinement and minor fixes. Some notable changes are:
 
 rtw88:
 
  * enable AP/ad-hoc modes for SDIO devices
 
 rtw89:
 
  * implement BT-coexistence for WiFi MLO
 
  * ongoing to develop STA+P2P MCC
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEuyEnvMdOsBl1WjpdjlvZYmhshd8FAmhbTUgACgkQjlvZYmhs
 hd9YYxAA0Pmi0KlEx4zA4dZSGrE5A91qpndQWLSYbePKkpIgDN6iD3qwxVtTzv2t
 CPMv4GAuefsyy/Rn+31jQbXgZV/yggmuwjxMCtvOFeHPdZWmYDJdP7GAwO0nMFfH
 QnTfE4KiN2eUD0qUXsx3snx8ceevENeWD8iE3LPl6jV3u/k4lhZJSxnnWHvM/VuY
 TSY+T49NcJ1scQS7bMuhCF5L8stCVdk9WYxdG6qk/sp+/16OXcGNqG4ZsbCMm/9y
 uwMFsP9fmf7ut+jx8FfiHii0a8lOMAwrGpwaDgS/t/Wz5JwV3VDXgB6wwimifsgp
 Z5iuUweAWdtOVXEg+jGjvefqSA7wk9SSuJOGiYHVabIG2OXM8S0LOaZmavEAHbTw
 YxqmFWCWjaCVKSSW217YZQ4JNBocNM35mQwIhnf3dXKZtmKCJsR9p7meC22Yj73E
 Z52tiz+77EM4eQ8x+THeBCquCzzNz95KyB+8JfGpgyk3ZhjurbZ3SBzT+PHdVSRM
 jX9HOyF9by1T3qaMYqznrB6dHLo2wxO1hr3LI/7EngRINWn5FszGFxXUrqOfk+xA
 zins7KFRvtpTZzQpNfnr7tfYyYpmlplECzAqhUEUPyAt8j1T9snzvOQMFweIgrhm
 7+5N/qeET6hOR0ABdOOyJAH9p/xHtaD4/DGOe5dP5l/Dg2qbTvs=
 =PoBt
 -----END PGP SIGNATURE-----

Merge tag 'rtw-next-2025-06-25' of https://github.com/pkshih/rtw

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

Regular development, refinement and minor fixes. Some notable changes are:

rtw88:

 * enable AP/ad-hoc modes for SDIO devices

rtw89:

 * implement BT-coexistence for WiFi MLO

 * ongoing to develop STA+P2P MCC
==================

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2025-06-25 08:47:03 +02:00
commit 5582cbdf7b
72 changed files with 2425 additions and 637 deletions

View File

@ -1041,10 +1041,11 @@ static void rtl8187_stop(struct ieee80211_hw *dev, bool suspend)
rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
usb_kill_anchored_urbs(&priv->anchored);
while ((skb = skb_dequeue(&priv->b_tx_status.queue)))
dev_kfree_skb_any(skb);
usb_kill_anchored_urbs(&priv->anchored);
mutex_unlock(&priv->conf_mutex);
if (!priv->is_rtl8187b)

View File

@ -572,8 +572,11 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
dma_map_single(&rtlpci->pdev->dev, skb_tail_pointer(skb),
rtlpci->rxbuffersize, DMA_FROM_DEVICE);
bufferaddress = *((dma_addr_t *)skb->cb);
if (dma_mapping_error(&rtlpci->pdev->dev, bufferaddress))
if (dma_mapping_error(&rtlpci->pdev->dev, bufferaddress)) {
if (!new_skb)
kfree_skb(skb);
return 0;
}
rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb;
if (rtlpriv->use_new_trx_flow) {
/* skb->cb may be 64 bit address */
@ -802,13 +805,19 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
skb = new_skb;
no_new:
if (rtlpriv->use_new_trx_flow) {
_rtl_pci_init_one_rxdesc(hw, skb, (u8 *)buffer_desc,
rxring_idx,
rtlpci->rx_ring[rxring_idx].idx);
if (!_rtl_pci_init_one_rxdesc(hw, skb, (u8 *)buffer_desc,
rxring_idx,
rtlpci->rx_ring[rxring_idx].idx)) {
if (new_skb)
dev_kfree_skb_any(skb);
}
} else {
_rtl_pci_init_one_rxdesc(hw, skb, (u8 *)pdesc,
rxring_idx,
rtlpci->rx_ring[rxring_idx].idx);
if (!_rtl_pci_init_one_rxdesc(hw, skb, (u8 *)pdesc,
rxring_idx,
rtlpci->rx_ring[rxring_idx].idx)) {
if (new_skb)
dev_kfree_skb_any(skb);
}
if (rtlpci->rx_ring[rxring_idx].idx ==
rtlpci->rxringcount - 1)
rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc,

View File

@ -1738,9 +1738,9 @@ static void read_power_value_fromprom(struct ieee80211_hw *hw,
}
}
static void _rtl88ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail,
u8 *hwinfo)
static noinline_for_stack void
_rtl88ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail, u8 *hwinfo)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));

View File

@ -190,7 +190,7 @@ static bool rtl88e_get_btc_status(void)
return false;
}
static struct rtl_hal_ops rtl8188ee_hal_ops = {
static const struct rtl_hal_ops rtl8188ee_hal_ops = {
.init_sw_vars = rtl88e_init_sw_vars,
.deinit_sw_vars = rtl88e_deinit_sw_vars,
.read_eeprom_info = rtl88ee_read_eeprom_info,

View File

@ -1412,9 +1412,9 @@ void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
rtl92ce_enable_interrupt(hw);
}
static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail,
u8 *hwinfo)
static noinline_for_stack void
_rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail, u8 *hwinfo)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));

View File

@ -167,7 +167,7 @@ static void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw)
}
}
static struct rtl_hal_ops rtl8192ce_hal_ops = {
static const struct rtl_hal_ops rtl8192ce_hal_ops = {
.init_sw_vars = rtl92c_init_sw_vars,
.deinit_sw_vars = rtl92c_deinit_sw_vars,
.read_eeprom_info = rtl92ce_read_eeprom_info,

View File

@ -95,9 +95,9 @@ static void _rtl92cu_phy_param_tab_init(struct ieee80211_hw *hw)
}
}
static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail,
u8 *hwinfo)
static noinline_for_stack void
_rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail, u8 *hwinfo)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));

View File

@ -81,7 +81,7 @@ static bool rtl92cu_get_btc_status(void)
return false;
}
static struct rtl_hal_ops rtl8192cu_hal_ops = {
static const struct rtl_hal_ops rtl8192cu_hal_ops = {
.init_sw_vars = rtl92cu_init_sw_vars,
.deinit_sw_vars = rtl92cu_deinit_sw_vars,
.read_chip_version = rtl92c_read_chip_version,
@ -156,7 +156,7 @@ static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = {
.usb_mq_to_hwq = rtl8192cu_mq_to_hwq,
};
static struct rtl_hal_cfg rtl92cu_hal_cfg = {
static const struct rtl_hal_cfg rtl92cu_hal_cfg = {
.name = "rtl92c_usb",
.alt_fw_name = "rtlwifi/rtl8192cufw.bin",
.ops = &rtl8192cu_hal_ops,

View File

@ -184,7 +184,7 @@ static void rtl92d_deinit_sw_vars(struct ieee80211_hw *hw)
skb_queue_purge(&rtlpriv->mac80211.skb_waitq[tid]);
}
static struct rtl_hal_ops rtl8192de_hal_ops = {
static const struct rtl_hal_ops rtl8192de_hal_ops = {
.init_sw_vars = rtl92d_init_sw_vars,
.deinit_sw_vars = rtl92d_deinit_sw_vars,
.read_eeprom_info = rtl92d_read_eeprom_info,

View File

@ -1731,7 +1731,7 @@ void rtl92ee_update_interrupt_mask(struct ieee80211_hw *hw,
rtl92ee_enable_interrupt(hw);
}
static u8 _rtl92ee_get_chnl_group(u8 chnl)
static __always_inline u8 _rtl92ee_get_chnl_group(u8 chnl)
{
u8 group = 0;
@ -2009,8 +2009,9 @@ static void _rtl8192ee_read_power_value_fromprom(struct ieee80211_hw *hw,
}
}
static void _rtl92ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail, u8 *hwinfo)
static noinline_for_stack void
_rtl92ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail, u8 *hwinfo)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_efuse *efu = rtl_efuse(rtl_priv(hw));

View File

@ -176,7 +176,7 @@ static bool rtl92ee_get_btc_status(void)
return true;
}
static struct rtl_hal_ops rtl8192ee_hal_ops = {
static const struct rtl_hal_ops rtl8192ee_hal_ops = {
.init_sw_vars = rtl92ee_init_sw_vars,
.deinit_sw_vars = rtl92ee_deinit_sw_vars,
.read_eeprom_info = rtl92ee_read_eeprom_info,

View File

@ -221,7 +221,7 @@ static bool rtl92se_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue,
return true;
}
static struct rtl_hal_ops rtl8192se_hal_ops = {
static const struct rtl_hal_ops rtl8192se_hal_ops = {
.init_sw_vars = rtl92s_init_sw_vars,
.deinit_sw_vars = rtl92s_deinit_sw_vars,
.read_eeprom_info = rtl92se_read_eeprom_info,

View File

@ -1381,9 +1381,9 @@ static u8 _rtl8723e_get_chnl_group(u8 chnl)
return group;
}
static void _rtl8723e_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail,
u8 *hwinfo)
static noinline_for_stack void
_rtl8723e_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail, u8 *hwinfo)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));

View File

@ -183,7 +183,7 @@ static bool is_fw_header(struct rtlwifi_firmware_header *hdr)
return (le16_to_cpu(hdr->signature) & 0xfff0) == 0x2300;
}
static struct rtl_hal_ops rtl8723e_hal_ops = {
static const struct rtl_hal_ops rtl8723e_hal_ops = {
.init_sw_vars = rtl8723e_init_sw_vars,
.deinit_sw_vars = rtl8723e_deinit_sw_vars,
.read_eeprom_info = rtl8723e_read_eeprom_info,

View File

@ -1935,9 +1935,9 @@ static void _rtl8723be_read_power_value_fromprom(struct ieee80211_hw *hw,
}
}
static void _rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail,
u8 *hwinfo)
static noinline_for_stack void
_rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail, u8 *hwinfo)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));

View File

@ -187,7 +187,7 @@ static bool is_fw_header(struct rtlwifi_firmware_header *hdr)
return (le16_to_cpu(hdr->signature) & 0xfff0) == 0x5300;
}
static struct rtl_hal_ops rtl8723be_hal_ops = {
static const struct rtl_hal_ops rtl8723be_hal_ops = {
.init_sw_vars = rtl8723be_init_sw_vars,
.deinit_sw_vars = rtl8723be_deinit_sw_vars,
.read_eeprom_info = rtl8723be_read_eeprom_info,

View File

@ -2782,9 +2782,9 @@ static void _rtl8812ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
"eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
}
#endif
static void _rtl8821ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail,
u8 *hwinfo)
static noinline_for_stack void
_rtl8821ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail, u8 *hwinfo)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
@ -3064,10 +3064,12 @@ static void _rtl8821ae_read_adapter_info(struct ieee80211_hw *hw, bool b_pseudo_
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
int params[] = {RTL_EEPROM_ID, EEPROM_VID, EEPROM_DID,
EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
COUNTRY_CODE_WORLD_WIDE_13};
static const int params[] = {
RTL_EEPROM_ID, EEPROM_VID, EEPROM_DID,
EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
COUNTRY_CODE_WORLD_WIDE_13
};
u8 *hwinfo;
if (b_pseudo_test) {

View File

@ -229,7 +229,7 @@ static bool rtl8821ae_get_btc_status(void)
return true;
}
static struct rtl_hal_ops rtl8821ae_hal_ops = {
static const struct rtl_hal_ops rtl8821ae_hal_ops = {
.init_sw_vars = rtl8821ae_init_sw_vars,
.deinit_sw_vars = rtl8821ae_deinit_sw_vars,
.read_eeprom_info = rtl8821ae_read_eeprom_info,

View File

@ -521,7 +521,7 @@ rtw_fw_send_general_info(struct rtw_dev *rtwdev)
u8 h2c_pkt[H2C_PKT_SIZE] = {0};
u16 total_size = H2C_PKT_HDR_SIZE + 4;
if (rtw_chip_wcpu_11n(rtwdev))
if (rtw_chip_wcpu_8051(rtwdev))
return;
rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_GENERAL_INFO);
@ -544,7 +544,7 @@ rtw_fw_send_phydm_info(struct rtw_dev *rtwdev)
u16 total_size = H2C_PKT_HDR_SIZE + 8;
u8 fw_rf_type = 0;
if (rtw_chip_wcpu_11n(rtwdev))
if (rtw_chip_wcpu_8051(rtwdev))
return;
if (hal->rf_type == RF_1T1R)
@ -1480,7 +1480,7 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
bckp[2] = rtw_read8(rtwdev, REG_BCN_CTRL);
if (rtw_chip_wcpu_11n(rtwdev)) {
if (rtw_chip_wcpu_8051(rtwdev)) {
rtw_write32_set(rtwdev, REG_DWBCN0_CTRL, BIT_BCN_VALID);
} else {
pg_addr &= BIT_MASK_BCN_HEAD_1_V1;
@ -1509,7 +1509,7 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
goto restore;
}
if (rtw_chip_wcpu_11n(rtwdev)) {
if (rtw_chip_wcpu_8051(rtwdev)) {
bcn_valid_addr = REG_DWBCN0_CTRL;
bcn_valid_mask = BIT_BCN_VALID;
} else {

View File

@ -41,7 +41,7 @@ void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw,
}
rtw_write32(rtwdev, REG_WMAC_TRXPTCL_CTL, value32);
if (rtw_chip_wcpu_11n(rtwdev))
if (rtw_chip_wcpu_8051(rtwdev))
return;
value32 = rtw_read32(rtwdev, REG_AFE_CTRL1) & ~(BIT_MAC_CLK_SEL);
@ -67,7 +67,7 @@ static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev)
rtw_write8(rtwdev, REG_RSV_CTRL, 0);
if (rtw_chip_wcpu_11n(rtwdev)) {
if (rtw_chip_wcpu_8051(rtwdev)) {
if (rtw_read32(rtwdev, REG_SYS_CFG1) & BIT_LDO)
rtw_write8(rtwdev, REG_LDO_SWR_CTRL, LDO_SEL);
else
@ -278,7 +278,7 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
bool cur_pwr;
int ret;
if (rtw_chip_wcpu_11ac(rtwdev)) {
if (rtw_chip_wcpu_3081(rtwdev)) {
rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr);
/* Check FW still exist or not */
@ -369,7 +369,7 @@ static int __rtw_mac_init_system_cfg_legacy(struct rtw_dev *rtwdev)
static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev)
{
if (rtw_chip_wcpu_11n(rtwdev))
if (rtw_chip_wcpu_8051(rtwdev))
return __rtw_mac_init_system_cfg_legacy(rtwdev);
return __rtw_mac_init_system_cfg(rtwdev);
@ -981,7 +981,7 @@ static int __rtw_download_firmware_legacy(struct rtw_dev *rtwdev,
static
int _rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw)
{
if (rtw_chip_wcpu_11n(rtwdev))
if (rtw_chip_wcpu_8051(rtwdev))
return __rtw_download_firmware_legacy(rtwdev, fw);
return __rtw_download_firmware(rtwdev, fw);
@ -1122,7 +1122,7 @@ static int txdma_queue_mapping(struct rtw_dev *rtwdev)
rtw_write8(rtwdev, REG_CR, 0);
rtw_write8(rtwdev, REG_CR, MAC_TRX_ENABLE);
if (rtw_chip_wcpu_11ac(rtwdev))
if (rtw_chip_wcpu_3081(rtwdev))
rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL);
if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) {
@ -1145,7 +1145,7 @@ int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev)
/* config rsvd page num */
fifo->rsvd_drv_pg_num = chip->rsvd_drv_pg_num;
fifo->txff_pg_num = chip->txff_size / chip->page_size;
if (rtw_chip_wcpu_11n(rtwdev))
if (rtw_chip_wcpu_8051(rtwdev))
fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num;
else
fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num +
@ -1163,7 +1163,7 @@ int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev)
fifo->rsvd_boundary = fifo->txff_pg_num - fifo->rsvd_pg_num;
cur_pg_addr = fifo->txff_pg_num;
if (rtw_chip_wcpu_11ac(rtwdev)) {
if (rtw_chip_wcpu_3081(rtwdev)) {
cur_pg_addr -= csi_buf_pg_num;
fifo->rsvd_csibuf_addr = cur_pg_addr;
cur_pg_addr -= RSVD_PG_FW_TXBUF_NUM;
@ -1292,7 +1292,7 @@ static int priority_queue_cfg(struct rtw_dev *rtwdev)
pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num -
pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num;
if (rtw_chip_wcpu_11n(rtwdev))
if (rtw_chip_wcpu_8051(rtwdev))
return __priority_queue_cfg_legacy(rtwdev, pg_tbl, pubq_num);
else
return __priority_queue_cfg(rtwdev, pg_tbl, pubq_num);
@ -1308,7 +1308,7 @@ static int init_h2c(struct rtw_dev *rtwdev)
u32 h2cq_free;
u32 wp, rp;
if (rtw_chip_wcpu_11n(rtwdev))
if (rtw_chip_wcpu_8051(rtwdev))
return 0;
h2cq_addr = fifo->rsvd_h2cq_addr << TX_PAGE_SIZE_SHIFT;
@ -1375,7 +1375,7 @@ static int rtw_drv_info_cfg(struct rtw_dev *rtwdev)
u8 value8;
rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE);
if (rtw_chip_wcpu_11ac(rtwdev)) {
if (rtw_chip_wcpu_3081(rtwdev)) {
value8 = rtw_read8(rtwdev, REG_TRXFF_BNDY + 1);
value8 &= 0xF0;
/* For rxdesc len = 0 issue */

View File

@ -636,6 +636,7 @@ void rtw_fw_recovery(struct rtw_dev *rtwdev)
if (!test_bit(RTW_FLAG_RESTARTING, rtwdev->flags))
ieee80211_queue_work(rtwdev->hw, &rtwdev->fw_recovery_work);
}
EXPORT_SYMBOL(rtw_fw_recovery);
static void __fw_recovery_work(struct rtw_dev *rtwdev)
{
@ -1765,7 +1766,7 @@ static void __update_firmware_info_legacy(struct rtw_dev *rtwdev,
static void update_firmware_info(struct rtw_dev *rtwdev,
struct rtw_fw_state *fw)
{
if (rtw_chip_wcpu_11n(rtwdev))
if (rtw_chip_wcpu_8051(rtwdev))
__update_firmware_info_legacy(rtwdev, fw);
else
__update_firmware_info(rtwdev, fw);
@ -2218,7 +2219,6 @@ EXPORT_SYMBOL(rtw_core_deinit);
int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
{
bool sta_mode_only = rtwdev->hci.type == RTW_HCI_TYPE_SDIO;
struct rtw_hal *hal = &rtwdev->hal;
int max_tx_headroom = 0;
int ret;
@ -2248,12 +2248,9 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
ieee80211_hw_set(hw, TX_AMSDU);
ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
if (sta_mode_only)
hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
else
hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_ADHOC);
hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_ADHOC);
hw->wiphy->available_antennas_tx = hal->antenna_tx;
hw->wiphy->available_antennas_rx = hal->antenna_rx;
@ -2264,7 +2261,7 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
hw->wiphy->max_scan_ssids = RTW_SCAN_MAX_SSIDS;
hw->wiphy->max_scan_ie_len = rtw_get_max_scan_ie_len(rtwdev);
if (!sta_mode_only && rtwdev->chip->id == RTW_CHIP_TYPE_8822C) {
if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) {
hw->wiphy->iface_combinations = rtw_iface_combs;
hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtw_iface_combs);
}

View File

@ -1173,8 +1173,8 @@ struct rtw_pwr_track_tbl {
};
enum rtw_wlan_cpu {
RTW_WCPU_11AC,
RTW_WCPU_11N,
RTW_WCPU_3081,
RTW_WCPU_8051,
};
enum rtw_fw_fifo_sel {
@ -2166,14 +2166,14 @@ static inline void rtw_chip_efuse_grant_off(struct rtw_dev *rtwdev)
rtwdev->chip->ops->efuse_grant(rtwdev, false);
}
static inline bool rtw_chip_wcpu_11n(struct rtw_dev *rtwdev)
static inline bool rtw_chip_wcpu_8051(struct rtw_dev *rtwdev)
{
return rtwdev->chip->wlan_cpu == RTW_WCPU_11N;
return rtwdev->chip->wlan_cpu == RTW_WCPU_8051;
}
static inline bool rtw_chip_wcpu_11ac(struct rtw_dev *rtwdev)
static inline bool rtw_chip_wcpu_3081(struct rtw_dev *rtwdev)
{
return rtwdev->chip->wlan_cpu == RTW_WCPU_11AC;
return rtwdev->chip->wlan_cpu == RTW_WCPU_3081;
}
static inline bool rtw_chip_has_rx_ldpc(struct rtw_dev *rtwdev)

View File

@ -405,7 +405,7 @@ static void rtw_pci_reset_buf_desc(struct rtw_dev *rtwdev)
dma = rtwpci->tx_rings[RTW_TX_QUEUE_BCN].r.dma;
rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_BCNQ, dma);
if (!rtw_chip_wcpu_11n(rtwdev)) {
if (!rtw_chip_wcpu_8051(rtwdev)) {
len = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.len;
dma = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.dma;
rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.rp = 0;
@ -467,7 +467,7 @@ static void rtw_pci_reset_buf_desc(struct rtw_dev *rtwdev)
rtw_write32(rtwdev, RTK_PCI_TXBD_RWPTR_CLR, 0xffffffff);
/* reset H2C Queue index in a single write */
if (rtw_chip_wcpu_11ac(rtwdev))
if (rtw_chip_wcpu_3081(rtwdev))
rtw_write32_set(rtwdev, RTK_PCI_TXBD_H2CQ_CSR,
BIT_CLR_H2CQ_HOST_IDX | BIT_CLR_H2CQ_HW_IDX);
}
@ -487,7 +487,7 @@ static void rtw_pci_enable_interrupt(struct rtw_dev *rtwdev,
rtw_write32(rtwdev, RTK_PCI_HIMR0, rtwpci->irq_mask[0] & ~imr0_unmask);
rtw_write32(rtwdev, RTK_PCI_HIMR1, rtwpci->irq_mask[1]);
if (rtw_chip_wcpu_11ac(rtwdev))
if (rtw_chip_wcpu_3081(rtwdev))
rtw_write32(rtwdev, RTK_PCI_HIMR3, rtwpci->irq_mask[3]);
rtwpci->irq_enabled = true;
@ -507,7 +507,7 @@ static void rtw_pci_disable_interrupt(struct rtw_dev *rtwdev,
rtw_write32(rtwdev, RTK_PCI_HIMR0, 0);
rtw_write32(rtwdev, RTK_PCI_HIMR1, 0);
if (rtw_chip_wcpu_11ac(rtwdev))
if (rtw_chip_wcpu_3081(rtwdev))
rtw_write32(rtwdev, RTK_PCI_HIMR3, 0);
rtwpci->irq_enabled = false;
@ -1125,7 +1125,7 @@ static void rtw_pci_irq_recognized(struct rtw_dev *rtwdev,
irq_status[0] = rtw_read32(rtwdev, RTK_PCI_HISR0);
irq_status[1] = rtw_read32(rtwdev, RTK_PCI_HISR1);
if (rtw_chip_wcpu_11ac(rtwdev))
if (rtw_chip_wcpu_3081(rtwdev))
irq_status[3] = rtw_read32(rtwdev, RTK_PCI_HISR3);
else
irq_status[3] = 0;
@ -1134,7 +1134,7 @@ static void rtw_pci_irq_recognized(struct rtw_dev *rtwdev,
irq_status[3] &= rtwpci->irq_mask[3];
rtw_write32(rtwdev, RTK_PCI_HISR0, irq_status[0]);
rtw_write32(rtwdev, RTK_PCI_HISR1, irq_status[1]);
if (rtw_chip_wcpu_11ac(rtwdev))
if (rtw_chip_wcpu_3081(rtwdev))
rtw_write32(rtwdev, RTK_PCI_HISR3, irq_status[3]);
spin_unlock_irqrestore(&rtwpci->hwirq_lock, flags);
@ -1707,6 +1707,43 @@ static void rtw_pci_napi_deinit(struct rtw_dev *rtwdev)
free_netdev(rtwpci->netdev);
}
static pci_ers_result_t rtw_pci_io_err_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
netif_device_detach(netdev);
return PCI_ERS_RESULT_NEED_RESET;
}
static pci_ers_result_t rtw_pci_io_slot_reset(struct pci_dev *pdev)
{
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct rtw_dev *rtwdev = hw->priv;
rtw_fw_recovery(rtwdev);
return PCI_ERS_RESULT_RECOVERED;
}
static void rtw_pci_io_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
/* ack any pending wake events, disable PME */
pci_enable_wake(pdev, PCI_D0, 0);
netif_device_attach(netdev);
}
const struct pci_error_handlers rtw_pci_err_handler = {
.error_detected = rtw_pci_io_err_detected,
.slot_reset = rtw_pci_io_slot_reset,
.resume = rtw_pci_io_resume,
};
EXPORT_SYMBOL(rtw_pci_err_handler);
int rtw_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{

View File

@ -231,6 +231,7 @@ struct rtw_pci {
};
extern const struct dev_pm_ops rtw_pm_ops;
extern const struct pci_error_handlers rtw_pci_err_handler;
int rtw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id);
void rtw_pci_remove(struct pci_dev *pdev);

View File

@ -1882,7 +1882,7 @@ const struct rtw_chip_info rtw8703b_hw_spec = {
.id = RTW_CHIP_TYPE_8703B,
.fw_name = "rtw88/rtw8703b_fw.bin",
.wlan_cpu = RTW_WCPU_11N,
.wlan_cpu = RTW_WCPU_8051,
.tx_pkt_desc_sz = 40,
.tx_buf_desc_sz = 16,
.rx_pkt_desc_sz = 24,

View File

@ -2116,7 +2116,7 @@ const struct rtw_chip_info rtw8723d_hw_spec = {
.ops = &rtw8723d_ops,
.id = RTW_CHIP_TYPE_8723D,
.fw_name = "rtw88/rtw8723d_fw.bin",
.wlan_cpu = RTW_WCPU_11N,
.wlan_cpu = RTW_WCPU_8051,
.tx_pkt_desc_sz = 40,
.tx_buf_desc_sz = 16,
.rx_pkt_desc_sz = 24,

View File

@ -23,6 +23,7 @@ static struct pci_driver rtw_8723de_driver = {
.remove = rtw_pci_remove,
.driver.pm = &rtw_pm_ops,
.shutdown = rtw_pci_shutdown,
.err_handler = &rtw_pci_err_handler,
};
module_pci_driver(rtw_8723de_driver);

View File

@ -1038,7 +1038,7 @@ const struct rtw_chip_info rtw8812a_hw_spec = {
.ops = &rtw8812a_ops,
.id = RTW_CHIP_TYPE_8812A,
.fw_name = "rtw88/rtw8812a_fw.bin",
.wlan_cpu = RTW_WCPU_11N,
.wlan_cpu = RTW_WCPU_8051,
.tx_pkt_desc_sz = 40,
.tx_buf_desc_sz = 16,
.rx_pkt_desc_sz = 24,

View File

@ -2180,7 +2180,7 @@ const struct rtw_chip_info rtw8814a_hw_spec = {
.ops = &rtw8814a_ops,
.id = RTW_CHIP_TYPE_8814A,
.fw_name = "rtw88/rtw8814a_fw.bin",
.wlan_cpu = RTW_WCPU_11AC,
.wlan_cpu = RTW_WCPU_3081,
.tx_pkt_desc_sz = 40,
.tx_buf_desc_sz = 16,
.rx_pkt_desc_sz = 24,

View File

@ -1138,7 +1138,7 @@ const struct rtw_chip_info rtw8821a_hw_spec = {
.ops = &rtw8821a_ops,
.id = RTW_CHIP_TYPE_8821A,
.fw_name = "rtw88/rtw8821a_fw.bin",
.wlan_cpu = RTW_WCPU_11N,
.wlan_cpu = RTW_WCPU_8051,
.tx_pkt_desc_sz = 40,
.tx_buf_desc_sz = 16,
.rx_pkt_desc_sz = 24,

View File

@ -1973,7 +1973,7 @@ const struct rtw_chip_info rtw8821c_hw_spec = {
.ops = &rtw8821c_ops,
.id = RTW_CHIP_TYPE_8821C,
.fw_name = "rtw88/rtw8821c_fw.bin",
.wlan_cpu = RTW_WCPU_11AC,
.wlan_cpu = RTW_WCPU_3081,
.tx_pkt_desc_sz = 48,
.tx_buf_desc_sz = 16,
.rx_pkt_desc_sz = 24,

View File

@ -27,6 +27,7 @@ static struct pci_driver rtw_8821ce_driver = {
.remove = rtw_pci_remove,
.driver.pm = &rtw_pm_ops,
.shutdown = rtw_pci_shutdown,
.err_handler = &rtw_pci_err_handler,
};
module_pci_driver(rtw_8821ce_driver);

View File

@ -2514,7 +2514,7 @@ const struct rtw_chip_info rtw8822b_hw_spec = {
.ops = &rtw8822b_ops,
.id = RTW_CHIP_TYPE_8822B,
.fw_name = "rtw88/rtw8822b_fw.bin",
.wlan_cpu = RTW_WCPU_11AC,
.wlan_cpu = RTW_WCPU_3081,
.tx_pkt_desc_sz = 48,
.tx_buf_desc_sz = 16,
.rx_pkt_desc_sz = 24,

View File

@ -23,6 +23,7 @@ static struct pci_driver rtw_8822be_driver = {
.remove = rtw_pci_remove,
.driver.pm = &rtw_pm_ops,
.shutdown = rtw_pci_shutdown,
.err_handler = &rtw_pci_err_handler,
};
module_pci_driver(rtw_8822be_driver);

View File

@ -5333,7 +5333,7 @@ const struct rtw_chip_info rtw8822c_hw_spec = {
.ops = &rtw8822c_ops,
.id = RTW_CHIP_TYPE_8822C,
.fw_name = "rtw88/rtw8822c_fw.bin",
.wlan_cpu = RTW_WCPU_11AC,
.wlan_cpu = RTW_WCPU_3081,
.tx_pkt_desc_sz = 48,
.tx_buf_desc_sz = 16,
.rx_pkt_desc_sz = 24,

View File

@ -27,6 +27,7 @@ static struct pci_driver rtw_8822ce_driver = {
.remove = rtw_pci_remove,
.driver.pm = &rtw_pm_ops,
.shutdown = rtw_pci_shutdown,
.err_handler = &rtw_pci_err_handler,
};
module_pci_driver(rtw_8822ce_driver);

View File

@ -547,7 +547,7 @@ static int rtw_sdio_check_free_txpg(struct rtw_dev *rtwdev, u8 queue,
{
unsigned int pages_free, pages_needed;
if (rtw_chip_wcpu_11n(rtwdev)) {
if (rtw_chip_wcpu_8051(rtwdev)) {
u32 free_txpg;
free_txpg = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG);
@ -1030,7 +1030,7 @@ static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev)
u32 rx_len, hisr, total_rx_bytes = 0;
do {
if (rtw_chip_wcpu_11n(rtwdev))
if (rtw_chip_wcpu_8051(rtwdev))
rx_len = rtw_read16(rtwdev, REG_SDIO_RX0_REQ_LEN);
else
rx_len = rtw_read32(rtwdev, REG_SDIO_RX0_REQ_LEN);
@ -1042,7 +1042,7 @@ static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev)
total_rx_bytes += rx_len;
if (rtw_chip_wcpu_11n(rtwdev)) {
if (rtw_chip_wcpu_8051(rtwdev)) {
/* Stop if no more RX requests are pending, even if
* rx_len could be greater than zero in the next
* iteration. This is needed because the RX buffer may
@ -1054,7 +1054,7 @@ static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev)
*/
hisr = rtw_read32(rtwdev, REG_SDIO_HISR);
} else {
/* RTW_WCPU_11AC chips have improved hardware or
/* RTW_WCPU_3081 chips have improved hardware or
* firmware and can use rx_len unconditionally.
*/
hisr = REG_SDIO_HISR_RX_REQUEST;

View File

@ -170,22 +170,26 @@ int rtw89_iterate_entity_chan(struct rtw89_dev *rtwdev,
static void __rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx idx,
const struct cfg80211_chan_def *chandef,
bool from_stack)
const struct cfg80211_chan_def *chandef)
{
struct rtw89_hal *hal = &rtwdev->hal;
hal->chanctx[idx].chandef = *chandef;
if (from_stack)
set_bit(idx, hal->entity_map);
}
void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx idx,
const struct cfg80211_chan_def *chandef)
{
__rtw89_config_entity_chandef(rtwdev, idx, chandef, true);
struct rtw89_hal *hal = &rtwdev->hal;
if (!chandef) {
clear_bit(idx, hal->entity_map);
return;
}
__rtw89_config_entity_chandef(rtwdev, idx, chandef);
set_bit(idx, hal->entity_map);
}
void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
@ -227,7 +231,7 @@ static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev)
struct cfg80211_chan_def chandef = {0};
rtw89_get_default_chandef(&chandef);
__rtw89_config_entity_chandef(rtwdev, RTW89_CHANCTX_0, &chandef, false);
__rtw89_config_entity_chandef(rtwdev, RTW89_CHANCTX_0, &chandef);
}
void rtw89_entity_init(struct rtw89_dev *rtwdev)
@ -265,6 +269,8 @@ static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif;
int idx;
w->registered_chanctxs = bitmap_weight(hal->entity_map, NUM_OF_RTW89_CHANCTX);
for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_CHANCTX) {
cfg = hal->chanctx[idx].cfg;
if (!cfg) {
@ -473,7 +479,8 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
bitmap_zero(recalc_map, NUM_OF_RTW89_CHANCTX);
fallthrough;
case 0:
rtw89_config_default_chandef(rtwdev);
if (!w.registered_chanctxs)
rtw89_config_default_chandef(rtwdev);
set_bit(RTW89_CHANCTX_0, recalc_map);
fallthrough;
case 1:
@ -953,6 +960,7 @@ static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev)
}
sel.bind_vif[i] = rtwvif_link;
rtw89_p2p_disable_all_noa(rtwdev, rtwvif_link, NULL);
}
ret = rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_fill_role_iterator, &sel);
@ -1265,6 +1273,8 @@ static int __rtw89_mcc_calc_pattern_anchor(struct rtw89_dev *rtwdev,
if (bcn_ofst < RTW89_MCC_MIN_RX_BCN_TIME)
small_bcn_ofst = true;
else if (bcn_ofst < aux->duration - aux->limit.max_toa)
small_bcn_ofst = true;
else if (mcc_intvl - bcn_ofst < RTW89_MCC_MIN_RX_BCN_TIME)
small_bcn_ofst = false;
else
@ -1595,6 +1605,35 @@ static bool rtw89_mcc_duration_decision_on_bt(struct rtw89_dev *rtwdev)
return false;
}
void rtw89_mcc_prepare_done_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
mcc_prepare_done_work.work);
lockdep_assert_wiphy(wiphy);
ieee80211_wake_queues(rtwdev->hw);
}
static void rtw89_mcc_prepare(struct rtw89_dev *rtwdev, bool start)
{
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
struct rtw89_mcc_config *config = &mcc->config;
if (start) {
ieee80211_stop_queues(rtwdev->hw);
wiphy_delayed_work_queue(rtwdev->hw->wiphy,
&rtwdev->mcc_prepare_done_work,
usecs_to_jiffies(config->prepare_delay));
} else {
wiphy_delayed_work_queue(rtwdev->hw->wiphy,
&rtwdev->mcc_prepare_done_work, 0);
wiphy_delayed_work_flush(rtwdev->hw->wiphy,
&rtwdev->mcc_prepare_done_work);
}
}
static int rtw89_mcc_fill_start_tsf(struct rtw89_dev *rtwdev)
{
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
@ -1630,6 +1669,8 @@ static int rtw89_mcc_fill_start_tsf(struct rtw89_dev *rtwdev)
config->start_tsf = start_tsf;
config->start_tsf_in_aux_domain = tsf_aux + start_tsf - tsf;
config->prepare_delay = start_tsf - tsf;
return 0;
}
@ -2177,6 +2218,18 @@ static void rtw89_mcc_stop_beacon_noa(struct rtw89_dev *rtwdev)
rtw89_mcc_handle_beacon_noa(rtwdev, false);
}
static bool rtw89_mcc_ignore_bcn(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role)
{
enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
if (role->is_go)
return true;
else if (chip_gen == RTW89_CHIP_BE && role->is_gc)
return true;
else
return false;
}
static int rtw89_mcc_start(struct rtw89_dev *rtwdev)
{
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
@ -2200,6 +2253,15 @@ static int rtw89_mcc_start(struct rtw89_dev *rtwdev)
else
mcc->mode = RTW89_MCC_MODE_GC_STA;
if (rtw89_mcc_ignore_bcn(rtwdev, ref)) {
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, false);
} else if (rtw89_mcc_ignore_bcn(rtwdev, aux)) {
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, false);
} else {
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, ref->rtwvif_link, true);
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, aux->rtwvif_link, true);
}
rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC sel mode: %d\n", mcc->mode);
mcc->group = RTW89_MCC_DFLT_GROUP;
@ -2219,6 +2281,8 @@ static int rtw89_mcc_start(struct rtw89_dev *rtwdev)
rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_START);
rtw89_mcc_start_beacon_noa(rtwdev);
rtw89_mcc_prepare(rtwdev, true);
return 0;
}
@ -2307,6 +2371,8 @@ static void rtw89_mcc_stop(struct rtw89_dev *rtwdev,
rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_STOP);
rtw89_mcc_stop_beacon_noa(rtwdev);
rtw89_mcc_prepare(rtwdev, false);
}
static int rtw89_mcc_update(struct rtw89_dev *rtwdev)
@ -2362,15 +2428,44 @@ static int rtw89_mcc_update(struct rtw89_dev *rtwdev)
return 0;
}
static void rtw89_mcc_detect_connection(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *role)
{
struct ieee80211_vif *vif;
int ret;
ret = rtw89_core_send_nullfunc(rtwdev, role->rtwvif_link, true, false,
RTW89_MCC_PROBE_TIMEOUT);
if (ret)
role->probe_count++;
else
role->probe_count = 0;
if (role->probe_count < RTW89_MCC_PROBE_MAX_TRIES)
return;
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"MCC <macid %d> can not detect AP\n", role->rtwvif_link->mac_id);
vif = rtwvif_link_to_vif(role->rtwvif_link);
ieee80211_connection_loss(vif);
}
static void rtw89_mcc_track(struct rtw89_dev *rtwdev)
{
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
struct rtw89_mcc_config *config = &mcc->config;
struct rtw89_mcc_pattern *pattern = &config->pattern;
struct rtw89_mcc_role *ref = &mcc->role_ref;
struct rtw89_mcc_role *aux = &mcc->role_aux;
u16 tolerance;
u16 bcn_ofst;
u16 diff;
if (rtw89_mcc_ignore_bcn(rtwdev, ref))
rtw89_mcc_detect_connection(rtwdev, aux);
else if (rtw89_mcc_ignore_bcn(rtwdev, aux))
rtw89_mcc_detect_connection(rtwdev, ref);
if (mcc->mode != RTW89_MCC_MODE_GC_STA)
return;
@ -2619,6 +2714,201 @@ void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev)
rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_CHANGE_DFLT);
}
static enum rtw89_mr_wtype __rtw89_query_mr_wtype(struct rtw89_dev *rtwdev)
{
struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt;
enum rtw89_chanctx_idx chanctx_idx;
struct ieee80211_vif *vif;
struct rtw89_vif *rtwvif;
unsigned int num_mld = 0;
unsigned int num_ml = 0;
unsigned int cnt = 0;
u8 role_idx;
u8 idx;
for (role_idx = 0; role_idx < RTW89_MAX_INTERFACE_NUM; role_idx++) {
rtwvif = mgnt->active_roles[role_idx];
if (!rtwvif)
continue;
cnt++;
vif = rtwvif_to_vif(rtwvif);
if (!ieee80211_vif_is_mld(vif))
continue;
num_mld++;
for (idx = 0; idx < __RTW89_MLD_MAX_LINK_NUM; idx++) {
chanctx_idx = mgnt->chanctx_tbl[role_idx][idx];
if (chanctx_idx != RTW89_CHANCTX_IDLE)
num_ml++;
}
}
if (num_mld > 1)
goto err;
switch (cnt) {
case 0:
return RTW89_MR_WTYPE_NONE;
case 1:
if (!num_mld)
return RTW89_MR_WTYPE_NONMLD;
switch (num_ml) {
case 1:
return RTW89_MR_WTYPE_MLD1L1R;
case 2:
return RTW89_MR_WTYPE_MLD2L1R;
default:
break;
}
break;
case 2:
if (!num_mld)
return RTW89_MR_WTYPE_NONMLD_NONMLD;
switch (num_ml) {
case 1:
return RTW89_MR_WTYPE_MLD1L1R_NONMLD;
case 2:
return RTW89_MR_WTYPE_MLD2L1R_NONMLD;
default:
break;
}
break;
default:
break;
}
err:
rtw89_warn(rtwdev, "%s: unhandled cnt %u mld %u ml %u\n", __func__,
cnt, num_mld, num_ml);
return RTW89_MR_WTYPE_UNKNOWN;
}
static enum rtw89_mr_wmode __rtw89_query_mr_wmode(struct rtw89_dev *rtwdev,
u8 inst_idx)
{
struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt;
unsigned int num[NUM_NL80211_IFTYPES] = {};
enum rtw89_chanctx_idx chanctx_idx;
struct ieee80211_vif *vif;
struct rtw89_vif *rtwvif;
unsigned int cnt = 0;
u8 role_idx;
if (unlikely(inst_idx >= __RTW89_MLD_MAX_LINK_NUM))
return RTW89_MR_WMODE_UNKNOWN;
for (role_idx = 0; role_idx < RTW89_MAX_INTERFACE_NUM; role_idx++) {
chanctx_idx = mgnt->chanctx_tbl[role_idx][inst_idx];
if (chanctx_idx == RTW89_CHANCTX_IDLE)
continue;
rtwvif = mgnt->active_roles[role_idx];
if (unlikely(!rtwvif))
continue;
vif = rtwvif_to_vif(rtwvif);
num[vif->type]++;
cnt++;
}
switch (cnt) {
case 0:
return RTW89_MR_WMODE_NONE;
case 1:
if (num[NL80211_IFTYPE_STATION])
return RTW89_MR_WMODE_1CLIENT;
if (num[NL80211_IFTYPE_AP])
return RTW89_MR_WMODE_1AP;
break;
case 2:
if (num[NL80211_IFTYPE_STATION] == 2)
return RTW89_MR_WMODE_2CLIENTS;
if (num[NL80211_IFTYPE_AP] == 2)
return RTW89_MR_WMODE_2APS;
if (num[NL80211_IFTYPE_STATION] && num[NL80211_IFTYPE_AP])
return RTW89_MR_WMODE_1AP_1CLIENT;
break;
default:
break;
}
rtw89_warn(rtwdev, "%s: unhandled cnt %u\n", __func__, cnt);
return RTW89_MR_WMODE_UNKNOWN;
}
static enum rtw89_mr_ctxtype __rtw89_query_mr_ctxtype(struct rtw89_dev *rtwdev,
u8 inst_idx)
{
struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt;
DECLARE_BITMAP(map, NUM_OF_RTW89_CHANCTX) = {};
unsigned int num[RTW89_BAND_NUM] = {};
enum rtw89_chanctx_idx chanctx_idx;
const struct rtw89_chan *chan;
unsigned int cnt = 0;
u8 role_idx;
if (unlikely(inst_idx >= __RTW89_MLD_MAX_LINK_NUM))
return RTW89_MR_CTX_UNKNOWN;
for (role_idx = 0; role_idx < RTW89_MAX_INTERFACE_NUM; role_idx++) {
chanctx_idx = mgnt->chanctx_tbl[role_idx][inst_idx];
if (chanctx_idx == RTW89_CHANCTX_IDLE)
continue;
if (__test_and_set_bit(chanctx_idx, map))
continue;
chan = rtw89_chan_get(rtwdev, chanctx_idx);
num[chan->band_type]++;
cnt++;
}
switch (cnt) {
case 0:
return RTW89_MR_CTX_NONE;
case 1:
if (num[RTW89_BAND_2G])
return RTW89_MR_CTX1_2GHZ;
if (num[RTW89_BAND_5G])
return RTW89_MR_CTX1_5GHZ;
if (num[RTW89_BAND_6G])
return RTW89_MR_CTX1_6GHZ;
break;
case 2:
if (num[RTW89_BAND_2G] == 2)
return RTW89_MR_CTX2_2GHZ;
if (num[RTW89_BAND_5G] == 2)
return RTW89_MR_CTX2_5GHZ;
if (num[RTW89_BAND_6G] == 2)
return RTW89_MR_CTX2_6GHZ;
if (num[RTW89_BAND_2G] && num[RTW89_BAND_5G])
return RTW89_MR_CTX2_2GHZ_5GHZ;
if (num[RTW89_BAND_2G] && num[RTW89_BAND_6G])
return RTW89_MR_CTX2_2GHZ_6GHZ;
if (num[RTW89_BAND_5G] && num[RTW89_BAND_6G])
return RTW89_MR_CTX2_5GHZ_6GHZ;
break;
default:
break;
}
rtw89_warn(rtwdev, "%s: unhandled cnt %u\n", __func__, cnt);
return RTW89_MR_CTX_UNKNOWN;
}
void rtw89_query_mr_chanctx_info(struct rtw89_dev *rtwdev, u8 inst_idx,
struct rtw89_mr_chanctx_info *info)
{
lockdep_assert_wiphy(rtwdev->hw->wiphy);
info->wtype = __rtw89_query_mr_wtype(rtwdev);
info->wmode = __rtw89_query_mr_wmode(rtwdev, inst_idx);
info->ctxtype = __rtw89_query_mr_ctxtype(rtwdev, inst_idx);
}
void rtw89_chanctx_track(struct rtw89_dev *rtwdev)
{
struct rtw89_hal *hal = &rtwdev->hal;
@ -2782,10 +3072,9 @@ int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
clear_bit(cfg->idx, hal->entity_map);
rtw89_config_entity_chandef(rtwdev, cfg->idx, NULL);
}
void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
@ -2816,6 +3105,9 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
rtwvif_link->chanctx_assigned = true;
cfg->ref_count++;
if (rtwdev->scanning)
rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
if (list_empty(&rtwvif->mgnt_entry))
list_add_tail(&rtwvif->mgnt_entry, &mgnt->active_list);
@ -2855,6 +3147,9 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
rtwvif_link->chanctx_assigned = false;
cfg->ref_count--;
if (rtwdev->scanning)
rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
if (!rtw89_vif_is_active_role(rtwvif))
list_del_init(&rtwvif->mgnt_entry);
@ -2906,3 +3201,35 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
break;
}
}
int rtw89_chanctx_ops_reassign_vif(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *old_ctx,
struct ieee80211_chanctx_conf *new_ctx,
bool replace)
{
int ret;
rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif_link, old_ctx);
if (!replace)
goto assign;
rtw89_chanctx_ops_remove(rtwdev, old_ctx);
ret = rtw89_chanctx_ops_add(rtwdev, new_ctx);
if (ret) {
rtw89_err(rtwdev, "%s: failed to add chanctx: %d\n",
__func__, ret);
return ret;
}
assign:
ret = rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif_link, new_ctx);
if (ret) {
rtw89_err(rtwdev, "%s: failed to assign chanctx: %d\n",
__func__, ret);
return ret;
}
return 0;
}

View File

@ -19,6 +19,9 @@
#define RTW89_MCC_MIN_RX_BCN_TIME 10
#define RTW89_MCC_DFLT_BCN_OFST_TIME 40
#define RTW89_MCC_PROBE_TIMEOUT 100
#define RTW89_MCC_PROBE_MAX_TRIES 3
#define RTW89_MCC_MIN_GO_DURATION \
(RTW89_MCC_EARLY_TX_BCN_TIME + RTW89_MCC_MIN_RX_BCN_TIME)
@ -28,7 +31,7 @@
#define RTW89_MCC_DFLT_GROUP 0
#define RTW89_MCC_NEXT_GROUP(cur) (((cur) + 1) % 4)
#define RTW89_MCC_DFLT_TX_NULL_EARLY 3
#define RTW89_MCC_DFLT_TX_NULL_EARLY 7
#define RTW89_MCC_DFLT_COURTESY_SLOT 3
#define RTW89_MCC_REQ_COURTESY_TIME 5
@ -41,6 +44,49 @@
#define NUM_OF_RTW89_MCC_ROLES 2
enum rtw89_mr_wtype {
RTW89_MR_WTYPE_NONE,
RTW89_MR_WTYPE_NONMLD,
RTW89_MR_WTYPE_MLD1L1R,
RTW89_MR_WTYPE_MLD2L1R,
RTW89_MR_WTYPE_MLD2L2R,
RTW89_MR_WTYPE_NONMLD_NONMLD,
RTW89_MR_WTYPE_MLD1L1R_NONMLD,
RTW89_MR_WTYPE_MLD2L1R_NONMLD,
RTW89_MR_WTYPE_MLD2L2R_NONMLD,
RTW89_MR_WTYPE_UNKNOWN,
};
enum rtw89_mr_wmode {
RTW89_MR_WMODE_NONE,
RTW89_MR_WMODE_1CLIENT,
RTW89_MR_WMODE_1AP,
RTW89_MR_WMODE_1AP_1CLIENT,
RTW89_MR_WMODE_2CLIENTS,
RTW89_MR_WMODE_2APS,
RTW89_MR_WMODE_UNKNOWN,
};
enum rtw89_mr_ctxtype {
RTW89_MR_CTX_NONE,
RTW89_MR_CTX1_2GHZ,
RTW89_MR_CTX1_5GHZ,
RTW89_MR_CTX1_6GHZ,
RTW89_MR_CTX2_2GHZ,
RTW89_MR_CTX2_5GHZ,
RTW89_MR_CTX2_6GHZ,
RTW89_MR_CTX2_2GHZ_5GHZ,
RTW89_MR_CTX2_2GHZ_6GHZ,
RTW89_MR_CTX2_5GHZ_6GHZ,
RTW89_MR_CTX_UNKNOWN,
};
struct rtw89_mr_chanctx_info {
enum rtw89_mr_wtype wtype;
enum rtw89_mr_wmode wmode;
enum rtw89_mr_ctxtype ctxtype;
};
enum rtw89_chanctx_pause_reasons {
RTW89_CHANCTX_PAUSE_REASON_HW_SCAN,
RTW89_CHANCTX_PAUSE_REASON_ROC,
@ -58,6 +104,7 @@ struct rtw89_chanctx_cb_parm {
};
struct rtw89_entity_weight {
unsigned int registered_chanctxs;
unsigned int active_chanctxs;
unsigned int active_roles;
};
@ -116,6 +163,8 @@ void rtw89_chanctx_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev);
void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_changes change);
void rtw89_query_mr_chanctx_info(struct rtw89_dev *rtwdev, u8 inst_idx,
struct rtw89_mr_chanctx_info *info);
void rtw89_chanctx_track(struct rtw89_dev *rtwdev);
void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
const struct rtw89_chanctx_pause_parm *parm);
@ -129,6 +178,8 @@ const struct rtw89_chan *__rtw89_mgnt_chan_get(struct rtw89_dev *rtwdev,
#define rtw89_mgnt_chan_get(rtwdev, link_index) \
__rtw89_mgnt_chan_get(rtwdev, __func__, link_index)
void rtw89_mcc_prepare_done_work(struct wiphy *wiphy, struct wiphy_work *work);
int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx);
void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
@ -142,5 +193,10 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx);
int rtw89_chanctx_ops_reassign_vif(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *old_ctx,
struct ieee80211_chanctx_conf *new_ctx,
bool replace);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -224,6 +224,13 @@ enum btc_wl_mode {
BTC_WL_MODE_NUM,
};
enum btc_mlo_rf_combin {
BTC_MLO_RF_2_PLUS_0 = 0,
BTC_MLO_RF_0_PLUS_2 = 1,
BTC_MLO_RF_1_PLUS_1 = 2,
BTC_MLO_RF_2_PLUS_2 = 3,
};
enum btc_wl_gpio_debug {
BTC_DBG_GNT_BT = 0,
BTC_DBG_GNT_WL = 1,

View File

@ -204,6 +204,7 @@ static const struct ieee80211_iface_combination rtw89_iface_combs[] = {
};
static const u8 rtw89_ext_capa_sta[] = {
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
};
@ -1722,7 +1723,7 @@ static u16 rtw89_core_get_phy_status_ie_len(struct rtw89_dev *rtwdev,
},
[RTW89_CHIP_BE] = {
32, 40, 24, 24, 8, 8, 8, 8, VAR_LEN, 8, VAR_LEN, 176, VAR_LEN,
VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, 16, 24, VAR_LEN,
VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, 88, 56, VAR_LEN,
VAR_LEN, VAR_LEN, 0, 24, 24, 24, 24, 32, 32, 32, 32
},
};
@ -1917,6 +1918,8 @@ static int rtw89_core_rx_parse_phy_sts(struct rtw89_dev *rtwdev,
return -EINVAL;
pos = phy_ppdu->buf + PHY_STS_HDR_LEN;
if (phy_ppdu->hdr_2_en)
pos += PHY_STS_HDR_LEN;
end = phy_ppdu->buf + phy_ppdu->len;
while (pos < end) {
const struct rtw89_phy_sts_iehdr *iehdr = pos;
@ -2158,6 +2161,11 @@ static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev,
if (rx_status->band != NL80211_BAND_6GHZ)
return;
if (unlikely(!(rtwdev->chip->support_bands & BIT(NL80211_BAND_6GHZ)))) {
rtw89_debug(rtwdev, RTW89_DBG_UNEXP, "invalid rx on unsupported 6 GHz\n");
return;
}
ssid_ie = cfg80211_find_ie(WLAN_EID_SSID, ies, skb->len);
list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) {
@ -2477,6 +2485,41 @@ static void rtw89_core_update_rx_freq_from_ie(struct rtw89_dev *rtwdev,
rx_status->freq = ieee80211_channel_to_frequency(chan, rx_status->band);
}
static void rtw89_core_correct_mcc_chan(struct rtw89_dev *rtwdev,
struct rtw89_rx_desc_info *desc_info,
struct ieee80211_rx_status *rx_status,
struct rtw89_rx_phy_ppdu *phy_ppdu)
{
enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_sta_link *rtwsta_link;
const struct rtw89_chan *chan;
u8 mac_id = desc_info->mac_id;
enum rtw89_entity_mode mode;
enum nl80211_band band;
mode = rtw89_get_entity_mode(rtwdev);
if (likely(mode != RTW89_ENTITY_MODE_MCC))
return;
if (chip_gen == RTW89_CHIP_BE && phy_ppdu)
mac_id = phy_ppdu->mac_id;
rcu_read_lock();
rtwsta_link = rtw89_assoc_link_rcu_dereference(rtwdev, mac_id);
if (!rtwsta_link)
goto out;
rtwvif_link = rtwsta_link->rtwvif_link;
chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
band = rtw89_hw_to_nl80211_band(chan->band_type);
rx_status->freq = ieee80211_channel_to_frequency(chan->primary_channel, band);
out:
rcu_read_unlock();
}
static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu,
struct rtw89_rx_desc_info *desc_info,
@ -2495,6 +2538,7 @@ static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev,
rtw89_core_update_radiotap(rtwdev, skb_ppdu, rx_status);
rtw89_core_validate_rx_signal(rx_status);
rtw89_core_update_rx_freq_from_ie(rtwdev, skb_ppdu, rx_status);
rtw89_core_correct_mcc_chan(rtwdev, desc_info, rx_status, phy_ppdu);
/* In low power mode, it does RX in thread context. */
local_bh_disable();
@ -2752,9 +2796,11 @@ static void rtw89_core_stats_sta_rx_status(struct rtw89_dev *rtwdev,
}
static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev,
struct sk_buff *skb,
struct rtw89_rx_desc_info *desc_info,
struct ieee80211_rx_status *rx_status)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
const struct cfg80211_chan_def *chandef =
rtw89_chandef_get(rtwdev, RTW89_CHANCTX_0);
u16 data_rate;
@ -2766,6 +2812,10 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev,
rx_status->freq = chandef->chan->center_freq;
rx_status->band = chandef->chan->band;
if (ieee80211_is_beacon(hdr->frame_control) ||
ieee80211_is_probe_resp(hdr->frame_control))
rx_status->boottime_ns = ktime_get_boottime_ns();
if (rtwdev->scanning &&
RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) {
const struct rtw89_chan *cur = rtw89_scan_chan_get(rtwdev);
@ -2922,7 +2972,7 @@ void rtw89_core_rx(struct rtw89_dev *rtwdev,
rx_status = IEEE80211_SKB_RXCB(skb);
memset(rx_status, 0, sizeof(*rx_status));
rtw89_core_update_rx_status(rtwdev, desc_info, rx_status);
rtw89_core_update_rx_status(rtwdev, skb, desc_info, rx_status);
rtw89_core_rx_pkt_hdl(rtwdev, skb, desc_info);
if (desc_info->long_rxdesc &&
BIT(desc_info->frame_type) & PPDU_FILTER_BITMAP)
@ -3330,8 +3380,8 @@ static void rtw89_core_handle_sta_pending_tx(struct rtw89_dev *rtwdev,
rtwvif_link);
}
static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link, bool qos, bool ps)
int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool qos, bool ps, int timeout)
{
struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
int link_id = ieee80211_vif_is_mld(vif) ? rtwvif_link->link_id : -1;
@ -3379,7 +3429,7 @@ static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev,
rcu_read_unlock();
return rtw89_core_tx_kick_off_and_wait(rtwdev, skb, qsel,
RTW89_ROC_TX_TIMEOUT);
timeout);
out:
rcu_read_unlock();
@ -3416,7 +3466,8 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
pause_parm.trigger = rtwvif_link;
rtw89_chanctx_pause(rtwdev, &pause_parm);
ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, true);
ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, true,
RTW89_ROC_TX_TIMEOUT);
if (ret)
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
"roc send null-1 failed: %d\n", ret);
@ -3476,7 +3527,8 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
roc->state = RTW89_ROC_IDLE;
rtw89_config_roc_chandef(rtwdev, rtwvif_link, NULL);
rtw89_chanctx_proceed(rtwdev, NULL);
ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, false);
ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, true, false,
RTW89_ROC_TX_TIMEOUT);
if (ret)
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
"roc send null-0 failed: %d\n", ret);
@ -3742,7 +3794,7 @@ static void rtw89_track_work(struct wiphy *wiphy, struct wiphy_work *work)
lockdep_assert_wiphy(wiphy);
if (test_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags))
if (test_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags))
return;
if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
@ -3967,6 +4019,12 @@ int rtw89_core_sta_link_add(struct rtw89_dev *rtwdev,
rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link,
BTC_ROLE_MSTS_STA_CONN_START);
rtw89_chip_rfk_channel(rtwdev, rtwvif_link);
if (vif->p2p) {
rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta_link,
&rtwsta_link->tx_retry);
rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false, 60);
}
} else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta_link->mac_id, false);
if (ret) {
@ -4151,6 +4209,10 @@ int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev,
}
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
if (vif->p2p)
rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false,
rtwsta_link->tx_retry);
}
rtw89_assoc_link_set(rtwsta_link);
@ -4169,6 +4231,10 @@ int rtw89_core_sta_link_remove(struct rtw89_dev *rtwdev,
rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, false);
rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link,
BTC_ROLE_MSTS_STA_DIS_CONN);
if (vif->p2p)
rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false,
rtwsta_link->tx_retry);
} else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link,
RTW89_ROLE_REMOVE);
@ -4655,6 +4721,43 @@ void rtw89_core_update_beacon_work(struct wiphy *wiphy, struct wiphy_work *work)
rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link);
}
void rtw89_core_csa_beacon_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_vif_link *rtwvif_link =
container_of(work, struct rtw89_vif_link, csa_beacon_work.work);
struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
struct rtw89_dev *rtwdev = rtwvif->rtwdev;
struct ieee80211_bss_conf *bss_conf;
unsigned int delay;
lockdep_assert_wiphy(wiphy);
if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE)
return;
rcu_read_lock();
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
if (!bss_conf->csa_active) {
rcu_read_unlock();
return;
}
delay = ieee80211_tu_to_usec(bss_conf->beacon_int);
rcu_read_unlock();
if (!ieee80211_beacon_cntdwn_is_complete(vif, rtwvif_link->link_id)) {
rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link);
wiphy_delayed_work_queue(wiphy, &rtwvif_link->csa_beacon_work,
usecs_to_jiffies(delay));
} else {
ieee80211_csa_finish(vif, rtwvif_link->link_id);
}
}
int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond)
{
struct completion *cmpl = &wait->completion;
@ -4808,6 +4911,7 @@ void rtw89_core_stop(struct rtw89_dev *rtwdev)
wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_bt_devinfo_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_rfk_chk_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->cfo_track_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->mcc_prepare_done_work);
cancel_delayed_work_sync(&rtwdev->forbid_ba_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->antdiv_work);
@ -5034,6 +5138,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
wiphy_delayed_work_init(&rtwdev->coex_bt_devinfo_work, rtw89_coex_bt_devinfo_work);
wiphy_delayed_work_init(&rtwdev->coex_rfk_chk_work, rtw89_coex_rfk_chk_work);
wiphy_delayed_work_init(&rtwdev->cfo_track_work, rtw89_phy_cfo_track_work);
wiphy_delayed_work_init(&rtwdev->mcc_prepare_done_work, rtw89_mcc_prepare_done_work);
INIT_DELAYED_WORK(&rtwdev->forbid_ba_work, rtw89_forbid_ba_work);
wiphy_delayed_work_init(&rtwdev->antdiv_work, rtw89_phy_antdiv_work);
rtwdev->txq_wq = alloc_workqueue("rtw89_tx_wq", WQ_UNBOUND | WQ_HIGHPRI, 0);
@ -5127,6 +5232,7 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
{
struct ieee80211_bss_conf *bss_conf;
struct rtw89_bb_ctx *bb;
int ret;
if (!rtwvif_link)
return;
@ -5146,6 +5252,14 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
rtw89_phy_config_edcca(rtwdev, bb, false);
rtw89_tas_scan(rtwdev, false);
if (hw_scan) {
ret = rtw89_core_send_nullfunc(rtwdev, rtwvif_link, false, false,
RTW89_SCAN_NULL_TIMEOUT);
if (ret)
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
"scan send null-0 failed: %d\n", ret);
}
rtwdev->scanning = false;
rtw89_for_each_active_bb(rtwdev, bb)
bb->dig.bypass_dig = true;
@ -5239,7 +5353,8 @@ int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
if (unlikely(!ieee80211_vif_is_mld(vif)))
return -EOPNOTSUPP;
if (unlikely(!(usable_links & BIT(link_id)))) {
if (unlikely(link_id >= IEEE80211_MLD_MAX_NUM_LINKS ||
!(usable_links & BIT(link_id)))) {
rtw89_warn(rtwdev, "%s: link id %u is not usable\n", __func__,
link_id);
return -ENOLINK;
@ -5504,6 +5619,7 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
ieee80211_hw_set(hw, WANT_MONITOR_VIF);
ieee80211_hw_set(hw, CHANCTX_STA_CSA);
if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160))
ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
@ -5530,6 +5646,7 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
WIPHY_FLAG_TDLS_EXTERNAL_SETUP |
WIPHY_FLAG_AP_UAPSD |
WIPHY_FLAG_HAS_CHANNEL_SWITCH |
WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK;
if (!chip->support_rnr)

View File

@ -1205,7 +1205,7 @@ struct rtw89_mac_ax_gnt {
struct rtw89_mac_ax_wl_act {
u8 wlan_act_en;
u8 wlan_act;
};
} __packed;
#define RTW89_MAC_AX_COEX_GNT_NR 2
struct rtw89_mac_ax_coex_gnt {
@ -1322,6 +1322,7 @@ enum rtw89_btc_bt_state_cnt {
BTC_BCNT_POLUT_NOW,
BTC_BCNT_POLUT_DIFF,
BTC_BCNT_RATECHG,
BTC_BCNT_BTTXPWR_UPDATE,
BTC_BCNT_NUM,
};
@ -1557,6 +1558,25 @@ struct rtw89_btc_wl_dbcc_info {
u8 role[RTW89_PHY_NUM]; /* role in each phy */
};
struct rtw89_btc_wl_mlo_info {
u8 wmode[RTW89_PHY_NUM]; /* enum phl_mr_wmode */
u8 ch_type[RTW89_PHY_NUM]; /* enum phl_mr_ch_type */
u8 hwb_rf_band[RTW89_PHY_NUM]; /* enum band_type, RF-band for HW-band */
u8 path_rf_band[RTW89_PHY_NUM]; /* enum band_type, RF-band for PHY0/1 */
u8 wtype; /* enum phl_mr_wtype */
u8 mrcx_mode;
u8 mrcx_act_hwb_map;
u8 mrcx_bt_slot_rsp;
u8 rf_combination; /* enum btc_mlo_rf_combin 0:2+0, 1:0+2, 2:1+1,3:2+2 */
u8 mlo_en; /* MLO enable */
u8 mlo_adie; /* a-die count */
u8 dual_hw_band_en; /* both 2 HW-band link exist */
u32 link_status; /* enum mlo_dbcc_mode_type */
};
struct rtw89_btc_wl_active_role {
u8 connected: 1;
u8 pid: 3;
@ -1791,6 +1811,13 @@ union rtw89_btc_bt_state_map {
#define BTC_BT_AFH_GROUP 12
#define BTC_BT_AFH_LE_GROUP 5
struct rtw89_btc_bt_txpwr_desc {
s8 br_dbm;
s8 le_dbm;
u8 br_gain_index;
u8 le_gain_index;
};
struct rtw89_btc_bt_link_info {
struct rtw89_btc_u8_sta_chg profile_cnt;
struct rtw89_btc_bool_sta_chg multi_link;
@ -1800,6 +1827,7 @@ struct rtw89_btc_bt_link_info {
struct rtw89_btc_bt_a2dp_desc a2dp_desc;
struct rtw89_btc_bt_pan_desc pan_desc;
union rtw89_btc_bt_state_map status;
struct rtw89_btc_bt_txpwr_desc bt_txpwr_desc;
u8 sut_pwr_level[BTC_PROFILE_MAX];
u8 golden_rx_shift[BTC_PROFILE_MAX];
@ -1895,6 +1923,7 @@ struct rtw89_btc_wl_info {
struct rtw89_btc_wl_role_info_v8 role_info_v8;
struct rtw89_btc_wl_scan_info scan_info;
struct rtw89_btc_wl_dbcc_info dbcc_info;
struct rtw89_btc_wl_mlo_info mlo_info;
struct rtw89_btc_rf_para rf_para;
struct rtw89_btc_wl_nhm nhm;
union rtw89_btc_wl_state_map status;
@ -1907,12 +1936,16 @@ struct rtw89_btc_wl_info {
u8 bt_polut_type[RTW89_PHY_NUM]; /* BT polluted WL-Tx type for phy0/1 */
bool is_5g_hi_channel;
bool go_client_exist;
bool noa_exist;
bool pta_reg_mac_chg;
bool bg_mode;
bool he_mode;
bool scbd_change;
bool fw_ver_mismatch;
bool client_cnt_inc_2g;
bool link_mode_chg;
bool dbcc_chg;
u32 scbd;
};
@ -2065,6 +2098,7 @@ struct rtw89_btc_bt_info {
union rtw89_btc_bt_rfk_info_map rfk_info;
u8 raw_info[BTC_BTINFO_MAX]; /* raw bt info from mailbox */
u8 txpwr_info[BTC_BTINFO_MAX];
u8 rssi_level;
u32 scbd;
@ -2903,12 +2937,32 @@ struct rtw89_btc_trx_info {
u32 rx_err_ratio;
};
enum btc_rf_path {
BTC_RF_S0 = 0,
BTC_RF_S1 = 1,
BTC_RF_NUM,
};
struct rtw89_btc_fbtc_outsrc_set_info {
u8 rf_band[BTC_RF_NUM]; /* 0:2G, 1:non-2G */
u8 btg_rx[BTC_RF_NUM];
u8 nbtg_tx[BTC_RF_NUM];
struct rtw89_mac_ax_gnt gnt_set[BTC_RF_NUM]; /* refer to btc_gnt_ctrl */
struct rtw89_mac_ax_wl_act wlact_set[BTC_RF_NUM]; /* BT0/BT1 */
u8 pta_req_hw_band;
u8 rf_gbt_source;
} __packed;
union rtw89_btc_fbtc_slot_u {
struct rtw89_btc_fbtc_slot v1[CXST_MAX];
struct rtw89_btc_fbtc_slot_v7 v7[CXST_MAX];
};
struct rtw89_btc_dm {
struct rtw89_btc_fbtc_outsrc_set_info ost_info_last; /* outsrc API setup info */
struct rtw89_btc_fbtc_outsrc_set_info ost_info; /* outsrc API setup info */
union rtw89_btc_fbtc_slot_u slot;
union rtw89_btc_fbtc_slot_u slot_now;
struct rtw89_btc_fbtc_tdma tdma;
@ -2998,6 +3052,7 @@ enum rtw89_btc_btf_fw_event {
BTF_EVNT_BT_LEAUDIO_INFO = 7, /* fwc2hfunc > 1 */
BTF_EVNT_BUF_OVERFLOW,
BTF_EVNT_C2H_LOOPBACK,
BTF_EVNT_BT_QUERY_TXPWR, /* fwc2hfunc > 3 */
BTF_EVNT_MAX,
};
@ -3116,31 +3171,6 @@ enum rtw89_btc_btfre_type {
BTFRE_MAX,
};
struct rtw89_btc_btf_fwinfo {
u32 cnt_c2h;
u32 cnt_h2c;
u32 cnt_h2c_fail;
u32 event[BTF_EVNT_MAX];
u32 err[BTFRE_MAX];
u32 len_mismch;
u32 fver_mismch;
u32 rpt_en_map;
struct rtw89_btc_report_ctrl_state rpt_ctrl;
struct rtw89_btc_rpt_fbtc_tdma rpt_fbtc_tdma;
struct rtw89_btc_rpt_fbtc_slots rpt_fbtc_slots;
struct rtw89_btc_rpt_fbtc_cysta rpt_fbtc_cysta;
struct rtw89_btc_rpt_fbtc_step rpt_fbtc_step;
struct rtw89_btc_rpt_fbtc_nullsta rpt_fbtc_nullsta;
struct rtw89_btc_rpt_fbtc_mreg rpt_fbtc_mregval;
struct rtw89_btc_rpt_fbtc_gpio_dbg rpt_fbtc_gpio_dbg;
struct rtw89_btc_rpt_fbtc_btver rpt_fbtc_btver;
struct rtw89_btc_rpt_fbtc_btscan rpt_fbtc_btscan;
struct rtw89_btc_rpt_fbtc_btafh rpt_fbtc_btafh;
struct rtw89_btc_rpt_fbtc_btdev rpt_fbtc_btdev;
};
struct rtw89_btc_ver {
enum rtw89_core_chip_id chip_id;
u32 fw_ver_code;
@ -3167,6 +3197,35 @@ struct rtw89_btc_ver {
u8 drvinfo_type;
u16 info_buf;
u8 max_role_num;
u8 fcxosi;
u8 fcxmlo;
u8 bt_desired;
};
struct rtw89_btc_btf_fwinfo {
u32 cnt_c2h;
u32 cnt_h2c;
u32 cnt_h2c_fail;
u32 event[BTF_EVNT_MAX];
u32 err[BTFRE_MAX];
u32 len_mismch;
u32 fver_mismch;
u32 rpt_en_map;
struct rtw89_btc_ver fw_subver;
struct rtw89_btc_report_ctrl_state rpt_ctrl;
struct rtw89_btc_rpt_fbtc_tdma rpt_fbtc_tdma;
struct rtw89_btc_rpt_fbtc_slots rpt_fbtc_slots;
struct rtw89_btc_rpt_fbtc_cysta rpt_fbtc_cysta;
struct rtw89_btc_rpt_fbtc_step rpt_fbtc_step;
struct rtw89_btc_rpt_fbtc_nullsta rpt_fbtc_nullsta;
struct rtw89_btc_rpt_fbtc_mreg rpt_fbtc_mregval;
struct rtw89_btc_rpt_fbtc_gpio_dbg rpt_fbtc_gpio_dbg;
struct rtw89_btc_rpt_fbtc_btver rpt_fbtc_btver;
struct rtw89_btc_rpt_fbtc_btscan rpt_fbtc_btscan;
struct rtw89_btc_rpt_fbtc_btafh rpt_fbtc_btafh;
struct rtw89_btc_rpt_fbtc_btdev rpt_fbtc_btdev;
};
#define RTW89_BTC_POLICY_MAXLEN 512
@ -3385,6 +3444,7 @@ struct rtw89_sta_link {
unsigned int link_id;
u8 mac_id;
u8 tx_retry;
bool er_cap;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_ra_info ra;
@ -3440,6 +3500,8 @@ struct rtw89_tx_skb_data {
u8 hci_priv[];
};
#define RTW89_SCAN_NULL_TIMEOUT 30
#define RTW89_ROC_IDLE_TIMEOUT 500
#define RTW89_ROC_TX_TIMEOUT 30
enum rtw89_roc_state {
@ -3533,6 +3595,7 @@ struct rtw89_vif_link {
bool pwr_diff_en;
u8 def_tri_idx;
struct wiphy_work update_beacon_work;
struct wiphy_delayed_work csa_beacon_work;
struct rtw89_addr_cam_entry addr_cam;
struct rtw89_bssid_cam_entry bssid_cam;
struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS];
@ -3645,6 +3708,8 @@ struct rtw89_chip_ops {
enum rtw89_phy_idx phy_idx);
int (*init_txpwr_unit)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
u8 (*get_thermal)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path);
u32 (*chan_to_rf18_val)(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan);
void (*ctrl_btg_bt_rx)(struct rtw89_dev *rtwdev, bool en,
enum rtw89_phy_idx phy_idx);
void (*query_ppdu)(struct rtw89_dev *rtwdev,
@ -4358,7 +4423,6 @@ struct rtw89_chip_info {
u32 para_ver;
u32 wlcx_desired;
u8 btcx_desired;
u8 scbd;
u8 mailbox;
@ -4513,6 +4577,7 @@ enum rtw89_fw_feature {
RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0,
RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V1,
RTW89_FW_FEATURE_RFK_RXDCK_V0,
RTW89_FW_FEATURE_RFK_IQK_V0,
RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX,
RTW89_FW_FEATURE_NOTIFY_AP_INFO,
RTW89_FW_FEATURE_CH_INFO_BE_V0,
@ -4520,6 +4585,8 @@ enum rtw89_fw_feature {
RTW89_FW_FEATURE_NO_PHYCAP_P1,
RTW89_FW_FEATURE_NO_POWER_DIFFERENCE,
RTW89_FW_FEATURE_BEACON_LOSS_COUNT_V1,
RTW89_FW_FEATURE_SCAN_OFFLOAD_EXTRA_OP,
RTW89_FW_FEATURE_RFK_NTFY_MCC_V0,
};
struct rtw89_fw_suit {
@ -4912,7 +4979,7 @@ enum rtw89_flags {
RTW89_FLAG_CRASH_SIMULATING,
RTW89_FLAG_SER_HANDLING,
RTW89_FLAG_WOWLAN,
RTW89_FLAG_FORBIDDEN_TRACK_WROK,
RTW89_FLAG_FORBIDDEN_TRACK_WORK,
RTW89_FLAG_CHANGING_INTERFACE,
RTW89_FLAG_HW_RFKILL_STATE,
@ -5447,11 +5514,18 @@ struct rtw89_early_h2c {
u16 h2c_len;
};
struct rtw89_hw_scan_extra_op {
bool set;
u8 macid;
struct rtw89_chan chan;
};
struct rtw89_hw_scan_info {
struct rtw89_vif_link *scanning_vif;
struct list_head pkt_list[NUM_NL80211_BANDS];
struct list_head chan_list;
struct rtw89_chan op_chan;
struct rtw89_hw_scan_extra_op extra_op;
bool connected;
bool abort;
};
@ -5672,6 +5746,7 @@ struct rtw89_mcc_role {
/* byte-array in LE order for FW */
u8 macid_bitmap[BITS_TO_BYTES(RTW89_MAX_MAC_ID_NUM)];
u8 probe_count;
u16 duration; /* TU */
u16 beacon_interval; /* TU */
@ -5728,6 +5803,7 @@ struct rtw89_mcc_config {
struct rtw89_mcc_sync sync;
u64 start_tsf;
u64 start_tsf_in_aux_domain;
u64 prepare_delay;
u16 mcc_interval; /* TU */
u16 beacon_offset; /* TU */
};
@ -5858,6 +5934,7 @@ struct rtw89_dev {
struct wiphy_delayed_work coex_bt_devinfo_work;
struct wiphy_delayed_work coex_rfk_chk_work;
struct wiphy_delayed_work cfo_track_work;
struct wiphy_delayed_work mcc_prepare_done_work;
struct delayed_work forbid_ba_work;
struct wiphy_delayed_work antdiv_work;
struct rtw89_ppdu_sts_info ppdu_sts;
@ -6880,6 +6957,17 @@ static inline u8 rtw89_chip_get_thermal(struct rtw89_dev *rtwdev,
return chip->ops->get_thermal(rtwdev, rf_path);
}
static inline u32 rtw89_chip_chan_to_rf18_val(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (!chip->ops->chan_to_rf18_val)
return 0;
return chip->ops->chan_to_rf18_val(rtwdev, chan);
}
static inline void rtw89_chip_query_ppdu(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu,
struct ieee80211_rx_status *status)
@ -7317,6 +7405,9 @@ void rtw89_complete_cond(struct rtw89_wait_info *wait, unsigned int cond,
int rtw89_core_start(struct rtw89_dev *rtwdev);
void rtw89_core_stop(struct rtw89_dev *rtwdev);
void rtw89_core_update_beacon_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_core_csa_beacon_work(struct wiphy *wiphy, struct wiphy_work *work);
int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool qos, bool ps, int timeout);
void rtw89_roc_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);

View File

@ -1114,6 +1114,7 @@ static int rtw89_debug_dump_mac_mem(struct rtw89_dev *rtwdev,
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u32 filter_model_addr = mac->filter_model_addr;
u32 indir_access_addr = mac->indir_access_addr;
u32 mem_page_size = mac->mem_page_size;
u32 base_addr, start_page, residue;
char *p = buf, *end = buf + bufsz;
u32 i, j, pp, pages;
@ -1121,14 +1122,14 @@ static int rtw89_debug_dump_mac_mem(struct rtw89_dev *rtwdev,
u32 val;
remain = len;
pages = len / MAC_MEM_DUMP_PAGE_SIZE + 1;
start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE;
residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE;
pages = len / mem_page_size + 1;
start_page = start_addr / mem_page_size;
residue = start_addr % mem_page_size;
base_addr = mac->mem_base_addrs[sel];
base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE;
base_addr += start_page * mem_page_size;
for (pp = 0; pp < pages; pp++) {
dump_len = min_t(u32, remain, MAC_MEM_DUMP_PAGE_SIZE);
dump_len = min_t(u32, remain, mem_page_size);
rtw89_write32(rtwdev, filter_model_addr, base_addr);
for (i = indir_access_addr + residue;
i < indir_access_addr + dump_len;) {
@ -1142,7 +1143,7 @@ static int rtw89_debug_dump_mac_mem(struct rtw89_dev *rtwdev,
}
p += scnprintf(p, end - p, "\n");
}
base_addr += MAC_MEM_DUMP_PAGE_SIZE;
base_addr += mem_page_size;
}
return p - buf;

View File

@ -833,17 +833,20 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 91, 0, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 110, 0, BEACON_FILTER),
__CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS),
__CFG_FW_FEAT(RTL8852C, ge, 0, 0, 0, 0, RFK_NTFY_MCC_V0),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 56, 10, BEACON_FILTER),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 80, 0, WOW_REASON_V1),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 128, 0, BEACON_LOSS_COUNT_V1),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 11, 0, MACID_PAUSE_SLEEP),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 21, 0, SCAN_OFFLOAD_BE_V0),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 12, 0, BEACON_FILTER),
__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, lt, 0, 35, 31, 0, LPS_CH_INFO),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 42, 0, RFK_RXDCK_V0),
@ -3030,12 +3033,10 @@ int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev,
#define H2C_P2P_ACT_LEN 20
int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf,
struct ieee80211_p2p_noa_desc *desc,
u8 act, u8 noa_id)
u8 act, u8 noa_id, u8 ctwindow_oppps)
{
bool p2p_type_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
u8 ctwindow_oppps = bss_conf->p2p_noa_attr.oppps_ctwindow;
struct sk_buff *skb;
u8 *cmd;
int ret;
@ -5083,6 +5084,46 @@ int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type)
return ret;
}
int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_fbtc_outsrc_set_info *osi = &btc->dm.ost_info;
struct rtw89_h2c_cxosi *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
int ret;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_osi\n");
return -ENOMEM;
}
skb_put(skb, len);
h2c = (struct rtw89_h2c_cxosi *)skb->data;
h2c->hdr.type = type;
h2c->hdr.ver = btc->ver->fcxosi;
h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7;
h2c->osi = *osi;
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, BTFC_SET,
SET_DRV_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;
}
#define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR)
int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type)
{
@ -5361,6 +5402,7 @@ static
int rtw89_fw_h2c_scan_list_offload_ax(struct rtw89_dev *rtwdev, int ch_num,
struct list_head *chan_list)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
struct rtw89_h2c_chinfo_elem *elem;
struct rtw89_mac_chinfo_ax *ch_info;
@ -5403,6 +5445,10 @@ int rtw89_fw_h2c_scan_list_offload_ax(struct rtw89_dev *rtwdev, int ch_num,
le32_encode_bits(ch_info->tx_null, RTW89_H2C_CHINFO_W1_TX_NULL) |
le32_encode_bits(ch_info->rand_seq_num, RTW89_H2C_CHINFO_W1_RANDOM);
if (scan_info->extra_op.set)
elem->w1 |= le32_encode_bits(ch_info->macid_tx,
RTW89_H2C_CHINFO_W1_MACID_TX);
elem->w2 = le32_encode_bits(ch_info->pkt_id[0], RTW89_H2C_CHINFO_W2_PKT0) |
le32_encode_bits(ch_info->pkt_id[1], RTW89_H2C_CHINFO_W2_PKT1) |
le32_encode_bits(ch_info->pkt_id[2], RTW89_H2C_CHINFO_W2_PKT2) |
@ -5543,6 +5589,7 @@ int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool wowlan)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
struct rtw89_chan *op = &rtwdev->scan_info.op_chan;
enum rtw89_scan_mode scan_mode = RTW89_SCAN_IMMEDIATE;
@ -5602,6 +5649,10 @@ int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
h2c->tsf_low = le32_encode_bits(lower_32_bits(tsf),
RTW89_H2C_SCANOFLD_W4_TSF_LOW);
if (scan_info->extra_op.set)
h2c->w6 = le32_encode_bits(scan_info->extra_op.macid,
RTW89_H2C_SCANOFLD_W6_SECOND_MACID);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
H2C_FUNC_SCANOFLD, 1, 1,
@ -5877,31 +5928,48 @@ int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,
int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
{
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
struct rtw89_fw_h2c_rf_get_mccch_v0 *mccch_v0;
struct rtw89_fw_h2c_rf_get_mccch *mccch;
u32 len = sizeof(*mccch);
struct sk_buff *skb;
u8 ver = U8_MAX;
int ret;
u8 idx;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, sizeof(*mccch));
if (RTW89_CHK_FW_FEATURE(RFK_NTFY_MCC_V0, &rtwdev->fw)) {
len = sizeof(*mccch_v0);
ver = 0;
}
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
return -ENOMEM;
}
skb_put(skb, sizeof(*mccch));
mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data;
skb_put(skb, len);
idx = rfk_mcc->table_idx;
mccch->ch_0 = cpu_to_le32(rfk_mcc->ch[0]);
mccch->ch_1 = cpu_to_le32(rfk_mcc->ch[1]);
mccch->band_0 = cpu_to_le32(rfk_mcc->band[0]);
mccch->band_1 = cpu_to_le32(rfk_mcc->band[1]);
mccch->current_channel = cpu_to_le32(rfk_mcc->ch[idx]);
mccch->current_band_type = cpu_to_le32(rfk_mcc->band[idx]);
if (ver == 0) {
mccch_v0 = (struct rtw89_fw_h2c_rf_get_mccch_v0 *)skb->data;
mccch_v0->ch_0 = cpu_to_le32(rfk_mcc->ch[0]);
mccch_v0->ch_1 = cpu_to_le32(rfk_mcc->ch[1]);
mccch_v0->band_0 = cpu_to_le32(rfk_mcc->band[0]);
mccch_v0->band_1 = cpu_to_le32(rfk_mcc->band[1]);
mccch_v0->current_band_type = cpu_to_le32(rfk_mcc->band[idx]);
mccch_v0->current_channel = cpu_to_le32(rfk_mcc->ch[idx]);
} else {
mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data;
mccch->ch_0_0 = cpu_to_le32(rfk_mcc->ch[0]);
mccch->ch_0_1 = cpu_to_le32(rfk_mcc->ch[0]);
mccch->ch_1_0 = cpu_to_le32(rfk_mcc->ch[1]);
mccch->ch_1_1 = cpu_to_le32(rfk_mcc->ch[1]);
mccch->current_channel = cpu_to_le32(rfk_mcc->ch[idx]);
}
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
H2C_FUNC_OUTSRC_RF_GET_MCCCH, 0, 0,
sizeof(*mccch));
len);
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
@ -5917,6 +5985,65 @@ int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
}
EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc);
int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_h2c_rf_ps_info *h2c;
const struct rtw89_chan *chan;
u32 len = sizeof(*h2c);
unsigned int link_id;
struct sk_buff *skb;
int ret;
u8 path;
u32 val;
if (chip->chip_gen != RTW89_CHIP_BE)
return 0;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c rf ps info\n");
return -ENOMEM;
}
skb_put(skb, len);
h2c = (struct rtw89_h2c_rf_ps_info *)skb->data;
h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
path = rtw89_phy_get_syn_sel(rtwdev, rtwvif_link->phy_idx);
val = rtw89_chip_chan_to_rf18_val(rtwdev, chan);
if (path >= chip->rf_path_num) {
rtw89_err(rtwdev, "unsupported rf path (%d)\n", path);
ret = -ENOENT;
goto fail;
}
h2c->rf18[path] = cpu_to_le32(val);
h2c->pri_ch[path] = chan->primary_channel;
}
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
H2C_FUNC_OUTSRC_RF_PS_INFO, 0, 0,
sizeof(*h2c));
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_rf_ps_info);
int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
@ -6031,6 +6158,7 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
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)
{
struct rtw89_efuse *efuse = &rtwdev->efuse;
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_h2c_rf_tssi *h2c;
u32 len = sizeof(*h2c);
@ -6053,6 +6181,7 @@ int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
h2c->hwtx_en = true;
h2c->cv = hal->cv;
h2c->tssi_mode = tssi_mode;
h2c->rfe_type = efuse->rfe_type;
rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(rtwdev, phy_idx, chan, h2c);
rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(rtwdev, phy_idx, chan, h2c);
@ -6077,22 +6206,47 @@ int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
int rtw89_fw_h2c_rf_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
const struct rtw89_chan *chan)
{
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_h2c_rf_iqk_v0 *h2c_v0;
struct rtw89_h2c_rf_iqk *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
u8 ver = U8_MAX;
int ret;
if (RTW89_CHK_FW_FEATURE(RFK_IQK_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 RF IQK\n");
return -ENOMEM;
}
skb_put(skb, len);
if (ver == 0) {
h2c_v0 = (struct rtw89_h2c_rf_iqk_v0 *)skb->data;
h2c_v0->phy_idx = cpu_to_le32(phy_idx);
h2c_v0->dbcc = cpu_to_le32(rtwdev->dbcc_en);
goto done;
}
h2c = (struct rtw89_h2c_rf_iqk *)skb->data;
h2c->phy_idx = cpu_to_le32(phy_idx);
h2c->dbcc = cpu_to_le32(rtwdev->dbcc_en);
h2c->len = sizeof(*h2c);
h2c->ktype = 0;
h2c->phy = phy_idx;
h2c->kpath = rtw89_phy_get_kpath(rtwdev, phy_idx);
h2c->band = chan->band_type;
h2c->bw = chan->band_width;
h2c->ch = chan->channel;
h2c->cv = hal->cv;
done:
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_RFK,
H2C_FUNC_RFK_IQK_OFFLOAD, 0, 0, len);
@ -6845,6 +6999,7 @@ static void rtw89_hw_scan_add_chan_ax(struct rtw89_dev *rtwdev, int chan_type,
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op;
struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
struct cfg80211_scan_request *req = rtwvif->scan_req;
@ -6915,6 +7070,15 @@ static void rtw89_hw_scan_add_chan_ax(struct rtw89_dev *rtwdev, int chan_type,
case RTW89_CHAN_ACTIVE:
ch_info->pause_data = true;
break;
case RTW89_CHAN_EXTRA_OP:
ch_info->central_ch = ext->chan.channel;
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;
ch_info->num_pkt = 0;
ch_info->macid_tx = true;
break;
default:
rtw89_err(rtwdev, "Channel type out of bound\n");
}
@ -7073,10 +7237,45 @@ int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
return ret;
}
static int rtw89_hw_scan_add_op_types_ax(struct rtw89_dev *rtwdev,
enum rtw89_chan_type type,
struct list_head *chan_list,
struct cfg80211_scan_request *req,
int *off_chan_time)
{
struct rtw89_mac_chinfo_ax *tmp;
tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
if (!tmp)
return -ENOMEM;
switch (type) {
case RTW89_CHAN_OPERATE:
tmp->period = req->duration_mandatory ?
req->duration : RTW89_CHANNEL_TIME;
*off_chan_time = 0;
break;
case RTW89_CHAN_EXTRA_OP:
tmp->period = RTW89_CHANNEL_TIME_EXTRA_OP;
/* still calc @off_chan_time for scan op */
*off_chan_time += tmp->period;
break;
default:
kfree(tmp);
return -EINVAL;
}
rtw89_hw_scan_add_chan_ax(rtwdev, type, 0, tmp);
list_add_tail(&tmp->list, chan_list);
return 0;
}
int rtw89_hw_scan_prep_chan_list_ax(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
const struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op;
struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct cfg80211_scan_request *req = rtwvif->scan_req;
struct rtw89_mac_chinfo_ax *ch_info, *tmp;
@ -7103,6 +7302,8 @@ int rtw89_hw_scan_prep_chan_list_ax(struct rtw89_dev *rtwdev,
else if (channel->band == NL80211_BAND_6GHZ)
ch_info->period = RTW89_CHANNEL_TIME_6G +
RTW89_DWELL_TIME_6G;
else if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)
ch_info->period = RTW89_P2P_CHAN_TIME;
else
ch_info->period = RTW89_CHANNEL_TIME;
@ -7119,22 +7320,28 @@ int rtw89_hw_scan_prep_chan_list_ax(struct rtw89_dev *rtwdev,
type = RTW89_CHAN_ACTIVE;
rtw89_hw_scan_add_chan_ax(rtwdev, type, req->n_ssids, ch_info);
if (scan_info->connected &&
off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME) {
tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
if (!tmp) {
ret = -ENOMEM;
kfree(ch_info);
goto out;
}
if (!(scan_info->connected &&
off_chan_time + ch_info->period > RTW89_OFF_CHAN_TIME))
goto next;
type = RTW89_CHAN_OPERATE;
tmp->period = req->duration_mandatory ?
req->duration : RTW89_CHANNEL_TIME;
rtw89_hw_scan_add_chan_ax(rtwdev, type, 0, tmp);
list_add_tail(&tmp->list, &chan_list);
off_chan_time = 0;
ret = rtw89_hw_scan_add_op_types_ax(rtwdev, RTW89_CHAN_OPERATE,
&chan_list, req, &off_chan_time);
if (ret) {
kfree(ch_info);
goto out;
}
if (!ext->set)
goto next;
ret = rtw89_hw_scan_add_op_types_ax(rtwdev, RTW89_CHAN_EXTRA_OP,
&chan_list, req, &off_chan_time);
if (ret) {
kfree(ch_info);
goto out;
}
next:
list_add_tail(&ch_info->list, &chan_list);
off_chan_time += ch_info->period;
}
@ -7273,6 +7480,8 @@ int rtw89_hw_scan_prep_chan_list_be(struct rtw89_dev *rtwdev,
ch_info->period = req->duration;
else if (channel->band == NL80211_BAND_6GHZ)
ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G;
else if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)
ch_info->period = RTW89_P2P_CHAN_TIME;
else
ch_info->period = RTW89_CHANNEL_TIME;
@ -7436,6 +7645,47 @@ static void rtw89_hw_scan_update_beacon_noa(struct rtw89_dev *rtwdev,
}
}
static void rtw89_hw_scan_set_extra_op_info(struct rtw89_dev *rtwdev,
struct rtw89_vif *scan_rtwvif,
const struct rtw89_chan *scan_op)
{
struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt;
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
struct rtw89_hw_scan_extra_op *ext = &scan_info->extra_op;
struct rtw89_vif *tmp;
ext->set = false;
if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_EXTRA_OP, &rtwdev->fw))
return;
list_for_each_entry(tmp, &mgnt->active_list, mgnt_entry) {
const struct rtw89_chan *tmp_chan;
struct rtw89_vif_link *tmp_link;
if (tmp == scan_rtwvif)
continue;
tmp_link = rtw89_vif_get_link_inst(tmp, 0);
if (unlikely(!tmp_link)) {
rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
"hw scan: no HW-0 link for extra op\n");
continue;
}
tmp_chan = rtw89_chan_get(rtwdev, tmp_link->chanctx_idx);
*ext = (struct rtw89_hw_scan_extra_op){
.set = true,
.macid = tmp_link->mac_id,
.chan = *tmp_chan,
};
rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
"hw scan: extra op: center %d primary %d\n",
ext->chan.channel, ext->chan.primary_channel);
break;
}
}
int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_scan_request *scan_req)
@ -7458,6 +7708,12 @@ int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
/* clone op and keep it during scan */
rtwdev->scan_info.op_chan = *chan;
rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
"hw scan: op: center %d primary %d\n",
chan->channel, chan->primary_channel);
rtw89_hw_scan_set_extra_op_info(rtwdev, rtwvif, chan);
rtwdev->scan_info.connected = rtw89_is_any_vif_connected_or_connecting(rtwdev);
rtwdev->scan_info.scanning_vif = rtwvif_link;
rtwdev->scan_info.abort = false;

View File

@ -237,6 +237,7 @@ enum rtw89_chan_type {
RTW89_CHAN_OPERATE = 0,
RTW89_CHAN_ACTIVE,
RTW89_CHAN_DFS,
RTW89_CHAN_EXTRA_OP,
};
enum rtw89_p2pps_action {
@ -316,8 +317,10 @@ struct rtw89_fw_macid_pause_sleep_grp {
#define RTW89_H2C_MAX_SIZE 2048
#define RTW89_CHANNEL_TIME 45
#define RTW89_CHANNEL_TIME_6G 20
#define RTW89_CHANNEL_TIME_EXTRA_OP 30
#define RTW89_DFS_CHAN_TIME 105
#define RTW89_OFF_CHAN_TIME 100
#define RTW89_P2P_CHAN_TIME 105
#define RTW89_DWELL_TIME 20
#define RTW89_DWELL_TIME_6G 10
#define RTW89_SCAN_WIDTH 0
@ -352,7 +355,8 @@ struct rtw89_mac_chinfo_ax {
u8 tx_null:1;
u8 rand_seq_num:1;
u8 cfg_tx_pwr:1;
u8 rsvd0: 4;
u8 macid_tx: 1;
u8 rsvd0: 3;
u8 pkt_id[RTW89_SCANOFLD_MAX_SSID];
u16 tx_pwr_idx;
u8 rsvd1;
@ -2247,6 +2251,11 @@ struct rtw89_h2c_cxrole_v8 {
struct rtw89_btc_wl_role_info_v8_u32 _u32;
} __packed;
struct rtw89_h2c_cxosi {
struct rtw89_h2c_cxhdr_v7 hdr;
struct rtw89_btc_fbtc_outsrc_set_info osi;
} __packed;
struct rtw89_h2c_cxinit {
struct rtw89_h2c_cxhdr hdr;
u8 ant_type;
@ -2674,6 +2683,7 @@ struct rtw89_h2c_chinfo_elem {
#define RTW89_H2C_CHINFO_W1_TX_NULL BIT(25)
#define RTW89_H2C_CHINFO_W1_RANDOM BIT(26)
#define RTW89_H2C_CHINFO_W1_CFG_TX BIT(27)
#define RTW89_H2C_CHINFO_W1_MACID_TX BIT(29)
#define RTW89_H2C_CHINFO_W2_PKT0 GENMASK(7, 0)
#define RTW89_H2C_CHINFO_W2_PKT1 GENMASK(15, 8)
#define RTW89_H2C_CHINFO_W2_PKT2 GENMASK(23, 16)
@ -2773,6 +2783,7 @@ struct rtw89_h2c_scanofld {
#define RTW89_H2C_SCANOFLD_W2_SLOW_PD GENMASK(23, 16)
#define RTW89_H2C_SCANOFLD_W3_TSF_HIGH GENMASK(31, 0)
#define RTW89_H2C_SCANOFLD_W4_TSF_LOW GENMASK(31, 0)
#define RTW89_H2C_SCANOFLD_W6_SECOND_MACID GENMASK(31, 24)
struct rtw89_h2c_scanofld_be_macc_role {
__le32 w0;
@ -4337,6 +4348,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_PS_INFO 0x10
#define H2C_CL_OUTSRC_RF_FW_RFK 0xb
enum rtw89_rfk_offload_h2c_func {
@ -4350,6 +4362,14 @@ enum rtw89_rfk_offload_h2c_func {
};
struct rtw89_fw_h2c_rf_get_mccch {
__le32 ch_0_0;
__le32 ch_0_1;
__le32 ch_1_0;
__le32 ch_1_1;
__le32 current_channel;
} __packed;
struct rtw89_fw_h2c_rf_get_mccch_v0 {
__le32 ch_0;
__le32 ch_1;
__le32 band_0;
@ -4361,6 +4381,12 @@ struct rtw89_fw_h2c_rf_get_mccch {
#define NUM_OF_RTW89_FW_RFK_PATH 2
#define NUM_OF_RTW89_FW_RFK_TBL 3
struct rtw89_h2c_rf_ps_info {
__le32 rf18[NUM_OF_RTW89_FW_RFK_PATH];
__le32 mlo_mode;
u8 pri_ch[NUM_OF_RTW89_FW_RFK_PATH];
} __packed;
struct rtw89_fw_h2c_rfk_pre_info_common {
struct {
__le32 ch[NUM_OF_RTW89_FW_RFK_PATH][NUM_OF_RTW89_FW_RFK_TBL];
@ -4435,11 +4461,23 @@ struct rtw89_h2c_rf_tssi {
u8 pg_thermal[2];
u8 ftable[2][128];
u8 tssi_mode;
u8 rfe_type;
} __packed;
struct rtw89_h2c_rf_iqk_v0 {
__le32 phy_idx;
__le32 dbcc;
} __packed;
struct rtw89_h2c_rf_iqk {
__le32 phy_idx;
__le32 dbcc;
u8 len;
u8 ktype;
u8 phy;
u8 kpath;
u8 band;
u8 bw;
u8 ch;
u8 cv;
} __packed;
struct rtw89_h2c_rf_dpk {
@ -4713,6 +4751,7 @@ int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_role_v7(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_trx(struct rtw89_dev *rtwdev, u8 type);
@ -4732,6 +4771,7 @@ int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,
struct rtw89_fw_h2c_rf_reg_info *info,
u16 len, u8 page);
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_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
@ -4815,9 +4855,8 @@ int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev,
const struct rtw89_pkt_drop_params *params);
int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf,
struct ieee80211_p2p_noa_desc *desc,
u8 act, u8 noa_id);
u8 act, u8 noa_id, u8 ctwindow_oppps);
int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool en);

View File

@ -4388,7 +4388,33 @@ static void rtw89_mac_port_cfg_tx_sw_by_nettype(struct rtw89_dev *rtwdev,
rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en);
}
void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en)
static void rtw89_mac_enable_ap_bcn_by_chan(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
const struct rtw89_chan *to_match,
bool en)
{
const struct rtw89_chan *chan;
if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE)
return;
if (!to_match)
goto doit;
/* @to_match may not be in the same domain as return of calling
* rtw89_chan_get(). So, cannot compare their addresses directly.
*/
chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
if (chan->channel != to_match->channel)
return;
doit:
rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en);
}
static void rtw89_mac_enable_aps_bcn_by_chan(struct rtw89_dev *rtwdev,
const struct rtw89_chan *to_match,
bool en)
{
struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
@ -4396,8 +4422,13 @@ void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en)
rtw89_for_each_rtwvif(rtwdev, rtwvif)
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en);
rtw89_mac_enable_ap_bcn_by_chan(rtwdev, rtwvif_link,
to_match, en);
}
void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en)
{
rtw89_mac_enable_aps_bcn_by_chan(rtwdev, NULL, en);
}
static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev,
@ -4891,11 +4922,22 @@ rtw89_mac_c2h_macid_pause(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len
{
}
static bool rtw89_is_op_chan(struct rtw89_dev *rtwdev, u8 band, u8 channel)
static const struct rtw89_chan *
rtw89_hw_scan_search_op_chan(struct rtw89_dev *rtwdev, u8 band, u8 channel)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
const struct rtw89_chan *op = &rtwdev->scan_info.op_chan;
return band == op->band_type && channel == op->primary_channel;
if (band == op->band_type && channel == op->primary_channel)
return op;
if (scan_info->extra_op.set) {
op = &scan_info->extra_op.chan;
if (band == op->band_type && channel == op->primary_channel)
return op;
}
return NULL;
}
static void
@ -4905,6 +4947,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
const struct rtw89_c2h_scanofld *c2h =
(const struct rtw89_c2h_scanofld *)skb->data;
struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
const struct rtw89_chan *op_chan;
struct rtw89_vif *rtwvif;
struct rtw89_chan new;
u16 actual_period, expect_period;
@ -4960,8 +5003,9 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
switch (reason) {
case RTW89_SCAN_LEAVE_OP_NOTIFY:
case RTW89_SCAN_LEAVE_CH_NOTIFY:
if (rtw89_is_op_chan(rtwdev, band, chan)) {
rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, false);
op_chan = rtw89_hw_scan_search_op_chan(rtwdev, band, chan);
if (op_chan) {
rtw89_mac_enable_aps_bcn_by_chan(rtwdev, op_chan, false);
ieee80211_stop_queues(rtwdev->hw);
}
return;
@ -4982,10 +5026,10 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
break;
case RTW89_SCAN_ENTER_OP_NOTIFY:
case RTW89_SCAN_ENTER_CH_NOTIFY:
if (rtw89_is_op_chan(rtwdev, band, chan)) {
rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx,
&rtwdev->scan_info.op_chan);
rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true);
op_chan = rtw89_hw_scan_search_op_chan(rtwdev, band, chan);
if (op_chan) {
rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx, op_chan);
rtw89_mac_enable_aps_bcn_by_chan(rtwdev, op_chan, true);
ieee80211_wake_queues(rtwdev->hw);
} else {
rtw89_chan_create(&new, chan, chan, band,
@ -5717,6 +5761,7 @@ void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
handler = rtw89_mac_c2h_ap_handler[func];
break;
case RTW89_MAC_C2H_CLASS_FWDBG:
case RTW89_MAC_C2H_CLASS_ROLE:
return;
default:
rtw89_info(rtwdev, "MAC c2h class %d not support\n", class);
@ -6869,6 +6914,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.filter_model_addr = R_AX_FILTER_MODEL_ADDR,
.indir_access_addr = R_AX_INDIR_ACCESS_ENTRY,
.mem_base_addrs = rtw89_mac_mem_base_addrs_ax,
.mem_page_size = MAC_MEM_DUMP_PAGE_SIZE_AX,
.rx_fltr = R_AX_RX_FLTR_OPT,
.port_base = &rtw89_port_base_ax,
.agg_len_ht = R_AX_AGG_LEN_HT_0,

View File

@ -8,7 +8,9 @@
#include "core.h"
#include "reg.h"
#define MAC_MEM_DUMP_PAGE_SIZE 0x40000
#define MAC_MEM_DUMP_PAGE_SIZE_AX 0x40000
#define MAC_MEM_DUMP_PAGE_SIZE_BE 0x80000
#define ADDR_CAM_ENT_SIZE 0x40
#define ADDR_CAM_ENT_SHORT_SIZE 0x20
#define BSSID_CAM_ENT_SIZE 0x08
@ -469,6 +471,7 @@ enum rtw89_mac_c2h_class {
RTW89_MAC_C2H_CLASS_MLO = 0xc,
RTW89_MAC_C2H_CLASS_MRC = 0xe,
RTW89_MAC_C2H_CLASS_AP = 0x18,
RTW89_MAC_C2H_CLASS_ROLE = 0x1b,
RTW89_MAC_C2H_CLASS_MAX,
};
@ -969,6 +972,7 @@ struct rtw89_mac_gen_def {
u32 filter_model_addr;
u32 indir_access_addr;
const u32 *mem_base_addrs;
u32 mem_page_size;
u32 rx_fltr;
const struct rtw89_port_reg *port_base;
u32 agg_len_ht;

View File

@ -112,6 +112,8 @@ static int __rtw89_ops_add_iface_link(struct rtw89_dev *rtwdev,
rtw89_vif_type_mapping(rtwvif_link, false);
wiphy_work_init(&rtwvif_link->update_beacon_work, rtw89_core_update_beacon_work);
wiphy_delayed_work_init(&rtwvif_link->csa_beacon_work, rtw89_core_csa_beacon_work);
INIT_LIST_HEAD(&rtwvif_link->general_pkt_list);
rtw89_p2p_noa_once_init(rtwvif_link);
@ -144,6 +146,7 @@ static void __rtw89_ops_remove_iface_link(struct rtw89_dev *rtwdev,
lockdep_assert_wiphy(rtwdev->hw->wiphy);
wiphy_work_cancel(rtwdev->hw->wiphy, &rtwvif_link->update_beacon_work);
wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwvif_link->csa_beacon_work);
rtw89_p2p_noa_once_deinit(rtwvif_link);
@ -1356,6 +1359,73 @@ static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw,
rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif_link, ctx);
}
static
int rtw89_ops_switch_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_vif_chanctx_switch *vifs,
int n_vifs,
enum ieee80211_chanctx_switch_mode mode)
{
struct rtw89_dev *rtwdev = hw->priv;
bool replace;
int ret;
int i;
lockdep_assert_wiphy(hw->wiphy);
switch (mode) {
case CHANCTX_SWMODE_REASSIGN_VIF:
replace = false;
break;
case CHANCTX_SWMODE_SWAP_CONTEXTS:
replace = true;
break;
default:
return -EOPNOTSUPP;
}
for (i = 0; i < n_vifs; i++) {
struct ieee80211_vif_chanctx_switch *p = &vifs[i];
struct ieee80211_bss_conf *link_conf = p->link_conf;
struct rtw89_vif *rtwvif = vif_to_rtwvif(p->vif);
struct rtw89_vif_link *rtwvif_link;
rtwvif_link = rtwvif->links[link_conf->link_id];
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev,
"%s: rtwvif link (link_id %u) is not active\n",
__func__, link_conf->link_id);
return -ENOLINK;
}
ret = rtw89_chanctx_ops_reassign_vif(rtwdev, rtwvif_link,
p->old_ctx, p->new_ctx,
replace);
if (ret)
return ret;
}
return 0;
}
static void rtw89_ops_channel_switch_beacon(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_chan_def *chandef)
{
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif_link *rtwvif_link;
BUILD_BUG_ON(RTW89_MLD_NON_STA_LINK_NUM != 1);
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev, "chsw bcn: find no link on HW-0\n");
return;
}
wiphy_delayed_work_queue(hw->wiphy, &rtwvif_link->csa_beacon_work, 0);
}
static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_channel *chan,
@ -1700,13 +1770,13 @@ static int rtw89_ops_suspend(struct ieee80211_hw *hw,
lockdep_assert_wiphy(hw->wiphy);
set_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags);
set_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags);
wiphy_delayed_work_cancel(hw->wiphy, &rtwdev->track_work);
ret = rtw89_wow_suspend(rtwdev, wowlan);
if (ret) {
rtw89_warn(rtwdev, "failed to suspend for wow %d\n", ret);
clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags);
clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags);
return 1;
}
@ -1724,7 +1794,7 @@ static int rtw89_ops_resume(struct ieee80211_hw *hw)
if (ret)
rtw89_warn(rtwdev, "failed to resume for wow %d\n", ret);
clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags);
clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WORK, rtwdev->flags);
wiphy_delayed_work_queue(hw->wiphy, &rtwdev->track_work,
RTW89_TRACK_WORK_PERIOD);
@ -1807,6 +1877,8 @@ const struct ieee80211_ops rtw89_ops = {
.change_chanctx = rtw89_ops_change_chanctx,
.assign_vif_chanctx = rtw89_ops_assign_vif_chanctx,
.unassign_vif_chanctx = rtw89_ops_unassign_vif_chanctx,
.switch_vif_chanctx = rtw89_ops_switch_vif_chanctx,
.channel_switch_beacon = rtw89_ops_channel_switch_beacon,
.remain_on_channel = rtw89_ops_remain_on_channel,
.cancel_remain_on_channel = rtw89_ops_cancel_remain_on_channel,
.set_sar_specs = rtw89_ops_set_sar_specs,

View File

@ -2567,6 +2567,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
.filter_model_addr = R_BE_FILTER_MODEL_ADDR,
.indir_access_addr = R_BE_INDIR_ACCESS_ENTRY,
.mem_base_addrs = rtw89_mac_mem_base_addrs_be,
.mem_page_size = MAC_MEM_DUMP_PAGE_SIZE_BE,
.rx_fltr = R_BE_RX_FLTR_OPT,
.port_base = &rtw89_port_base_be,
.agg_len_ht = R_BE_AGG_LEN_HT_0,

View File

@ -4353,6 +4353,43 @@ static int __maybe_unused rtw89_pci_resume(struct device *dev)
SIMPLE_DEV_PM_OPS(rtw89_pm_ops, rtw89_pci_suspend, rtw89_pci_resume);
EXPORT_SYMBOL(rtw89_pm_ops);
static pci_ers_result_t rtw89_pci_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
netif_device_detach(netdev);
return PCI_ERS_RESULT_NEED_RESET;
}
static pci_ers_result_t rtw89_pci_io_slot_reset(struct pci_dev *pdev)
{
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct rtw89_dev *rtwdev = hw->priv;
rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION);
return PCI_ERS_RESULT_RECOVERED;
}
static void rtw89_pci_io_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
/* ack any pending wake events, disable PME */
pci_enable_wake(pdev, PCI_D0, 0);
netif_device_attach(netdev);
}
const struct pci_error_handlers rtw89_pci_err_handler = {
.error_detected = rtw89_pci_io_error_detected,
.slot_reset = rtw89_pci_io_slot_reset,
.resume = rtw89_pci_io_resume,
};
EXPORT_SYMBOL(rtw89_pci_err_handler);
const struct rtw89_pci_gen_def rtw89_pci_gen_ax = {
.isr_rdu = B_AX_RDU_INT,
.isr_halt_c2h = B_AX_HALT_C2H_INT_EN,

View File

@ -1622,6 +1622,7 @@ static inline bool rtw89_pci_ltr_is_err_reg_val(u32 val)
extern const struct dev_pm_ops rtw89_pm_ops;
extern const struct dev_pm_ops rtw89_pm_ops_be;
extern const struct pci_error_handlers rtw89_pci_err_handler;
extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set;
extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_v1;
extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_be;

View File

@ -119,10 +119,12 @@ static u64 get_eht_mcs_ra_mask(u8 *max_nss, u8 start_mcs, u8 n_nss)
return mask;
}
static u64 get_eht_ra_mask(struct ieee80211_link_sta *link_sta)
static u64 get_eht_ra_mask(struct rtw89_vif_link *rtwvif_link,
struct ieee80211_link_sta *link_sta)
{
struct ieee80211_sta_eht_cap *eht_cap = &link_sta->eht_cap;
struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
struct ieee80211_eht_mcs_nss_supp_20mhz_only *mcs_nss_20mhz;
struct ieee80211_sta_eht_cap *eht_cap = &link_sta->eht_cap;
struct ieee80211_eht_mcs_nss_supp_bw *mcs_nss;
u8 *he_phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info;
@ -136,8 +138,8 @@ static u64 get_eht_ra_mask(struct ieee80211_link_sta *link_sta)
/* MCS 9, 11, 13 */
return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3);
case IEEE80211_STA_RX_BW_20:
if (!(he_phy_cap[0] &
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) {
if (vif->type == NL80211_IFTYPE_AP &&
!(he_phy_cap[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) {
mcs_nss_20mhz = &eht_cap->eht_mcs_nss_supp.only_20mhz;
/* MCS 7, 9, 11, 13 */
return get_eht_mcs_ra_mask(mcs_nss_20mhz->rx_tx_max_nss, 7, 4);
@ -332,7 +334,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
/* Set the ra mask from sta's capability */
if (link_sta->eht_cap.has_eht) {
mode |= RTW89_RA_MODE_EHT;
ra_mask |= get_eht_ra_mask(link_sta);
ra_mask |= get_eht_ra_mask(rtwvif_link, link_sta);
if (rtwdev->hal.no_mcs_12_13)
high_rate_masks = rtw89_ra_mask_eht_mcs0_11;
@ -5828,14 +5830,20 @@ void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev)
__rtw89_phy_env_monitor_track(rtwdev, bb);
}
static bool rtw89_physts_ie_page_valid(enum rtw89_phy_status_bitmap *ie_page)
static bool rtw89_physts_ie_page_valid(struct rtw89_dev *rtwdev,
enum rtw89_phy_status_bitmap *ie_page)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (*ie_page >= RTW89_PHYSTS_BITMAP_NUM ||
*ie_page == RTW89_RSVD_9)
return false;
else if (*ie_page > RTW89_RSVD_9)
else if (*ie_page > RTW89_RSVD_9 && *ie_page < RTW89_EHT_PKT)
*ie_page -= 1;
if (*ie_page == RTW89_EHT_PKT && chip->chip_gen == RTW89_CHIP_AX)
return false;
return true;
}
@ -5843,6 +5851,9 @@ static u32 rtw89_phy_get_ie_bitmap_addr(enum rtw89_phy_status_bitmap ie_page)
{
static const u8 ie_page_shift = 2;
if (ie_page == RTW89_EHT_PKT)
return R_PHY_STS_BITMAP_EHT;
return R_PHY_STS_BITMAP_ADDR_START + (ie_page << ie_page_shift);
}
@ -5852,7 +5863,7 @@ static u32 rtw89_physts_get_ie_bitmap(struct rtw89_dev *rtwdev,
{
u32 addr;
if (!rtw89_physts_ie_page_valid(&ie_page))
if (!rtw89_physts_ie_page_valid(rtwdev, &ie_page))
return 0;
addr = rtw89_phy_get_ie_bitmap_addr(ie_page);
@ -5867,7 +5878,7 @@ static void rtw89_physts_set_ie_bitmap(struct rtw89_dev *rtwdev,
const struct rtw89_chip_info *chip = rtwdev->chip;
u32 addr;
if (!rtw89_physts_ie_page_valid(&ie_page))
if (!rtw89_physts_ie_page_valid(rtwdev, &ie_page))
return;
if (chip->chip_id == RTL8852A)
@ -5877,21 +5888,6 @@ static void rtw89_physts_set_ie_bitmap(struct rtw89_dev *rtwdev,
rtw89_phy_write32_idx(rtwdev, addr, MASKDWORD, val, phy_idx);
}
static void rtw89_physts_enable_ie_bitmap(struct rtw89_dev *rtwdev,
enum rtw89_phy_status_bitmap bitmap,
enum rtw89_phy_status_ie_type ie,
bool enable, enum rtw89_phy_idx phy_idx)
{
u32 val = rtw89_physts_get_ie_bitmap(rtwdev, bitmap, phy_idx);
if (enable)
val |= BIT(ie);
else
val &= ~BIT(ie);
rtw89_physts_set_ie_bitmap(rtwdev, bitmap, val, phy_idx);
}
static void rtw89_physts_enable_fail_report(struct rtw89_dev *rtwdev,
bool enable,
enum rtw89_phy_idx phy_idx)
@ -5915,30 +5911,37 @@ static void rtw89_physts_enable_fail_report(struct rtw89_dev *rtwdev,
static void __rtw89_physts_parsing_init(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
u32 val;
u8 i;
rtw89_physts_enable_fail_report(rtwdev, false, phy_idx);
for (i = 0; i < RTW89_PHYSTS_BITMAP_NUM; i++) {
if (i >= RTW89_CCK_PKT)
rtw89_physts_enable_ie_bitmap(rtwdev, i,
RTW89_PHYSTS_IE09_FTR_0,
true, phy_idx);
if ((i >= RTW89_CCK_BRK && i <= RTW89_VHT_MU) ||
(i >= RTW89_RSVD_9 && i <= RTW89_CCK_PKT))
if (i == RTW89_RSVD_9 ||
(i == RTW89_EHT_PKT && chip->chip_gen == RTW89_CHIP_AX))
continue;
rtw89_physts_enable_ie_bitmap(rtwdev, i,
RTW89_PHYSTS_IE24_OFDM_TD_PATH_A,
true, phy_idx);
}
rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_VHT_PKT,
RTW89_PHYSTS_IE13_DL_MU_DEF, true, phy_idx);
rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_HE_PKT,
RTW89_PHYSTS_IE13_DL_MU_DEF, true, phy_idx);
/* force IE01 for channel index, only channel field is valid */
rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_CCK_PKT,
RTW89_PHYSTS_IE01_CMN_OFDM, true, phy_idx);
val = rtw89_physts_get_ie_bitmap(rtwdev, i, phy_idx);
if (i == RTW89_HE_MU || i == RTW89_VHT_MU) {
val |= BIT(RTW89_PHYSTS_IE13_DL_MU_DEF);
} else if (i == RTW89_TRIG_BASE_PPDU) {
val |= BIT(RTW89_PHYSTS_IE13_DL_MU_DEF) |
BIT(RTW89_PHYSTS_IE01_CMN_OFDM);
} else if (i >= RTW89_CCK_PKT) {
val |= BIT(RTW89_PHYSTS_IE09_FTR_0);
val &= ~(GENMASK(RTW89_PHYSTS_IE07_CMN_EXT_PATH_D,
RTW89_PHYSTS_IE04_CMN_EXT_PATH_A));
if (i == RTW89_CCK_PKT)
val |= BIT(RTW89_PHYSTS_IE01_CMN_OFDM);
else if (i >= RTW89_HT_PKT)
val |= BIT(RTW89_PHYSTS_IE20_DBG_OFDM_FD_USER_SEG_0);
}
rtw89_physts_set_ie_bitmap(rtwdev, i, val, phy_idx);
}
}
static void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev)
@ -7125,7 +7128,7 @@ static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *b
const struct rtw89_edcca_p_regs *edcca_p_regs;
bool flag_fb, flag_p20, flag_s20, flag_s40, flag_s80;
s8 pwdb_fb, pwdb_p20, pwdb_s20, pwdb_s40, pwdb_s80;
u8 path, per20_bitmap;
u8 path, per20_bitmap = 0;
u8 pwdb[8];
u32 tmp;
@ -7155,14 +7158,11 @@ static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *b
pwdb_fb = u32_get_bits(tmp, MASKBYTE3);
rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel,
edcca_p_regs->rpt_sel_mask, 4);
edcca_p_regs->rpt_sel_mask, 5);
tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b);
pwdb_s80 = u32_get_bits(tmp, MASKBYTE1);
pwdb_s40 = u32_get_bits(tmp, MASKBYTE2);
per20_bitmap = rtw89_phy_read32_mask(rtwdev, edcca_p_regs->rpt_a,
MASKBYTE0);
if (rtwdev->chip->chip_id == RTL8922A) {
rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be,
edcca_regs->rpt_sel_be_mask, 4);
@ -7171,6 +7171,8 @@ static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *b
pwdb[1] = u32_get_bits(tmp, MASKBYTE2);
pwdb[2] = u32_get_bits(tmp, MASKBYTE1);
pwdb[3] = u32_get_bits(tmp, MASKBYTE0);
per20_bitmap = rtw89_phy_read32_mask(rtwdev, edcca_p_regs->rpt_a,
MASKBYTE0);
rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be,
edcca_regs->rpt_sel_be_mask, 5);
@ -7187,7 +7189,7 @@ static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *b
pwdb[1] = u32_get_bits(tmp, MASKBYTE2);
rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel,
edcca_p_regs->rpt_sel_mask, 1);
edcca_p_regs->rpt_sel_mask, 5);
tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a);
pwdb[2] = u32_get_bits(tmp, MASKBYTE3);
pwdb[3] = u32_get_bits(tmp, MASKBYTE2);

View File

@ -252,6 +252,7 @@ enum rtw89_phy_status_bitmap {
RTW89_HT_PKT = 13,
RTW89_VHT_PKT = 14,
RTW89_HE_PKT = 15,
RTW89_EHT_PKT = 16,
RTW89_PHYSTS_BITMAP_NUM
};

View File

@ -137,6 +137,8 @@ void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
can_ps_mode = false;
}
rtw89_fw_h2c_rf_ps_info(rtwdev, rtwvif);
if (RTW89_CHK_FW_FEATURE(LPS_CH_INFO, &rtwdev->fw))
rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif);
else
@ -236,13 +238,23 @@ static void rtw89_tsf32_toggle(struct rtw89_dev *rtwdev,
rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif_link, false);
}
static void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf)
void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf)
{
enum rtw89_p2pps_action act;
u8 oppps_ctwindow;
u8 noa_id;
rcu_read_lock();
if (!bss_conf)
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
oppps_ctwindow = bss_conf->p2p_noa_attr.oppps_ctwindow;
rcu_read_unlock();
if (rtwvif_link->last_noa_nr == 0)
return;
@ -252,8 +264,8 @@ static void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev,
else
act = RTW89_P2P_ACT_REMOVE;
rtw89_tsf32_toggle(rtwdev, rtwvif_link, act);
rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, bss_conf,
NULL, act, noa_id);
rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, NULL,
act, noa_id, oppps_ctwindow);
}
}
@ -275,8 +287,8 @@ static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev,
else
act = RTW89_P2P_ACT_UPDATE;
rtw89_tsf32_toggle(rtwdev, rtwvif_link, act);
rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, bss_conf,
desc, act, noa_id);
rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, desc, act, noa_id,
bss_conf->p2p_noa_attr.oppps_ctwindow);
}
rtwvif_link->last_noa_nr = noa_id;
}

View File

@ -25,6 +25,9 @@ u8 rtw89_p2p_noa_fetch(struct rtw89_vif_link *rtwvif_link, void **data);
void rtw89_p2p_noa_once_init(struct rtw89_vif_link *rtwvif_link);
void rtw89_p2p_noa_once_deinit(struct rtw89_vif_link *rtwvif_link);
void rtw89_p2p_noa_once_recalc(struct rtw89_vif_link *rtwvif_link);
void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf);
static inline void rtw89_leave_ips_by_hwflags(struct rtw89_dev *rtwdev)
{

View File

@ -6070,6 +6070,7 @@
#define B_BE_MACID_ACQ_GRP0_CLR_P BIT(2)
#define B_BE_R_MACID_ACQ_CHK_EN BIT(0)
#define R_BE_BTC_CFG 0x0E300
#define R_BE_BT_BREAK_TABLE 0x0E344
#define R_BE_GNT_SW_CTRL 0x0E348
@ -8024,6 +8025,7 @@
#define R_PHY_STS_BITMAP_HT 0x076C
#define R_PHY_STS_BITMAP_VHT 0x0770
#define R_PHY_STS_BITMAP_HE 0x0774
#define R_PHY_STS_BITMAP_EHT 0x0788
#define R_EDCCA_RPTREG_SEL_BE 0x078C
#define B_EDCCA_RPTREG_SEL_BE_MSK GENMASK(22, 20)
#define R_PMAC_GNT 0x0980

View File

@ -2402,6 +2402,7 @@ static const struct rtw89_chip_ops rtw8851b_chip_ops = {
.set_txpwr_ctrl = rtw8851b_set_txpwr_ctrl,
.init_txpwr_unit = rtw8851b_init_txpwr_unit,
.get_thermal = rtw8851b_get_thermal,
.chan_to_rf18_val = NULL,
.ctrl_btg_bt_rx = rtw8851b_ctrl_btg_bt_rx,
.query_ppdu = rtw8851b_query_ppdu,
.convert_rpl_to_rssi = NULL,
@ -2528,7 +2529,6 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.phycap_size = 128,
.para_ver = 0,
.wlcx_desired = 0x06000000,
.btcx_desired = 0x7,
.scbd = 0x1,
.mailbox = 0x1,

View File

@ -89,6 +89,7 @@ static struct pci_driver rtw89_8851be_driver = {
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops,
.err_handler = &rtw89_pci_err_handler,
};
module_pci_driver(rtw89_8851be_driver);

View File

@ -2128,6 +2128,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
.set_txpwr_ctrl = rtw8852a_set_txpwr_ctrl,
.init_txpwr_unit = rtw8852a_init_txpwr_unit,
.get_thermal = rtw8852a_get_thermal,
.chan_to_rf18_val = NULL,
.ctrl_btg_bt_rx = rtw8852a_ctrl_btg_bt_rx,
.query_ppdu = rtw8852a_query_ppdu,
.convert_rpl_to_rssi = NULL,
@ -2246,7 +2247,6 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.phycap_size = 128,
.para_ver = 0x0,
.wlcx_desired = 0x06000000,
.btcx_desired = 0x7,
.scbd = 0x1,
.mailbox = 0x1,

View File

@ -91,6 +91,7 @@ static struct pci_driver rtw89_8852ae_driver = {
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops,
.err_handler = &rtw89_pci_err_handler,
};
module_pci_driver(rtw89_8852ae_driver);

View File

@ -755,6 +755,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
.set_txpwr_ctrl = rtw8852bx_set_txpwr_ctrl,
.init_txpwr_unit = rtw8852bx_init_txpwr_unit,
.get_thermal = rtw8852bx_get_thermal,
.chan_to_rf18_val = NULL,
.ctrl_btg_bt_rx = rtw8852bx_ctrl_btg_bt_rx,
.query_ppdu = rtw8852bx_query_ppdu,
.convert_rpl_to_rssi = rtw8852bx_convert_rpl_to_rssi,
@ -882,7 +883,6 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.phycap_size = 128,
.para_ver = 0,
.wlcx_desired = 0x05050000,
.btcx_desired = 0x5,
.scbd = 0x1,
.mailbox = 0x1,

View File

@ -93,6 +93,7 @@ static struct pci_driver rtw89_8852be_driver = {
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops,
.err_handler = &rtw89_pci_err_handler,
};
module_pci_driver(rtw89_8852be_driver);

View File

@ -689,6 +689,7 @@ static const struct rtw89_chip_ops rtw8852bt_chip_ops = {
.set_txpwr_ctrl = rtw8852bx_set_txpwr_ctrl,
.init_txpwr_unit = rtw8852bx_init_txpwr_unit,
.get_thermal = rtw8852bx_get_thermal,
.chan_to_rf18_val = NULL,
.ctrl_btg_bt_rx = rtw8852bx_ctrl_btg_bt_rx,
.query_ppdu = rtw8852bx_query_ppdu,
.convert_rpl_to_rssi = rtw8852bx_convert_rpl_to_rssi,
@ -815,7 +816,6 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
.phycap_size = 128,
.para_ver = 0,
.wlcx_desired = 0x070e0000,
.btcx_desired = 0x7,
.scbd = 0x1,
.mailbox = 0x1,

View File

@ -95,6 +95,7 @@ static struct pci_driver rtw89_8852bte_driver = {
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops,
.err_handler = &rtw89_pci_err_handler,
};
module_pci_driver(rtw89_8852bte_driver);

View File

@ -2948,6 +2948,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
.set_txpwr_ctrl = rtw8852c_set_txpwr_ctrl,
.init_txpwr_unit = rtw8852c_init_txpwr_unit,
.get_thermal = rtw8852c_get_thermal,
.chan_to_rf18_val = NULL,
.ctrl_btg_bt_rx = rtw8852c_ctrl_btg_bt_rx,
.query_ppdu = rtw8852c_query_ppdu,
.convert_rpl_to_rssi = NULL,
@ -3069,7 +3070,6 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.phycap_size = 0x60,
.para_ver = 0x1,
.wlcx_desired = 0x06000000,
.btcx_desired = 0x7,
.scbd = 0x1,
.mailbox = 0x1,

View File

@ -118,6 +118,7 @@ static struct pci_driver rtw89_8852ce_driver = {
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops,
.err_handler = &rtw89_pci_err_handler,
};
module_pci_driver(rtw89_8852ce_driver);

View File

@ -15,7 +15,7 @@
#include "sar.h"
#include "util.h"
#define RTW8922A_FW_FORMAT_MAX 3
#define RTW8922A_FW_FORMAT_MAX 4
#define RTW8922A_FW_BASENAME "rtw89/rtw8922a_fw"
#define RTW8922A_MODULE_FIRMWARE \
RTW8922A_FW_BASENAME "-" __stringify(RTW8922A_FW_FORMAT_MAX) ".bin"
@ -2390,6 +2390,48 @@ static u8 rtw8922a_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_p
return clamp_t(int, th, 0, U8_MAX);
}
static u32 rtw8922a_chan_to_rf18_val(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan)
{
u32 val = u32_encode_bits(chan->channel, RR_CFGCH_CH);
switch (chan->band_type) {
case RTW89_BAND_2G:
default:
break;
case RTW89_BAND_5G:
val |= u32_encode_bits(CFGCH_BAND1_5G, RR_CFGCH_BAND1) |
u32_encode_bits(CFGCH_BAND0_5G, RR_CFGCH_BAND0);
break;
case RTW89_BAND_6G:
val |= u32_encode_bits(CFGCH_BAND1_6G, RR_CFGCH_BAND1) |
u32_encode_bits(CFGCH_BAND0_6G, RR_CFGCH_BAND0);
break;
}
switch (chan->band_width) {
case RTW89_CHANNEL_WIDTH_5:
case RTW89_CHANNEL_WIDTH_10:
case RTW89_CHANNEL_WIDTH_20:
default:
break;
case RTW89_CHANNEL_WIDTH_40:
val |= u32_encode_bits(CFGCH_BW_V2_40M, RR_CFGCH_BW_V2);
break;
case RTW89_CHANNEL_WIDTH_80:
val |= u32_encode_bits(CFGCH_BW_V2_80M, RR_CFGCH_BW_V2);
break;
case RTW89_CHANNEL_WIDTH_160:
val |= u32_encode_bits(CFGCH_BW_V2_160M, RR_CFGCH_BW_V2);
break;
case RTW89_CHANNEL_WIDTH_320:
val |= u32_encode_bits(CFGCH_BW_V2_320M, RR_CFGCH_BW_V2);
break;
}
return val;
}
static void rtw8922a_btc_set_rfe(struct rtw89_dev *rtwdev)
{
union rtw89_btc_module_info *md = &rtwdev->btc.mdinfo;
@ -2761,6 +2803,7 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = {
.set_txpwr_ctrl = rtw8922a_set_txpwr_ctrl,
.init_txpwr_unit = NULL,
.get_thermal = rtw8922a_get_thermal,
.chan_to_rf18_val = rtw8922a_chan_to_rf18_val,
.ctrl_btg_bt_rx = rtw8922a_ctrl_btg_bt_rx,
.query_ppdu = rtw8922a_query_ppdu,
.convert_rpl_to_rssi = rtw8922a_convert_rpl_to_rssi,
@ -2880,7 +2923,6 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.phycap_size = 0x38,
.para_ver = 0xf,
.wlcx_desired = 0x07110000,
.btcx_desired = 0x7,
.scbd = 0x1,
.mailbox = 0x1,

View File

@ -36,8 +36,7 @@ void rtw8922a_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx)
static
void rtw8922a_ctl_band_ch_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
u8 central_ch, enum rtw89_band band,
enum rtw89_bandwidth bw)
const struct rtw89_chan *chan)
{
const u32 rf_addr[2] = {RR_CFGCH, RR_CFGCH_V1};
struct rtw89_hal *hal = &rtwdev->hal;
@ -73,49 +72,9 @@ void rtw8922a_ctl_band_ch_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
return;
}
rf_reg[path][i] &= ~(RR_CFGCH_BAND1 | RR_CFGCH_BW |
rf_reg[path][i] &= ~(RR_CFGCH_BAND1 | RR_CFGCH_BW_V2 |
RR_CFGCH_BAND0 | RR_CFGCH_CH);
rf_reg[path][i] |= u32_encode_bits(central_ch, RR_CFGCH_CH);
switch (band) {
case RTW89_BAND_2G:
default:
break;
case RTW89_BAND_5G:
rf_reg[path][i] |=
u32_encode_bits(CFGCH_BAND1_5G, RR_CFGCH_BAND1) |
u32_encode_bits(CFGCH_BAND0_5G, RR_CFGCH_BAND0);
break;
case RTW89_BAND_6G:
rf_reg[path][i] |=
u32_encode_bits(CFGCH_BAND1_6G, RR_CFGCH_BAND1) |
u32_encode_bits(CFGCH_BAND0_6G, RR_CFGCH_BAND0);
break;
}
switch (bw) {
case RTW89_CHANNEL_WIDTH_5:
case RTW89_CHANNEL_WIDTH_10:
case RTW89_CHANNEL_WIDTH_20:
default:
break;
case RTW89_CHANNEL_WIDTH_40:
rf_reg[path][i] |=
u32_encode_bits(CFGCH_BW_V2_40M, RR_CFGCH_BW_V2);
break;
case RTW89_CHANNEL_WIDTH_80:
rf_reg[path][i] |=
u32_encode_bits(CFGCH_BW_V2_80M, RR_CFGCH_BW_V2);
break;
case RTW89_CHANNEL_WIDTH_160:
rf_reg[path][i] |=
u32_encode_bits(CFGCH_BW_V2_160M, RR_CFGCH_BW_V2);
break;
case RTW89_CHANNEL_WIDTH_320:
rf_reg[path][i] |=
u32_encode_bits(CFGCH_BW_V2_320M, RR_CFGCH_BW_V2);
break;
}
rf_reg[path][i] |= rtw89_chip_chan_to_rf18_val(rtwdev, chan);
rtw89_write_rf(rtwdev, path, rf_addr[i],
RFREG_MASK, rf_reg[path][i]);
@ -126,7 +85,7 @@ void rtw8922a_ctl_band_ch_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
if (hal->cv != CHIP_CAV)
return;
if (band == RTW89_BAND_2G) {
if (chan->band_type == RTW89_BAND_2G) {
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x00003);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c990);
@ -145,8 +104,7 @@ void rtw8922a_set_channel_rf(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
rtw8922a_ctl_band_ch_bw(rtwdev, phy_idx, chan->channel, chan->band_type,
chan->band_width);
rtw8922a_ctl_band_ch_bw(rtwdev, phy_idx, chan);
}
enum _rf_syn_pow {

View File

@ -106,6 +106,7 @@ static struct pci_driver rtw89_8922ae_driver = {
.probe = rtw89_pci_probe,
.remove = rtw89_pci_remove,
.driver.pm = &rtw89_pm_ops_be,
.err_handler = &rtw89_pci_err_handler,
};
module_pci_driver(rtw89_8922ae_driver);

View File

@ -199,7 +199,8 @@ struct rtw89_sar_handler rtw89_sar_handlers[RTW89_SAR_SOURCE_NR] = {
typeof(_dev) _d = (_dev); \
BUILD_BUG_ON(!rtw89_sar_handlers[_s].descr_sar_source); \
BUILD_BUG_ON(!rtw89_sar_handlers[_s].query_sar_config); \
lockdep_assert_wiphy(_d->hw->wiphy); \
if (test_bit(RTW89_FLAG_PROBE_DONE, _d->flags)) \
lockdep_assert_wiphy(_d->hw->wiphy); \
_d->sar._cfg_name = *(_cfg_data); \
_d->sar.src = _s; \
} while (0)
@ -499,8 +500,6 @@ static void rtw89_set_sar_from_acpi(struct rtw89_dev *rtwdev)
struct rtw89_sar_cfg_acpi *cfg;
int ret;
lockdep_assert_wiphy(rtwdev->hw->wiphy);
cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
if (!cfg)
return;

View File

@ -566,21 +566,22 @@ static void ser_mac_mem_dump(struct rtw89_dev *rtwdev, u8 *buf,
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u32 filter_model_addr = mac->filter_model_addr;
u32 indir_access_addr = mac->indir_access_addr;
u32 mem_page_size = mac->mem_page_size;
u32 *ptr = (u32 *)buf;
u32 base_addr, start_page, residue;
u32 cnt = 0;
u32 i;
start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE;
residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE;
start_page = start_addr / mem_page_size;
residue = start_addr % mem_page_size;
base_addr = mac->mem_base_addrs[sel];
base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE;
base_addr += start_page * mem_page_size;
while (cnt < len) {
rtw89_write32(rtwdev, filter_model_addr, base_addr);
for (i = indir_access_addr + residue;
i < indir_access_addr + MAC_MEM_DUMP_PAGE_SIZE;
i < indir_access_addr + mem_page_size;
i += 4, ptr++) {
*ptr = rtw89_read32(rtwdev, i);
cnt += 4;
@ -589,7 +590,7 @@ static void ser_mac_mem_dump(struct rtw89_dev *rtwdev, u8 *buf,
}
residue = 0;
base_addr += MAC_MEM_DUMP_PAGE_SIZE;
base_addr += mem_page_size;
}
}