All of lore.kernel.org
 help / color / mirror / Atom feed
From: Luka Gejak <luka.gejak@linux.dev>
To: Ping-Ke Shih <pkshih@realtek.com>
Cc: linux-wireless@vger.kernel.org, Luka Gejak <luka.gejak@linux.dev>
Subject: [PATCH rtw-next v2 1/2] wifi: rtw88: move the bmc high queue decision to tx.c
Date: Wed, 21 Oct 2026 12:43:17 +0000	[thread overview]
Message-ID: <20261021124318.15993-1-luka.gejak@linux.dev> (raw)

USB decides in usb.c which broadcast and multicast (bmc) frames may use
the high queue. SDIO needs the same decision, so move the helpers to
tx.c behind a single exported rtw_tx_bmc_use_hiq() and keep the budget
state in struct rtw_dev.

No functional change.

Signed-off-by: Luka Gejak <luka.gejak@linux.dev>
---
 drivers/net/wireless/realtek/rtw88/main.c |  3 ++
 drivers/net/wireless/realtek/rtw88/main.h |  5 ++
 drivers/net/wireless/realtek/rtw88/tx.c   | 59 +++++++++++++++++++++
 drivers/net/wireless/realtek/rtw88/tx.h   |  4 ++
 drivers/net/wireless/realtek/rtw88/usb.c  | 64 ++---------------------
 drivers/net/wireless/realtek/rtw88/usb.h  |  5 --
 6 files changed, 74 insertions(+), 66 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 0f23498b5c96..b72173964bdd 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -2177,6 +2177,9 @@ int rtw_core_init(struct rtw_dev *rtwdev)
 
 	spin_lock_init(&rtwdev->txq_lock);
 	spin_lock_init(&rtwdev->tx_report.q_lock);
