wifi: rtw89: pci: fix PCI doesn't reclaim TX BD properly
authorPing-Ke Shih <pkshih@realtek.com>
Fri, 10 Jun 2022 07:26:09 +0000 (15:26 +0800)
committerKalle Valo <kvalo@kernel.org>
Tue, 21 Jun 2022 06:15:48 +0000 (09:15 +0300)
TX BD (TX ring index) and TX WD (WiFi descriptor buffer) are freed
asynchronously. With burst packets, we free TX WD, but the corresponding
TX BD couldn't be freed yet. Then, TX can possibly get stuck due to no
more TX BD.

To avoid this, ignore reclaiming TX BD only if TX WD is no free space,
because at this moment TX BD must have some spaces. Otherwise, we reclaim
TX BD to resolve TX stuck issue.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220610072610.27095-11-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/pci.c

index fd5d9bde010855f3c2af995e246b4cbae2b347d6..73b3b7e9fe6f5bc7c9d27875363a893b70adcd0f 100644 (file)
@@ -952,9 +952,10 @@ static u32 __rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev,
 
        if (wd_cnt == 0 || bd_cnt == 0) {
                cnt = rtw89_pci_rxbd_recalc(rtwdev, rx_ring);
-               if (!cnt)
+               if (cnt)
+                       rtw89_pci_release_tx(rtwdev, rx_ring, cnt);
+               else if (wd_cnt == 0)
                        goto out_unlock;
-               rtw89_pci_release_tx(rtwdev, rx_ring, cnt);
 
                bd_cnt = rtw89_pci_get_avail_txbd_num(tx_ring);
                if (bd_cnt == 0)
@@ -965,7 +966,9 @@ static u32 __rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev,
        wd_cnt = wd_ring->curr_num;
        min_cnt = min(bd_cnt, wd_cnt);
        if (min_cnt == 0)
-               rtw89_warn(rtwdev, "still no tx resource after reclaim\n");
+               rtw89_debug(rtwdev, rtwpci->low_power ? RTW89_DBG_TXRX : RTW89_DBG_UNEXP,
+                           "still no tx resource after reclaim: wd_cnt=%d bd_cnt=%d\n",
+                           wd_cnt, bd_cnt);
 
 out_unlock:
        spin_unlock_bh(&rtwpci->trx_lock);