Linux wireless drivers development
 help / color / mirror / Atom feed
From: Ping-Ke Shih <pkshih@realtek.com>
To: "luka.gejak@linux.dev" <luka.gejak@linux.dev>,
	"linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"Michael Straube" <straube.linux@gmail.com>,
	Bitterblue Smith <rtl8821cerfe2@gmail.com>,
	Peter Robinson <pbrobinson@gmail.com>,
	"Hans de Goede" <johannes.goede@oss.qualcomm.com>
Subject: RE: [PATCH v4 5/7] wifi: rtw88: sdio: track free TX pages and OQT credits for RTL8723BS
Date: Fri, 14 Aug 2026 06:32:15 +0000	[thread overview]
Message-ID: <4e17292f3b424b71a4194c0b8ebb705e@realtek.com> (raw)
In-Reply-To: <20260811091203.26841-6-luka.gejak@linux.dev>

luka.gejak@linux.dev <luka.gejak@linux.dev> wrote:
> From: Luka Gejak <luka.gejak@linux.dev>
> 
> The RTL8723BS reports free TX page counts that the generic 8051 path
> reads back from the chip on every transfer, which is both slow over SDIO
> and unreliable on this part: the register frequently reads back zero
> while pages are in fact available. It also gates transmission on a free
> count in the SDIO output queue, REG_SDIO_OQT_FREE_PG, which rtw88 does

It seems like I asked you what OQT is... Output Queue Track?
Please mention it in commit message. I'd be easier to reviewers. 

> not track at all. That count is how many more descriptors the SDIO
> engine can accept, and the chip discards writes that arrive with none
> left.
> 
> Mirror the vendor driver and keep the per-queue and public page counts
> in software, seeded at start and resynchronised from the chip only when
> the cached counts say there is not enough room. Wait for a free output
> queue entry before writing, and account for the pages consumed after a
> successful transfer.
> 
> Transfers also have to be padded up to the SDIO block size for this
> chip rather than using the generic alignment, so size the write
> separately from the frame and trim the skb back afterwards.
> 
> Measured on RTL8723BS hardware against an iperf3 server one hop behind
> the AP, with the wlan0 byte counters as ground truth. On the generic
> path the association completes but no data passes at all: TCP and UDP
> both measure 0 bit/s in either direction. With this patch TCP is
> 25.3 Mbit/s up and 37.3 Mbit/s down, and UDP is 25.0 Mbit/s up at 0%
> loss.
> 
> Signed-off-by: Luka Gejak <luka.gejak@linux.dev>
> ---
>  drivers/net/wireless/realtek/rtw88/sdio.c | 245 ++++++++++++++++++++--
>  drivers/net/wireless/realtek/rtw88/sdio.h |  10 +
>  2 files changed, 243 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
> index 5b40d74b16ee..493eda559607 100644
> --- a/drivers/net/wireless/realtek/rtw88/sdio.c
> +++ b/drivers/net/wireless/realtek/rtw88/sdio.c
> @@ -20,6 +20,7 @@
>  #include "tx.h"
> 
>  #define RTW_SDIO_INDIRECT_RW_RETRIES                   50
> +#define RTW_SDIO_OQT_TIMEOUT_MS                                1000

nit: The unit can be '_MS' only if the delay in the loop is
'usleep_range(1000, 2000);' (1ms). 

With _MS, it is easier to understand, but any opinion to improve it?

> 
>  static bool rtw_sdio_is_bus_addr(u32 addr)
>  {
> @@ -548,12 +549,122 @@ static int rtw_sdio_read_port(struct rtw_dev *rtwdev, u8 *buf, size_t count)
>         return ret;
>  }
> 
> +/*
> + * The cached free page counters are a fast path hint only. They are written
> + * from the single threaded TX work and, for H2C and reserved page writes,
> + * from process context, so they are atomic_t; whenever they claim there is
> + * not enough room they are resynchronised from the chip before the caller
> + * gives up, which also absorbs a lost update.
> + */
> +static void rtw_sdio_8723bs_store_free_txpg(struct rtw_dev *rtwdev,
> +                                           u32 free_txpg)
> +{

nit: It looks like you can combine callers of rtw_sdio_8723bs_store_free_txpg()
into single function. Maybe, just rtw_sdio_8723bs_sync_free_txpg(), and add
a return value for rtw_sdio_8723bs_init_free_txpg().

How about you?

> +       struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
> +
> +       atomic_set(&rtwsdio->free_pg_high,
> +                  u32_get_bits(free_txpg, BIT_FREE_TXPG_HIGH));
> +       atomic_set(&rtwsdio->free_pg_normal,
> +                  u32_get_bits(free_txpg, BIT_FREE_TXPG_NORMAL));
> +       atomic_set(&rtwsdio->free_pg_low,
> +                  u32_get_bits(free_txpg, BIT_FREE_TXPG_LOW));
> +       atomic_set(&rtwsdio->free_pg_pub,
> +                  u32_get_bits(free_txpg, BIT_FREE_TXPG_PUB));
> +}
> +

