public inbox for linux-wireless@vger.kernel.org
 help / color / mirror / Atom feed
From: Isaiah <isaiah@realtek.com>
To: Bitterblue Smith <rtl8821cerfe2@gmail.com>,
	Ping-Ke Shih <pkshih@realtek.com>,
	"linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>
Cc: Mh_chen <mh_chen@realtek.com>
Subject: RE: [PATCH rtw-next] wifi: rtw89: usb: Rx aggregation for RTL8832CU/RTL8851BU
Date: Thu, 12 Mar 2026 02:30:22 +0000	[thread overview]
Message-ID: <2e5466501ba44d2194f355154cf26d56@realtek.com> (raw)
In-Reply-To: <197660d0061246518129933398072dd5@realtek.com>

________________________________________
寄件者: Bitterblue Smith <mailto:rtl8821cerfe2@gmail.com>
寄件日期: 2026年3月11日 上午 06:16
收件者: Ping-Ke Shih; mailto:linux-wireless@vger.kernel.org
副本: Mh_chen; Isaiah
主旨: Re: [PATCH rtw-next] wifi: rtw89: usb: Rx aggregation for RTL8832CU/RTL8851BU 
 

External mail : This email originated from outside the organization. Do not reply, click links, or open attachments unless you recognize the sender and know the content is safe.



On 09/03/2026 10:58, Ping-Ke Shih wrote:
> From: Shin-Yi Lin <mailto: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.

Sorry, I made a mistake in the data.
Details as below. The corrected data will be included in next patch.
[6G 160Mhz]:

 RTL8832CU-USB3.0
       before   after
 TX    941      941
 RX    847      919

 RTL8832CU-USB2.0
       before   after
 TX    293      286
 RX    342      356

-------------------------------
[5G 80Mhz]:

 RTL8832CU-USB3.0
       before   after
 TX    864      877
 RX    864      902

 RTL8832CU-USB2.0
       before   after
 TX    279      271
 RX    327      349

 RTL8851BU
       before   after
 TX    115      114
 RX    295      306


>
> RTL8851BU
>       before   after
> TX    115      114
> RX    295      306
>
> Signed-off-by: Shin-Yi Lin <mailto:isaiah@realtek.com>
> Signed-off-by: Ping-Ke Shih <mailto: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?

OK, I will refine in next patch

> +{
> +     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.

Basically all are supported, but I have only verified RTL8832CU and RTL8851BU.

> +}
> +
>  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 ?

OK, I will refine in next patch

> +
> +#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

      parent reply	other threads:[~2026-03-12  2:30 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
     [not found]   ` <197660d0061246518129933398072dd5@realtek.com>
2026-03-12  2:30     ` Isaiah [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=2e5466501ba44d2194f355154cf26d56@realtek.com \
    --to=isaiah@realtek.com \
    --cc=linux-wireless@vger.kernel.org \
    --cc=mh_chen@realtek.com \
    --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