86 lines
3.4 KiB
Diff
86 lines
3.4 KiB
Diff
From 67d7f24b194e6e8e82540aa4fe97580f6cfa0902 Mon Sep 17 00:00:00 2001
|
|
From: Chih-Kang Chang <gary.chang@realtek.com>
|
|
Date: Fri, 16 Jun 2023 11:17:13 +0800
|
|
Subject: [PATCH 2/8] wifi: rtw88: process VO packets without workqueue to
|
|
avoid PTK rekey failed
|
|
|
|
In the wpa_supplicant rekey flow, it sends an EAPOL packet 4/4 through
|
|
nl80211_tx_control_port() and triggers wake_tx_queue() in the driver.
|
|
Then, it sends nl80211_new_key() to configure a new key in mac80211.
|
|
However, in wake_tx_queue(), a workqueue is used to process the tx packet,
|
|
which might cause the driver to process the EAPOL packet later than
|
|
nl80211_new_key(). As a result, the EAPOL 4/4 packet is dropped by mac80211
|
|
due to the rekey configuration being finished. The EAPOL packets belongs to
|
|
VO packets that need high priority. Therefore, we process VO packets
|
|
directly without workqueue to ensure that packets can process immediately.
|
|
|
|
VO is normally used by voice application that is low traffic load and low
|
|
latency, that doesn't affect user experience.
|
|
We test iperf with VO packets(iperf3 -P4 -u -b 10000M -S 0xdf)
|
|
before after
|
|
TX throughput 162M 162M
|
|
ping RTT 3.8ms 3.7ms
|
|
|
|
Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
|
|
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
|
Signed-off-by: Kalle Valo <kvalo@kernel.org>
|
|
Link: https://lore.kernel.org/r/20230616031713.16769-1-pkshih@realtek.com
|
|
---
|
|
drivers/net/wireless/realtek/rtw88/mac80211.c | 6 +++++-
|
|
drivers/net/wireless/realtek/rtw88/tx.c | 10 ++++++++--
|
|
drivers/net/wireless/realtek/rtw88/tx.h | 1 +
|
|
3 files changed, 14 insertions(+), 3 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
|
|
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
|
|
@@ -43,7 +43,11 @@ static void rtw_ops_wake_tx_queue(struct
|
|
list_add_tail(&rtwtxq->list, &rtwdev->txqs);
|
|
spin_unlock_bh(&rtwdev->txq_lock);
|
|
|
|
- queue_work(rtwdev->tx_wq, &rtwdev->tx_work);
|
|
+ /* ensure to dequeue EAPOL (4/4) at the right time */
|
|
+ if (txq->ac == IEEE80211_AC_VO)
|
|
+ __rtw_tx_work(rtwdev);
|
|
+ else
|
|
+ queue_work(rtwdev->tx_wq, &rtwdev->tx_work);
|
|
}
|
|
|
|
static int rtw_ops_start(struct ieee80211_hw *hw)
|
|
--- a/drivers/net/wireless/realtek/rtw88/tx.c
|
|
+++ b/drivers/net/wireless/realtek/rtw88/tx.c
|
|
@@ -635,9 +635,8 @@ static void rtw_txq_push(struct rtw_dev
|
|
rcu_read_unlock();
|
|
}
|
|
|
|
-void rtw_tx_work(struct work_struct *w)
|
|
+void __rtw_tx_work(struct rtw_dev *rtwdev)
|
|
{
|
|
- struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work);
|
|
struct rtw_txq *rtwtxq, *tmp;
|
|
|
|
spin_lock_bh(&rtwdev->txq_lock);
|
|
@@ -658,6 +657,13 @@ void rtw_tx_work(struct work_struct *w)
|
|
spin_unlock_bh(&rtwdev->txq_lock);
|
|
}
|
|
|
|
+void rtw_tx_work(struct work_struct *w)
|
|
+{
|
|
+ struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work);
|
|
+
|
|
+ __rtw_tx_work(rtwdev);
|
|
+}
|
|
+
|
|
void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq)
|
|
{
|
|
struct rtw_txq *rtwtxq;
|
|
--- a/drivers/net/wireless/realtek/rtw88/tx.h
|
|
+++ b/drivers/net/wireless/realtek/rtw88/tx.h
|
|
@@ -111,6 +111,7 @@ void rtw_tx(struct rtw_dev *rtwdev,
|
|
void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq);
|
|
void rtw_txq_cleanup(struct rtw_dev *rtwdev, struct ieee80211_txq *txq);
|
|
void rtw_tx_work(struct work_struct *w);
|
|
+void __rtw_tx_work(struct rtw_dev *rtwdev);
|
|
void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
|
|
struct rtw_tx_pkt_info *pkt_info,
|
|
struct ieee80211_sta *sta,
|