[...]

> @@ -749,8 +939,39 @@ static int rtw_sdio_setup(struct rtw_dev *rtwdev)
>         return 0;
>  }
> 
> +static void rtw_sdio_8723bs_check_rqpn(struct rtw_dev *rtwdev)
> +{
> +       const struct rtw_chip_info *chip = rtwdev->chip;
> +       struct rtw_fifo_conf *fifo = &rtwdev->fifo;
> +       const struct rtw_page_table *pg_tbl;
> +       u16 reserved_num;
> +       u32 free_txpg;
> +       u16 pubq_num;
> +
> +       free_txpg = rtw_read32(rtwdev, REG_SDIO_FREE_TXPG);
> +       if (free_txpg || !fifo->acq_pg_num)

It will return directly if free_txpg is not zero... what does it mean?

> +               return;
> +
> +       pg_tbl = &chip->page_table[0];
> +       reserved_num = pg_tbl->hq_num + pg_tbl->lq_num + pg_tbl->nq_num +
> +                      pg_tbl->exq_num + pg_tbl->gapq_num;
> +       if (fifo->acq_pg_num <= reserved_num)

If it falls into this case, can it still work? If not, should it return
an error?

> +               return;
> +
> +       pubq_num = fifo->acq_pg_num - reserved_num;
> +       rtw_write32(rtwdev, REG_RQPN_NPQ,
> +                   BIT_RQPN_NE(pg_tbl->nq_num, pg_tbl->exq_num));
> +       rtw_write32(rtwdev, REG_RQPN,
> +                   BIT_RQPN_HLP(pg_tbl->hq_num, pg_tbl->lq_num, pubq_num));
> +}
> +
>  static int rtw_sdio_start(struct rtw_dev *rtwdev)
>  {
> +       if (rtw_is_8723bs(rtwdev)) {
> +               rtw_sdio_8723bs_check_rqpn(rtwdev);
> +               rtw_sdio_8723bs_init_free_txpg(rtwdev);
> +       }
> +
>         rtw_sdio_enable_rx_aggregation(rtwdev);
>         rtw_sdio_enable_interrupt(rtwdev);
> 

[...]


  reply	other threads:[~2026-08-14  6:32 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-11  9:11 [PATCH v4 0/7] wifi: rtw88: preparations for RTL8723B/RTL8723BS luka.gejak
2026-08-11  9:11 ` [PATCH v4 1/7] wifi: rtw88: add the RTL8723B chip type and SDIO helper luka.gejak
2026-08-14  7:15   ` Ping-Ke Shih
2026-08-11  9:11 ` [PATCH v4 2/7] wifi: rtw88: rx: mark zero length packets on RTL8723BS luka.gejak
2026-08-14  5:44   ` Ping-Ke Shih
2026-08-11  9:11 ` [PATCH v4 3/7] wifi: rtw88: tx: extend the TX report purge timeout to RTL8723BS luka.gejak
2026-08-14  7:15   ` Ping-Ke Shih
2026-08-11  9:12 ` [PATCH v4 4/7] wifi: rtw88: fw: handle the RTL8723BS management TX reports luka.gejak
2026-08-11 11:42   ` Bitterblue Smith
2026-08-14  5:52     ` Ping-Ke Shih
2026-08-11  9:12 ` [PATCH v4 5/7] wifi: rtw88: sdio: track free TX pages and OQT credits for RTL8723BS luka.gejak
2026-08-14  6:32   ` Ping-Ke Shih [this message]
2026-08-11  9:12 ` [PATCH v4 6/7] wifi: rtw88: sdio: set up RX aggregation and interrupts " luka.gejak
2026-08-14  6:41   ` Ping-Ke Shih
2026-08-11  9:12 ` [PATCH v4 7/7] wifi: rtw88: sdio: add TX back-pressure and retry on page starvation luka.gejak
2026-08-14  7:14   ` Ping-Ke Shih

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=4e17292f3b424b71a4194c0b8ebb705e@realtek.com \
    --to=pkshih@realtek.com \
    --cc=johannes.goede@oss.qualcomm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=luka.gejak@linux.dev \
    --cc=pbrobinson@gmail.com \
    --cc=rtl8821cerfe2@gmail.com \
    --cc=straube.linux@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