* [PATCH rtw-next 0/3] wifi: rtw89: support hw_scan v3 format for WiFI 7 chips
@ 2026-07-24 14:22 Ping-Ke Shih
2026-07-24 14:22 ` [PATCH rtw-next 1/3] wifi: rtw89: refine RX filter configuration for WiFi 7 generation Ping-Ke Shih
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Ping-Ke Shih @ 2026-07-24 14:22 UTC (permalink / raw)
To: linux-wireless; +Cc: dian_syuan0116, phhuang
Due to firmware change the hw_scan format, update the format accordingly
to support current new firmware. (By patch 2/3 and 3/3)
The patch 1/3 is to store RX filter settings by a variable, so hardware
leaves from idle can restore the setting from the variable. Otherwise,
the RX filter is unexpected, and AP mode can't receive certain types of
frames.
Dian-Syuan Yang (1):
wifi: rtw89: refine RX filter configuration for WiFi 7 generation
Po-Hao Huang (2):
wifi: rtw89: fix scan offload version check logic
wifi: rtw89: change scan offload format to V3 for WiFi 7 IC
drivers/net/wireless/realtek/rtw89/core.c | 3 +-
drivers/net/wireless/realtek/rtw89/core.h | 4 +
drivers/net/wireless/realtek/rtw89/fw.c | 126 ++++++++++++++++++--
drivers/net/wireless/realtek/rtw89/fw.h | 1 +
drivers/net/wireless/realtek/rtw89/mac.c | 1 +
drivers/net/wireless/realtek/rtw89/mac.h | 1 +
drivers/net/wireless/realtek/rtw89/mac_be.c | 7 +-
drivers/net/wireless/realtek/rtw89/reg.h | 6 +-
8 files changed, 131 insertions(+), 18 deletions(-)
base-commit: b0034a2e415603daa1cf00363b407cc145bbcd31
--
2.25.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH rtw-next 1/3] wifi: rtw89: refine RX filter configuration for WiFi 7 generation
2026-07-24 14:22 [PATCH rtw-next 0/3] wifi: rtw89: support hw_scan v3 format for WiFI 7 chips Ping-Ke Shih
@ 2026-07-24 14:22 ` Ping-Ke Shih
2026-07-24 14:22 ` [PATCH rtw-next 2/3] wifi: rtw89: fix scan offload version check logic Ping-Ke Shih
2026-07-24 14:22 ` [PATCH rtw-next 3/3] wifi: rtw89: change scan offload format to V3 for WiFi 7 IC Ping-Ke Shih
2 siblings, 0 replies; 4+ messages in thread
From: Ping-Ke Shih @ 2026-07-24 14:22 UTC (permalink / raw)
To: linux-wireless; +Cc: dian_syuan0116, phhuang
From: Dian-Syuan Yang <dian_syuan0116@realtek.com>
When an AP interface is registered and starts AP, mac80211 calls the
configure_filter() to clear B_AX_A_UC_CAM_MATCH and B_AX_A_BC_CAM_MATCH
so that frames from un-associated stations can be received. However, for
a dedicated AP interface created via iw command, configure_filter() is
only triggered on the initial AP startup. Since the interface remains up
even after hostapd stops, and it isn't triggered again on later restarts.
Additionally, each AP start causes IPS leave, reverting the RX filter to
its default value.
For WiFi 7 chips, the default value is hardcoded in rx_fltr_init_be(),
so the reverted value does not match hal.rx_fltr. Therefore, refine
the behavior of WiFi 7 chips to align with the WiFi 6 implementation.
Signed-off-by: Dian-Syuan Yang <dian_syuan0116@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.c | 3 ++-
drivers/net/wireless/realtek/rtw89/mac.c | 1 +
drivers/net/wireless/realtek/rtw89/mac.h | 1 +
drivers/net/wireless/realtek/rtw89/mac_be.c | 7 ++-----
drivers/net/wireless/realtek/rtw89/reg.h | 6 +++++-
5 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 77a0e2582dbe..097e9b0312a1 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -6960,6 +6960,7 @@ void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id)
int rtw89_core_init(struct rtw89_dev *rtwdev)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct rtw89_btc *btc = &rtwdev->btc;
u8 band;
@@ -7016,7 +7017,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
rtw89_core_ppdu_sts_init(rtwdev);
rtw89_traffic_stats_init(rtwdev, &rtwdev->stats);
- rtwdev->hal.rx_fltr = DEFAULT_AX_RX_FLTR;
+ rtwdev->hal.rx_fltr = mac->default_rx_fltr;
rtwdev->dbcc_en = false;
rtwdev->mlo_dbcc_mode = MLO_DBCC_NOT_SUPPORT;
rtwdev->mac.qta_mode = RTW89_QTA_SCC;
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index db9fca828829..ca08fe520eaa 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -7458,6 +7458,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.mem_base_addrs = rtw89_mac_mem_base_addrs_ax,
.mem_page_size = MAC_MEM_DUMP_PAGE_SIZE_AX,
.rx_fltr = R_AX_RX_FLTR_OPT,
+ .default_rx_fltr = DEFAULT_AX_RX_FLTR,
.port_base = &rtw89_port_base_ax,
.agg_len_ht = R_AX_AGG_LEN_HT_0,
.ps_status = R_AX_PPWRBIT_SETTING,
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index 493d2b9626a6..8419bcd3956a 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -1063,6 +1063,7 @@ struct rtw89_mac_gen_def {
const u32 *mem_base_addrs;
u32 mem_page_size;
u32 rx_fltr;
+ u32 default_rx_fltr;
const struct rtw89_port_reg *port_base;
u32 agg_len_ht;
u32 ps_status;
diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c
index 8de0fe5a3b1d..413c214d968a 100644
--- a/drivers/net/wireless/realtek/rtw89/mac_be.c
+++ b/drivers/net/wireless/realtek/rtw89/mac_be.c
@@ -1332,11 +1332,7 @@ static int rx_fltr_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
rtw89_mac_typ_fltr_opt_be(rtwdev, RTW89_DATA, RTW89_FWD_TO_HOST, mac_idx);
reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_FLTR_OPT, mac_idx);
- val = B_BE_A_BC_CAM_MATCH | B_BE_A_UC_CAM_MATCH | B_BE_A_MC |
- B_BE_A_BC | B_BE_A_A1_MATCH |
- u32_encode_bits(15, B_BE_UID_FILTER_MASK);
- rtw89_write32(rtwdev, reg, val);
- u32p_replace_bits(&rtwdev->hal.rx_fltr, 15, B_BE_UID_FILTER_MASK);
+ rtw89_write32(rtwdev, reg, rtwdev->hal.rx_fltr);
reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PLCP_HDR_FLTR, mac_idx);
val = B_BE_HE_SIGB_CRC_CHK | B_BE_VHT_MU_SIGB_CRC_CHK |
@@ -3280,6 +3276,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
.mem_base_addrs = rtw89_mac_mem_base_addrs_be,
.mem_page_size = MAC_MEM_DUMP_PAGE_SIZE_BE,
.rx_fltr = R_BE_RX_FLTR_OPT,
+ .default_rx_fltr = DEFAULT_BE_RX_FLTR,
.port_base = &rtw89_port_base_be,
.agg_len_ht = R_BE_AGG_LEN_HT_0,
.ps_status = R_BE_WMTX_POWER_BE_BIT_CTL,
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index 756b94dcd475..abeeb61007dc 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -3348,7 +3348,7 @@
#define DEFAULT_AX_RX_FLTR (B_AX_A_A1_MATCH | B_AX_A_BC | B_AX_A_MC | \
B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH | \
B_AX_A_PWR_MGNT | B_AX_A_FTM_REQ | \
- u32_encode_bits(3, B_AX_UID_FILTER_MASK) | \
+ FIELD_PREP_CONST(B_AX_UID_FILTER_MASK, 3) | \
B_AX_A_BCN_CHK_EN)
#define B_AX_RX_FLTR_CFG_MASK ((u32)~B_AX_RX_MPDU_MAX_LEN_MASK)
@@ -8209,6 +8209,10 @@
#define B_BE_A_BC BIT(2)
#define B_BE_A_A1_MATCH BIT(1)
#define B_BE_SNIFFER_MODE BIT(0)
+#define DEFAULT_BE_RX_FLTR (B_BE_A_BC_CAM_MATCH | B_BE_A_UC_CAM_MATCH | \
+ B_BE_A_MC | B_BE_A_BC | B_BE_A_A1_MATCH | \
+ FIELD_PREP_CONST(B_BE_UID_FILTER_MASK, 15) | \
+ B_BE_A_FTM_REQ | B_BE_A_BCN_CHK_EN)
#define R_BE_CTRL_FLTR 0x11424
#define R_BE_CTRL_FLTR_C1 0x15424
--
2.25.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH rtw-next 2/3] wifi: rtw89: fix scan offload version check logic
2026-07-24 14:22 [PATCH rtw-next 0/3] wifi: rtw89: support hw_scan v3 format for WiFI 7 chips Ping-Ke Shih
2026-07-24 14:22 ` [PATCH rtw-next 1/3] wifi: rtw89: refine RX filter configuration for WiFi 7 generation Ping-Ke Shih
@ 2026-07-24 14:22 ` Ping-Ke Shih
2026-07-24 14:22 ` [PATCH rtw-next 3/3] wifi: rtw89: change scan offload format to V3 for WiFi 7 IC Ping-Ke Shih
2 siblings, 0 replies; 4+ messages in thread
From: Ping-Ke Shih @ 2026-07-24 14:22 UTC (permalink / raw)
To: linux-wireless; +Cc: dian_syuan0116, phhuang
From: Po-Hao Huang <phhuang@realtek.com>
The version check with less than should check for smallest upper-bound
first, or some branch will be unreachable.
Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/fw.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 3b8c144e0e98..7d68ee870ed5 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -7615,12 +7615,12 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
rtw89_scan_get_6g_disabled_chan(rtwdev, option);
- if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V1, &rtwdev->fw)) {
- cfg_len = offsetofend(typeof(*h2c), w9);
- scan_offload_ver = 1;
- } else if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw)) {
+ if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw)) {
cfg_len = offsetofend(typeof(*h2c), w8);
scan_offload_ver = 0;
+ } else if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V1, &rtwdev->fw)) {
+ cfg_len = offsetofend(typeof(*h2c), w9);
+ scan_offload_ver = 1;
}
len = cfg_len + macc_role_size + opch_size;
--
2.25.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH rtw-next 3/3] wifi: rtw89: change scan offload format to V3 for WiFi 7 IC
2026-07-24 14:22 [PATCH rtw-next 0/3] wifi: rtw89: support hw_scan v3 format for WiFI 7 chips Ping-Ke Shih
2026-07-24 14:22 ` [PATCH rtw-next 1/3] wifi: rtw89: refine RX filter configuration for WiFi 7 generation Ping-Ke Shih
2026-07-24 14:22 ` [PATCH rtw-next 2/3] wifi: rtw89: fix scan offload version check logic Ping-Ke Shih
@ 2026-07-24 14:22 ` Ping-Ke Shih
2 siblings, 0 replies; 4+ messages in thread
From: Ping-Ke Shih @ 2026-07-24 14:22 UTC (permalink / raw)
To: linux-wireless; +Cc: dian_syuan0116, phhuang
From: Po-Hao Huang <phhuang@realtek.com>
Adapt H2C formt to fit firmware version after 0.35.113.2, which
only supports active scanning with a provided SSID list.
Keep original style also to support older firmwares.
Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.h | 4 +
drivers/net/wireless/realtek/rtw89/fw.c | 118 ++++++++++++++++++++--
drivers/net/wireless/realtek/rtw89/fw.h | 1 +
3 files changed, 116 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 7573f1965c98..9e6e0b2b47da 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -5700,6 +5700,7 @@ enum rtw89_fw_feature {
RTW89_FW_FEATURE_MACID_PAUSE_SLEEP,
RTW89_FW_FEATURE_SCAN_OFFLOAD_BE_V0,
RTW89_FW_FEATURE_SCAN_OFFLOAD_BE_V1,
+ RTW89_FW_FEATURE_SCAN_OFFLOAD_BE_V2,
RTW89_FW_FEATURE_WOW_REASON_V1,
RTW89_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY,
RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0,
@@ -6894,6 +6895,9 @@ struct rtw89_hw_scan_info {
struct list_head chan_list;
struct rtw89_chan op_chan;
struct rtw89_hw_scan_extra_op extra_op;
+ u8 wildcard_pkt_id[NUM_NL80211_BANDS];
+ u16 ssid_total_len;
+ int n_ssids;
bool connected;
bool abort;
u16 delay; /* in unit of ms */
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 7d68ee870ed5..52ea1282f26e 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -934,6 +934,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 100, 0, SER_POST_RECOVER_DMAC),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 108, 0, SIM_SER_L0L1_BY_HALT_H2C),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 109, 1, SCAN_OFFLOAD_BE_V1),
+ __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 113, 2, SCAN_OFFLOAD_BE_V2),
__CFG_FW_FEAT(RTL8922D, ge, 0, 0, 0, 0, MACID_PAUSE_SLEEP),
__CFG_FW_FEAT(RTL8922D, ge, 0, 35, 75, 2, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8922D, ge, 0, 35, 75, 2, BEACON_FILTER),
@@ -949,6 +950,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8922D, ge, 0, 35, 108, 0, SIM_SER_L0L1_BY_HALT_H2C),
__CFG_FW_FEAT(RTL8922D, lt, 0, 35, 109, 1, SCAN_OFFLOAD_BE_V1),
__CFG_FW_FEAT(RTL8922D, lt, 0, 35, 113, 0, RFK_TXIQK_V0),
+ __CFG_FW_FEAT(RTL8922D, lt, 0, 35, 113, 2, SCAN_OFFLOAD_BE_V2),
};
static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw,
@@ -7365,6 +7367,7 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
struct rtw89_h2c_chinfo_elem_be *elem;
struct rtw89_mac_chinfo_be *ch_info;
struct rtw89_h2c_chinfo_be *h2c;
+ bool wildcard_by_drv;
struct sk_buff *skb;
unsigned int cond;
u8 ver = U8_MAX;
@@ -7383,6 +7386,10 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw))
ver = 0;
+ wildcard_by_drv = !(RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw) ||
+ RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V1, &rtwdev->fw) ||
+ RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V2, &rtwdev->fw));
+
skb_put(skb, sizeof(*h2c));
h2c = (struct rtw89_h2c_chinfo_be *)skb->data;
@@ -7392,6 +7399,8 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
RTW89_H2C_CHINFO_ARG_MAC_IDX_MASK);
list_for_each_entry(ch_info, chan_list, list) {
+ bool with_probe_id = ch_info->probe_id != RTW89_SCANOFLD_PKT_NONE;
+
elem = (struct rtw89_h2c_chinfo_elem_be *)skb_put(skb, sizeof(*elem));
elem->w0 = le32_encode_bits(ch_info->dwell_time, RTW89_H2C_CHINFO_BE_W0_DWELL) |
@@ -7409,7 +7418,7 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
RTW89_H2C_CHINFO_BE_W1_RANDOM) |
le32_encode_bits(ch_info->notify_action,
RTW89_H2C_CHINFO_BE_W1_NOTIFY) |
- le32_encode_bits(ch_info->probe_id != 0xff ? 1 : 0,
+ le32_encode_bits(wildcard_by_drv || with_probe_id,
RTW89_H2C_CHINFO_BE_W1_PROBE) |
le32_encode_bits(ch_info->leave_crit,
RTW89_H2C_CHINFO_BE_W1_EARLY_LEAVE_CRIT) |
@@ -7574,6 +7583,27 @@ static void rtw89_scan_get_6g_disabled_chan(struct rtw89_dev *rtwdev,
}
}
+static void rtw89_hw_scan_calc_req_ssid(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ struct cfg80211_scan_request *req = rtwvif->scan_req;
+ int i, num = 0;
+ u16 sum = 0;
+
+ for (i = 0; i < req->n_ssids; i++) {
+ if (req->ssids[i].ssid_len == 0)
+ continue;
+
+ num++;
+ sum += req->ssids[i].ssid_len + 1;
+ }
+
+ scan_info->n_ssids = num;
+ scan_info->ssid_total_len = sum;
+}
+
int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
struct rtw89_scan_option *option,
struct rtw89_vif_link *rtwvif_link,
@@ -7594,12 +7624,13 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
struct sk_buff *skb;
u8 macc_role_size = sizeof(*macc_role) * option->num_macc_role;
u8 opch_size = sizeof(*opch) * option->num_opch;
+ u8 *probe_id = scan_info->wildcard_pkt_id;
enum rtw89_scan_be_opmode opmode;
- u8 probe_id[NUM_NL80211_BANDS];
u8 scan_offload_ver = U8_MAX;
u8 cfg_len = sizeof(*h2c);
unsigned int cond;
u8 ver = U8_MAX;
+ u8 n_ssids = 0;
u8 policy_val;
void *ptr;
u8 txnull;
@@ -7621,9 +7652,14 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
} else if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V1, &rtwdev->fw)) {
cfg_len = offsetofend(typeof(*h2c), w9);
scan_offload_ver = 1;
+ } else if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V2, &rtwdev->fw)) {
+ scan_offload_ver = 2;
}
len = cfg_len + macc_role_size + opch_size;
+ if (scan_offload_ver > 2)
+ len += scan_info->ssid_total_len;
+
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c scan offload\n");
@@ -7634,8 +7670,6 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
h2c = (struct rtw89_h2c_scanofld_be *)skb->data;
ptr = skb->data;
- memset(probe_id, RTW89_SCANOFLD_PKT_NONE, sizeof(probe_id));
-
if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw))
ver = 0;
@@ -7667,7 +7701,10 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
le32_encode_bits(option->norm_cy, RTW89_H2C_SCANOFLD_BE_W2_NORM_CY) |
le32_encode_bits(option->opch_end, RTW89_H2C_SCANOFLD_BE_W2_OPCH_END);
- h2c->w3 = le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_SSID) |
+ if (scan_offload_ver > 2)
+ n_ssids = scan_info->n_ssids;
+
+ h2c->w3 = le32_encode_bits(n_ssids, RTW89_H2C_SCANOFLD_BE_W3_NUM_SSID) |
le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_SHORT_SSID) |
le32_encode_bits(0, RTW89_H2C_SCANOFLD_BE_W3_NUM_BSSID) |
le32_encode_bits(probe_id[NL80211_BAND_2GHZ], RTW89_H2C_SCANOFLD_BE_W3_PROBEID);
@@ -7794,6 +7831,20 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
ptr += sizeof(*opch);
}
+ if (scan_offload_ver <= 2)
+ goto set_hdr;
+
+ for (i = 0; i < req->n_ssids; i++) {
+ if (req->ssids[i].ssid_len == 0)
+ continue;
+
+ memcpy(ptr, &req->ssids[i].ssid_len, 1);
+ ptr++;
+ memcpy(ptr, req->ssids[i].ssid, req->ssids[i].ssid_len);
+ ptr += req->ssids[i].ssid_len;
+ }
+
+set_hdr:
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD,
H2C_FUNC_SCANOFLD_BE, 1, 1,
@@ -9123,14 +9174,19 @@ void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev)
static void rtw89_hw_scan_release_pkt_list(struct rtw89_dev *rtwdev)
{
+ struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
struct rtw89_pktofld_info *info, *tmp;
- u8 idx;
+ u8 idx, wildcard_pkt_id;
for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) {
if (!(rtwdev->chip->support_bands & BIT(idx)))
continue;
+ wildcard_pkt_id = scan_info->wildcard_pkt_id[idx];
+ if (wildcard_pkt_id != RTW89_SCANOFLD_PKT_NONE)
+ rtw89_fw_h2c_del_pkt_offload(rtwdev, wildcard_pkt_id);
+
list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) {
if (test_bit(info->id, rtwdev->pkt_offload))
rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id);
@@ -9225,16 +9281,57 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev,
return ret;
}
+static int rtw89_hw_scan_append_wildcard_probe_req(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ const u8 *mac_addr)
+{
+ struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
+ struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
+ struct cfg80211_scan_request *req = rtwvif->scan_req;
+ struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
+ enum nl80211_band band;
+ struct sk_buff *skb;
+ int ret;
+ u8 id;
+
+ for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
+ if (!(rtwdev->chip->support_bands & BIT(band)))
+ continue;
+
+ skb = ieee80211_probereq_get(rtwdev->hw, mac_addr,
+ NULL, 0, req->ie_len);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_put_data(skb, ies->ies[band], ies->len[band]);
+ skb_put_data(skb, ies->common_ies, ies->common_ie_len);
+
+ ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &id, skb);
+ kfree_skb(skb);
+
+ if (ret)
+ return ret;
+
+ scan_info->wildcard_pkt_id[band] = id;
+ }
+
+ return 0;
+}
+
static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
const u8 *mac_addr)
{
struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct cfg80211_scan_request *req = rtwvif->scan_req;
- struct sk_buff *skb;
u8 num = req->n_ssids, i;
+ struct sk_buff *skb;
int ret;
+ ret = rtw89_hw_scan_append_wildcard_probe_req(rtwdev, rtwvif_link, mac_addr);
+ if (ret)
+ return ret;
+
for (i = 0; i < num; i++) {
skb = ieee80211_probereq_get(rtwdev->hw, mac_addr,
req->ssids[i].ssid,
@@ -9542,6 +9639,9 @@ static void rtw89_hw_scan_add_chan_be(struct rtw89_dev *rtwdev, int chan_type,
if (probe_count >= RTW89_SCANOFLD_MAX_SSID)
break;
}
+
+ if (scan_info->n_ssids)
+ ch_info->fw_probe0_ssids = GENMASK(scan_info->n_ssids - 1, 0);
}
if (ch_info->ch_band == RTW89_BAND_6G) {
@@ -10144,6 +10244,10 @@ int rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
rtwdev->scan_info.delay = 0;
rtwvif->scan_ies = &scan_req->ies;
rtwvif->scan_req = req;
+ rtw89_hw_scan_calc_req_ssid(rtwdev, rtwvif_link);
+
+ memset(rtwdev->scan_info.wildcard_pkt_id, RTW89_SCANOFLD_PKT_NONE,
+ sizeof(rtwdev->scan_info.wildcard_pkt_id));
if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
get_random_mask_addr(mac_addr, req->mac_addr,
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index e86014ca249a..f70b096a542d 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -3099,6 +3099,7 @@ struct rtw89_h2c_scanofld_be {
__le32 w11; /* Added after SCAN_OFFLOAD_BE_V2 */
/* struct rtw89_h2c_scanofld_be_macc_role (flexible number) */
/* struct rtw89_h2c_scanofld_be_opch (flexible number) */
+ /* probe SSID list (flexible number); Added after SCAN_OFFLOAD_BE_V3 */
} __packed;
#define RTW89_H2C_SCANOFLD_BE_W0_OP GENMASK(1, 0)
--
2.25.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-07-24 14:23 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-24 14:22 [PATCH rtw-next 0/3] wifi: rtw89: support hw_scan v3 format for WiFI 7 chips Ping-Ke Shih
2026-07-24 14:22 ` [PATCH rtw-next 1/3] wifi: rtw89: refine RX filter configuration for WiFi 7 generation Ping-Ke Shih
2026-07-24 14:22 ` [PATCH rtw-next 2/3] wifi: rtw89: fix scan offload version check logic Ping-Ke Shih
2026-07-24 14:22 ` [PATCH rtw-next 3/3] wifi: rtw89: change scan offload format to V3 for WiFi 7 IC 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