* [rtw-next 0/8] wifi: rtw89: some fixes and improvements
@ 2025-10-21 13:33 Ping-Ke Shih
2025-10-21 13:33 ` [rtw-next 1/8] wifi: rtw89: splice C2H events queue to local to prevent racing Ping-Ke Shih
` (7 more replies)
0 siblings, 8 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2025-10-21 13:33 UTC (permalink / raw)
To: linux-wireless; +Cc: timlee, emma_tsai, damon.chen, kevin_yang
First two patches are to prevent potential racing in C2H work queue,
because it doesn't add locks properly. Third is MLO link switching
handling. Forth is to support fix rate of EHT rate. Fifth is to correctly
apply country code programmed in efuse.
Also, correct RF setting to improve RTL8852C performance. The next one
is to recover firmware from abnormal states if power-save functions
work improperly. The last one is to improve scan time in 6 GHz band.
Chin-Yen Lee (1):
wifi: rtw89: restart hardware to recover firmware if power-save
becomes abnormal
Jui-Peng Tsai (1):
wifi: rtw89: improve scan time on 6 GHz band
Kuan-Chung Chen (1):
wifi: rtw89: 8852c: fix ADC oscillation in 160MHz affecting RX
performance
Ping-Ke Shih (2):
wifi: rtw89: splice C2H events queue to local to prevent racing
wifi: rtw89: use skb_dequeue() for queued ROC packets to prevent
racing
Zong-Zhe Yang (3):
wifi: rtw89: mlo: handle needed H2C when link switching is requested
by stack
wifi: rtw89: support EHT rate pattern via bitrate mask
wifi: rtw89: regd: apply ACPI policy even if country code is
programmed
drivers/net/wireless/realtek/rtw89/core.c | 31 +++------
drivers/net/wireless/realtek/rtw89/core.h | 12 ++++
drivers/net/wireless/realtek/rtw89/fw.c | 39 ++++++++---
drivers/net/wireless/realtek/rtw89/mac.c | 7 +-
drivers/net/wireless/realtek/rtw89/mac80211.c | 64 ++++++++++++++++++-
drivers/net/wireless/realtek/rtw89/phy.c | 39 ++++++++++-
drivers/net/wireless/realtek/rtw89/ps.c | 23 ++++++-
drivers/net/wireless/realtek/rtw89/regd.c | 22 +++----
.../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 59 +++++++++++------
9 files changed, 227 insertions(+), 69 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [rtw-next 1/8] wifi: rtw89: splice C2H events queue to local to prevent racing
2025-10-21 13:33 [rtw-next 0/8] wifi: rtw89: some fixes and improvements Ping-Ke Shih
@ 2025-10-21 13:33 ` Ping-Ke Shih
2025-10-28 1:59 ` Ping-Ke Shih
2025-10-21 13:33 ` [rtw-next 2/8] wifi: rtw89: use skb_dequeue() for queued ROC packets " Ping-Ke Shih
` (6 subsequent siblings)
7 siblings, 1 reply; 10+ messages in thread
From: Ping-Ke Shih @ 2025-10-21 13:33 UTC (permalink / raw)
To: linux-wireless; +Cc: timlee, emma_tsai, damon.chen, kevin_yang
RX task enqueues C2H events and fork a C2H work to handle events, but
the work uses skb_queue_walk_safe() without a lock causing potential
racing. Use skb_queue_splice() and its friends with spin_lock to splice
the queue to local, and then still use skb_queue_walk_safe() to iterate
all events.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/fw.c | 31 ++++++++++++++++++-------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index ab904a7def1b..9a926bb2cf00 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -6891,11 +6891,18 @@ void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work)
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
c2h_work);
struct sk_buff *skb, *tmp;
+ struct sk_buff_head c2hq;
+ unsigned long flags;
lockdep_assert_wiphy(rtwdev->hw->wiphy);
- skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) {
- skb_unlink(skb, &rtwdev->c2h_queue);
+ __skb_queue_head_init(&c2hq);
+
+ spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags);
+ skb_queue_splice_init(&rtwdev->c2h_queue, &c2hq);
+ spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags);
+
+ skb_queue_walk_safe(&c2hq, skb, tmp) {
rtw89_fw_c2h_cmd_handle(rtwdev, skb);
dev_kfree_skb_any(skb);
}
@@ -6905,17 +6912,19 @@ void rtw89_fw_c2h_purge_obsoleted_scan_events(struct rtw89_dev *rtwdev)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
struct sk_buff *skb, *tmp;
- int limit;
+ struct sk_buff_head c2hq;
+ unsigned long flags;
lockdep_assert_wiphy(rtwdev->hw->wiphy);
- limit = skb_queue_len(&rtwdev->c2h_queue);
+ __skb_queue_head_init(&c2hq);
- skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) {
- struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb);
+ spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags);
+ skb_queue_splice_init(&rtwdev->c2h_queue, &c2hq);
+ spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags);
- if (--limit < 0)
- return;
+ skb_queue_walk_safe(&c2hq, skb, tmp) {
+ struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb);
if (!attr->is_scan_event || attr->scan_seq == scan_info->seq)
continue;
@@ -6924,9 +6933,13 @@ void rtw89_fw_c2h_purge_obsoleted_scan_events(struct rtw89_dev *rtwdev)
"purge obsoleted scan event with seq=%d (cur=%d)\n",
attr->scan_seq, scan_info->seq);
- skb_unlink(skb, &rtwdev->c2h_queue);
+ __skb_unlink(skb, &c2hq);
dev_kfree_skb_any(skb);
}
+
+ spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags);
+ skb_queue_splice(&c2hq, &rtwdev->c2h_queue);
+ spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags);
}
static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev,
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [rtw-next 2/8] wifi: rtw89: use skb_dequeue() for queued ROC packets to prevent racing
2025-10-21 13:33 [rtw-next 0/8] wifi: rtw89: some fixes and improvements Ping-Ke Shih
2025-10-21 13:33 ` [rtw-next 1/8] wifi: rtw89: splice C2H events queue to local to prevent racing Ping-Ke Shih
@ 2025-10-21 13:33 ` Ping-Ke Shih
2025-10-21 13:33 ` [rtw-next 3/8] wifi: rtw89: mlo: handle needed H2C when link switching is requested by stack Ping-Ke Shih
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2025-10-21 13:33 UTC (permalink / raw)
To: linux-wireless; +Cc: timlee, emma_tsai, damon.chen, kevin_yang
TX task can enqueue ROC skb, but other tasks dequeue the skb. Using
skb_queue_walk_safe() without locking will cause potential racing.
Use skb_dequeue() with lock instead.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 917b2adede61..8b40cada4149 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -3632,12 +3632,10 @@ void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev,
struct ieee80211_sta *sta)
{
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
- struct sk_buff *skb, *tmp;
+ struct sk_buff *skb;
- skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) {
- skb_unlink(skb, &rtwsta->roc_queue);
+ while ((skb = skb_dequeue(&rtwsta->roc_queue)))
dev_kfree_skb_any(skb);
- }
}
static void rtw89_core_stop_tx_ba_session(struct rtw89_dev *rtwdev,
@@ -3881,8 +3879,8 @@ static void rtw89_core_sta_pending_tx_iter(void *data,
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
struct rtw89_vif_link *target = data;
struct rtw89_vif_link *rtwvif_link;
- struct sk_buff *skb, *tmp;
unsigned int link_id;
+ struct sk_buff *skb;
int qsel, ret;
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
@@ -3895,9 +3893,7 @@ static void rtw89_core_sta_pending_tx_iter(void *data,
if (skb_queue_len(&rtwsta->roc_queue) == 0)
return;
- skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) {
- skb_unlink(skb, &rtwsta->roc_queue);
-
+ while ((skb = skb_dequeue(&rtwsta->roc_queue))) {
ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel);
if (ret) {
rtw89_warn(rtwdev, "pending tx failed with %d\n", ret);
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [rtw-next 3/8] wifi: rtw89: mlo: handle needed H2C when link switching is requested by stack
2025-10-21 13:33 [rtw-next 0/8] wifi: rtw89: some fixes and improvements Ping-Ke Shih
2025-10-21 13:33 ` [rtw-next 1/8] wifi: rtw89: splice C2H events queue to local to prevent racing Ping-Ke Shih
2025-10-21 13:33 ` [rtw-next 2/8] wifi: rtw89: use skb_dequeue() for queued ROC packets " Ping-Ke Shih
@ 2025-10-21 13:33 ` Ping-Ke Shih
2025-10-21 13:33 ` [rtw-next 4/8] wifi: rtw89: support EHT rate pattern via bitrate mask Ping-Ke Shih
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2025-10-21 13:33 UTC (permalink / raw)
To: linux-wireless; +Cc: timlee, emma_tsai, damon.chen, kevin_yang
From: Zong-Zhe Yang <kevin_yang@realtek.com>
To switch link, FW needs H2C commands to indicate which link is on or off.
Originally, these H2C commands are considered only when the link switching
is initiated by driver. But, in some cases, e.g. ml_reconf or TTLM, link
switching would be initiated by stack. Hence, plan these H2C commands into
ieee80211_ops.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.c | 18 +-----
drivers/net/wireless/realtek/rtw89/core.h | 8 +++
drivers/net/wireless/realtek/rtw89/mac80211.c | 64 ++++++++++++++++++-
3 files changed, 74 insertions(+), 16 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 8b40cada4149..a3f156bf708e 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -6010,7 +6010,7 @@ int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
u16 usable_links = ieee80211_vif_usable_links(vif);
u16 active_links = vif->active_links;
- struct rtw89_vif_link *target, *cur;
+ struct rtw89_vif_link *target;
int ret;
lockdep_assert_wiphy(rtwdev->hw->wiphy);
@@ -6036,11 +6036,9 @@ int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
ieee80211_stop_queues(rtwdev->hw);
flush_work(&rtwdev->txq_work);
- cur = rtw89_get_designated_link(rtwvif);
-
- ret = ieee80211_set_active_links(vif, active_links | BIT(link_id));
+ ret = ieee80211_set_active_links(vif, BIT(link_id));
if (ret) {
- rtw89_err(rtwdev, "%s: failed to activate link id %u\n",
+ rtw89_err(rtwdev, "%s: failed to work on link id %u\n",
__func__, link_id);
goto wake_queue;
}
@@ -6055,16 +6053,6 @@ int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
goto wake_queue;
}
- if (likely(cur))
- rtw89_fw_h2c_mlo_link_cfg(rtwdev, cur, false);
-
- rtw89_fw_h2c_mlo_link_cfg(rtwdev, target, true);
-
- ret = ieee80211_set_active_links(vif, BIT(link_id));
- if (ret)
- rtw89_err(rtwdev, "%s: failed to inactivate links 0x%x\n",
- __func__, active_links);
-
rtw89_chip_rfk_channel(rtwdev, target);
rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 928c8c84c964..7c74ed3cfaf7 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -5933,6 +5933,7 @@ struct rtw89_mcc_info {
enum rtw89_mlo_mode {
RTW89_MLO_MODE_MLSR = 0,
+ RTW89_MLO_MODE_EMLSR = 1,
NUM_OF_RTW89_MLO_MODE,
};
@@ -6097,6 +6098,12 @@ struct rtw89_link_conf_container {
struct ieee80211_bss_conf *link_conf[IEEE80211_MLD_MAX_NUM_LINKS];
};
+struct rtw89_vif_ml_trans {
+ u16 mediate_links;
+ u16 links_to_del;
+ u16 links_to_add;
+};
+
#define RTW89_VIF_IDLE_LINK_ID 0
struct rtw89_vif {
@@ -6119,6 +6126,7 @@ struct rtw89_vif {
bool offchan;
enum rtw89_mlo_mode mlo_mode;
+ struct rtw89_vif_ml_trans ml_trans;
struct list_head dlink_pool;
u8 links_inst_valid_num;
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 7b04183a3a5d..a19304ff8306 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -718,6 +718,17 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_ARP_FILTER)
rtwvif->ip_addr = vif->cfg.arp_addr_list[0];
+
+ if (changed & BSS_CHANGED_MLD_VALID_LINKS) {
+ struct rtw89_vif_link *cur = rtw89_get_designated_link(rtwvif);
+
+ rtw89_chip_rfk_channel(rtwdev, cur);
+
+ if (hweight16(vif->active_links) == 1)
+ rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR;
+ else
+ rtwvif->mlo_mode = RTW89_MLO_MODE_EMLSR;
+ }
}
static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw,
@@ -1531,10 +1542,29 @@ static bool rtw89_ops_can_activate_links(struct ieee80211_hw *hw,
u16 active_links)
{
struct rtw89_dev *rtwdev = hw->priv;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
+ u16 current_links = vif->active_links;
+ struct rtw89_vif_ml_trans trans = {
+ .mediate_links = current_links | active_links,
+ .links_to_del = current_links & ~active_links,
+ .links_to_add = active_links & ~current_links,
+ };
lockdep_assert_wiphy(hw->wiphy);
- return rtw89_can_work_on_links(rtwdev, vif, active_links);
+ if (!rtw89_can_work_on_links(rtwdev, vif, active_links))
+ return false;
+
+ /*
+ * Leave LPS at the beginning of ieee80211_set_active_links().
+ * Because the entire process takes the same lock as our track
+ * work, LPS will not enter during ieee80211_set_active_links().
+ */
+ rtw89_leave_lps(rtwdev);
+
+ rtwvif->ml_trans = trans;
+
+ return true;
}
static void __rtw89_ops_clr_vif_links(struct rtw89_dev *rtwdev,
@@ -1579,6 +1609,36 @@ static int __rtw89_ops_set_vif_links(struct rtw89_dev *rtwdev,
return 0;
}
+static void rtw89_vif_cfg_fw_links(struct rtw89_dev *rtwdev,
+ struct rtw89_vif *rtwvif,
+ unsigned long links, bool en)
+{
+ struct rtw89_vif_link *rtwvif_link;
+ unsigned int link_id;
+
+ for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) {
+ rtwvif_link = rtwvif->links[link_id];
+ if (unlikely(!rtwvif_link))
+ continue;
+
+ rtw89_fw_h2c_mlo_link_cfg(rtwdev, rtwvif_link, en);
+ }
+}
+
+static void rtw89_vif_update_fw_links(struct rtw89_dev *rtwdev,
+ struct rtw89_vif *rtwvif,
+ u16 current_links)
+{
+ struct rtw89_vif_ml_trans *trans = &rtwvif->ml_trans;
+
+ /* Do follow-up when all updating links exist. */
+ if (current_links != trans->mediate_links)
+ return;
+
+ rtw89_vif_cfg_fw_links(rtwdev, rtwvif, trans->links_to_del, false);
+ rtw89_vif_cfg_fw_links(rtwdev, rtwvif, trans->links_to_add, true);
+}
+
static
int rtw89_ops_change_vif_links(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
@@ -1620,6 +1680,8 @@ int rtw89_ops_change_vif_links(struct ieee80211_hw *hw,
if (rtwdev->scanning)
rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
+ rtw89_vif_update_fw_links(rtwdev, rtwvif, old_links);
+
if (!old_links)
__rtw89_ops_clr_vif_links(rtwdev, rtwvif,
BIT(RTW89_VIF_IDLE_LINK_ID));
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [rtw-next 4/8] wifi: rtw89: support EHT rate pattern via bitrate mask
2025-10-21 13:33 [rtw-next 0/8] wifi: rtw89: some fixes and improvements Ping-Ke Shih
` (2 preceding siblings ...)
2025-10-21 13:33 ` [rtw-next 3/8] wifi: rtw89: mlo: handle needed H2C when link switching is requested by stack Ping-Ke Shih
@ 2025-10-21 13:33 ` Ping-Ke Shih
2025-10-21 13:33 ` [rtw-next 5/8] wifi: rtw89: regd: apply ACPI policy even if country code is programmed Ping-Ke Shih
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2025-10-21 13:33 UTC (permalink / raw)
To: linux-wireless; +Cc: timlee, emma_tsai, damon.chen, kevin_yang
From: Zong-Zhe Yang <kevin_yang@realtek.com>
When setting bitrate mask, e.g. using iw set bitrates, there are some
designated patterns to be recognized, called rate pattern. When a rate
pattern is matched, treat the setting as asking a fixed rate. Now, add
support to recognize EHT rates.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/phy.c | 39 +++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index ba7feadd7582..23892c1359a5 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -231,7 +231,12 @@ static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev,
return -1;
}
- if (link_sta->he_cap.has_he) {
+ if (link_sta->eht_cap.has_eht) {
+ cfg_mask |= u64_encode_bits(mask->control[band].eht_mcs[0],
+ RA_MASK_EHT_1SS_RATES);
+ cfg_mask |= u64_encode_bits(mask->control[band].eht_mcs[1],
+ RA_MASK_EHT_2SS_RATES);
+ } else if (link_sta->he_cap.has_he) {
cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[0],
RA_MASK_HE_1SS_RATES);
cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[1],
@@ -557,6 +562,14 @@ static bool __check_rate_pattern(struct rtw89_phy_rate_pattern *next,
return true;
}
+enum __rtw89_hw_rate_invalid_bases {
+ /* no EHT rate for ax chip */
+ RTW89_HW_RATE_EHT_NSS1_MCS0 = RTW89_HW_RATE_INVAL,
+ RTW89_HW_RATE_EHT_NSS2_MCS0 = RTW89_HW_RATE_INVAL,
+ RTW89_HW_RATE_EHT_NSS3_MCS0 = RTW89_HW_RATE_INVAL,
+ RTW89_HW_RATE_EHT_NSS4_MCS0 = RTW89_HW_RATE_INVAL,
+};
+
#define RTW89_HW_RATE_BY_CHIP_GEN(rate) \
{ \
[RTW89_CHIP_AX] = RTW89_HW_RATE_ ## rate, \
@@ -572,6 +585,12 @@ void __rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
struct rtw89_phy_rate_pattern next_pattern = {0};
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
rtwvif_link->chanctx_idx);
+ static const u16 hw_rate_eht[][RTW89_CHIP_GEN_NUM] = {
+ RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS1_MCS0),
+ RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS2_MCS0),
+ RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS3_MCS0),
+ RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS4_MCS0),
+ };
static const u16 hw_rate_he[][RTW89_CHIP_GEN_NUM] = {
RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS1_MCS0),
RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS2_MCS0),
@@ -596,6 +615,17 @@ void __rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
u8 tx_nss = rtwdev->hal.tx_nss;
u8 i;
+ if (chip_gen == RTW89_CHIP_AX)
+ goto rs_11ax;
+
+ for (i = 0; i < tx_nss; i++)
+ if (!__check_rate_pattern(&next_pattern, hw_rate_eht[i][chip_gen],
+ RA_MASK_EHT_RATES, RTW89_RA_MODE_EHT,
+ mask->control[nl_band].eht_mcs[i],
+ 0, true))
+ goto out;
+
+rs_11ax:
for (i = 0; i < tx_nss; i++)
if (!__check_rate_pattern(&next_pattern, hw_rate_he[i][chip_gen],
RA_MASK_HE_RATES, RTW89_RA_MODE_HE,
@@ -640,6 +670,13 @@ void __rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
if (!next_pattern.enable)
goto out;
+ if (unlikely(next_pattern.rate >= RTW89_HW_RATE_INVAL)) {
+ rtw89_debug(rtwdev, RTW89_DBG_RA,
+ "pattern invalid target: chip_gen %d, mode 0x%x\n",
+ chip_gen, next_pattern.ra_mode);
+ goto out;
+ }
+
rtwvif_link->rate_pattern = next_pattern;
rtw89_debug(rtwdev, RTW89_DBG_RA,
"configure pattern: rate 0x%x, mask 0x%llx, mode 0x%x\n",
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [rtw-next 5/8] wifi: rtw89: regd: apply ACPI policy even if country code is programmed
2025-10-21 13:33 [rtw-next 0/8] wifi: rtw89: some fixes and improvements Ping-Ke Shih
` (3 preceding siblings ...)
2025-10-21 13:33 ` [rtw-next 4/8] wifi: rtw89: support EHT rate pattern via bitrate mask Ping-Ke Shih
@ 2025-10-21 13:33 ` Ping-Ke Shih
2025-10-21 13:34 ` [rtw-next 6/8] wifi: rtw89: 8852c: fix ADC oscillation in 160MHz affecting RX performance Ping-Ke Shih
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2025-10-21 13:33 UTC (permalink / raw)
To: linux-wireless; +Cc: timlee, emma_tsai, damon.chen, kevin_yang
From: Zong-Zhe Yang <kevin_yang@realtek.com>
There are regulatory related policy according to BIOS/ACPI configuration,
e.g. distro decides to disable some bands or some channels. Even if chip
has a programmed country code, these policy should still be applied within
regulatory notifier.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.h | 2 ++
drivers/net/wireless/realtek/rtw89/regd.c | 22 +++++++++++-----------
2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 7c74ed3cfaf7..ae98d6866b30 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -5449,6 +5449,8 @@ struct rtw89_regd_ctrl {
struct rtw89_regulatory_info {
struct rtw89_regd_ctrl ctrl;
const struct rtw89_regd *regd;
+ bool programmed;
+
enum rtw89_reg_6ghz_power reg_6ghz_power;
struct rtw89_reg_6ghz_tpe reg_6ghz_tpe;
bool txpwr_uk_follow_etsi;
diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c
index 58582f8d2b74..209d84909f88 100644
--- a/drivers/net/wireless/realtek/rtw89/regd.c
+++ b/drivers/net/wireless/realtek/rtw89/regd.c
@@ -723,6 +723,8 @@ int rtw89_regd_init_hint(struct rtw89_dev *rtwdev)
chip_regd = rtw89_regd_find_reg_by_name(rtwdev, rtwdev->efuse.country_code);
if (!rtw89_regd_is_ww(chip_regd)) {
rtwdev->regulatory.regd = chip_regd;
+ rtwdev->regulatory.programmed = true;
+
/* Ignore country ie if there is a country domain programmed in chip */
wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
@@ -867,11 +869,6 @@ static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev,
wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
else
wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE;
-
- rtw89_regd_apply_policy_unii4(rtwdev, wiphy);
- rtw89_regd_apply_policy_6ghz(rtwdev, wiphy);
- rtw89_regd_apply_policy_tas(rtwdev);
- rtw89_regd_apply_policy_ant_gain(rtwdev);
}
static
@@ -883,19 +880,22 @@ void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request
wiphy_lock(wiphy);
rtw89_leave_ps_mode(rtwdev);
- if (wiphy->regd) {
- rtw89_debug(rtwdev, RTW89_DBG_REGD,
- "There is a country domain programmed in chip, ignore notifications\n");
- goto exit;
- }
+ if (rtwdev->regulatory.programmed)
+ goto policy;
+
rtw89_regd_notifier_apply(rtwdev, wiphy, request);
rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd,
"get from initiator %d, alpha2",
request->initiator);
+policy:
+ rtw89_regd_apply_policy_unii4(rtwdev, wiphy);
+ rtw89_regd_apply_policy_6ghz(rtwdev, wiphy);
+ rtw89_regd_apply_policy_tas(rtwdev);
+ rtw89_regd_apply_policy_ant_gain(rtwdev);
+
rtw89_core_set_chip_txpwr(rtwdev);
-exit:
wiphy_unlock(wiphy);
}
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [rtw-next 6/8] wifi: rtw89: 8852c: fix ADC oscillation in 160MHz affecting RX performance
2025-10-21 13:33 [rtw-next 0/8] wifi: rtw89: some fixes and improvements Ping-Ke Shih
` (4 preceding siblings ...)
2025-10-21 13:33 ` [rtw-next 5/8] wifi: rtw89: regd: apply ACPI policy even if country code is programmed Ping-Ke Shih
@ 2025-10-21 13:34 ` Ping-Ke Shih
2025-10-21 13:34 ` [rtw-next 7/8] wifi: rtw89: restart hardware to recover firmware if power-save becomes abnormal Ping-Ke Shih
2025-10-21 13:34 ` [rtw-next 8/8] wifi: rtw89: improve scan time on 6 GHz band Ping-Ke Shih
7 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2025-10-21 13:34 UTC (permalink / raw)
To: linux-wireless; +Cc: timlee, emma_tsai, damon.chen, kevin_yang
From: Kuan-Chung Chen <damon.chen@realtek.com>
When operating in 160 MHz, the ADC may oscillate and affect AGC, leading
to unstable RX quality. This issue can be resolved by ensuring proper
RF filter bandwidth switching to avoid ADC oscillation.
Signed-off-by: Kuan-Chung Chen <damon.chen@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
.../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 59 ++++++++++++-------
1 file changed, 39 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
index e7fd028c5e82..cbee484dee30 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
@@ -3987,37 +3987,56 @@ static void _ctrl_ch(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}
}
+static void _set_rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
+ enum rtw89_bandwidth bw)
+{
+ u32 val;
+
+ rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1);
+ rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0xa);
+
+ switch (bw) {
+ case RTW89_CHANNEL_WIDTH_20:
+ val = 0x1b;
+ break;
+ case RTW89_CHANNEL_WIDTH_40:
+ val = 0x13;
+ break;
+ case RTW89_CHANNEL_WIDTH_80:
+ val = 0xb;
+ break;
+ case RTW89_CHANNEL_WIDTH_160:
+ default:
+ val = 0x3;
+ break;
+ }
+
+ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, val);
+ rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0);
+}
+
+static void _set_tia_bw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
+ enum rtw89_bandwidth bw)
+{
+ if (bw == RTW89_CHANNEL_WIDTH_160)
+ rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_EBW, 0x0);
+ else
+ rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_EBW, 0x2);
+}
+
static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_bandwidth bw)
{
u8 kpath;
u8 path;
- u32 val;
kpath = _kpath(rtwdev, phy);
for (path = 0; path < 2; path++) {
if (!(kpath & BIT(path)))
continue;
- rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1);
- rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0xa);
- switch (bw) {
- case RTW89_CHANNEL_WIDTH_20:
- val = 0x1b;
- break;
- case RTW89_CHANNEL_WIDTH_40:
- val = 0x13;
- break;
- case RTW89_CHANNEL_WIDTH_80:
- val = 0xb;
- break;
- case RTW89_CHANNEL_WIDTH_160:
- default:
- val = 0x3;
- break;
- }
- rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, val);
- rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0);
+ _set_rxbb_bw(rtwdev, path, bw);
+ _set_tia_bw(rtwdev, path, bw);
}
}
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [rtw-next 7/8] wifi: rtw89: restart hardware to recover firmware if power-save becomes abnormal
2025-10-21 13:33 [rtw-next 0/8] wifi: rtw89: some fixes and improvements Ping-Ke Shih
` (5 preceding siblings ...)
2025-10-21 13:34 ` [rtw-next 6/8] wifi: rtw89: 8852c: fix ADC oscillation in 160MHz affecting RX performance Ping-Ke Shih
@ 2025-10-21 13:34 ` Ping-Ke Shih
2025-10-21 13:34 ` [rtw-next 8/8] wifi: rtw89: improve scan time on 6 GHz band Ping-Ke Shih
7 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2025-10-21 13:34 UTC (permalink / raw)
To: linux-wireless; +Cc: timlee, emma_tsai, damon.chen, kevin_yang
From: Chin-Yen Lee <timlee@realtek.com>
Somehow power-save related functions get failure, such as failed to
send null packet, or no response form firmware, and then WiFi will
become unstable. Trigger SER function actively to reset firmware/driver
to recover from abnormal states, including
- firmware failed to ACK for entering PS mode
- firmware failed to ACK for leaving PS mode
- check PS H2C command received by firmware fail
- failed to leave PS state
Signed-off-by: Chin-Yen Lee <timlee@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.c | 1 +
drivers/net/wireless/realtek/rtw89/core.h | 2 ++
drivers/net/wireless/realtek/rtw89/mac.c | 7 +++++--
drivers/net/wireless/realtek/rtw89/ps.c | 23 +++++++++++++++++++++--
4 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index a3f156bf708e..1b5a40e9821c 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -5538,6 +5538,7 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
rtw89_fw_h2c_fw_log(rtwdev, rtwdev->fw.log.enable);
rtw89_fw_h2c_init_ba_cam(rtwdev);
rtw89_tas_fw_timer_enable(rtwdev, true);
+ rtwdev->ps_hang_cnt = 0;
return 0;
}
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index ae98d6866b30..f8b443894db9 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -42,6 +42,7 @@ extern const struct ieee80211_ops rtw89_ops;
#define RTW89_TRACK_WORK_PERIOD round_jiffies_relative(HZ * 2)
#define RTW89_TRACK_PS_WORK_PERIOD msecs_to_jiffies(100)
#define RTW89_FORBID_BA_TIMER round_jiffies_relative(HZ * 4)
+#define RTW89_PS_HANG_MAX_CNT 3
#define CFO_TRACK_MAX_USER 64
#define MAX_RSSI 110
#define RSSI_FACTOR 1
@@ -6082,6 +6083,7 @@ struct rtw89_dev {
struct rtw89_btc btc;
enum rtw89_ps_mode ps_mode;
bool lps_enabled;
+ u8 ps_hang_cnt;
struct rtw89_wow_param wow;
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index fd11b8fb3c89..d837513f4e92 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -12,6 +12,7 @@
#include "phy.h"
#include "ps.h"
#include "reg.h"
+#include "ser.h"
#include "util.h"
static const u32 rtw89_mac_mem_base_addrs_ax[RTW89_MAC_MEM_NUM] = {
@@ -1423,13 +1424,15 @@ void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter)
if (!ret)
break;
- if (i == RPWM_TRY_CNT - 1)
+ if (i == RPWM_TRY_CNT - 1) {
rtw89_err(rtwdev, "firmware failed to ack for %s ps mode\n",
enter ? "entering" : "leaving");
- else
+ rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION);
+ } else {
rtw89_debug(rtwdev, RTW89_DBG_UNEXP,
"%d time firmware failed to ack for %s ps mode\n",
i + 1, enter ? "entering" : "leaving");
+ }
}
}
diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c
index cf58121eb541..3f69dd4361c3 100644
--- a/drivers/net/wireless/realtek/rtw89/ps.c
+++ b/drivers/net/wireless/realtek/rtw89/ps.c
@@ -11,6 +11,7 @@
#include "phy.h"
#include "ps.h"
#include "reg.h"
+#include "ser.h"
#include "util.h"
static int rtw89_fw_receive_lps_h2c_check(struct rtw89_dev *rtwdev, u8 macid)
@@ -26,16 +27,27 @@ static int rtw89_fw_receive_lps_h2c_check(struct rtw89_dev *rtwdev, u8 macid)
c2h_info.id = RTW89_FWCMD_C2HREG_FUNC_PS_LEAVE_ACK;
ret = rtw89_fw_msg_reg(rtwdev, NULL, &c2h_info);
if (ret)
- return ret;
+ goto fw_fail;
c2hreg_macid = u32_get_bits(c2h_info.u.c2hreg[0],
RTW89_C2HREG_PS_LEAVE_ACK_MACID);
c2hreg_ret = u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_PS_LEAVE_ACK_RET);
- if (macid != c2hreg_macid || c2hreg_ret)
+ if (macid != c2hreg_macid || c2hreg_ret) {
rtw89_warn(rtwdev, "rtw89: check lps h2c received by firmware fail\n");
+ ret = -EINVAL;
+ goto fw_fail;
+ }
+ rtwdev->ps_hang_cnt = 0;
return 0;
+
+fw_fail:
+ rtwdev->ps_hang_cnt++;
+ if (rtwdev->ps_hang_cnt >= RTW89_PS_HANG_MAX_CNT)
+ rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION);
+
+ return ret;
}
static int rtw89_fw_leave_lps_check(struct rtw89_dev *rtwdev, u8 macid)
@@ -51,9 +63,16 @@ static int rtw89_fw_leave_lps_check(struct rtw89_dev *rtwdev, u8 macid)
mac->ps_status, chk_msk);
if (ret) {
rtw89_info(rtwdev, "rtw89: failed to leave lps state\n");
+
+ rtwdev->ps_hang_cnt++;
+ if (rtwdev->ps_hang_cnt >= RTW89_PS_HANG_MAX_CNT)
+ rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION);
+
return -EBUSY;
}
+ rtwdev->ps_hang_cnt = 0;
+
return 0;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [rtw-next 8/8] wifi: rtw89: improve scan time on 6 GHz band
2025-10-21 13:33 [rtw-next 0/8] wifi: rtw89: some fixes and improvements Ping-Ke Shih
` (6 preceding siblings ...)
2025-10-21 13:34 ` [rtw-next 7/8] wifi: rtw89: restart hardware to recover firmware if power-save becomes abnormal Ping-Ke Shih
@ 2025-10-21 13:34 ` Ping-Ke Shih
7 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2025-10-21 13:34 UTC (permalink / raw)
To: linux-wireless; +Cc: timlee, emma_tsai, damon.chen, kevin_yang
From: Jui-Peng Tsai <emma_tsai@realtek.com>
Reduce scan time for all supported channels from 4.4s to 3.5s.
If NL80211_SCAN_FLAG_COLOCATED_6GHZ is set in scan request, only scan PSC
channels and the channels from the RNR element found on the 2.4/5 GHz
channels. When firmware support parsing RNR element from received beacon
or probe response, offload the decision about non-PSC channels to firmware.
Driver do not need to fill non-PSC channels to scan list. If
NL80211_SCAN_FLAG_COLOCATED_6GHZ is not set, scan all supported channels.
Signed-off-by: Jui-Peng Tsai <emma_tsai@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/fw.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 9a926bb2cf00..cb431c8a65ac 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -7787,15 +7787,23 @@ int rtw89_hw_scan_prep_chan_list_be(struct rtw89_dev *rtwdev,
struct ieee80211_channel *channel;
struct list_head chan_list;
enum rtw89_chan_type type;
+ bool chan_by_rnr;
bool random_seq;
int ret;
u32 idx;
random_seq = !!(req->flags & NL80211_SCAN_FLAG_RANDOM_SN);
+ chan_by_rnr = rtwdev->chip->support_rnr &&
+ (req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ);
INIT_LIST_HEAD(&chan_list);
for (idx = 0; idx < req->n_channels; idx++) {
channel = req->channels[idx];
+
+ if (channel->band == NL80211_BAND_6GHZ &&
+ !cfg80211_channel_is_psc(channel) && chan_by_rnr)
+ continue;
+
ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
if (!ch_info) {
ret = -ENOMEM;
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [rtw-next 1/8] wifi: rtw89: splice C2H events queue to local to prevent racing
2025-10-21 13:33 ` [rtw-next 1/8] wifi: rtw89: splice C2H events queue to local to prevent racing Ping-Ke Shih
@ 2025-10-28 1:59 ` Ping-Ke Shih
0 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2025-10-28 1:59 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless; +Cc: timlee, emma_tsai, damon.chen, kevin_yang
Ping-Ke Shih <pkshih@realtek.com> wrote:
> RX task enqueues C2H events and fork a C2H work to handle events, but
> the work uses skb_queue_walk_safe() without a lock causing potential
> racing. Use skb_queue_splice() and its friends with spin_lock to splice
> the queue to local, and then still use skb_queue_walk_safe() to iterate
> all events.
>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
8 patch(es) applied to rtw-next branch of rtw.git, thanks.
b47d748110fd wifi: rtw89: splice C2H events queue to local to prevent racing
f44a9b14a78f wifi: rtw89: use skb_dequeue() for queued ROC packets to prevent racing
e79382ab0347 wifi: rtw89: mlo: handle needed H2C when link switching is requested by stack
438c9178cd8a wifi: rtw89: support EHT rate pattern via bitrate mask
0ac5ead00bf9 wifi: rtw89: regd: apply ACPI policy even if country code is programmed
a48ae54a67f7 wifi: rtw89: 8852c: fix ADC oscillation in 160MHz affecting RX performance
e139b1c1f01a wifi: rtw89: restart hardware to recover firmware if power-save becomes abnormal
a62b65412506 wifi: rtw89: improve scan time on 6 GHz band
---
https://github.com/pkshih/rtw.git
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-10-28 1:59 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-21 13:33 [rtw-next 0/8] wifi: rtw89: some fixes and improvements Ping-Ke Shih
2025-10-21 13:33 ` [rtw-next 1/8] wifi: rtw89: splice C2H events queue to local to prevent racing Ping-Ke Shih
2025-10-28 1:59 ` Ping-Ke Shih
2025-10-21 13:33 ` [rtw-next 2/8] wifi: rtw89: use skb_dequeue() for queued ROC packets " Ping-Ke Shih
2025-10-21 13:33 ` [rtw-next 3/8] wifi: rtw89: mlo: handle needed H2C when link switching is requested by stack Ping-Ke Shih
2025-10-21 13:33 ` [rtw-next 4/8] wifi: rtw89: support EHT rate pattern via bitrate mask Ping-Ke Shih
2025-10-21 13:33 ` [rtw-next 5/8] wifi: rtw89: regd: apply ACPI policy even if country code is programmed Ping-Ke Shih
2025-10-21 13:34 ` [rtw-next 6/8] wifi: rtw89: 8852c: fix ADC oscillation in 160MHz affecting RX performance Ping-Ke Shih
2025-10-21 13:34 ` [rtw-next 7/8] wifi: rtw89: restart hardware to recover firmware if power-save becomes abnormal Ping-Ke Shih
2025-10-21 13:34 ` [rtw-next 8/8] wifi: rtw89: improve scan time on 6 GHz band Ping-Ke Shih
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).