diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h index 5de67308889c..654c3c2e5721 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.h +++ b/drivers/net/wireless/realtek/rtw88/fw.h @@ -111,6 +111,7 @@ enum rtw_fw_feature { FW_FEATURE_LPS_C2H = BIT(1), FW_FEATURE_LCLK = BIT(2), FW_FEATURE_PG = BIT(3), + FW_FEATURE_TX_WAKE = BIT(4), FW_FEATURE_BCN_FILTER = BIT(5), FW_FEATURE_NOTIFY_SCAN = BIT(6), FW_FEATURE_ADAPTIVITY = BIT(7), diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index 08cf66141889..a0991d3f15c0 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -611,6 +611,9 @@ static void rtw_pci_deep_ps_enter(struct rtw_dev *rtwdev) bool tx_empty = true; u8 queue; + if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_TX_WAKE)) + goto enter_deep_ps; + lockdep_assert_held(&rtwpci->irq_lock); /* Deep PS state is not allowed to TX-DMA */ @@ -636,7 +639,7 @@ static void rtw_pci_deep_ps_enter(struct rtw_dev *rtwdev) "TX path not empty, cannot enter deep power save state\n"); return; } - +enter_deep_ps: set_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags); rtw_power_mode_change(rtwdev, true); } @@ -807,7 +810,8 @@ static void rtw_pci_tx_kick_off_queue(struct rtw_dev *rtwdev, u8 queue) bd_idx = rtw_pci_tx_queue_idx_addr[queue]; spin_lock_bh(&rtwpci->irq_lock); - rtw_pci_deep_ps_leave(rtwdev); + if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_TX_WAKE)) + rtw_pci_deep_ps_leave(rtwdev); rtw_write16(rtwdev, bd_idx, ring->r.wp & TRX_BD_IDX_MASK); spin_unlock_bh(&rtwpci->irq_lock); } diff --git a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c index 3f0ac33156d6..bfa64c038f5f 100644 --- a/drivers/net/wireless/realtek/rtw88/ps.c +++ b/drivers/net/wireless/realtek/rtw88/ps.c @@ -83,6 +83,9 @@ void rtw_power_mode_change(struct rtw_dev *rtwdev, bool enter) /* Each request require an ack from firmware */ request |= POWER_MODE_ACK; + if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_TX_WAKE)) + request |= POWER_TX_WAKE; + rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, request); /* Check firmware get the power requset and ack via cpwm register */ diff --git a/drivers/net/wireless/realtek/rtw88/ps.h b/drivers/net/wireless/realtek/rtw88/ps.h index 7819391c8663..c194386f6db5 100644 --- a/drivers/net/wireless/realtek/rtw88/ps.h +++ b/drivers/net/wireless/realtek/rtw88/ps.h @@ -9,6 +9,7 @@ #define POWER_MODE_ACK BIT(6) #define POWER_MODE_PG BIT(4) +#define POWER_TX_WAKE BIT(1) #define POWER_MODE_LCLK BIT(0) #define LEAVE_LPS_TRY_CNT 5