+	spin_lock_init(&rtwdev->hiq_lock);
+	rtwdev->hiq_budget = RTW_TX_HIQ_BUDGET_MAX;
+	rtwdev->hiq_refill = jiffies;
 
 	mutex_init(&rtwdev->mutex);
 	mutex_init(&rtwdev->hal.tx_power_mutex);
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index d59f6e323adf..c14c834c27fd 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -2104,6 +2104,11 @@ struct rtw_dev {
 
 	struct rtw_tx_report tx_report;
 
+	/* protects hiq_budget and hiq_refill */
+	spinlock_t hiq_lock;
+	u32 hiq_budget;
+	unsigned long hiq_refill;
+
 	struct {
 		/* indicate the mail box to use with fw */
 		u8 last_box_num;
diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c
index 701ed7c4f3f7..82c1af94f1cc 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.c
+++ b/drivers/net/wireless/realtek/rtw88/tx.c
@@ -2,6 +2,8 @@
 /* Copyright(c) 2018-2019  Realtek Corporation
  */
 
+#include <linux/ip.h>
+#include <linux/udp.h>
 #include "main.h"
 #include "tx.h"
 #include "fw.h"
@@ -745,3 +747,60 @@ enum rtw_tx_queue_type rtw_tx_queue_mapping(struct sk_buff *skb)
 	return queue;
 }
 EXPORT_SYMBOL(rtw_tx_queue_mapping);
+
+static bool rtw_tx_bmc_needs_dtim(struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct udphdr *udphdr;
+
+	if (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)
+		return true;
+
+	if (skb->protocol == htons(ETH_P_ARP))
+		return true;
+
+	if (skb->protocol == htons(ETH_P_IP) &&
+	    ip_hdr(skb)->protocol == IPPROTO_UDP) {
+		udphdr = udp_hdr(skb);
+
+		return udphdr->dest == htons(67) || udphdr->dest == htons(68);
+	}
+
+	return false;
+}
+
+static bool rtw_tx_hiq_take_budget(struct rtw_dev *rtwdev)
+{
+	unsigned long flags, elapsed, add;
+	bool ok;
+
+	spin_lock_irqsave(&rtwdev->hiq_lock, flags);
+
+	elapsed = jiffies - rtwdev->hiq_refill;
+	add = elapsed / RTW_TX_HIQ_REFILL_INTERVAL;
+	if (add) {
+		rtwdev->hiq_budget = min_t(unsigned long, rtwdev->hiq_budget + add,
+					   RTW_TX_HIQ_BUDGET_MAX);
+
+		/* keep the unfinished part of the interval for the next unit */
+		rtwdev->hiq_refill = jiffies - elapsed % RTW_TX_HIQ_REFILL_INTERVAL;
+	}
+
+	ok = rtwdev->hiq_budget > 0;
+	if (ok)
+		rtwdev->hiq_budget--;
+
+	spin_unlock_irqrestore(&rtwdev->hiq_lock, flags);
+
+	return ok;
+}
+
+bool rtw_tx_bmc_use_hiq(struct rtw_dev *rtwdev, struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+	return (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) &&
+	       rtw_tx_bmc_needs_dtim(skb) &&
+	       rtw_tx_hiq_take_budget(rtwdev);
+}
+EXPORT_SYMBOL(rtw_tx_bmc_use_hiq);
diff --git a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h
index 168f48e87853..a68ba3b12159 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.h
+++ b/drivers/net/wireless/realtek/rtw88/tx.h
@@ -10,6 +10,9 @@
 #define RTW_TX_PROBE_TIMEOUT_SHORT	msecs_to_jiffies(500)
 #define RTW_TX_PROBE_TIMEOUT_LONG	msecs_to_jiffies(2500)
 
+#define RTW_TX_HIQ_REFILL_INTERVAL	(HZ / 10)
+#define RTW_TX_HIQ_BUDGET_MAX		16
+
 struct rtw_tx_desc {
 	__le32 w0;
 	__le32 w1;
@@ -115,6 +118,7 @@ rtw_tx_write_data_h2c_get(struct rtw_dev *rtwdev,
 
 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);
+bool rtw_tx_bmc_use_hiq(struct rtw_dev *rtwdev, struct sk_buff *skb);
 
 static inline
 void fill_txdesc_checksum_common(u8 *txdesc, size_t words)
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
index 715a2ce342d9..13adbd415158 100644
--- a/drivers/net/wireless/realtek/rtw88/usb.c
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
@@ -2,10 +2,8 @@
 /* Copyright(c) 2018-2019  Realtek Corporation
  */
 
-#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
-#include <linux/udp.h>
 #include <linux/usb.h>
 #include "main.h"
 #include "debug.h"
@@ -564,61 +562,10 @@ static int rtw_usb_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size)
 	return rtw_usb_write_data(rtwdev, &pkt_info, buf);
 }
 
