From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
To: Ping-Ke Shih <pkshih@realtek.com>, linux-wireless@vger.kernel.org
Cc: mh_chen@realtek.com, isaiah@realtek.com
Subject: Re: [PATCH rtw-next] wifi: rtw89: usb: Rx aggregation for RTL8832CU/RTL8851BU
Date: Wed, 11 Mar 2026 00:16:23 +0200 [thread overview]
Message-ID: <cd41b8ba-1141-43e5-88b4-917945ad56ea@gmail.com> (raw)
In-Reply-To: <20260309085819.25174-1-pkshih@realtek.com>
On 09/03/2026 10:58, Ping-Ke Shih wrote:
> From: Shin-Yi Lin <isaiah@realtek.com>
>
> USB RX Aggregation is a performance optimization technique used
> in USB network devices to increase throughput.
>
> Instead of sending every received network packet to the host computer
> individually, the device hardware groups multiple smaller packets
> into a single, large USB Bulk Transfer.
>
> * toAP/toNB use iperf3 respectively.
>
> With BE6000 - iperf3 tcp 10 pair (to another NB)
>
> RTL8832CU-USB3.0
> before after
> TX 941 941
> RX 847 919
>
> RTL8832CU-USB2.0
> before after
> TX 864 877
> RX 864 902
I wonder if these numbers are actually from a different scenario?
USB 2.0 can't go that fast.
>
> RTL8851BU
> before after
> TX 115 114
> RX 295 306
>
> Signed-off-by: Shin-Yi Lin <isaiah@realtek.com>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
> ---
> This one is to add USB RX aggregation to improve performance. The other
> one is TX aggregation, which we are working on.
That is wonderful news.
> ---
> .../net/wireless/realtek/rtw89/rtw8851bu.c | 1 +
> .../net/wireless/realtek/rtw89/rtw8852au.c | 1 +
> .../net/wireless/realtek/rtw89/rtw8852bu.c | 1 +
> .../net/wireless/realtek/rtw89/rtw8852cu.c | 1 +
> drivers/net/wireless/realtek/rtw89/usb.c | 84 ++++++++++++++++---
> drivers/net/wireless/realtek/rtw89/usb.h | 12 +++
> 6 files changed, 87 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851bu.c b/drivers/net/wireless/realtek/rtw89/rtw8851bu.c
> index 959d62aefdd8..6a8d31544314 100644
> --- a/drivers/net/wireless/realtek/rtw89/rtw8851bu.c
> +++ b/drivers/net/wireless/realtek/rtw89/rtw8851bu.c
> @@ -15,6 +15,7 @@ static const struct rtw89_usb_info rtw8851b_usb_info = {
> .usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0,
> .usb_endpoint_0 = R_AX_USB_ENDPOINT_0,
> .usb_endpoint_2 = R_AX_USB_ENDPOINT_2,
> + .rx_agg_alignment = 8,
> .bulkout_id = {
> [RTW89_DMA_ACH0] = 3,
> [RTW89_DMA_ACH1] = 4,
> diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852au.c b/drivers/net/wireless/realtek/rtw89/rtw8852au.c
> index ccdbcc178c2a..4cced4619b7d 100644
> --- a/drivers/net/wireless/realtek/rtw89/rtw8852au.c
> +++ b/drivers/net/wireless/realtek/rtw89/rtw8852au.c
> @@ -15,6 +15,7 @@ static const struct rtw89_usb_info rtw8852a_usb_info = {
> .usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0,
> .usb_endpoint_0 = R_AX_USB_ENDPOINT_0,
> .usb_endpoint_2 = R_AX_USB_ENDPOINT_2,
> + .rx_agg_alignment = 8,
> .bulkout_id = {
> [RTW89_DMA_ACH0] = 3,
> [RTW89_DMA_ACH2] = 5,
> diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bu.c b/drivers/net/wireless/realtek/rtw89/rtw8852bu.c
> index 84cd3ec971f9..37111fed276f 100644
> --- a/drivers/net/wireless/realtek/rtw89/rtw8852bu.c
> +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bu.c
> @@ -15,6 +15,7 @@ static const struct rtw89_usb_info rtw8852b_usb_info = {
> .usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0,
> .usb_endpoint_0 = R_AX_USB_ENDPOINT_0,
> .usb_endpoint_2 = R_AX_USB_ENDPOINT_2,
> + .rx_agg_alignment = 8,
> .bulkout_id = {
> [RTW89_DMA_ACH0] = 3,
> [RTW89_DMA_ACH1] = 4,
> diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852cu.c b/drivers/net/wireless/realtek/rtw89/rtw8852cu.c
> index 3b9825c92a0d..0c5aebaed873 100644
> --- a/drivers/net/wireless/realtek/rtw89/rtw8852cu.c
> +++ b/drivers/net/wireless/realtek/rtw89/rtw8852cu.c
> @@ -15,6 +15,7 @@ static const struct rtw89_usb_info rtw8852c_usb_info = {
> .usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0_V1,
> .usb_endpoint_0 = R_AX_USB_ENDPOINT_0_V1,
> .usb_endpoint_2 = R_AX_USB_ENDPOINT_2_V1,
> + .rx_agg_alignment = 8,
> .bulkout_id = {
> [RTW89_DMA_ACH0] = 3,
> [RTW89_DMA_ACH2] = 5,
> diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireless/realtek/rtw89/usb.c
> index da1b7ce8089e..4482ce61592b 100644
> --- a/drivers/net/wireless/realtek/rtw89/usb.c
> +++ b/drivers/net/wireless/realtek/rtw89/usb.c
> @@ -408,11 +408,14 @@ static int rtw89_usb_ops_tx_write(struct rtw89_dev *rtwdev,
> static void rtw89_usb_rx_handler(struct work_struct *work)
> {
> struct rtw89_usb *rtwusb = container_of(work, struct rtw89_usb, rx_work);
> + const struct rtw89_usb_info *info = rtwusb->info;
> struct rtw89_dev *rtwdev = rtwusb->rtwdev;
> struct rtw89_rx_desc_info desc_info;
> + s32 aligned_offset, remaining;
> struct sk_buff *rx_skb;
> struct sk_buff *skb;
> u32 pkt_offset;
> + u8 *pkt_ptr;
> int limit;
>
> for (limit = 0; limit < 200; limit++) {
> @@ -425,23 +428,38 @@ static void rtw89_usb_rx_handler(struct work_struct *work)
> goto free_or_reuse;
> }
>
> - memset(&desc_info, 0, sizeof(desc_info));
> - rtw89_chip_query_rxdesc(rtwdev, &desc_info, rx_skb->data, 0);
> + pkt_ptr = rx_skb->data;
> + remaining = rx_skb->len;
>
> - skb = rtw89_alloc_skb_for_rx(rtwdev, desc_info.pkt_size);
> - if (!skb) {
> - rtw89_debug(rtwdev, RTW89_DBG_HCI,
> - "failed to allocate RX skb of size %u\n",
> - desc_info.pkt_size);
> - goto free_or_reuse;
> - }
> + do {
> + memset(&desc_info, 0, sizeof(desc_info));
> + rtw89_chip_query_rxdesc(rtwdev, &desc_info, pkt_ptr, 0);
>
> - pkt_offset = desc_info.offset + desc_info.rxd_len;
> + pkt_offset = desc_info.offset + desc_info.rxd_len;
> + if (remaining < (pkt_offset + desc_info.pkt_size)) {
> + rtw89_debug(rtwdev, RTW89_DBG_HCI,
> + "Failed to get remaining RX pkt %u > %u\n",
> + pkt_offset + desc_info.pkt_size, remaining);
> + goto free_or_reuse;
> + }
>
> - skb_put_data(skb, rx_skb->data + pkt_offset,
> - desc_info.pkt_size);
> + skb = rtw89_alloc_skb_for_rx(rtwdev, desc_info.pkt_size);
> + if (!skb) {
> + rtw89_debug(rtwdev, RTW89_DBG_HCI,
> + "failed to allocate RX skb of size %u\n",
> + desc_info.pkt_size);
> + goto free_or_reuse;
> + }
> +
> + skb_put_data(skb, pkt_ptr + pkt_offset, desc_info.pkt_size);
> + rtw89_core_rx(rtwdev, &desc_info, skb);
>
> - rtw89_core_rx(rtwdev, &desc_info, skb);
> + /* next frame */
> + pkt_offset += desc_info.pkt_size;
> + aligned_offset = ALIGN(pkt_offset, info->rx_agg_alignment);
> + pkt_ptr += aligned_offset;
> + remaining -= aligned_offset;
> + } while (remaining > 0);
>
> free_or_reuse:
> if (skb_queue_len(&rtwusb->rx_free_queue) >= RTW89_USB_RX_SKB_NUM)
> @@ -745,6 +763,44 @@ static int rtw89_usb_ops_mac_pre_deinit(struct rtw89_dev *rtwdev)
> return 0; /* Nothing to do. */
> }
>
> +static void usb_rx_agg_cfg_v1(struct rtw89_dev *rtwdev)
Maybe give the new functions the usual "rtw89_" prefix?
> +{
> + const u32 rxagg_0 = FIELD_PREP_CONST(B_AX_RXAGG_0_EN, 1) |
> + FIELD_PREP_CONST(B_AX_RXAGG_0_NUM_TH, 0) |
> + FIELD_PREP_CONST(B_AX_RXAGG_0_TIME_32US_TH, 32) |
> + FIELD_PREP_CONST(B_AX_RXAGG_0_BUF_SZ_4K, 5);
> +
> + rtw89_write32(rtwdev, R_AX_RXAGG_0, rxagg_0);
> +}
> +
> +static void usb_rx_agg_cfg_v2(struct rtw89_dev *rtwdev)
> +{
> + const u32 rxagg_0 = FIELD_PREP_CONST(B_AX_RXAGG_0_EN, 1) |
> + FIELD_PREP_CONST(B_AX_RXAGG_0_NUM_TH, 255) |
> + FIELD_PREP_CONST(B_AX_RXAGG_0_TIME_32US_TH, 32) |
> + FIELD_PREP_CONST(B_AX_RXAGG_0_BUF_SZ_K, 20);
> +
> + rtw89_write32(rtwdev, R_AX_RXAGG_0_V1, rxagg_0);
> + rtw89_write32(rtwdev, R_AX_RXAGG_1_V1, 0x1F);
> +}
> +
> +static void usb_rx_agg_cfg(struct rtw89_dev *rtwdev)
> +{
> + switch (rtwdev->chip->chip_id) {
> + case RTL8851B:
> + case RTL8852A:
> + case RTL8852B:
> + usb_rx_agg_cfg_v1(rtwdev);
> + break;
> + case RTL8852C:
> + usb_rx_agg_cfg_v2(rtwdev);
> + break;
> + default:
> + rtw89_warn(rtwdev, "%s: USB RX agg not support\n", __func__);
> + return;
> + }
The subject only mentions RTL8832CU and RTL8851BU, but looks like you
implemented it for every chip currently supported.
> +}
> +
> static int rtw89_usb_ops_mac_post_init(struct rtw89_dev *rtwdev)
> {
> struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev);
> @@ -773,6 +829,8 @@ static int rtw89_usb_ops_mac_post_init(struct rtw89_dev *rtwdev)
> rtw89_write8(rtwdev, info->usb_endpoint_2 + 1, NUMP);
> }
>
> + usb_rx_agg_cfg(rtwdev);
> +
> return 0;
> }
>
> diff --git a/drivers/net/wireless/realtek/rtw89/usb.h b/drivers/net/wireless/realtek/rtw89/usb.h
> index 203ec8e993e9..afc62c1f687f 100644
> --- a/drivers/net/wireless/realtek/rtw89/usb.h
> +++ b/drivers/net/wireless/realtek/rtw89/usb.h
> @@ -20,6 +20,17 @@
> #define RTW89_MAX_ENDPOINT_NUM 9
> #define RTW89_MAX_BULKOUT_NUM 7
>
> +#define R_AX_RXAGG_0_V1 0x6000
> +#define B_AX_RXAGG_0_EN BIT(31)
> +#define B_AX_RXAGG_0_NUM_TH GENMASK(23, 16)
> +#define B_AX_RXAGG_0_TIME_32US_TH GENMASK(15, 8)
> +#define B_AX_RXAGG_0_BUF_SZ_K GENMASK(7, 0)
Is it missing a number before the letter K ?
> +
> +#define R_AX_RXAGG_1_V1 0x6004
> +
> +#define R_AX_RXAGG_0 0x8900
> +#define B_AX_RXAGG_0_BUF_SZ_4K GENMASK(7, 0)
> +
> struct rtw89_usb_info {
> u32 usb_host_request_2;
> u32 usb_wlan0_1;
> @@ -27,6 +38,7 @@ struct rtw89_usb_info {
> u32 usb3_mac_npi_config_intf_0;
> u32 usb_endpoint_0;
> u32 usb_endpoint_2;
> + u8 rx_agg_alignment;
> u8 bulkout_id[RTW89_DMA_CH_NUM];
> };
>
>
> base-commit: 039cd522dc70151da13329a5e3ae19b1736f468a
next prev parent reply other threads:[~2026-03-10 22:16 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-09 8:58 [PATCH rtw-next] wifi: rtw89: usb: Rx aggregation for RTL8832CU/RTL8851BU Ping-Ke Shih
2026-03-10 22:16 ` Bitterblue Smith [this message]
[not found] ` <197660d0061246518129933398072dd5@realtek.com>
2026-03-12 2:30 ` Isaiah
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=cd41b8ba-1141-43e5-88b4-917945ad56ea@gmail.com \
--to=rtl8821cerfe2@gmail.com \
--cc=isaiah@realtek.com \
--cc=linux-wireless@vger.kernel.org \
--cc=mh_chen@realtek.com \
--cc=pkshih@realtek.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