summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/realtek
diff options
context:
space:
mode:
authorPing-Ke Shih <pkshih@realtek.com>2022-04-21 14:08:56 +0200
committerKalle Valo <kvalo@kernel.org>2022-04-24 13:30:35 +0200
commitd7259cdbd05598ec7e1e5a14f4c3644d80331758 (patch)
tree884c1431844351c9be3348d8c5fee0964eb74761 /drivers/net/wireless/realtek
parentrtw89: ps: access TX/RX rings via another registers in low power mode (diff)
downloadlinux-d7259cdbd05598ec7e1e5a14f4c3644d80331758.tar.xz
linux-d7259cdbd05598ec7e1e5a14f4c3644d80331758.zip
rtw89: pci: allow to process RPP prior to TX BD
RPP is to report certain skb(s) can be freed, and TX BD indicates which TX descriptors can be freed. Normally, TX BD is happened before RPP. In low power mode, RPP can happen ahead, so change flow to handle this case. Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/20220421120903.73715-8-pkshih@realtek.com
Diffstat (limited to 'drivers/net/wireless/realtek')
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
index 31c62d116f44..2bdce7024f25 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.c
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
@@ -382,6 +382,10 @@ static void rtw89_pci_reclaim_txbd(struct rtw89_dev *rtwdev, struct rtw89_pci_tx
}
list_del_init(&txwd->list);
+
+ /* this skb has been freed by RPP */
+ if (skb_queue_len(&txwd->queue) == 0)
+ rtw89_pci_enqueue_txwd(tx_ring, txwd);
}
}
@@ -413,18 +417,12 @@ static void rtw89_pci_release_txwd_skb(struct rtw89_dev *rtwdev,
if (!list_empty(&txwd->list)) {
rtw89_pci_reclaim_txbd(rtwdev, tx_ring);
- if (!list_empty(&txwd->list)) {
+ /* In low power mode, RPP can receive before updating of TX BD.
+ * In normal mode, it should not happen so give it a warning.
+ */
+ if (!rtwpci->low_power && !list_empty(&txwd->list))
rtw89_warn(rtwdev, "queue %d txwd %d is not idle\n",
txch, seq);
- return;
- }
- }
-
- /* currently, support for only one frame */
- if (skb_queue_len(&txwd->queue) != 1) {
- rtw89_warn(rtwdev, "empty pending queue %d page %d\n",
- txch, seq);
- return;
}
skb_queue_walk_safe(&txwd->queue, skb, tmp) {
@@ -437,7 +435,8 @@ static void rtw89_pci_release_txwd_skb(struct rtw89_dev *rtwdev,
rtw89_pci_tx_status(rtwdev, tx_ring, skb, tx_status);
}
- rtw89_pci_enqueue_txwd(tx_ring, txwd);
+ if (list_empty(&txwd->list))
+ rtw89_pci_enqueue_txwd(tx_ring, txwd);
}
static void rtw89_pci_release_rpp(struct rtw89_dev *rtwdev,