From patchwork Wed Apr 19 11:45:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ping-Ke Shih X-Patchwork-Id: 676131 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 14E8AC6FD18 for ; Wed, 19 Apr 2023 11:46:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232901AbjDSLqC (ORCPT ); Wed, 19 Apr 2023 07:46:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232403AbjDSLqA (ORCPT ); Wed, 19 Apr 2023 07:46:00 -0400 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 585DB13F84 for ; Wed, 19 Apr 2023 04:45:59 -0700 (PDT) Authenticated-By: X-SpamFilter-By: ArmorX SpamTrap 5.77 with qID 33JBjqcP7009728, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexh36506.realtek.com.tw[172.21.6.27]) by rtits2.realtek.com.tw (8.15.2/2.81/5.90) with ESMTPS id 33JBjqcP7009728 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Wed, 19 Apr 2023 19:45:52 +0800 Received: from RTEXMBS05.realtek.com.tw (172.21.6.98) by RTEXH36506.realtek.com.tw (172.21.6.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.17; Wed, 19 Apr 2023 19:45:52 +0800 Received: from RTEXMBS04.realtek.com.tw (172.21.6.97) by RTEXMBS05.realtek.com.tw (172.21.6.98) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.34; Wed, 19 Apr 2023 19:45:51 +0800 Received: from RTEXMBS04.realtek.com.tw ([fe80::e138:e7f1:4709:ff4d]) by RTEXMBS04.realtek.com.tw ([fe80::e138:e7f1:4709:ff4d%5]) with mapi id 15.01.2375.007; Wed, 19 Apr 2023 19:45:51 +0800 From: Ping-Ke Shih To: "kvalo@kernel.org" CC: "linux-wireless@vger.kernel.org" , "Kevin Yang" Subject: [PATCH 1/5] wifi: rtw89: release bit in rtw89_fw_h2c_del_pkt_offload() Thread-Topic: [PATCH 1/5] wifi: rtw89: release bit in rtw89_fw_h2c_del_pkt_offload() Thread-Index: AQHZcrR9Osl2uZogzEeLKGRhJ2En9Q== Date: Wed, 19 Apr 2023 11:45:51 +0000 Message-ID: <8cf5d45c5b04e7b680d4eb9dda62056cdce14cec.camel@realtek.com> Accept-Language: en-US, zh-TW Content-Language: zh-TW X-MS-Has-Attach: X-MS-TNEF-Correlator: user-agent: Evolution 3.36.1-2 x-originating-ip: [172.16.16.139] x-kse-serverinfo: RTEXMBS05.realtek.com.tw, 9 x-kse-antispam-interceptor-info: fallback x-kse-antivirus-interceptor-info: fallback Content-ID: <3DF0A47FECE78F46B9CC07F9C0538E89@realtek.com> MIME-Version: 1.0 X-KSE-AntiSpam-Interceptor-Info: fallback Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Zong-Zhe Yang We have a pair of FW functions, rtw89_fw_h2c_add_pkt_offload() and rtw89_fw_h2c_del_pkt_offload(). The rtw89_fw_h2c_add_pkt_offload() acquires the bit itself, but the bit needs to be released by the caller of rtw89_fw_h2c_del_pkt_offload(). This looks asymmetrical and is not friendly to callers. Second, if callers always releases the bits, it might make driver unaligned to bitmap status of FW after some failures of calling rtw89_fw_h2c_del_pkt_offload(). So, this commit move bit release into rtw89_fw_h2c_del_pkt_offload(). In general, driver will call rtw89_fw_h2c_add_pkt_offload() and rtw89_fw_h2c_del_pkt_offload(), and then, SW bitmap can align with FW one. There is one exception when notify_fw is false. It happens when driver detects FW problems and is going to reset FW. Only in this case, driver needs to release bits outside rtw89_fw_h2c_del_pkt_offload(). Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/fw.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index b9b675bf9d050..4051d337ef4ef 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -997,8 +997,8 @@ void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, list_for_each_entry_safe(info, tmp, pkt_list, list) { if (notify_fw) rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); - rtw89_core_release_bit_map(rtwdev->pkt_offload, - info->id); + else + rtw89_core_release_bit_map(rtwdev->pkt_offload, info->id); list_del(&info->list); kfree(info); } @@ -2466,6 +2466,7 @@ int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id) goto fail; } + rtw89_core_release_bit_map(rtwdev->pkt_offload, id); return 0; fail: dev_kfree_skb_any(skb); @@ -3020,8 +3021,6 @@ static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev) list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) { rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); - rtw89_core_release_bit_map(rtwdev->pkt_offload, - info->id); list_del(&info->list); kfree(info); } From patchwork Wed Apr 19 11:45:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ping-Ke Shih X-Patchwork-Id: 675577 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6F0F0C6FD18 for ; Wed, 19 Apr 2023 11:46:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232947AbjDSLqG (ORCPT ); Wed, 19 Apr 2023 07:46:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41048 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232403AbjDSLqE (ORCPT ); Wed, 19 Apr 2023 07:46:04 -0400 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9582913F9D for ; Wed, 19 Apr 2023 04:46:02 -0700 (PDT) Authenticated-By: X-SpamFilter-By: ArmorX SpamTrap 5.77 with qID 33JBjt1V3009732, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexh36506.realtek.com.tw[172.21.6.27]) by rtits2.realtek.com.tw (8.15.2/2.81/5.90) with ESMTPS id 33JBjt1V3009732 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Wed, 19 Apr 2023 19:45:55 +0800 Received: from RTEXMBS01.realtek.com.tw (172.21.6.94) by RTEXH36506.realtek.com.tw (172.21.6.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.17; Wed, 19 Apr 2023 19:45:55 +0800 Received: from RTEXMBS04.realtek.com.tw (172.21.6.97) by RTEXMBS01.realtek.com.tw (172.21.6.94) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.7; Wed, 19 Apr 2023 19:45:55 +0800 Received: from RTEXMBS04.realtek.com.tw ([fe80::e138:e7f1:4709:ff4d]) by RTEXMBS04.realtek.com.tw ([fe80::e138:e7f1:4709:ff4d%5]) with mapi id 15.01.2375.007; Wed, 19 Apr 2023 19:45:55 +0800 From: Ping-Ke Shih To: "kvalo@kernel.org" CC: "linux-wireless@vger.kernel.org" , "Kevin Yang" Subject: [PATCH 2/5] wifi: rtw89: refine packet offload delete flow of 6 GHz probe Thread-Topic: [PATCH 2/5] wifi: rtw89: refine packet offload delete flow of 6 GHz probe Thread-Index: AQHZcrR/CynML36agkylmltJGS2grg== Date: Wed, 19 Apr 2023 11:45:55 +0000 Message-ID: <091966e5709cd7caecf9b81f7fd6388ae2b70a7e.camel@realtek.com> Accept-Language: en-US, zh-TW Content-Language: zh-TW X-MS-Has-Attach: X-MS-TNEF-Correlator: user-agent: Evolution 3.36.1-2 x-originating-ip: [172.16.16.139] x-kse-serverinfo: RTEXMBS01.realtek.com.tw, 9 x-kse-antispam-interceptor-info: fallback x-kse-antivirus-interceptor-info: fallback Content-ID: MIME-Version: 1.0 X-KSE-AntiSpam-Interceptor-Info: fallback Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Zong-Zhe Yang There are two places where offload packets of 6 GHz probe would be deleted from FW, i.e. calling rtw89_fw_h2c_del_pkt_offload(). * rtw89_core_cancel_6ghz_probe_tx() * rtw89_release_pkt_list() It is possible that we try to delete the same one from FW twice. Although it might not be a big problem for now, it will depend on the runtime chip firmware. So, we add a check to avoid it. In case things becomes complex due to racing problem, we don't choose to do list_del(info->list) and kfree(info) in both sides. Besides, rtw89_fw_h2c_del_pkt_offload() will needs to wait for completion after the follow-up commit. However, rtw89_core_cancel_6ghz_probe_tx() was called in interrupt context. So, we move the stuffs of calling rtw89_fw_h2c_del_pkt_offload() from rtw89_core_cancel_6ghz_probe_tx() into a work. Then, we also need a check there before we call it. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/core.c | 43 +++++++++++++++++++++-- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/fw.c | 3 +- drivers/net/wireless/realtek/rtw89/fw.h | 1 + 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 7fc0a26a4d731..254cb371054b3 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -1481,6 +1481,34 @@ static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev, } } +static void rtw89_cancel_6ghz_probe_work(struct work_struct *work) +{ + struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, + cancel_6ghz_probe_work); + struct list_head *pkt_list = rtwdev->scan_info.pkt_list; + struct rtw89_pktofld_info *info; + + mutex_lock(&rtwdev->mutex); + + if (!rtwdev->scanning) + goto out; + + list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) { + if (!info->cancel || !test_bit(info->id, rtwdev->pkt_offload)) + continue; + + rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); + + /* Don't delete/free info from pkt_list at this moment. Let it + * be deleted/freed in rtw89_release_pkt_list() after scanning, + * since if during scanning, pkt_list is accessed in bottom half. + */ + } + +out: + mutex_unlock(&rtwdev->mutex); +} + static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev, struct sk_buff *skb) { @@ -1489,6 +1517,7 @@ static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev, struct list_head *pkt_list = rtwdev->scan_info.pkt_list; struct rtw89_pktofld_info *info; const u8 *ies = mgmt->u.beacon.variable, *ssid_ie; + bool queue_work = false; if (rx_status->band != NL80211_BAND_6GHZ) return; @@ -1497,16 +1526,22 @@ static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev, list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) { if (ether_addr_equal(info->bssid, mgmt->bssid)) { - rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); + info->cancel = true; + queue_work = true; continue; } if (!ssid_ie || ssid_ie[1] != info->ssid_len || info->ssid_len == 0) continue; - if (memcmp(&ssid_ie[2], info->ssid, info->ssid_len) == 0) - rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); + if (memcmp(&ssid_ie[2], info->ssid, info->ssid_len) == 0) { + info->cancel = true; + queue_work = true; + } } + + if (queue_work) + ieee80211_queue_work(rtwdev->hw, &rtwdev->cancel_6ghz_probe_work); } static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, @@ -3433,6 +3468,7 @@ void rtw89_core_stop(struct rtw89_dev *rtwdev) mutex_unlock(&rtwdev->mutex); cancel_work_sync(&rtwdev->c2h_work); + cancel_work_sync(&rtwdev->cancel_6ghz_probe_work); cancel_work_sync(&btc->eapol_notify_work); cancel_work_sync(&btc->arp_notify_work); cancel_work_sync(&btc->dhcp_notify_work); @@ -3493,6 +3529,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work); INIT_WORK(&rtwdev->ips_work, rtw89_ips_work); INIT_WORK(&rtwdev->load_firmware_work, rtw89_load_firmware_work); + INIT_WORK(&rtwdev->cancel_6ghz_probe_work, rtw89_cancel_6ghz_probe_work); skb_queue_head_init(&rtwdev->c2h_queue); rtw89_core_ppdu_sts_init(rtwdev); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 6df386a38fb41..d2c0d7972235a 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -4054,6 +4054,7 @@ struct rtw89_dev { struct work_struct c2h_work; struct work_struct ips_work; struct work_struct load_firmware_work; + struct work_struct cancel_6ghz_probe_work; struct list_head early_h2c_list; diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 4051d337ef4ef..2390bcb3b46a8 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -3020,7 +3020,8 @@ static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev) continue; list_for_each_entry_safe(info, tmp, &pkt_list[idx], list) { - rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); + if (test_bit(info->id, rtwdev->pkt_offload)) + rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); list_del(&info->list); kfree(info); } diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 675f85c41471b..74a691e352878 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -277,6 +277,7 @@ struct rtw89_pktofld_info { u8 ssid_len; u8 bssid[ETH_ALEN]; u16 channel_6ghz; + bool cancel; }; static inline void RTW89_SET_FWCMD_RA_IS_DIS(void *cmd, u32 val) From patchwork Wed Apr 19 11:45:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ping-Ke Shih X-Patchwork-Id: 676130 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BABAAC77B73 for ; Wed, 19 Apr 2023 11:46:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232879AbjDSLqL (ORCPT ); Wed, 19 Apr 2023 07:46:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41172 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232955AbjDSLqJ (ORCPT ); Wed, 19 Apr 2023 07:46:09 -0400 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9F0CED330 for ; Wed, 19 Apr 2023 04:46:05 -0700 (PDT) Authenticated-By: X-SpamFilter-By: ArmorX SpamTrap 5.77 with qID 33JBjwAF3009736, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexh36506.realtek.com.tw[172.21.6.27]) by rtits2.realtek.com.tw (8.15.2/2.81/5.90) with ESMTPS id 33JBjwAF3009736 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Wed, 19 Apr 2023 19:45:58 +0800 Received: from RTEXMBS03.realtek.com.tw (172.21.6.96) by RTEXH36506.realtek.com.tw (172.21.6.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.17; Wed, 19 Apr 2023 19:45:58 +0800 Received: from RTEXMBS04.realtek.com.tw (172.21.6.97) by RTEXMBS03.realtek.com.tw (172.21.6.96) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.7; Wed, 19 Apr 2023 19:45:58 +0800 Received: from RTEXMBS04.realtek.com.tw ([fe80::e138:e7f1:4709:ff4d]) by RTEXMBS04.realtek.com.tw ([fe80::e138:e7f1:4709:ff4d%5]) with mapi id 15.01.2375.007; Wed, 19 Apr 2023 19:45:58 +0800 From: Ping-Ke Shih To: "kvalo@kernel.org" CC: "linux-wireless@vger.kernel.org" , "Kevin Yang" Subject: [PATCH 3/5] wifi: rtw89: packet offload wait for FW response Thread-Topic: [PATCH 3/5] wifi: rtw89: packet offload wait for FW response Thread-Index: AQHZcrSB+bV+QcLlm0+YVpdfbG9JHA== Date: Wed, 19 Apr 2023 11:45:58 +0000 Message-ID: <9ae8c1f105901c65e3171276a9fd6c99ae51803f.camel@realtek.com> Accept-Language: en-US, zh-TW Content-Language: zh-TW X-MS-Has-Attach: X-MS-TNEF-Correlator: user-agent: Evolution 3.36.1-2 x-originating-ip: [172.16.16.139] x-kse-serverinfo: RTEXMBS03.realtek.com.tw, 9 x-kse-antispam-interceptor-info: fallback x-kse-antivirus-interceptor-info: fallback Content-ID: <3E393001AA069F4FAB7B023FA7177D14@realtek.com> MIME-Version: 1.0 X-KSE-AntiSpam-Interceptor-Info: fallback Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Zong-Zhe Yang The H2Cs (host to chip packets) related to packet offload functions need to wait for FW responses in case FW state machine gets wrong and makes driver status no longer able to align FW one. In flow, driver may continuously send multiple H2Cs of packet offload series. If somehow FW doesn't deal with the former yet but the latter has gotten in, it might cause the problem mentioned above. So, we block these H2Cs by rtw89_wait_for_cond(). And then, when the corresponding C2Hs (chip to host packets) is received, we call rtw89_complete_cond(). Besides, RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP's C2H handler should be executed in interrupt context to make our wait/complete process work as expected. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/core.c | 1 + drivers/net/wireless/realtek/rtw89/core.h | 19 +++++---- drivers/net/wireless/realtek/rtw89/fw.c | 34 +++++++++------- drivers/net/wireless/realtek/rtw89/fw.h | 48 +++++++++++++++++------ drivers/net/wireless/realtek/rtw89/mac.c | 22 ++++++++++- 5 files changed, 90 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 254cb371054b3..56693f3d69d3f 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -3525,6 +3525,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) rtwdev->total_sta_assoc = 0; rtw89_init_wait(&rtwdev->mcc.wait); + rtw89_init_wait(&rtwdev->mac.fw_ofld_wait); INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work); INIT_WORK(&rtwdev->ips_work, rtw89_ips_work); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index d2c0d7972235a..db21a84e01c6c 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3248,14 +3248,6 @@ enum rtw89_host_rpr_mode { RTW89_RPR_MODE_STF }; -struct rtw89_mac_info { - struct rtw89_dle_info dle_info; - struct rtw89_hfc_param hfc_param; - enum rtw89_qta_mode qta_mode; - u8 rpwm_seq_num; - u8 cpwm_seq_num; -}; - #define RTW89_COMPLETION_BUF_SIZE 24 #define RTW89_WAIT_COND_IDLE UINT_MAX @@ -3278,6 +3270,17 @@ static inline void rtw89_init_wait(struct rtw89_wait_info *wait) atomic_set(&wait->cond, RTW89_WAIT_COND_IDLE); } +struct rtw89_mac_info { + struct rtw89_dle_info dle_info; + struct rtw89_hfc_param hfc_param; + enum rtw89_qta_mode qta_mode; + u8 rpwm_seq_num; + u8 cpwm_seq_num; + + /* see RTW89_FW_OFLD_WAIT_COND series for wait condition */ + struct rtw89_wait_info fw_ofld_wait; +}; + enum rtw89_fw_type { RTW89_FW_NORMAL = 1, RTW89_FW_WOWLAN = 3, diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 2390bcb3b46a8..84e04b5a5f004 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -14,6 +14,8 @@ static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb); +static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, + struct rtw89_wait_info *wait, unsigned int cond); static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len, bool header) @@ -2440,7 +2442,9 @@ int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev) #define H2C_LEN_PKT_OFLD 4 int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id) { + struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; struct sk_buff *skb; + unsigned int cond; u8 *cmd; int ret; @@ -2460,24 +2464,26 @@ int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id) H2C_FUNC_PACKET_OFLD, 1, 1, H2C_LEN_PKT_OFLD); - ret = rtw89_h2c_tx(rtwdev, skb, false); + cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(id, RTW89_PKT_OFLD_OP_DEL); + + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); if (ret) { - rtw89_err(rtwdev, "failed to send h2c\n"); - goto fail; + rtw89_debug(rtwdev, RTW89_DBG_FW, + "failed to del pkt ofld: id %d, ret %d\n", + id, ret); + return ret; } rtw89_core_release_bit_map(rtwdev->pkt_offload, id); return 0; -fail: - dev_kfree_skb_any(skb); - - return ret; } int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, struct sk_buff *skb_ofld) { + struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; struct sk_buff *skb; + unsigned int cond; u8 *cmd; u8 alloc_id; int ret; @@ -2508,18 +2514,18 @@ int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, H2C_FUNC_PACKET_OFLD, 1, 1, H2C_LEN_PKT_OFLD + skb_ofld->len); - ret = rtw89_h2c_tx(rtwdev, skb, false); + cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(alloc_id, RTW89_PKT_OFLD_OP_ADD); + + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); if (ret) { - rtw89_err(rtwdev, "failed to send h2c\n"); + rtw89_debug(rtwdev, RTW89_DBG_FW, + "failed to add pkt ofld: id %d, ret %d\n", + alloc_id, ret); rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); - goto fail; + return ret; } return 0; -fail: - dev_kfree_skb_any(skb); - - return ret; } #define H2C_LEN_SCAN_LIST_OFFLOAD 4 diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 74a691e352878..b7c8f6f0506de 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -138,8 +138,13 @@ enum rtw89_pkt_offload_op { RTW89_PKT_OFLD_OP_ADD, RTW89_PKT_OFLD_OP_DEL, RTW89_PKT_OFLD_OP_READ, + + NUM_OF_RTW89_PKT_OFFLOAD_OP, }; +#define RTW89_PKT_OFLD_WAIT_TAG(pkt_id, pkt_op) \ + ((pkt_id) * NUM_OF_RTW89_PKT_OFFLOAD_OP + (pkt_op)) + enum rtw89_scanofld_notify_reason { RTW89_SCAN_DWELL_NOTIFY, RTW89_SCAN_PRE_TX_NOTIFY, @@ -3340,6 +3345,16 @@ static_assert(sizeof(struct rtw89_mac_mcc_tsf_rpt) <= RTW89_COMPLETION_BUF_SIZE) #define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_HIGH(c2h) \ le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0)) +struct rtw89_c2h_pkt_ofld_rsp { + __le32 w0; + __le32 w1; + __le32 w2; +} __packed; + +#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_ID GENMASK(7, 0) +#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_OP GENMASK(10, 8) +#define RTW89_C2H_PKT_OFLD_RSP_W2_PTK_LEN GENMASK(31, 16) + struct rtw89_h2c_bcnfltr { __le32 w0; } __packed; @@ -3498,17 +3513,28 @@ struct rtw89_fw_h2c_rf_reg_info { /* CLASS 9 - FW offload */ #define H2C_CL_MAC_FW_OFLD 0x9 -#define H2C_FUNC_PACKET_OFLD 0x1 -#define H2C_FUNC_MAC_MACID_PAUSE 0x8 -#define H2C_FUNC_USR_EDCA 0xF -#define H2C_FUNC_TSF32_TOGL 0x10 -#define H2C_FUNC_OFLD_CFG 0x14 -#define H2C_FUNC_ADD_SCANOFLD_CH 0x16 -#define H2C_FUNC_SCANOFLD 0x17 -#define H2C_FUNC_PKT_DROP 0x1b -#define H2C_FUNC_CFG_BCNFLTR 0x1e -#define H2C_FUNC_OFLD_RSSI 0x1f -#define H2C_FUNC_OFLD_TP 0x20 +enum rtw89_fw_ofld_h2c_func { + H2C_FUNC_PACKET_OFLD = 0x1, + H2C_FUNC_MAC_MACID_PAUSE = 0x8, + H2C_FUNC_USR_EDCA = 0xF, + H2C_FUNC_TSF32_TOGL = 0x10, + H2C_FUNC_OFLD_CFG = 0x14, + H2C_FUNC_ADD_SCANOFLD_CH = 0x16, + H2C_FUNC_SCANOFLD = 0x17, + H2C_FUNC_PKT_DROP = 0x1b, + H2C_FUNC_CFG_BCNFLTR = 0x1e, + H2C_FUNC_OFLD_RSSI = 0x1f, + H2C_FUNC_OFLD_TP = 0x20, + + NUM_OF_RTW89_FW_OFLD_H2C_FUNC, +}; + +#define RTW89_FW_OFLD_WAIT_COND(tag, func) \ + ((tag) * NUM_OF_RTW89_FW_OFLD_H2C_FUNC + (func)) + +#define RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(pkt_id, pkt_op) \ + RTW89_FW_OFLD_WAIT_COND(RTW89_PKT_OFLD_WAIT_TAG(pkt_id, pkt_op), \ + H2C_FUNC_PACKET_OFLD) /* CLASS 10 - Security CAM */ #define H2C_CL_MAC_SEC_CAM 0xa diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 9b47d80b900b0..ee0d1e423297b 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -4356,9 +4356,22 @@ rtw89_mac_c2h_bcn_cnt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) } static void -rtw89_mac_c2h_pkt_ofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h, +rtw89_mac_c2h_pkt_ofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len) { + struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; + const struct rtw89_c2h_pkt_ofld_rsp *c2h = + (const struct rtw89_c2h_pkt_ofld_rsp *)skb_c2h->data; + u16 pkt_len = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_LEN); + u8 pkt_id = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_ID); + u8 pkt_op = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_OP); + struct rtw89_completion_data data = {}; + unsigned int cond; + + data.err = !pkt_len; + cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(pkt_id, pkt_op); + + rtw89_complete_cond(wait, cond, &data); } static void @@ -4566,6 +4579,13 @@ bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func) switch (class) { default: return false; + case RTW89_MAC_C2H_CLASS_OFLD: + switch (func) { + default: + return false; + case RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP: + return true; + } case RTW89_MAC_C2H_CLASS_MCC: return true; } From patchwork Wed Apr 19 11:46:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ping-Ke Shih X-Patchwork-Id: 675576 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 52416C6FD18 for ; Wed, 19 Apr 2023 11:46:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232955AbjDSLqP (ORCPT ); Wed, 19 Apr 2023 07:46:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41292 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232957AbjDSLqO (ORCPT ); Wed, 19 Apr 2023 07:46:14 -0400 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D930C14478 for ; Wed, 19 Apr 2023 04:46:08 -0700 (PDT) Authenticated-By: X-SpamFilter-By: ArmorX SpamTrap 5.77 with qID 33JBk1auD009741, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexh36506.realtek.com.tw[172.21.6.27]) by rtits2.realtek.com.tw (8.15.2/2.81/5.90) with ESMTPS id 33JBk1auD009741 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Wed, 19 Apr 2023 19:46:01 +0800 Received: from RTEXMBS02.realtek.com.tw (172.21.6.95) by RTEXH36506.realtek.com.tw (172.21.6.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.17; Wed, 19 Apr 2023 19:46:01 +0800 Received: from RTEXMBS04.realtek.com.tw (172.21.6.97) by RTEXMBS02.realtek.com.tw (172.21.6.95) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.7; Wed, 19 Apr 2023 19:46:01 +0800 Received: from RTEXMBS04.realtek.com.tw ([fe80::e138:e7f1:4709:ff4d]) by RTEXMBS04.realtek.com.tw ([fe80::e138:e7f1:4709:ff4d%5]) with mapi id 15.01.2375.007; Wed, 19 Apr 2023 19:46:01 +0800 From: Ping-Ke Shih To: "kvalo@kernel.org" CC: "linux-wireless@vger.kernel.org" , "Kevin Yang" Subject: [PATCH 4/5] wifi: rtw89: mac: handle C2H receive/done ACK in interrupt context Thread-Topic: [PATCH 4/5] wifi: rtw89: mac: handle C2H receive/done ACK in interrupt context Thread-Index: AQHZcrSDVkC0UVs+FEqeKc7x9ArKXQ== Date: Wed, 19 Apr 2023 11:46:01 +0000 Message-ID: Accept-Language: en-US, zh-TW Content-Language: zh-TW X-MS-Has-Attach: X-MS-TNEF-Correlator: user-agent: Evolution 3.36.1-2 x-originating-ip: [172.16.16.139] x-kse-serverinfo: RTEXMBS02.realtek.com.tw, 9 x-kse-antispam-interceptor-info: fallback x-kse-antivirus-interceptor-info: fallback Content-ID: MIME-Version: 1.0 X-KSE-AntiSpam-Interceptor-Info: fallback Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Zong-Zhe Yang We have some MAC H2Cs (host to chip packets), which have no clear individual C2Hs (chip to host packets) to indicate FW execution response, but they are going to require to wait for FW completion. So, we have to deal with this via common MAC C2H receive/done ACKs. This commit changes the context, where common MAC C2H receive/done ACK handlers are executed, to interrupt context. And, code comments are added to prevent future commits from using it incorrectly. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/mac.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index ee0d1e423297b..002c4dc2f5d50 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -4323,6 +4323,8 @@ rtw89_mac_c2h_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, static void rtw89_mac_c2h_rec_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) { + /* N.B. This will run in interrupt context. */ + rtw89_debug(rtwdev, RTW89_DBG_FW, "C2H rev ack recv, cat: %d, class: %d, func: %d, seq : %d\n", RTW89_GET_MAC_C2H_REV_ACK_CAT(c2h->data), @@ -4334,6 +4336,8 @@ rtw89_mac_c2h_rec_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) static void rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) { + /* N.B. This will run in interrupt context. */ + rtw89_debug(rtwdev, RTW89_DBG_FW, "C2H done ack recv, cat: %d, class: %d, func: %d, ret: %d, seq : %d\n", RTW89_GET_MAC_C2H_DONE_ACK_CAT(c2h->data), @@ -4579,6 +4583,14 @@ bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func) switch (class) { default: return false; + case RTW89_MAC_C2H_CLASS_INFO: + switch (func) { + default: + return false; + case RTW89_MAC_C2H_FUNC_REC_ACK: + case RTW89_MAC_C2H_FUNC_DONE_ACK: + return true; + } case RTW89_MAC_C2H_CLASS_OFLD: switch (func) { default: From patchwork Wed Apr 19 11:46:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ping-Ke Shih X-Patchwork-Id: 676129 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7F985C6FD18 for ; Wed, 19 Apr 2023 11:46:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232966AbjDSLqT (ORCPT ); Wed, 19 Apr 2023 07:46:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41378 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232963AbjDSLqS (ORCPT ); Wed, 19 Apr 2023 07:46:18 -0400 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F344014448 for ; Wed, 19 Apr 2023 04:46:10 -0700 (PDT) Authenticated-By: X-SpamFilter-By: ArmorX SpamTrap 5.77 with qID 33JBk4Ox9009766, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexh36505.realtek.com.tw[172.21.6.25]) by rtits2.realtek.com.tw (8.15.2/2.81/5.90) with ESMTPS id 33JBk4Ox9009766 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Wed, 19 Apr 2023 19:46:04 +0800 Received: from RTEXDAG02.realtek.com.tw (172.21.6.101) by RTEXH36505.realtek.com.tw (172.21.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.32; Wed, 19 Apr 2023 19:46:04 +0800 Received: from RTEXMBS04.realtek.com.tw (172.21.6.97) by RTEXDAG02.realtek.com.tw (172.21.6.101) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.7; Wed, 19 Apr 2023 19:46:04 +0800 Received: from RTEXMBS04.realtek.com.tw ([fe80::e138:e7f1:4709:ff4d]) by RTEXMBS04.realtek.com.tw ([fe80::e138:e7f1:4709:ff4d%5]) with mapi id 15.01.2375.007; Wed, 19 Apr 2023 19:46:04 +0800 From: Ping-Ke Shih To: "kvalo@kernel.org" CC: "linux-wireless@vger.kernel.org" , "Kevin Yang" Subject: [PATCH 5/5] wifi: rtw89: scan offload wait for FW done ACK Thread-Topic: [PATCH 5/5] wifi: rtw89: scan offload wait for FW done ACK Thread-Index: AQHZcrSFOUzH5yUYgka/E0Ds0PDTgg== Date: Wed, 19 Apr 2023 11:46:03 +0000 Message-ID: Accept-Language: en-US, zh-TW Content-Language: zh-TW X-MS-Has-Attach: X-MS-TNEF-Correlator: user-agent: Evolution 3.36.1-2 x-originating-ip: [172.16.16.139] x-kse-serverinfo: RTEXDAG02.realtek.com.tw, 9 x-kse-antispam-interceptor-info: fallback x-kse-antivirus-interceptor-info: fallback Content-ID: <176EEE7A24A20A4B91BEA2E412F8FA43@realtek.com> MIME-Version: 1.0 X-KSE-AntiSpam-Interceptor-Info: fallback X-KSE-ServerInfo: RTEXH36505.realtek.com.tw, 9 X-KSE-AntiSpam-Interceptor-Info: fallback X-KSE-Antivirus-Interceptor-Info: fallback X-KSE-AntiSpam-Interceptor-Info: fallback Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Zong-Zhe Yang The following are scan offload related H2C (host to chip) function types. * H2C_FUNC_ADD_SCANOFLD_CH * H2C_FUNC_SCANOFLD Before doing FW scan, we will continuously send multiple H2Cs with above types which are used to tell FW the scan configuration of this time. But, if FW doesn't handle one of these H2Cs well, the FW scan process might not run as expected and driver should notice it early. So, this commits makes scan offload related H2Cs wait for FW done ACK via rtw89_wait_for_cond() and rtw89_complete_cond(). And, we check the return code of these H2Cs from FW. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/fw.c | 28 ++++++++--------- drivers/net/wireless/realtek/rtw89/fw.h | 21 +++++++------ drivers/net/wireless/realtek/rtw89/mac.c | 39 ++++++++++++++++++++---- 3 files changed, 58 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 84e04b5a5f004..f85f9ce2a7c15 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -2532,9 +2532,11 @@ int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int len, struct list_head *chan_list) { + struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; struct rtw89_mac_chinfo *ch_info; struct sk_buff *skb; int skb_len = H2C_LEN_SCAN_LIST_OFFLOAD + len * RTW89_MAC_CHINFO_SIZE; + unsigned int cond; u8 *cmd; int ret; @@ -2581,27 +2583,27 @@ int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int len, H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, H2C_FUNC_ADD_SCANOFLD_CH, 1, 1, skb_len); - ret = rtw89_h2c_tx(rtwdev, skb, false); + cond = RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_ADD_SCANOFLD_CH); + + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); if (ret) { - rtw89_err(rtwdev, "failed to send h2c\n"); - goto fail; + rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to add scan ofld ch\n"); + return ret; } return 0; -fail: - dev_kfree_skb_any(skb); - - return ret; } int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev, struct rtw89_scan_option *option, struct rtw89_vif *rtwvif) { + struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; struct rtw89_chan *op = &rtwdev->scan_info.op_chan; struct rtw89_h2c_scanofld *h2c; u32 len = sizeof(*h2c); struct sk_buff *skb; + unsigned int cond; int ret; skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); @@ -2640,17 +2642,15 @@ int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev, H2C_FUNC_SCANOFLD, 1, 1, len); - ret = rtw89_h2c_tx(rtwdev, skb, false); + cond = RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_SCANOFLD); + + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond); if (ret) { - rtw89_err(rtwdev, "failed to send h2c\n"); - goto fail; + rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to scan ofld\n"); + return ret; } return 0; -fail: - dev_kfree_skb_any(skb); - - return ret; } int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index b7c8f6f0506de..22a187e41965f 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -3221,16 +3221,17 @@ static inline struct rtw89_fw_c2h_attr *RTW89_SKB_C2H_CB(struct sk_buff *skb) #define RTW89_GET_C2H_LOG_SRT_PRT(c2h) (char *)((__le32 *)(c2h) + 2) #define RTW89_GET_C2H_LOG_LEN(len) ((len) - RTW89_C2H_HEADER_LEN) -#define RTW89_GET_MAC_C2H_DONE_ACK_CAT(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(1, 0)) -#define RTW89_GET_MAC_C2H_DONE_ACK_CLASS(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(7, 2)) -#define RTW89_GET_MAC_C2H_DONE_ACK_FUNC(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) -#define RTW89_GET_MAC_C2H_DONE_ACK_H2C_RETURN(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(23, 16)) -#define RTW89_GET_MAC_C2H_DONE_ACK_H2C_SEQ(c2h) \ - le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(31, 24)) +struct rtw89_c2h_done_ack { + __le32 w0; + __le32 w1; + __le32 w2; +} __packed; + +#define RTW89_C2H_DONE_ACK_W2_CAT GENMASK(1, 0) +#define RTW89_C2H_DONE_ACK_W2_CLASS GENMASK(7, 2) +#define RTW89_C2H_DONE_ACK_W2_FUNC GENMASK(15, 8) +#define RTW89_C2H_DONE_ACK_W2_H2C_RETURN GENMASK(23, 16) +#define RTW89_C2H_DONE_ACK_W2_H2C_SEQ GENMASK(31, 24) #define RTW89_GET_MAC_C2H_REV_ACK_CAT(c2h) \ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(1, 0)) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 002c4dc2f5d50..72f3a2e15063d 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -4334,17 +4334,44 @@ rtw89_mac_c2h_rec_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) } static void -rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) +rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len) { /* N.B. This will run in interrupt context. */ + struct rtw89_wait_info *fw_ofld_wait = &rtwdev->mac.fw_ofld_wait; + const struct rtw89_c2h_done_ack *c2h = + (const struct rtw89_c2h_done_ack *)skb_c2h->data; + u8 h2c_cat = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_CAT); + u8 h2c_class = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_CLASS); + u8 h2c_func = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_FUNC); + u8 h2c_return = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_H2C_RETURN); + u8 h2c_seq = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_H2C_SEQ); + struct rtw89_completion_data data = {}; + unsigned int cond; rtw89_debug(rtwdev, RTW89_DBG_FW, "C2H done ack recv, cat: %d, class: %d, func: %d, ret: %d, seq : %d\n", - RTW89_GET_MAC_C2H_DONE_ACK_CAT(c2h->data), - RTW89_GET_MAC_C2H_DONE_ACK_CLASS(c2h->data), - RTW89_GET_MAC_C2H_DONE_ACK_FUNC(c2h->data), - RTW89_GET_MAC_C2H_DONE_ACK_H2C_RETURN(c2h->data), - RTW89_GET_MAC_C2H_DONE_ACK_H2C_SEQ(c2h->data)); + h2c_cat, h2c_class, h2c_func, h2c_return, h2c_seq); + + if (h2c_cat != H2C_CAT_MAC) + return; + + switch (h2c_class) { + default: + return; + case H2C_CL_MAC_FW_OFLD: + switch (h2c_func) { + default: + return; + case H2C_FUNC_ADD_SCANOFLD_CH: + case H2C_FUNC_SCANOFLD: + cond = RTW89_FW_OFLD_WAIT_COND(0, h2c_func); + break; + } + + data.err = !!h2c_return; + rtw89_complete_cond(fw_ofld_wait, cond, &data); + return; + } } static void