From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 39CFB483811 for ; Wed, 29 Jul 2026 12:44:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785329065; cv=none; b=OaxnftGgUprePp2//OfI/CgewUHcd1xJJDPfiMnVYyzXN4eBnnZ4XRSSseclhDBrB/Y6KLvFDJnwHYo1Y8Kz4XmqzP9myvPHkAvCqUwPYc9e/VAECp+QPvC5Hr8ZSC9ZDGAmPKVyc+OuBfjlDT4Mlc5xsxLgEWov3kPc1JutqJE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785329065; c=relaxed/simple; bh=BdOhhgMeo2eanBVnRQS7KkGApkIdF5EVoxPj9yaa6uI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=n/Rk30jCH+U4fiBRcR61Z+LJe3uuNyLkS1p63ttQdMB4m6aQaIZtwi1KYb4N2N7TqgnR3quefZX4JXo4VZ5CDrAByFg5Xez2QSkHaO3OR2791TqUXMy8m+zEbT8bIK9/WkfYpbDCe8kTHVl0KTGzwcc5PZVTZGJ1Xk2pMBVwZTI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=jMbhxIfL; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="jMbhxIfL" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 66TCi9941421738, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1785329049; bh=TEWGzTE//Ao2pAt5w4PbA3DqTHvZnz08iKAUtQxuyvE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=jMbhxIfLjIcSfBdUHkPWxuLNBKg0V8zIPEZQTB9/DVD64OjbSkSm+dgDbVGL+XfjF gs5KkHKzDmt2m3koJCBnyCD5rXzzbicFCvQq2e73U0iDL5BkT3s4YUdEyrCWRjtkgN tGmk/nyrJzhyTbrpcDu+vMCzJjZQOCMe9IcFpF3XgBiiSI8CVrJrR09Syilxs5eCwA rOshe1nWXuHjyiQrohzP3IQ9b5TzpfsdR4EF97mIkoN8WrMVxaQbGr0FRo3JgcDicK A8CLmikIa8efWN7MPLW/PP/8N0eX21vLwp/jDJdb6n7uC70ioTylXY9A4TdG5mfk9Z vHcx9YSVRS7lA== Received: from mail.realtek.com (rtkexhmbs04.realtek.com.tw[10.21.1.54]) by rtits2.realtek.com.tw (8.15.2/3.29/5.94) with ESMTPS id 66TCi9941421738 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Wed, 29 Jul 2026 20:44:09 +0800 Received: from RTKEXHMBS06.realtek.com.tw (10.21.1.56) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Wed, 29 Jul 2026 20:44:10 +0800 Received: from RTKEXHMBS05.realtek.com.tw (10.21.1.55) by RTKEXHMBS06.realtek.com.tw (10.21.1.56) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Wed, 29 Jul 2026 20:44:10 +0800 Received: from [127.0.1.1] (172.21.40.76) by RTKEXHMBS05.realtek.com.tw (10.21.1.55) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17 via Frontend Transport; Wed, 29 Jul 2026 20:44:10 +0800 From: Ping-Ke Shih To: CC: , Subject: [PATCH rtw-next v2 3/3] wifi: rtw89: change scan offload format to V3 for WiFi 7 IC Date: Wed, 29 Jul 2026 20:43:54 +0800 Message-ID: <20260729124354.3231368-4-pkshih@realtek.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260729124354.3231368-1-pkshih@realtek.com> References: <20260729124354.3231368-1-pkshih@realtek.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain From: Po-Hao Huang Adapt H2C format to fit firmware version after 0.35.113.2, which only supports active scanning with a provided SSID list. The wildcard_6ghz field is no longer required for WiFi 7 chips' new format, but not removed since WiFi 6 still requires it. Keep original H2C style also to support older firmwares. Signed-off-by: Po-Hao Huang Signed-off-by: Ping-Ke Shih --- v2: consider WoWLAN PNO user scenario, and not consider wildcard_6ghz field for WiFi 7 chips. --- drivers/net/wireless/realtek/rtw89/core.h | 4 + drivers/net/wireless/realtek/rtw89/fw.c | 160 +++++++++++++++++++--- drivers/net/wireless/realtek/rtw89/fw.h | 6 + drivers/net/wireless/realtek/rtw89/wow.c | 20 +++ 4 files changed, 172 insertions(+), 18 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..3cf41952d8ff 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,34 @@ static void rtw89_scan_get_6g_disabled_chan(struct rtw89_dev *rtwdev, } } +void rtw89_hw_scan_calc_req_ssid(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool wowlan) +{ + 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 rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct cfg80211_sched_scan_request *nd_config; + struct cfg80211_ssid *s; + u16 sum = 0, n_ssids; + int i, num = 0; + + nd_config = rtw_wow->nd_config; + n_ssids = wowlan ? nd_config->n_match_sets : req->n_ssids; + + for (i = 0; i < n_ssids; i++) { + s = wowlan ? &nd_config->match_sets[i].ssid : &req->ssids[i]; + if (s->ssid_len == 0) + continue; + + num++; + sum += s->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, @@ -7588,18 +7625,21 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, struct rtw89_hw_scan_extra_op scan_op[2] = {}; struct rtw89_chan *op = &scan_info->op_chan; struct rtw89_h2c_scanofld_be_opch *opch; - struct rtw89_pktofld_info *pkt_info; struct rtw89_h2c_scanofld_be *h2c; struct ieee80211_vif *vif; struct sk_buff *skb; u8 macc_role_size = sizeof(*macc_role) * option->num_macc_role; u8 opch_size = sizeof(*opch) * option->num_opch; + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct cfg80211_sched_scan_request *nd_config; + 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); + struct cfg80211_ssid *s; unsigned int cond; u8 ver = U8_MAX; + u8 n_ssids = 0; u8 policy_val; void *ptr; u8 txnull; @@ -7621,9 +7661,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,21 +7679,9 @@ 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; - if (!wowlan) { - list_for_each_entry(pkt_info, &scan_info->pkt_list[NL80211_BAND_6GHZ], list) { - if (pkt_info->wildcard_6ghz) { - /* Provide wildcard as template */ - probe_id[NL80211_BAND_6GHZ] = pkt_info->id; - break; - } - } - } - h2c->w0 = le32_encode_bits(option->operation, RTW89_H2C_SCANOFLD_BE_W0_OP) | le32_encode_bits(option->scan_mode, RTW89_H2C_SCANOFLD_BE_W0_SCAN_MODE) | @@ -7667,7 +7700,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 +7830,24 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, ptr += sizeof(*opch); } + if (scan_offload_ver <= 2) + goto set_hdr; + + nd_config = rtw_wow->nd_config; + n_ssids = wowlan ? nd_config->n_match_sets : req->n_ssids; + + for (i = 0; i < n_ssids; i++) { + s = wowlan ? &nd_config->match_sets[i].ssid : &req->ssids[i]; + if (s->ssid_len == 0) + continue; + + memcpy(ptr, &s->ssid_len, 1); + ptr++; + memcpy(ptr, s->ssid, s->ssid_len); + ptr += s->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 +9177,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 +9284,74 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, return ret; } +int rtw89_hw_scan_append_wildcard_probe_req(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + const u8 *mac_addr, bool wowlan) +{ + static const u8 basic_rate_ie[] = {WLAN_EID_SUPP_RATES, 0x08, 0x0c, 0x12, + 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c}; + 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; + struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct cfg80211_sched_scan_request *nd_config; + 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; + + if (wowlan) { + nd_config = rtw_wow->nd_config; + + skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, NULL, 0, + nd_config->ie_len + + sizeof(basic_rate_ie)); + if (!skb) + return -ENOMEM; + + skb_put_data(skb, basic_rate_ie, sizeof(basic_rate_ie)); + skb_put_data(skb, nd_config->ie, nd_config->ie_len); + } else { + 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, false); + if (ret) + return ret; + for (i = 0; i < num; i++) { skb = ieee80211_probereq_get(rtwdev->hw, mac_addr, req->ssids[i].ssid, @@ -9542,6 +9659,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 +10264,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, false); + + 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..9057ca4d8ea6 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) @@ -5577,6 +5578,11 @@ int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); +int rtw89_hw_scan_append_wildcard_probe_req(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + const u8 *mac_addr, bool wowlan); +void rtw89_hw_scan_calc_req_ssid(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, bool wowlan); int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev); int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev, const struct rtw89_pkt_drop_params *params); diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index d6bf5cd8be3b..2dfa24c54e7d 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -1457,9 +1457,20 @@ static int rtw89_wow_disable_trx_post(struct rtw89_dev *rtwdev) static void rtw89_fw_release_pno_pkt_list(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; struct rtw89_wow_param *rtw_wow = &rtwdev->wow; struct list_head *pkt_list = &rtw_wow->pno_pkt_list; struct rtw89_pktofld_info *info, *tmp; + 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, list) { rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); @@ -1480,6 +1491,11 @@ static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev, struct sk_buff *skb; int ret; + ret = rtw89_hw_scan_append_wildcard_probe_req(rtwdev, rtwvif_link, + rtwvif_link->mac_addr, true); + if (ret) + return ret; + for (i = 0; i < num; i++) { skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, nd_config->match_sets[i].ssid.ssid, @@ -1523,6 +1539,10 @@ static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable) int ret; if (enable) { + rtw89_hw_scan_calc_req_ssid(rtwdev, rtwvif_link, true); + memset(rtwdev->scan_info.wildcard_pkt_id, RTW89_SCANOFLD_PKT_NONE, + sizeof(rtwdev->scan_info.wildcard_pkt_id)); + ret = rtw89_pno_scan_update_probe_req(rtwdev, rtwvif_link); if (ret) { rtw89_err(rtwdev, "Update probe request failed\n"); -- 2.25.1