public inbox for linux-wireless@vger.kernel.org
 help / color / mirror / Atom feed
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


  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