From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
To: "linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>
Cc: Ping-Ke Shih <pkshih@realtek.com>
Subject: [PATCH rtw-next 2/5] wifi: rtw88: Pass TX descriptor to rtw_tx_fill_tx_desc()
Date: Sat, 24 Oct 2026 02:00:22 +0300 [thread overview]
Message-ID: <572b1037-c5f6-447b-94de-21fc62565303@gmail.com> (raw)
In-Reply-To: <2033f1b1-fb12-4a04-aef4-923590e64463@gmail.com>
The current code assumes the TX descriptor is in the same buffer as
the 802.11 frame, but that's not true for the RTL8821AE. It uses an
older design which keeps the TX descriptor in the TX ring.
In order to support the RTL8821AE (PCIe) give rtw_tx_fill_tx_desc() a
pointer to struct rtw_tx_desc instead of struct sk_buff.
Also pass the TX descriptor to rtw_tx_fill_txdesc_checksum() as
pointer to struct rtw_tx_desc instead of u8.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
drivers/net/wireless/realtek/rtw88/fw.c | 4 ++--
drivers/net/wireless/realtek/rtw88/main.h | 3 ++-
drivers/net/wireless/realtek/rtw88/pci.c | 4 ++--
drivers/net/wireless/realtek/rtw88/rtw8723b.c | 2 +-
drivers/net/wireless/realtek/rtw88/rtw8723x.c | 2 +-
drivers/net/wireless/realtek/rtw88/rtw8723x.h | 4 ++--
drivers/net/wireless/realtek/rtw88/rtw8812a.c | 2 +-
drivers/net/wireless/realtek/rtw88/rtw8814a.c | 2 +-
drivers/net/wireless/realtek/rtw88/rtw8821a.c | 2 +-
drivers/net/wireless/realtek/rtw88/rtw8821c.c | 2 +-
drivers/net/wireless/realtek/rtw88/rtw8822b.c | 2 +-
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 2 +-
drivers/net/wireless/realtek/rtw88/sdio.c | 4 ++--
drivers/net/wireless/realtek/rtw88/tx.c | 4 ++--
drivers/net/wireless/realtek/rtw88/tx.h | 10 +++++-----
drivers/net/wireless/realtek/rtw88/usb.c | 17 +++++++++--------
16 files changed, 34 insertions(+), 32 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index 945fedcd375b..3a9e1325a519 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -1302,12 +1302,12 @@ static void rtw_fill_rsvd_page_desc(struct rtw_dev *rtwdev, struct sk_buff *skb,
{
struct rtw_tx_pkt_info pkt_info = {0};
const struct rtw_chip_info *chip = rtwdev->chip;
- u8 *pkt_desc;
+ struct rtw_tx_desc *pkt_desc;
rtw_tx_rsvd_page_pkt_info_update(rtwdev, &pkt_info, skb, type);
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
- rtw_tx_fill_tx_desc(rtwdev, &pkt_info, skb);
+ rtw_tx_fill_tx_desc(rtwdev, &pkt_info, pkt_desc);
}
static inline u8 rtw_len_to_page(unsigned int len, u16 page_size)
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index d59f6e323adf..6287994f9b31 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -51,6 +51,7 @@ extern const struct ieee80211_ops rtw_ops;
struct rtw_dev;
struct rtw_debugfs;
+struct rtw_tx_desc;
enum rtw_hci_type {
RTW_HCI_TYPE_PCIE,
@@ -913,7 +914,7 @@ struct rtw_chip_ops {
/* for USB/SDIO only */
void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
- u8 *txdesc);
+ struct rtw_tx_desc *txdesc);
/* for coex */
void (*coex_set_init)(struct rtw_dev *rtwdev);
diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c
index c2d6d3a939cd..d8c5c11bf728 100644
--- a/drivers/net/wireless/realtek/rtw88/pci.c
+++ b/drivers/net/wireless/realtek/rtw88/pci.c
@@ -811,7 +811,7 @@ static int rtw_pci_tx_write_data(struct rtw_dev *rtwdev,
u32 tx_buf_desc_sz = chip->tx_buf_desc_sz;
u32 size;
u32 psb_len;
- u8 *pkt_desc;
+ struct rtw_tx_desc *pkt_desc;
struct rtw_pci_tx_buffer_desc *buf_desc;
ring = &rtwpci->tx_rings[queue];
@@ -826,7 +826,7 @@ static int rtw_pci_tx_write_data(struct rtw_dev *rtwdev,
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
memset(pkt_desc, 0, tx_pkt_desc_sz);
pkt_info->qsel = rtw_pci_get_tx_qsel(skb, queue);
- rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
+ rtw_tx_fill_tx_desc(rtwdev, pkt_info, pkt_desc);
dma = dma_map_single(&rtwpci->pdev->dev, skb->data, skb->len,
DMA_TO_DEVICE);
if (dma_mapping_error(&rtwpci->pdev->dev, dma))
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723b.c b/drivers/net/wireless/realtek/rtw88/rtw8723b.c
index 8bb9c03d769c..af78277fcb17 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723b.c
@@ -2343,7 +2343,7 @@ static void rtw8723b_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
static void rtw8723b_fill_txdesc_checksum(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
- u8 *txdesc)
+ struct rtw_tx_desc *txdesc)
{
/* Unlike the shared 8723x helper, the checksum is not inverted here. */
fill_txdesc_checksum_common(txdesc, 16);
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.c b/drivers/net/wireless/realtek/rtw88/rtw8723x.c
index 97e6f6a62c0d..9a039cd5c299 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723x.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.c
@@ -681,7 +681,7 @@ void __rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path,
static
void __rtw8723x_fill_txdesc_checksum(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
- u8 *txdesc)
+ struct rtw_tx_desc *txdesc)
{
size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */
__le16 chksum = 0;
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.h b/drivers/net/wireless/realtek/rtw88/rtw8723x.h
index e07b6ca99b3d..5e674784dfb1 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723x.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.h
@@ -154,7 +154,7 @@ struct rtw8723x_common {
void (*coex_cfg_init)(struct rtw_dev *rtwdev);
void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
- u8 *txdesc);
+ struct rtw_tx_desc *txdesc);
void (*debug_txpwr_limit)(struct rtw_dev *rtwdev,
struct rtw_txpwr_idx *table,
int tx_path_count);
@@ -510,7 +510,7 @@ static inline void rtw8723x_coex_cfg_init(struct rtw_dev *rtwdev)
static inline
void rtw8723x_fill_txdesc_checksum(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
- u8 *txdesc)
+ struct rtw_tx_desc *txdesc)
{
rtw8723x_common.fill_txdesc_checksum(rtwdev, pkt_info, txdesc);
}
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a.c b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
index 781b66ccde67..61afaa02b857 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8812a.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.c
@@ -886,7 +886,7 @@ static void rtw8812a_led_set(struct led_classdev *led,
static void rtw8812a_fill_txdesc_checksum(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
- u8 *txdesc)
+ struct rtw_tx_desc *txdesc)
{
fill_txdesc_checksum_common(txdesc, 16);
}
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8814a.c b/drivers/net/wireless/realtek/rtw88/rtw8814a.c
index fa02aa299b5e..fac69e8fb222 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8814a.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8814a.c
@@ -2041,7 +2041,7 @@ static void rtw8814a_led_set(struct led_classdev *led,
static void rtw8814a_fill_txdesc_checksum(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
- u8 *txdesc)
+ struct rtw_tx_desc *txdesc)
{
size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.c b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
index 6096d3b8e41b..f0987196caee 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821a.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.c
@@ -733,7 +733,7 @@ static void rtw8821a_led_set(struct led_classdev *led,
static void rtw8821a_fill_txdesc_checksum(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
- u8 *txdesc)
+ struct rtw_tx_desc *txdesc)
{
fill_txdesc_checksum_common(txdesc, 16);
}
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
index ee689fa3d87f..da67a6845fd5 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
@@ -1230,7 +1230,7 @@ static void rtw8821c_led_set(struct led_classdev *led,
static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
- u8 *txdesc)
+ struct rtw_tx_desc *txdesc)
{
fill_txdesc_checksum_common(txdesc, 16);
}
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
index a56c8befa077..a33ed11b2a63 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -1593,7 +1593,7 @@ static void rtw8822b_led_set(struct led_classdev *led,
static void rtw8822b_fill_txdesc_checksum(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
- u8 *txdesc)
+ struct rtw_tx_desc *txdesc)
{
size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index 32d9709f2c24..d2d98ae98e33 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -4562,7 +4562,7 @@ static void rtw8822c_led_set(struct led_classdev *led,
static void rtw8822c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
- u8 *txdesc)
+ struct rtw_tx_desc *txdesc)
{
const struct rtw_chip_info *chip = rtwdev->chip;
size_t words;
diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
index 2f0a6739df41..d9a73d30b7f5 100644
--- a/drivers/net/wireless/realtek/rtw88/sdio.c
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c
@@ -1180,8 +1180,8 @@ static void rtw_sdio_tx_skb_prepare(struct rtw_dev *rtwdev,
{
const struct rtw_chip_info *chip = rtwdev->chip;
unsigned long data_addr, aligned_addr;
+ struct rtw_tx_desc *pkt_desc;
size_t offset;
- u8 *pkt_desc;
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
@@ -1207,7 +1207,7 @@ static void rtw_sdio_tx_skb_prepare(struct rtw_dev *rtwdev,
pkt_info->qsel = rtw_sdio_get_tx_qsel(rtwdev, skb, queue);
- rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
+ rtw_tx_fill_tx_desc(rtwdev, pkt_info, pkt_desc);
rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc);
}
diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c
index 701ed7c4f3f7..49ce16352334 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.c
+++ b/drivers/net/wireless/realtek/rtw88/tx.c
@@ -33,9 +33,9 @@ void rtw_tx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
}
void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev,
- struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
+ struct rtw_tx_pkt_info *pkt_info,
+ struct rtw_tx_desc *tx_desc)
{
- struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data;
bool more_data = false;
if (pkt_info->qsel == TX_DESC_QSEL_HIGH)
diff --git a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h
index 168f48e87853..af031c02b4b7 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.h
+++ b/drivers/net/wireless/realtek/rtw88/tx.h
@@ -97,7 +97,8 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
struct ieee80211_sta *sta,
struct sk_buff *skb);
void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev,
- struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
+ struct rtw_tx_pkt_info *pkt_info,
+ struct rtw_tx_desc *tx_desc);
void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn);
void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src);
void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
@@ -117,11 +118,10 @@ enum rtw_tx_queue_type rtw_tx_ac_to_hwq(enum ieee80211_ac_numbers ac);
enum rtw_tx_queue_type rtw_tx_queue_mapping(struct sk_buff *skb);
static inline
-void fill_txdesc_checksum_common(u8 *txdesc, size_t words)
+void fill_txdesc_checksum_common(struct rtw_tx_desc *tx_desc, size_t words)
{
__le16 chksum = 0;
- __le16 *data = (__le16 *)(txdesc);
- struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc;
+ __le16 *data = (__le16 *)(tx_desc);
le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM);
@@ -134,7 +134,7 @@ void fill_txdesc_checksum_common(u8 *txdesc, size_t words)
static inline void rtw_tx_fill_txdesc_checksum(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
- u8 *txdesc)
+ struct rtw_tx_desc *txdesc)
{
const struct rtw_chip_info *chip = rtwdev->chip;
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
index a1b58061eb46..599e80650c65 100644
--- a/drivers/net/wireless/realtek/rtw88/usb.c
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
@@ -38,7 +38,7 @@ static void rtw_usb_fill_tx_checksum(struct rtw_usb *rtwusb,
le32p_replace_bits(&tx_desc->w7, agg_num, RTW_TX_DESC_W7_DMA_TXAGG_NUM);
pkt_info.pkt_offset = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_PKT_OFFSET);
- rtw_tx_fill_txdesc_checksum(rtwdev, &pkt_info, skb->data);
+ rtw_tx_fill_txdesc_checksum(rtwdev, &pkt_info, tx_desc);
}
static void rtw_usb_reg_sec(struct rtw_dev *rtwdev, u32 addr, __le32 *data)
@@ -511,6 +511,7 @@ static int rtw_usb_write_data(struct rtw_dev *rtwdev,
u8 *buf)
{
const struct rtw_chip_info *chip = rtwdev->chip;
+ struct rtw_tx_desc *pkt_desc;
struct sk_buff *skb;
unsigned int size;
u8 qsel;
@@ -525,10 +526,10 @@ static int rtw_usb_write_data(struct rtw_dev *rtwdev,
skb_reserve(skb, chip->tx_pkt_desc_sz);
skb_put_data(skb, buf, size);
- skb_push(skb, chip->tx_pkt_desc_sz);
- memset(skb->data, 0, chip->tx_pkt_desc_sz);
- rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
- rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
+ pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
+ memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
+ rtw_tx_fill_tx_desc(rtwdev, pkt_info, pkt_desc);
+ rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc);
ret = rtw_usb_write_port(rtwdev, qsel, skb,
rtw_usb_write_port_complete, skb);
@@ -644,15 +645,15 @@ static int rtw_usb_tx_write(struct rtw_dev *rtwdev,
struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
const struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_usb_tx_data *tx_data;
- u8 *pkt_desc;
+ struct rtw_tx_desc *pkt_desc;
int ep;
pkt_info->qsel = rtw_usb_tx_queue_mapping_to_qsel(rtwusb, skb);
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
ep = qsel_to_ep(rtwusb, pkt_info->qsel);
- rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
- rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
+ rtw_tx_fill_tx_desc(rtwdev, pkt_info, pkt_desc);
+ rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc);
tx_data = rtw_usb_get_tx_data(skb);
tx_data->sn = pkt_info->sn;
--
2.55.0
next prev parent reply other threads:[~2026-10-23 23:00 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-23 22:57 [PATCH rtw-next 0/5] wifi: rtw88: pci: Support an older design, like RTL8821AE/RTL8812AE Bitterblue Smith
2026-10-23 22:59 ` [PATCH rtw-next 1/5] wifi: rtw88: Pass RX buffer to rtw_rx_query_rx_desc() Bitterblue Smith
2026-10-23 23:00 ` Bitterblue Smith [this message]
2026-10-23 23:01 ` [PATCH rtw-next 3/5] wifi: rtw88: pci: Introduce struct rtw_pci_gen Bitterblue Smith
2026-10-24 8:41 ` Luka Gejak
2026-10-23 23:02 ` [PATCH rtw-next 4/5] wifi: rtw88: pci: Add functions to support older chips Bitterblue Smith
2026-10-24 8:36 ` Luka Gejak
2026-10-23 23:05 ` [PATCH rtw-next 5/5] wifi: rtw88: pci: Handle more RX interrupts for RTL8821AE Bitterblue Smith
2026-10-27 1:52 ` [PATCH rtw-next 0/5] wifi: rtw88: pci: Support an older design, like RTL8821AE/RTL8812AE 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=572b1037-c5f6-447b-94de-21fc62565303@gmail.com \
--to=rtl8821cerfe2@gmail.com \
--cc=linux-wireless@vger.kernel.org \
--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