-static bool rtw_usb_bmc_needs_dtim(struct sk_buff *skb)
-{
-	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct udphdr *udphdr;
-
-	if (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)
-		return true;
-
-	if (skb->protocol == htons(ETH_P_ARP))
-		return true;
-
-	if (skb->protocol == htons(ETH_P_IP) &&
-	    ip_hdr(skb)->protocol == IPPROTO_UDP) {
-		udphdr = udp_hdr(skb);
-
-		return udphdr->dest == htons(67) || udphdr->dest == htons(68);
-	}
-
-	return false;
-}
-
-#define RTW_USB_HIQ_REFILL_INTERVAL	(HZ / 10)	/* one unit of budget per 100 ms */
-#define RTW_USB_HIQ_BUDGET_MAX		16
-
-static bool rtw_usb_hiq_take_budget(struct rtw_usb *rtwusb)
-{
-	unsigned long flags, elapsed, add;
-	bool ok;
-
-	spin_lock_irqsave(&rtwusb->hiq_lock, flags);
-
-	elapsed = jiffies - rtwusb->hiq_refill;
-	add = elapsed / RTW_USB_HIQ_REFILL_INTERVAL;
-	if (add) {
-		rtwusb->hiq_budget = min_t(unsigned long, rtwusb->hiq_budget + add,
-					   RTW_USB_HIQ_BUDGET_MAX);
-
-		/* keep the unfinished part of the interval for the next unit */
-		rtwusb->hiq_refill = jiffies - elapsed % RTW_USB_HIQ_REFILL_INTERVAL;
-	}
-
-	ok = rtwusb->hiq_budget > 0;
-	if (ok)
-		rtwusb->hiq_budget--;
-
-	spin_unlock_irqrestore(&rtwusb->hiq_lock, flags);
-
-	return ok;
-}
-
-static u8 rtw_usb_tx_queue_mapping_to_qsel(struct rtw_usb *rtwusb,
+static u8 rtw_usb_tx_queue_mapping_to_qsel(struct rtw_dev *rtwdev,
 					   struct sk_buff *skb)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	__le16 fc = hdr->frame_control;
 	u8 qsel;
 
@@ -626,8 +573,7 @@ static u8 rtw_usb_tx_queue_mapping_to_qsel(struct rtw_usb *rtwusb,
 		qsel = TX_DESC_QSEL_MGMT;
 	else if (is_broadcast_ether_addr(hdr->addr1) ||
 		 is_multicast_ether_addr(hdr->addr1))
-		qsel = (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) &&
-		       rtw_usb_bmc_needs_dtim(skb) && rtw_usb_hiq_take_budget(rtwusb) ?
+		qsel = rtw_tx_bmc_use_hiq(rtwdev, skb) ?
 		       TX_DESC_QSEL_HIGH : skb->priority;
 	else if (skb_get_queue_mapping(skb) <= IEEE80211_AC_BK)
 		qsel = skb->priority;
@@ -647,7 +593,7 @@ static int rtw_usb_tx_write(struct rtw_dev *rtwdev,
 	u8 *pkt_desc;
 	int ep;
 
-	pkt_info->qsel = rtw_usb_tx_queue_mapping_to_qsel(rtwusb, skb);
+	pkt_info->qsel = rtw_usb_tx_queue_mapping_to_qsel(rtwdev, 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);
@@ -1088,10 +1034,6 @@ static int rtw_usb_init_tx(struct rtw_dev *rtwdev)
 	struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
 	int i;
 
-	spin_lock_init(&rtwusb->hiq_lock);
-	rtwusb->hiq_budget = RTW_USB_HIQ_BUDGET_MAX;
-	rtwusb->hiq_refill = jiffies;
-
 	rtwusb->txwq = create_singlethread_workqueue("rtw88_usb: tx wq");
 	if (!rtwusb->txwq) {
 		rtw_err(rtwdev, "failed to create TX work queue\n");
diff --git a/drivers/net/wireless/realtek/rtw88/usb.h b/drivers/net/wireless/realtek/rtw88/usb.h
index 94ff21dd0846..9b695b688b24 100644
--- a/drivers/net/wireless/realtek/rtw88/usb.h
+++ b/drivers/net/wireless/realtek/rtw88/usb.h
@@ -75,11 +75,6 @@ struct rtw_usb {
 	u8 out_ep[RTW_USB_EP_MAX];
 	int qsel_to_ep[TX_DESC_QSEL_MAX];
 
-	/* protects hiq_budget and hiq_refill */
-	spinlock_t hiq_lock;
-	u32 hiq_budget;
-	unsigned long hiq_refill;
-
 	struct workqueue_struct *txwq, *rxwq;
 
 	struct sk_buff_head tx_queue[RTW_USB_EP_MAX];
-- 
2.53.0


             reply	other threads:[~2026-10-21 12:43 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-21 12:43 Luka Gejak [this message]
2026-10-21 12:43 ` [PATCH rtw-next v2 2/2] wifi: rtw88: sdio: limit the high queue to DTIM delivery Luka Gejak
2026-10-22  2:24   ` Ping-Ke Shih
2026-10-22  4:30     ` Luka Gejak
2026-10-22  4:33       ` Ping-Ke Shih
2026-10-22  2:20 ` [PATCH rtw-next v2 1/2] wifi: rtw88: move the bmc high queue decision to tx.c Ping-Ke Shih
2026-10-22  5:11   ` Luka Gejak
2026-10-23 21:34     ` Luka Gejak
2026-10-25  2:49       ` Ping-Ke Shih
2026-10-25  8:26         ` Luka Gejak
2026-10-27  1:19           ` Ping-Ke Shih
2026-10-27  5:22             ` Luka Gejak

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=20261021124318.15993-1-luka.gejak@linux.dev \
    --to=luka.gejak@linux.dev \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.