From: Ho Jie Feng <hjf3108@gmail.com>
To: Ping-Ke Shih <pkshih@realtek.com>, linux-wireless@vger.kernel.org
Cc: Bitterblue Smith <rtl8821cerfe2@gmail.com>, linux-kernel@vger.kernel.org
Subject: [PATCH rtw-next v2 5/5] wifi: rtlwifi: rtl8192du: enable USB RX aggregation
Date: Tue, 10 Nov 2026 16:01:41 +0800 [thread overview]
Message-ID: <20261110080143.1362021-6-hjf3108@gmail.com> (raw)
In-Reply-To: <20261110080143.1362021-1-hjf3108@gmail.com>
Allow RX aggregation of up to 48 pages of 128 bytes or 24 with two MACs.
In an aggregated transfer, rtl92du_rx_segregate_hdl() copies each
frame into a new skb with room for the radiotap header like in usb.c.
The last frame reuses the original skb by pulling it to the frame's start
and trimmed to its length.
Test results (2.4 GHz):
before after
TX 5.2 6.4
RX 27.1 32.0
Signed-off-by: Ho Jie Feng <hjf3108@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
---
.../wireless/realtek/rtlwifi/rtl8192d/reg.h | 4 ++
.../wireless/realtek/rtlwifi/rtl8192du/hw.c | 18 +++++++-
.../wireless/realtek/rtlwifi/rtl8192du/sw.c | 2 +-
.../wireless/realtek/rtlwifi/rtl8192du/trx.c | 45 +++++++++++++++++++
.../wireless/realtek/rtlwifi/rtl8192du/trx.h | 4 ++
5 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/reg.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/reg.h
index 639aa0d92e..7cc46f411a 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192d/reg.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192d/reg.h
@@ -329,6 +329,7 @@
#define REG_USB_Queue_Select_MAC0 0xFE44
#define REG_USB_Queue_Select_MAC1 0xFE47
+#define REG_USB_DMA_AGG_TO 0xFE5B
/* ----------------------------------------------------- */
/* Redifine 8192C register definition for compatibility */
@@ -940,6 +941,9 @@
#define ENSWBCN BIT(8)
#define ENSEC BIT(9)
+/* REG_TRXDMA_CTRL */
+#define RXDMA_AGG_EN BIT(2)
+
#define HQSEL_VOQ BIT(0)
#define HQSEL_VIQ BIT(1)
#define HQSEL_BEQ BIT(2)
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/hw.c
index ff458fb851..3edd5bc432 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/hw.c
@@ -489,6 +489,22 @@ static void _rtl92du_init_retry_function(struct ieee80211_hw *hw)
rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
}
+static void _rtl92du_init_usb_aggregation(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 page_count = 48;
+
+ if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY)
+ page_count = 24;
+
+ rtl_write_byte(rtlpriv, REG_TRXDMA_CTRL,
+ rtl_read_byte(rtlpriv, REG_TRXDMA_CTRL) | RXDMA_AGG_EN);
+ /* unit: 128 bytes */
+ rtl_write_byte(rtlpriv, REG_RXDMA_AGG_PG_TH, page_count);
+ /* A larger value is a shorter timeout. */
+ rtl_write_byte(rtlpriv, REG_USB_DMA_AGG_TO, 6);
+}
+
static void _rtl92du_init_operation_mode(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -712,7 +728,7 @@ int rtl92du_hw_init(struct ieee80211_hw *hw)
rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x08070605);
_rtl92du_init_retry_function(hw);
- /* _InitUsbAggregationSetting(padapter); no aggregation for now */
+ _rtl92du_init_usb_aggregation(hw);
_rtl92du_init_operation_mode(hw);
_rtl92du_init_beacon_parameters(hw);
_rtl92du_init_ampdu_aggregation(hw);
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/sw.c
index 88e8cc590c..6b90002b69 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/sw.c
@@ -238,7 +238,7 @@ static const struct rtl_hal_usbint_cfg rtl92du_interface_cfg = {
.rx_urb_num = 8,
.rx_max_size = 15360,
.usb_rx_hdl = NULL,
- .usb_rx_segregate_hdl = NULL,
+ .usb_rx_segregate_hdl = rtl92du_rx_segregate_hdl,
/* tx */
.usb_tx_cleanup = rtl92du_tx_cleanup,
.usb_tx_post_hdl = rtl92du_tx_post_hdl,
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.c
index c608c51f1b..1641099368 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.c
@@ -19,6 +19,51 @@ int rtl92du_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb,
return 0;
}
+void rtl92du_rx_segregate_hdl(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct sk_buff_head *queue)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ unsigned int offset = 0, pkt_size;
+ struct sk_buff *new_skb;
+ __le32 *rxdesc;
+
+ while (skb->len - offset >= RTL_RX_DESC_SIZE) {
+ rxdesc = (__le32 *)(skb->data + offset);
+ pkt_size = RTL_RX_DESC_SIZE +
+ get_rx_desc_drv_info_size(rxdesc) *
+ RX_DRV_INFO_SIZE_UNIT +
+ get_rx_desc_shift(rxdesc) +
+ get_rx_desc_pkt_len(rxdesc);
+
+ if (get_rx_desc_pkt_len(rxdesc) == 0 ||
+ pkt_size > skb->len - offset) {
+ rtl_dbg(rtlpriv, COMP_RECV, DBG_WARNING,
+ "bad frame at %u of %u, size %u\n",
+ offset, skb->len, pkt_size);
+ break;
+ }
+
+ /* The last frame keeps the original skb. */
+ if (ALIGN(pkt_size, RTL92DU_RX_AGG_ALIGN) >= skb->len - offset) {
+ skb_pull(skb, offset);
+ skb_trim(skb, pkt_size);
+ __skb_queue_tail(queue, skb);
+ return;
+ }
+
+ new_skb = dev_alloc_skb(pkt_size + RTL_RADIO_TAP_SIZE_RSV);
+ if (!new_skb)
+ break;
+ skb_reserve(new_skb, RTL_RADIO_TAP_SIZE_RSV);
+ skb_put_data(new_skb, rxdesc, pkt_size);
+ __skb_queue_tail(queue, new_skb);
+
+ offset += ALIGN(pkt_size, RTL92DU_RX_AGG_ALIGN);
+ }
+
+ dev_kfree_skb_any(skb);
+}
+
struct sk_buff *rtl92du_tx_aggregate_hdl(struct ieee80211_hw *hw,
struct sk_buff_head *list)
{
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.h
index 8c3d24622f..47d7d6ad8c 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.h
@@ -18,6 +18,8 @@
#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER 0xF5
+#define RTL92DU_RX_AGG_ALIGN 128
+
#define WMM_NORMAL_PAGE_NUM_PUBQ_92D 0x65
#define WMM_NORMAL_PAGE_NUM_HPQ_92D 0x30
#define WMM_NORMAL_PAGE_NUM_LPQ_92D 0x30
@@ -56,5 +58,7 @@ struct sk_buff *rtl92du_tx_aggregate_hdl(struct ieee80211_hw *hw,
void rtl92du_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb);
int rtl92du_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb,
struct sk_buff *skb);
+void rtl92du_rx_segregate_hdl(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct sk_buff_head *queue);
#endif
--
2.53.0
prev parent reply other threads:[~2026-11-10 8:02 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20261110080143.1362021-1-hjf3108@gmail.com>
2026-11-10 8:01 ` [PATCH rtw-next v2 1/5] wifi: rtlwifi: rc: start no BA session for QoS null frames Ho Jie Feng
2026-11-10 8:01 ` [PATCH rtw-next v2 2/5] wifi: rtlwifi: rtl8192d: report no signal for frames without PHY status Ho Jie Feng
2026-11-10 8:01 ` [PATCH rtw-next v2 3/5] wifi: rtlwifi: usb: unify the RX code path Ho Jie Feng
2026-11-10 8:01 ` [PATCH rtw-next v2 4/5] wifi: rtlwifi: usb: move the radiotap headroom size to usb.h Ho Jie Feng
2026-11-10 8:01 ` Ho Jie Feng [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261110080143.1362021-6-hjf3108@gmail.com \
--to=hjf3108@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=pkshih@realtek.com \
--cc=rtl8821cerfe2@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®