From nobody Sun Dec 14 11:18:47 2025 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 45F84358D3A; Wed, 29 Oct 2025 19:03:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=83.149.199.84 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764582; cv=none; b=R+t1Z0qQpxYqCQDrIFQb/LUbXjnOo32hyLm7YqpTekimVwjAgSrYNkCN1S20p0fZ7MZXkda9CoTh92HBBDcd9iHpC3Nyi3RnithDUHDrStRyILuNHNzdiaBwKNs6An5+jgDmfTNjgfZKVL2EJiuYlxndBiKtsJJYPgrZ30IWHBg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764582; c=relaxed/simple; bh=++JqY2xRgABgVWB1JTlQICX2Upy1cT/z7ThhUN/t6yQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TrL2eQ8Hm8VFazAR9xyfiWIuY2f9q+R+RVT6anbHjYG91259UCSfpQ93S7jKrRRXmUwjAco3302DKPFFOR0pRMVEeZT298N9g7eV5bfNAHFPdUQZk4nU3O4Ewbn8b9+ozb4rSy1USFX0rV+VnruFc49ptOYgM2MpmtbXdYEhDhw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru; spf=pass smtp.mailfrom=ispras.ru; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b=eVTWyWKi; arc=none smtp.client-ip=83.149.199.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ispras.ru Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b="eVTWyWKi" Received: from debian.intra.ispras.ru (unknown [10.10.165.6]) by mail.ispras.ru (Postfix) with ESMTPSA id A54224076B5F; Wed, 29 Oct 2025 19:02:57 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru A54224076B5F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1761764577; bh=Dy/hIZdPh5Pv16L0oxcsQ5VJFKqKn0FbiTRBt6QMWVI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eVTWyWKilIV/ckhZTteHFJqhMzlU1zdn1wUFhYOIiok5Yryo64ZtiSbVRPb46f3oz Y37I6VgSUmEh9IYwnUeUME1WKQEk7XHf2tu4LM5bKmRbCxqxpjFBuCps3IDNv0ViNz 2ppwpgbUUQ24UwzII7RsrKnf35UHWYZhAGsIUpjY= From: Fedor Pchelkin To: Ping-Ke Shih , Bitterblue Smith Cc: Fedor Pchelkin , Zong-Zhe Yang , Po-Hao Huang , linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org Subject: [PATCH rtw-next v4 01/10] wifi: rtw89: usb: use common error path for skbs in rtw89_usb_rx_handler() Date: Wed, 29 Oct 2025 22:02:29 +0300 Message-ID: <20251029190241.1023856-2-pchelkin@ispras.ru> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251029190241.1023856-1-pchelkin@ispras.ru> References: <20251029190241.1023856-1-pchelkin@ispras.ru> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow adding rx_skb to rx_free_queue for later reuse on the common error handling path, otherwise free it. Found by Linux Verification Center (linuxtesting.org). Fixes: 2135c28be6a8 ("wifi: rtw89: Add usb.{c,h}") Signed-off-by: Fedor Pchelkin Acked-by: Ping-Ke Shih --- v2: - do goto 'free_or_reuse' (Ping-Ke) drivers/net/wireless/realtek/rtw89/usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireles= s/realtek/rtw89/usb.c index afbd1fb79021..15fba22b4f5d 100644 --- a/drivers/net/wireless/realtek/rtw89/usb.c +++ b/drivers/net/wireless/realtek/rtw89/usb.c @@ -410,8 +410,7 @@ static void rtw89_usb_rx_handler(struct work_struct *wo= rk) =20 if (skb_queue_len(&rtwusb->rx_queue) >=3D RTW89_USB_MAX_RXQ_LEN) { rtw89_warn(rtwdev, "rx_queue overflow\n"); - dev_kfree_skb_any(rx_skb); - continue; + goto free_or_reuse; } =20 memset(&desc_info, 0, sizeof(desc_info)); @@ -422,7 +421,7 @@ static void rtw89_usb_rx_handler(struct work_struct *wo= rk) rtw89_debug(rtwdev, RTW89_DBG_HCI, "failed to allocate RX skb of size %u\n", desc_info.pkt_size); - continue; + goto free_or_reuse; } =20 pkt_offset =3D desc_info.offset + desc_info.rxd_len; @@ -432,6 +431,7 @@ static void rtw89_usb_rx_handler(struct work_struct *wo= rk) =20 rtw89_core_rx(rtwdev, &desc_info, skb); =20 +free_or_reuse: if (skb_queue_len(&rtwusb->rx_free_queue) >=3D RTW89_USB_RX_SKB_NUM) dev_kfree_skb_any(rx_skb); else --=20 2.51.0 From nobody Sun Dec 14 11:18:47 2025 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 460023590AB; Wed, 29 Oct 2025 19:03:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=83.149.199.84 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764584; cv=none; b=O5QvTqRgConAoHS7xG+RsyMyz3W2Y6RdSbALOBa9MWtiLD7BIJjGuL/MRQzK1S9XJwNOC26TT17kX0nlg4VmhtLo5vHGlz9N2JZID5Z5KoX9MV53ZrFt0PLcgtPsSLU9PeQ74u4lSIHC58IfDLOhngqa3/amAAZyW0PstlxXCjA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764584; c=relaxed/simple; bh=1FtZW4U1ojwEyztWuRwA0Bae7MsM11HBqcUXmyFU5Ps=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Pnhev9jWP9oE4I8Yu1f2XdtHez79tdHoqMJF9Cso3JWCrTcsQf0kELEWJn7ikMCx1FzguBydU2DW+vfHQsEwj03oSRmKCgPFSptXjxQXdaZFLD93lFsVcSXS8UHnxWy97P2mK8P27GBcpPTmdEtQTn0lnkz0+jvH8/eG5XsLPSY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru; spf=pass smtp.mailfrom=ispras.ru; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b=O9+u1rCJ; arc=none smtp.client-ip=83.149.199.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ispras.ru Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b="O9+u1rCJ" Received: from debian.intra.ispras.ru (unknown [10.10.165.6]) by mail.ispras.ru (Postfix) with ESMTPSA id 58D0D40777A0; Wed, 29 Oct 2025 19:02:58 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 58D0D40777A0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1761764578; bh=OfAgYaOUI1AFIjwkIwYHMJ5+77hecm5s5YXZ1vh9cCE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O9+u1rCJS1rgqa1mCKytKYlzWq+fvWNitjDFaXHJYHus+tz62Vv50OKFZppIZRHUe WYaUnSiilORgv+ljNbDubL/L0HTaLuGAufcQpYDLaAjb9jDN0UvQEtIWlegloX1TIY Pd6NDkemgArPILXoMbMCy1OEFPNKbcsEG9kHnMX0= From: Fedor Pchelkin To: Ping-Ke Shih , Bitterblue Smith Cc: Fedor Pchelkin , Zong-Zhe Yang , Po-Hao Huang , linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org Subject: [PATCH rtw-next v4 02/10] wifi: rtw89: usb: fix leak in rtw89_usb_write_port() Date: Wed, 29 Oct 2025 22:02:30 +0300 Message-ID: <20251029190241.1023856-3-pchelkin@ispras.ru> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251029190241.1023856-1-pchelkin@ispras.ru> References: <20251029190241.1023856-1-pchelkin@ispras.ru> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When there is an attempt to write data and RTW89_FLAG_UNPLUGGED is set, this means device is disconnected and no urb is submitted. Return appropriate error code to the caller to properly free the allocated resources. Found by Linux Verification Center (linuxtesting.org). Fixes: 2135c28be6a8 ("wifi: rtw89: Add usb.{c,h}") Signed-off-by: Fedor Pchelkin Acked-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/usb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireles= s/realtek/rtw89/usb.c index 15fba22b4f5d..1d9760e5eae7 100644 --- a/drivers/net/wireless/realtek/rtw89/usb.c +++ b/drivers/net/wireless/realtek/rtw89/usb.c @@ -256,7 +256,7 @@ static int rtw89_usb_write_port(struct rtw89_dev *rtwde= v, u8 ch_dma, int ret; =20 if (test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) - return 0; + return -ENODEV; =20 urb =3D usb_alloc_urb(0, GFP_ATOMIC); if (!urb) @@ -305,8 +305,9 @@ static void rtw89_usb_ops_tx_kick_off(struct rtw89_dev = *rtwdev, u8 txch) ret =3D rtw89_usb_write_port(rtwdev, txch, skb->data, skb->len, txcb); if (ret) { - rtw89_err(rtwdev, "write port txch %d failed: %d\n", - txch, ret); + if (ret !=3D -ENODEV) + rtw89_err(rtwdev, "write port txch %d failed: %d\n", + txch, ret); =20 skb_dequeue(&txcb->tx_ack_queue); kfree(txcb); --=20 2.51.0 From nobody Sun Dec 14 11:18:47 2025 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EB69C2F12CC; Wed, 29 Oct 2025 19:03:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=83.149.199.84 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764582; cv=none; b=qt7gbqLD+fTses/HKrU+En4mi/UR2BHO3T/qTH0JbgVwMu21hk7J+IIrrN/k4WoKnhe2J+RavqkDvUZ/X3NOVFUD9xtMy2bp2qsj0tTmgOKtpCby3OMqwan7KM0rnVBCFo3XjsiAdOVvtc8zl9P83iA8r2M6Yp4grM6t54NeFFc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764582; c=relaxed/simple; bh=m1ThU6s/OuTsfPXh0aCqXOqnYksqYIpXdR+yR8bMpS4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kjj6uD9Ksd/jMkiKiGGtflA7yySggHftxFDmCfkY4bYXwxjN7JxwpizU1cjUDkKpMhDjEFHP0pneWUJWiMTCXvxmV+z4RJkByrYTRFSdtiZf1GNK/7Q4mAwYT9SGOCRbU+hkC0YgTInKkOlb0xRwD8fHLsr4RdRyHRAosZ8BQTs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru; spf=pass smtp.mailfrom=ispras.ru; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b=si0mvWm0; arc=none smtp.client-ip=83.149.199.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ispras.ru Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b="si0mvWm0" Received: from debian.intra.ispras.ru (unknown [10.10.165.6]) by mail.ispras.ru (Postfix) with ESMTPSA id E970040777A3; Wed, 29 Oct 2025 19:02:58 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru E970040777A3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1761764579; bh=8jiWoBq2G+KYWCFKuOBzxu0i0MoFGVrc86YGBUTtZb0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=si0mvWm02txeDnjF2v3nO5P9NTgZ4CjDskBXw5QAzVzq/EIfYV5ucJhoA6sOCtvMP tfVVmf+Y+WSOx7g7NzkX3QeKd2ywFeelE0EUmIqhpbNXTIGoyTRLKvD5oJOsUxQimi zfcPmJHE/ADFYT6RRJW5QRzqP8FWJxnVfJOXz4AM= From: Fedor Pchelkin To: Ping-Ke Shih , Bitterblue Smith Cc: Fedor Pchelkin , Zong-Zhe Yang , Po-Hao Huang , linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org Subject: [PATCH rtw-next v4 03/10] wifi: rtw89: usb: use ieee80211_free_txskb() where appropriate Date: Wed, 29 Oct 2025 22:02:31 +0300 Message-ID: <20251029190241.1023856-4-pchelkin@ispras.ru> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251029190241.1023856-1-pchelkin@ispras.ru> References: <20251029190241.1023856-1-pchelkin@ispras.ru> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" rtw89_usb_ops_tx_kick_off() may need to release skb if a failure occurs. It operates mainly on skbs coming from the core wireless stack and the ones containing firmware commands. Use ieee80211_free_txskb() for the former case. Suggested-by: Ping-Ke Shih Signed-off-by: Fedor Pchelkin Acked-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/usb.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireles= s/realtek/rtw89/usb.c index 1d9760e5eae7..93dc4e91c1d4 100644 --- a/drivers/net/wireless/realtek/rtw89/usb.c +++ b/drivers/net/wireless/realtek/rtw89/usb.c @@ -278,6 +278,15 @@ static int rtw89_usb_write_port(struct rtw89_dev *rtwd= ev, u8 ch_dma, return ret; } =20 +static void rtw89_usb_tx_free_skb(struct rtw89_dev *rtwdev, u8 txch, + struct sk_buff *skb) +{ + if (txch =3D=3D RTW89_TXCH_CH12) + dev_kfree_skb_any(skb); + else + ieee80211_free_txskb(rtwdev->hw, skb); +} + static void rtw89_usb_ops_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) { struct rtw89_usb *rtwusb =3D rtw89_usb_priv(rtwdev); @@ -292,7 +301,7 @@ static void rtw89_usb_ops_tx_kick_off(struct rtw89_dev = *rtwdev, u8 txch) =20 txcb =3D kmalloc(sizeof(*txcb), GFP_ATOMIC); if (!txcb) { - dev_kfree_skb_any(skb); + rtw89_usb_tx_free_skb(rtwdev, txch, skb); continue; } =20 @@ -311,7 +320,7 @@ static void rtw89_usb_ops_tx_kick_off(struct rtw89_dev = *rtwdev, u8 txch) =20 skb_dequeue(&txcb->tx_ack_queue); kfree(txcb); - dev_kfree_skb_any(skb); + rtw89_usb_tx_free_skb(rtwdev, txch, skb); } } } --=20 2.51.0 From nobody Sun Dec 14 11:18:47 2025 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8A5002F692B; Wed, 29 Oct 2025 19:03:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=83.149.199.84 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764583; cv=none; b=DesBlD9OsW3g8QZ65RZLFKkhVPXkPu2NVilNXOFgkGKXxi298RxgqjuF18c9uSDAJiZNvk5aJrJBP3DrqPnpFmIxK03hqWcYeN8aVl8rUg4tOOILdwd0QyfHt4P2cp4DvdukoPE1kuM0PtKCERa4uADTCqN6x45r09Z0Ez/9OjA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764583; c=relaxed/simple; bh=+MwIgeCdFC6C3CVyWwqR9oHsy7ZPQ9JePOZ5xEvzlV0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PkCJ8jKkayd7U4/vloBJ3OHcboRoL9nO8JxFNc07oj0DWXbG190JBsURHSWyqZASqIgdgG8hub1Lin4Pn+hzRq5d/Wf7C6NuHsxP6hIUCgEYcNjYsswrWuZO/qKIVSi3NfUjZTpMHOsZLF5v0jvFZcYZ0WNesSLO4NuZSVTACnU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru; spf=pass smtp.mailfrom=ispras.ru; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b=fqP3z2VN; arc=none smtp.client-ip=83.149.199.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ispras.ru Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b="fqP3z2VN" Received: from debian.intra.ispras.ru (unknown [10.10.165.6]) by mail.ispras.ru (Postfix) with ESMTPSA id 7DEFA40777A6; Wed, 29 Oct 2025 19:02:59 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 7DEFA40777A6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1761764579; bh=xDw8yrRISWroUYdZcgNui+Pb/xDmwNBDMu9OXyGUGpE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fqP3z2VNCRCH8h7pIPo7FqPzC6Gqhe5wu8JrmKPzJ0u52MckYG13OEiHWOMYGAs0Q H56LPVpXK+98WBuemKvKpOdybh9b+3J6WygxmCnJL+q+KHWs8uuCH5jgWHbvO/eZ4T JdVx5cc1ZYQjowxQ8Ucn78gLENEFwYDb9fHNsQjY= From: Fedor Pchelkin To: Ping-Ke Shih , Bitterblue Smith Cc: Fedor Pchelkin , Zong-Zhe Yang , Po-Hao Huang , linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org Subject: [PATCH rtw-next v4 04/10] wifi: rtw89: refine rtw89_core_tx_wait_complete() Date: Wed, 29 Oct 2025 22:02:32 +0300 Message-ID: <20251029190241.1023856-5-pchelkin@ispras.ru> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251029190241.1023856-1-pchelkin@ispras.ru> References: <20251029190241.1023856-1-pchelkin@ispras.ru> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Pass TX status value directly into rtw89_core_tx_wait_complete(). This will make it a bit in sync with further patches and will give flexibility in future work. Also use scope based RCU locking which simplifies the code of the function. Found by Linux Verification Center (linuxtesting.org). Signed-off-by: Fedor Pchelkin Acked-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/core.h | 20 ++++++++++---------- drivers/net/wireless/realtek/rtw89/pci.c | 2 +- drivers/net/wireless/realtek/rtw89/pci.h | 4 ---- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wirele= ss/realtek/rtw89/core.h index f8b443894db9..a490b4124cd6 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3508,6 +3508,11 @@ struct rtw89_phy_rate_pattern { bool enable; }; =20 +#define RTW89_TX_DONE 0x0 +#define RTW89_TX_RETRY_LIMIT 0x1 +#define RTW89_TX_LIFE_TIME 0x2 +#define RTW89_TX_MACID_DROP 0x3 + #define RTW89_TX_WAIT_WORK_TIMEOUT msecs_to_jiffies(500) struct rtw89_tx_wait_info { struct rcu_head rcu_head; @@ -7386,25 +7391,20 @@ static inline struct sk_buff *rtw89_alloc_skb_for_r= x(struct rtw89_dev *rtwdev, =20 static inline bool rtw89_core_tx_wait_complete(struct rtw89_dev *rtwdev, struct rtw89_tx_skb_data *skb_data, - bool tx_done) + u8 tx_status) { struct rtw89_tx_wait_info *wait; - bool ret =3D false; =20 - rcu_read_lock(); + guard(rcu)(); =20 wait =3D rcu_dereference(skb_data->wait); if (!wait) - goto out; + return false; =20 - ret =3D true; - wait->tx_done =3D tx_done; + wait->tx_done =3D tx_status =3D=3D RTW89_TX_DONE; /* Don't access skb anymore after completion */ complete_all(&wait->completion); - -out: - rcu_read_unlock(); - return ret; + return true; } =20 static inline bool rtw89_is_mlo_1_1(struct rtw89_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireles= s/realtek/rtw89/pci.c index 0ee5f8579447..b1985193a18f 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -464,7 +464,7 @@ static void rtw89_pci_tx_status(struct rtw89_dev *rtwde= v, struct rtw89_tx_skb_data *skb_data =3D RTW89_TX_SKB_CB(skb); struct ieee80211_tx_info *info; =20 - if (rtw89_core_tx_wait_complete(rtwdev, skb_data, tx_status =3D=3D RTW89_= TX_DONE)) + if (rtw89_core_tx_wait_complete(rtwdev, skb_data, tx_status)) return; =20 info =3D IEEE80211_SKB_CB(skb); diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireles= s/realtek/rtw89/pci.h index cb05c83dfd56..16dfb0e79d77 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -1487,10 +1487,6 @@ struct rtw89_pci_tx_addr_info_32_v1 { #define RTW89_PCI_RPP_POLLUTED BIT(31) #define RTW89_PCI_RPP_SEQ GENMASK(30, 16) #define RTW89_PCI_RPP_TX_STATUS GENMASK(15, 13) -#define RTW89_TX_DONE 0x0 -#define RTW89_TX_RETRY_LIMIT 0x1 -#define RTW89_TX_LIFE_TIME 0x2 -#define RTW89_TX_MACID_DROP 0x3 #define RTW89_PCI_RPP_QSEL GENMASK(12, 8) #define RTW89_PCI_RPP_MACID GENMASK(7, 0) =20 --=20 2.51.0 From nobody Sun Dec 14 11:18:47 2025 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6D48A359FBA; Wed, 29 Oct 2025 19:03:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=83.149.199.84 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764588; cv=none; b=LrKB3XrO6E75KGFXbZ3lvyMNQYxgrdTkIP+oSXfbBblSWY2vZW7BJ7HsXwrfZvDeK+Dj+o8FMHJBZPWRbkLbCZWHswn0qH1rKhNKUNZHCQm3dvl5l2c2xMfszUv/KWWD/5+Ulbvw0jYkz0qm9KufYc8BhFBQ859uiqBskhD5ItA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764588; c=relaxed/simple; bh=XhUCMxZaXRWdbkAShVjgcecbTd9jOsMgdukonWupDqg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jHKftEa+eGF3v8K/cSo5C9qkPV/YFKgDjEzEKO75Wb+21LMZJqvb0vkV7K9LwCXyKtbOTJ307avtAOYrj5cG8KlnoMms43jVPNXP9ryps4z7BUWC/lmpV7l6uraAH2zoBw8X2J6Bm5hF0xj1RPjft9FH2eN7+w348dDDwAEzg0g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru; spf=pass smtp.mailfrom=ispras.ru; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b=QJG7hl9i; arc=none smtp.client-ip=83.149.199.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ispras.ru Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b="QJG7hl9i" Received: from debian.intra.ispras.ru (unknown [10.10.165.6]) by mail.ispras.ru (Postfix) with ESMTPSA id 0826840777AD; Wed, 29 Oct 2025 19:03:00 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 0826840777AD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1761764580; bh=W6FgRyjUPY3ZGpF7NxIzSbnzZ/WxgCnDPCvsQkCbd8g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QJG7hl9i8AoMRZQ8UzONoH3TpjEr0qhFNzBQsGt5jHkd60ldb7vJuT0u/le71Ouj5 myWW21Xi6V0fXmXTw+usonSpQKKqLX4pxMgo5ao4/x4V8J5bWi6HERgXtxavdLIyY7 5PpWMOpu18oSMLvvhg4ypCm9DdhDGEp3hQRBSKtI= From: Fedor Pchelkin To: Ping-Ke Shih , Bitterblue Smith Cc: Fedor Pchelkin , Zong-Zhe Yang , Po-Hao Huang , linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org Subject: [PATCH rtw-next v4 05/10] wifi: rtw89: implement C2H TX report handler Date: Wed, 29 Oct 2025 22:02:33 +0300 Message-ID: <20251029190241.1023856-6-pchelkin@ispras.ru> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251029190241.1023856-1-pchelkin@ispras.ru> References: <20251029190241.1023856-1-pchelkin@ispras.ru> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" rtw89 has several ways of handling TX status report events. The first one is based on RPP feature which is used by PCIe HCI. The other one depends on firmware sending a corresponding C2H message, quite similar to what rtw88 has. Toggle a bit in the TX descriptor to indicate to the firmware that TX report for the frame is expected. This will allow handling TX wait skbs and the ones flagged with IEEE80211_TX_CTL_REQ_TX_STATUS correctly. Do the bulk of the patch according to the vendor driver for RTL8851BU. However, there are slight differences in C2H message format between different types of chips. RTL885xB ones follow format V0. RTL8852C has format V1, and RTL8922AU has format V2. Found by Linux Verification Center (linuxtesting.org). Suggested-by: Bitterblue Smith Signed-off-by: Fedor Pchelkin Acked-by: Ping-Ke Shih --- v4: - use __packed for C2H message structs (Ping-Ke) - shorten extremely long lines (Ping-Ke) v3: - consider V1 and V2 C2H message formats inside rtw89_mac_c2h_tx_rpt() = (Bitterblue) - use X'mas tree order (Ping-Ke) - update changelog considering further patches v2: - fix bit masks and consider TX transmission retry limit for TX reporting (Bitterblue) - use newer style for C2H message type definitions and drop unimplemented funcs from 'enum rtw89_mac_c2h_misc_func' (Ping-Ke) - modify rtw89_core_fill_txdesc_v1() and rtw89_core_fill_txdesc_v2() accordingly (Ping-Ke) drivers/net/wireless/realtek/rtw89/core.c | 28 +++++++++++--- drivers/net/wireless/realtek/rtw89/core.h | 4 ++ drivers/net/wireless/realtek/rtw89/fw.h | 41 ++++++++++++++++++++ drivers/net/wireless/realtek/rtw89/mac.c | 46 +++++++++++++++++++++++ drivers/net/wireless/realtek/rtw89/mac.h | 7 ++++ drivers/net/wireless/realtek/rtw89/txrx.h | 6 ++- 6 files changed, 126 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wirele= ss/realtek/rtw89/core.c index 1b5a40e9821c..8d73d9d9c15b 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -1396,7 +1396,10 @@ static __le32 rtw89_build_txwd_info1(struct rtw89_tx= _desc_info *desc_info) u32 dword =3D FIELD_PREP(RTW89_TXWD_INFO1_MAX_AGGNUM, desc_info->ampdu_nu= m) | FIELD_PREP(RTW89_TXWD_INFO1_A_CTRL_BSR, desc_info->a_ctrl_bsr) | FIELD_PREP(RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE, - desc_info->data_retry_lowest_rate); + desc_info->data_retry_lowest_rate) | + FIELD_PREP(RTW89_TXWD_INFO1_DATA_TXCNT_LMT_SEL, + desc_info->tx_cnt_lmt_en) | + FIELD_PREP(RTW89_TXWD_INFO1_DATA_TXCNT_LMT, desc_info->tx_cnt_lmt); =20 return cpu_to_le32(dword); } @@ -1420,11 +1423,19 @@ static __le32 rtw89_build_txwd_info2_v1(struct rtw8= 9_tx_desc_info *desc_info) return cpu_to_le32(dword); } =20 +static __le32 rtw89_build_txwd_info3(struct rtw89_tx_desc_info *desc_info) +{ + u32 dword =3D FIELD_PREP(RTW89_TXWD_INFO3_SPE_RPT, desc_info->report); + + return cpu_to_le32(dword); +} + static __le32 rtw89_build_txwd_info4(struct rtw89_tx_desc_info *desc_info) { bool rts_en =3D !desc_info->is_bmc; u32 dword =3D FIELD_PREP(RTW89_TXWD_INFO4_RTS_EN, rts_en) | - FIELD_PREP(RTW89_TXWD_INFO4_HW_RTS_EN, 1); + FIELD_PREP(RTW89_TXWD_INFO4_HW_RTS_EN, 1) | + FIELD_PREP(RTW89_TXWD_INFO4_SW_DEFINE, desc_info->sn); =20 return cpu_to_le32(dword); } @@ -1447,6 +1458,7 @@ void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev, txwd_info->dword0 =3D rtw89_build_txwd_info0(desc_info); txwd_info->dword1 =3D rtw89_build_txwd_info1(desc_info); txwd_info->dword2 =3D rtw89_build_txwd_info2(desc_info); + txwd_info->dword3 =3D rtw89_build_txwd_info3(desc_info); txwd_info->dword4 =3D rtw89_build_txwd_info4(desc_info); =20 } @@ -1476,6 +1488,7 @@ void rtw89_core_fill_txdesc_v1(struct rtw89_dev *rtwd= ev, txwd_info->dword0 =3D rtw89_build_txwd_info0_v1(desc_info); txwd_info->dword1 =3D rtw89_build_txwd_info1(desc_info); txwd_info->dword2 =3D rtw89_build_txwd_info2_v1(desc_info); + txwd_info->dword3 =3D rtw89_build_txwd_info3(desc_info); txwd_info->dword4 =3D rtw89_build_txwd_info4(desc_info); } EXPORT_SYMBOL(rtw89_core_fill_txdesc_v1); @@ -1561,7 +1574,10 @@ static __le32 rtw89_build_txwd_info0_v2(struct rtw89= _tx_desc_info *desc_info) u32 dword =3D FIELD_PREP(BE_TXD_INFO0_DATA_STBC, desc_info->stbc) | FIELD_PREP(BE_TXD_INFO0_DATA_LDPC, desc_info->ldpc) | FIELD_PREP(BE_TXD_INFO0_DISDATAFB, desc_info->dis_data_fb) | - FIELD_PREP(BE_TXD_INFO0_MULTIPORT_ID, desc_info->port); + FIELD_PREP(BE_TXD_INFO0_MULTIPORT_ID, desc_info->port) | + FIELD_PREP(BE_TXD_INFO0_DATA_TXCNT_LMT_SEL, + desc_info->tx_cnt_lmt_en) | + FIELD_PREP(BE_TXD_INFO0_DATA_TXCNT_LMT, desc_info->tx_cnt_lmt); =20 return cpu_to_le32(dword); } @@ -1571,7 +1587,8 @@ static __le32 rtw89_build_txwd_info1_v2(struct rtw89_= tx_desc_info *desc_info) u32 dword =3D FIELD_PREP(BE_TXD_INFO1_MAX_AGG_NUM, desc_info->ampdu_num) | FIELD_PREP(BE_TXD_INFO1_A_CTRL_BSR, desc_info->a_ctrl_bsr) | FIELD_PREP(BE_TXD_INFO1_DATA_RTY_LOWEST_RATE, - desc_info->data_retry_lowest_rate); + desc_info->data_retry_lowest_rate) | + FIELD_PREP(BE_TXD_INFO1_SW_DEFINE, desc_info->sn); =20 return cpu_to_le32(dword); } @@ -1580,7 +1597,8 @@ static __le32 rtw89_build_txwd_info2_v2(struct rtw89_= tx_desc_info *desc_info) { u32 dword =3D FIELD_PREP(BE_TXD_INFO2_AMPDU_DENSITY, desc_info->ampdu_den= sity) | FIELD_PREP(BE_TXD_INFO2_FORCE_KEY_EN, desc_info->sec_en) | - FIELD_PREP(BE_TXD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx); + FIELD_PREP(BE_TXD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx) | + FIELD_PREP(BE_TXD_INFO2_SPE_RPT_V1, desc_info->report); =20 return cpu_to_le32(dword); } diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wirele= ss/realtek/rtw89/core.h index a490b4124cd6..9372e30a0039 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -1168,6 +1168,10 @@ struct rtw89_tx_desc_info { u8 ampdu_density; u8 ampdu_num; bool sec_en; + bool report; + bool tx_cnt_lmt_en; + u8 sn: 4; + u8 tx_cnt_lmt: 6; u8 addr_info_nr; u8 sec_keyid; u8 sec_type; diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless= /realtek/rtw89/fw.h index ddebf7972068..310580206368 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -3747,6 +3747,47 @@ struct rtw89_c2h_scanofld { #define RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_FUNC(c2h) \ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) =20 +struct rtw89_c2h_mac_tx_rpt { + struct rtw89_c2h_hdr hdr; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; +} __packed; + +#define RTW89_C2H_MAC_TX_RPT_W2_TX_STATE GENMASK(7, 6) +#define RTW89_C2H_MAC_TX_RPT_W2_SW_DEFINE GENMASK(11, 8) +#define RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT GENMASK(13, 8) +#define RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT_V1 GENMASK(15, 10) + +struct rtw89_c2h_mac_tx_rpt_v2 { + struct rtw89_c2h_hdr hdr; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; + __le32 w7; + __le32 w8; + __le32 w9; + __le32 w10; + __le32 w11; + __le32 w12; + __le32 w13; + __le32 w14; + __le32 w15; + __le32 w16; + __le32 w17; + __le32 w18; + __le32 w19; +} __packed; + +#define RTW89_C2H_MAC_TX_RPT_W12_TX_STATE_V2 GENMASK(9, 8) +#define RTW89_C2H_MAC_TX_RPT_W12_SW_DEFINE_V2 GENMASK(15, 12) +#define RTW89_C2H_MAC_TX_RPT_W14_DATA_TX_CNT_V2 GENMASK(15, 10) + struct rtw89_mac_mcc_tsf_rpt { u32 macid_x; u32 macid_y; diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireles= s/realtek/rtw89/mac.c index d837513f4e92..e4e126a4428b 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -5460,6 +5460,40 @@ rtw89_mac_c2h_mcc_status_rpt(struct rtw89_dev *rtwde= v, struct sk_buff *c2h, u32 rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data); } =20 +static void +rtw89_mac_c2h_tx_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 le= n) +{ + u8 sw_define, tx_status, txcnt; + + if (rtwdev->chip->chip_id =3D=3D RTL8922A) { + const struct rtw89_c2h_mac_tx_rpt_v2 *rpt_v2; + + rpt_v2 =3D (const struct rtw89_c2h_mac_tx_rpt_v2 *)c2h->data; + sw_define =3D le32_get_bits(rpt_v2->w12, + RTW89_C2H_MAC_TX_RPT_W12_SW_DEFINE_V2); + tx_status =3D le32_get_bits(rpt_v2->w12, + RTW89_C2H_MAC_TX_RPT_W12_TX_STATE_V2); + txcnt =3D le32_get_bits(rpt_v2->w14, + RTW89_C2H_MAC_TX_RPT_W14_DATA_TX_CNT_V2); + } else { + const struct rtw89_c2h_mac_tx_rpt *rpt; + + rpt =3D (const struct rtw89_c2h_mac_tx_rpt *)c2h->data; + sw_define =3D le32_get_bits(rpt->w2, RTW89_C2H_MAC_TX_RPT_W2_SW_DEFINE); + tx_status =3D le32_get_bits(rpt->w2, RTW89_C2H_MAC_TX_RPT_W2_TX_STATE); + if (rtwdev->chip->chip_id =3D=3D RTL8852C) + txcnt =3D le32_get_bits(rpt->w5, + RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT_V1); + else + txcnt =3D le32_get_bits(rpt->w5, + RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT); + } + + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "C2H TX RPT: sn %d, tx_status %d, txcnt %d\n", + sw_define, tx_status, txcnt); +} + static void rtw89_mac_c2h_mrc_tsf_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u= 32 len) { @@ -5694,6 +5728,12 @@ void (* const rtw89_mac_c2h_mcc_handler[])(struct rt= w89_dev *rtwdev, [RTW89_MAC_C2H_FUNC_MCC_STATUS_RPT] =3D rtw89_mac_c2h_mcc_status_rpt, }; =20 +static +void (* const rtw89_mac_c2h_misc_handler[])(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) =3D { + [RTW89_MAC_C2H_FUNC_TX_REPORT] =3D rtw89_mac_c2h_tx_rpt, +}; + static void (* const rtw89_mac_c2h_mlo_handler[])(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) =3D { @@ -5780,6 +5820,8 @@ bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwde= v, struct sk_buff *c2h, } case RTW89_MAC_C2H_CLASS_MCC: return true; + case RTW89_MAC_C2H_CLASS_MISC: + return true; case RTW89_MAC_C2H_CLASS_MLO: return true; case RTW89_MAC_C2H_CLASS_MRC: @@ -5815,6 +5857,10 @@ void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, = struct sk_buff *skb, if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MCC) handler =3D rtw89_mac_c2h_mcc_handler[func]; break; + case RTW89_MAC_C2H_CLASS_MISC: + if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MISC) + handler =3D rtw89_mac_c2h_misc_handler[func]; + break; case RTW89_MAC_C2H_CLASS_MLO: if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MLO) handler =3D rtw89_mac_c2h_mlo_handler[func]; diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireles= s/realtek/rtw89/mac.h index 25fe5e5c8a97..15c5c7e4033c 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -432,6 +432,12 @@ enum rtw89_mac_c2h_mcc_func { NUM_OF_RTW89_MAC_C2H_FUNC_MCC, }; =20 +enum rtw89_mac_c2h_misc_func { + RTW89_MAC_C2H_FUNC_TX_REPORT =3D 1, + + NUM_OF_RTW89_MAC_C2H_FUNC_MISC, +}; + enum rtw89_mac_c2h_mlo_func { RTW89_MAC_C2H_FUNC_MLO_GET_TBL =3D 0x0, RTW89_MAC_C2H_FUNC_MLO_EMLSR_TRANS_DONE =3D 0x1, @@ -470,6 +476,7 @@ enum rtw89_mac_c2h_class { RTW89_MAC_C2H_CLASS_WOW =3D 0x3, RTW89_MAC_C2H_CLASS_MCC =3D 0x4, RTW89_MAC_C2H_CLASS_FWDBG =3D 0x5, + RTW89_MAC_C2H_CLASS_MISC =3D 0x9, RTW89_MAC_C2H_CLASS_MLO =3D 0xc, RTW89_MAC_C2H_CLASS_MRC =3D 0xe, RTW89_MAC_C2H_CLASS_AP =3D 0x18, diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wirele= ss/realtek/rtw89/txrx.h index 984c9fdbb018..b37dbac7b790 100644 --- a/drivers/net/wireless/realtek/rtw89/txrx.h +++ b/drivers/net/wireless/realtek/rtw89/txrx.h @@ -127,6 +127,8 @@ static inline u8 rtw89_get_data_nss(struct rtw89_dev *r= twdev, u16 hw_rate) #define RTW89_TXWD_INFO0_MULTIPORT_ID GENMASK(6, 4) =20 /* TX WD INFO DWORD 1 */ +#define RTW89_TXWD_INFO1_DATA_TXCNT_LMT_SEL BIT(31) +#define RTW89_TXWD_INFO1_DATA_TXCNT_LMT GENMASK(30, 25) #define RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE GENMASK(24, 16) #define RTW89_TXWD_INFO1_A_CTRL_BSR BIT(14) #define RTW89_TXWD_INFO1_MAX_AGGNUM GENMASK(7, 0) @@ -139,10 +141,12 @@ static inline u8 rtw89_get_data_nss(struct rtw89_dev = *rtwdev, u16 hw_rate) #define RTW89_TXWD_INFO2_SEC_CAM_IDX GENMASK(7, 0) =20 /* TX WD INFO DWORD 3 */ +#define RTW89_TXWD_INFO3_SPE_RPT BIT(10) =20 /* TX WD INFO DWORD 4 */ -#define RTW89_TXWD_INFO4_RTS_EN BIT(27) #define RTW89_TXWD_INFO4_HW_RTS_EN BIT(31) +#define RTW89_TXWD_INFO4_RTS_EN BIT(27) +#define RTW89_TXWD_INFO4_SW_DEFINE GENMASK(3, 0) =20 /* TX WD INFO DWORD 5 */ =20 --=20 2.51.0 From nobody Sun Dec 14 11:18:47 2025 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6C76A359FB8; Wed, 29 Oct 2025 19:03:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=83.149.199.84 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764587; cv=none; b=lG5f7nIifWhoOFSfdllT7yRcIlqZaasTDpR7/pwcP9PDPQzX/yspTpwdoXOqhIBMzenSUD014tOveA0hXOzY5ys858ZVyeZ8X3mWYjy2LCJkd5kzXO/UscZJec7UCfFcVoMbHyVmGSguorqDQrkTsKSlk9z+AvlUJNM8y7wfJMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764587; c=relaxed/simple; bh=/qWMK8vpdTizLzGRvoCNpBH5BD+N40jnSQGbpSIPulc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ALsnchk/u0qNV+ph15ze07x812SYxSmbpFyNssopUQ/NObvdDxe1AlT7qFefRltluOK3YlVYLppYScGLDJ8TgyyEmP8QXV0Uca1djtdfaQifkVdL630+/wxRHvJhAI+1UqCm258hqghwnm9IKyjB4FeIiHUVMQGbLmek1w9c01o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru; spf=pass smtp.mailfrom=ispras.ru; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b=OkS/PAF7; arc=none smtp.client-ip=83.149.199.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ispras.ru Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b="OkS/PAF7" Received: from debian.intra.ispras.ru (unknown [10.10.165.6]) by mail.ispras.ru (Postfix) with ESMTPSA id 8551340777B0; Wed, 29 Oct 2025 19:03:00 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 8551340777B0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1761764580; bh=0L2eoPc/YQNOVXtDGM+uLLtk7qXUJPSHRMSid7VBzr8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OkS/PAF7u+Dj1wqrksjICazynsJITNqKbdwKt1PimmY7IOH+cxXKFG5BVJwPNPdqF 8dfYeeOpdvc3RvSglxQW1rfJsnuF3Wh5vtmkmoX5UGz4huXPA+XLzkcayikI3OdLLN Q2DBl0HuUnAgIgWuvzdRgtLqcKycKnOW/xfckHO4= From: Fedor Pchelkin To: Ping-Ke Shih , Bitterblue Smith Cc: Fedor Pchelkin , Zong-Zhe Yang , Po-Hao Huang , linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org Subject: [PATCH rtw-next v4 06/10] wifi: rtw89: fill TX descriptor of FWCMD in shortcut Date: Wed, 29 Oct 2025 22:02:34 +0300 Message-ID: <20251029190241.1023856-7-pchelkin@ispras.ru> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251029190241.1023856-1-pchelkin@ispras.ru> References: <20251029190241.1023856-1-pchelkin@ispras.ru> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ping-Ke Shih TX type FWCMD is used to download firmware and send H2C commands, and it only fill few fields of TX description, such as desc_info->pkt_size. Therefore, early return the TX type FWCMD. Signed-off-by: Ping-Ke Shih Signed-off-by: Fedor Pchelkin --- drivers/net/wireless/realtek/rtw89/core.c | 26 ++++++++++++----------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wirele= ss/realtek/rtw89/core.c index 8d73d9d9c15b..c069bde8b44e 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -1087,32 +1087,35 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rt= wdev, struct ieee80211_tx_info *info =3D IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr =3D (void *)skb->data; struct rtw89_addr_cam_entry *addr_cam; - enum rtw89_core_tx_type tx_type; enum btc_pkt_type pkt_type; bool upd_wlan_hdr =3D false; bool is_bmc; u16 seq; =20 + desc_info->pkt_size =3D skb->len; + + if (unlikely(tx_req->tx_type =3D=3D RTW89_CORE_TX_TYPE_FWCMD)) { + rtw89_core_tx_update_h2c_info(rtwdev, tx_req); + return; + } + + tx_req->tx_type =3D rtw89_core_get_tx_type(rtwdev, skb); + if (tx_req->sta) desc_info->mlo =3D tx_req->sta->mlo; else if (tx_req->vif) desc_info->mlo =3D ieee80211_vif_is_mld(tx_req->vif); =20 seq =3D (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; - if (tx_req->tx_type !=3D RTW89_CORE_TX_TYPE_FWCMD) { - tx_type =3D rtw89_core_get_tx_type(rtwdev, skb); - tx_req->tx_type =3D tx_type; + addr_cam =3D rtw89_get_addr_cam_of(tx_req->rtwvif_link, + tx_req->rtwsta_link); + if (addr_cam->valid && desc_info->mlo) + upd_wlan_hdr =3D true; =20 - addr_cam =3D rtw89_get_addr_cam_of(tx_req->rtwvif_link, - tx_req->rtwsta_link); - if (addr_cam->valid && desc_info->mlo) - upd_wlan_hdr =3D true; - } is_bmc =3D (is_broadcast_ether_addr(hdr->addr1) || is_multicast_ether_addr(hdr->addr1)); =20 desc_info->seq =3D seq; - desc_info->pkt_size =3D skb->len; desc_info->is_bmc =3D is_bmc; desc_info->wd_page =3D true; desc_info->hiq =3D info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM; @@ -1129,8 +1132,7 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwd= ev, rtw89_core_tx_update_ampdu_info(rtwdev, tx_req, pkt_type); rtw89_core_tx_update_llc_hdr(rtwdev, desc_info, skb); break; - case RTW89_CORE_TX_TYPE_FWCMD: - rtw89_core_tx_update_h2c_info(rtwdev, tx_req); + default: break; } } --=20 2.51.0 From nobody Sun Dec 14 11:18:47 2025 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 88A3F359F82; Wed, 29 Oct 2025 19:03:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=83.149.199.84 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764586; cv=none; b=HJwydAKpOlV/nt+OAwcMTuyRb8l5pQg2kWAbWy6lCYZ66A1NNimoiIzIjC0WMYjGWDd1V3BeKEFd/MmkI8RZ8odnlsTm85i6MOwNfWUxjhdJU0Q0Upjy/cmOz1E8/eHFbBcOQodTA0PllcB8OP0tIk9pCW4ULmwBU1hLTeR5Jm4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764586; c=relaxed/simple; bh=4dtliad1hDVDUDG9X7pXCghu4QfFymCPJNzSElZI5EY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uvw4DoDWksdahG/CbgMFr9TTDLUhOiq91zNkgb9r0e3cYKi/Ve83EcqkTYMeOMLhZvRwMgp8/tAIZ4nDp/VlHWHFQTRSNqTrQkfn7rGt05ELF0c2DT9fcpKupMEBVeCa7tX0IJSZJRAsKKvngDrAoVg1vtNDuHmdNFl2Sc2IlfM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru; spf=pass smtp.mailfrom=ispras.ru; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b=e682F4O5; arc=none smtp.client-ip=83.149.199.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ispras.ru Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b="e682F4O5" Received: from debian.intra.ispras.ru (unknown [10.10.165.6]) by mail.ispras.ru (Postfix) with ESMTPSA id 015F840777B1; Wed, 29 Oct 2025 19:03:00 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 015F840777B1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1761764581; bh=anMhG7Ma5+cYRiOaaeXJ2RVavZMucYrc2CMe9I9gcgo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e682F4O5MvqfueHwl6NsUq2V9XhTfwz1i8nkd1UXmjEr+l1Ql7w8+aruIgwyk99n1 Qng+2MTSrd/DW7u+vUrkfhtl/sdZCr6QFDb1al+JZ3DVKlcQGRR+dWZsDdF+q0efBU tYDjOOHwV+pGCTQKlokHMBmzaj//Sk2zUmlNMYWk= From: Fedor Pchelkin To: Ping-Ke Shih , Bitterblue Smith Cc: Fedor Pchelkin , Zong-Zhe Yang , Po-Hao Huang , linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org Subject: [PATCH rtw-next v4 07/10] wifi: rtw89: usb: anchor TX URBs Date: Wed, 29 Oct 2025 22:02:35 +0300 Message-ID: <20251029190241.1023856-8-pchelkin@ispras.ru> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251029190241.1023856-1-pchelkin@ispras.ru> References: <20251029190241.1023856-1-pchelkin@ispras.ru> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" During HCI reset all pending TX URBs should be canceled. Use anchor to keep track of them and have an ability to cancel them synchronously. Note however that canceling RX URBs can't be done here in rtw89_usb_ops_reset() as it breaks driver initialization. Found by Linux Verification Center (linuxtesting.org). Signed-off-by: Fedor Pchelkin Acked-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/usb.c | 24 ++++++++++++++++++++---- drivers/net/wireless/realtek/rtw89/usb.h | 1 + 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireles= s/realtek/rtw89/usb.c index 93dc4e91c1d4..c359b469aabe 100644 --- a/drivers/net/wireless/realtek/rtw89/usb.c +++ b/drivers/net/wireless/realtek/rtw89/usb.c @@ -242,7 +242,6 @@ static void rtw89_usb_write_port_complete(struct urb *u= rb) } =20 kfree(txcb); - usb_free_urb(urb); } =20 static int rtw89_usb_write_port(struct rtw89_dev *rtwdev, u8 ch_dma, @@ -267,10 +266,17 @@ static int rtw89_usb_write_port(struct rtw89_dev *rtw= dev, u8 ch_dma, usb_fill_bulk_urb(urb, usbd, pipe, data, len, rtw89_usb_write_port_complete, context); urb->transfer_flags |=3D URB_ZERO_PACKET; - ret =3D usb_submit_urb(urb, GFP_ATOMIC); + usb_anchor_urb(urb, &rtwusb->tx_submitted); =20 + ret =3D usb_submit_urb(urb, GFP_ATOMIC); if (ret) - usb_free_urb(urb); + usb_unanchor_urb(urb); + + /* release our reference to this URB, USB core will eventually free it + * on its own after the completion callback finishes (or URB is + * immediately freed here if its submission has failed) + */ + usb_free_urb(urb); =20 if (ret =3D=3D -ENODEV) set_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags); @@ -577,6 +583,11 @@ static void rtw89_usb_cancel_rx_bufs(struct rtw89_usb = *rtwusb) } } =20 +static void rtw89_usb_cancel_tx_bufs(struct rtw89_usb *rtwusb) +{ + usb_kill_anchored_urbs(&rtwusb->tx_submitted); +} + static void rtw89_usb_free_rx_bufs(struct rtw89_usb *rtwusb) { struct rtw89_usb_rx_ctrl_block *rxcb; @@ -678,7 +689,9 @@ static void rtw89_usb_deinit_tx(struct rtw89_dev *rtwde= v) =20 static void rtw89_usb_ops_reset(struct rtw89_dev *rtwdev) { - /* TODO: anything to do here? */ + struct rtw89_usb *rtwusb =3D rtw89_usb_priv(rtwdev); + + rtw89_usb_cancel_tx_bufs(rtwusb); } =20 static int rtw89_usb_ops_start(struct rtw89_dev *rtwdev) @@ -911,6 +924,8 @@ static int rtw89_usb_intf_init(struct rtw89_dev *rtwdev, struct rtw89_usb *rtwusb =3D rtw89_usb_priv(rtwdev); int ret; =20 + init_usb_anchor(&rtwusb->tx_submitted); + ret =3D rtw89_usb_parse(rtwdev, intf); if (ret) return ret; @@ -1036,6 +1051,7 @@ void rtw89_usb_disconnect(struct usb_interface *intf) rtwusb =3D rtw89_usb_priv(rtwdev); =20 rtw89_usb_cancel_rx_bufs(rtwusb); + rtw89_usb_cancel_tx_bufs(rtwusb); =20 rtw89_core_unregister(rtwdev); rtw89_core_deinit(rtwdev); diff --git a/drivers/net/wireless/realtek/rtw89/usb.h b/drivers/net/wireles= s/realtek/rtw89/usb.h index c1b4bfa20979..320002c1df42 100644 --- a/drivers/net/wireless/realtek/rtw89/usb.h +++ b/drivers/net/wireless/realtek/rtw89/usb.h @@ -49,6 +49,7 @@ struct rtw89_usb { struct sk_buff_head rx_free_queue; struct work_struct rx_work; struct work_struct rx_urb_work; + struct usb_anchor tx_submitted; =20 struct sk_buff_head tx_queue[RTW89_TXCH_NUM]; }; --=20 2.51.0 From nobody Sun Dec 14 11:18:47 2025 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 889B5359F81; Wed, 29 Oct 2025 19:03:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=83.149.199.84 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764587; cv=none; b=AqbD9/sy1Xt7PkpH+yduAaintnyiZQwP6cfdSzfmy+L7K17lHLDSD14O5CaYdmLSkgVeQQ5LbWSZU5+3dzfYvFsXUztlSyjWaDmWO8nxdFI4CSca1qznnpYXNjtupGigSM71hSFjv2QXqG7qWIxIPV9/yqirprbscH1YJb/puYo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764587; c=relaxed/simple; bh=MmZnm8c8K/KdjD4ZMfwtWe/jnPVSTOAeA3O2c5jY+uo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=suwr8VIQh85GrM+GTXWLlmYqHKM3aGr136GBxNLzJkV5e13SQZtfWDRytTUun/Z6oXWO2x/VYx27XwujLkfvFQCwmbLGL9E2JFV3/MmB6BpQn7mtPFn25XIPIfbEvgAukCd/65wjHB6TqBKLDUSjPXllG3+j9w1Vxk73YeFPtQ4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru; spf=pass smtp.mailfrom=ispras.ru; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b=VKwZN5t4; arc=none smtp.client-ip=83.149.199.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ispras.ru Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b="VKwZN5t4" Received: from debian.intra.ispras.ru (unknown [10.10.165.6]) by mail.ispras.ru (Postfix) with ESMTPSA id 7F17540777B3; Wed, 29 Oct 2025 19:03:01 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 7F17540777B3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1761764581; bh=S2i7jF9OmAeePWQbw7BoE8r46UITUtxwGtyawLeFRhc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VKwZN5t4XfD4KikvdU9Iy9n+FOi9fimQMgd/Zr1lACS4JsSv6LbXx119kItzE9Nmm 3+qhN1/YVC/+bvDKdE+pD0Bww7D1s3A8Ky6DCXZou1Lb3+iHonDSI6F4tk0zwUxgLr bsrwb9+F1oKFKrhPghKeiML2npmelTHMv+KSNDpk= From: Fedor Pchelkin To: Ping-Ke Shih , Bitterblue Smith Cc: Fedor Pchelkin , Zong-Zhe Yang , Po-Hao Huang , linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org Subject: [PATCH rtw-next v4 08/10] wifi: rtw89: handle IEEE80211_TX_CTL_REQ_TX_STATUS frames for USB Date: Wed, 29 Oct 2025 22:02:36 +0300 Message-ID: <20251029190241.1023856-9-pchelkin@ispras.ru> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251029190241.1023856-1-pchelkin@ispras.ru> References: <20251029190241.1023856-1-pchelkin@ispras.ru> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Frames flagged with IEEE80211_TX_CTL_REQ_TX_STATUS mean the driver has to report to mac80211 stack whether AP sent ACK for the null frame/probe request or not. It's not implemented in USB part of the driver yet. PCIe HCI has its own way of getting TX status incorporated into RPP feature, and it's always enabled there. Other HCIs need a different scheme based on processing C2H messages. Thus define a .tx_rpt_enabled flag indicating which HCIs need to enable a TX report feature. Currently it is USB only. Toggle a bit in the TX descriptor and place flagged skbs in a fix-sized queue to wait for a message from the firmware. Firmware maintains a 4-bit sequence number for required frames hence the queue can contain just 16 elements simultaneously. That's enough for normal driver / firmware communication. If the firmware crashes for any reason and doesn't provide TX reports in time, driver will handle this and report the obsolete frames as dropped. rtw89 also has a new feature providing a TX report for each transmission attempt. Ignore a failed TX status reported by the firmware until retry limit is reached or successful status appears. When there is no success and the retry limit is reached, report the frame up to the wireless stack as failed eventually. HCI reset should stop all pending TX activity so forcefully flush the queue there. Found by Linux Verification Center (linuxtesting.org). Signed-off-by: Fedor Pchelkin --- v4: - use fix-sized queue for storing pending TX frames, replace skb queue list implementation - update the changelog accordingly - make comment right after hci->reset to explicitly point out we should complete all TX waits skbs (Ping-Ke) - check urb->status for TX rpt frames, too (Ping-Ke) v3: - don't mix TX RPT queue with TX wait list processing (Ping-Ke) - add struct rtw89_tx_rpt for convenience, that's also like in rtw88 - update changelog to reflect TX RPT retry logic and add some comments inside rtw89_mac_c2h_tx_rpt() v2: - update TX rpt description in rtw89_core_tx_update_desc_info() - add a flag in rtw89_hci_info to determine if we should enable TX repo= rt (Ping-Ke) - refine rtw89_tx_rpt_queue_purge() - it's called on USB HCI reset and at rtw89_tx_wait_work. Queueing delayed rtw89_tx_wait_work may be suboptimal but basically it's what rtw88 does with timer stuff. drivers/net/wireless/realtek/rtw89/core.c | 4 ++ drivers/net/wireless/realtek/rtw89/core.h | 13 ++++ drivers/net/wireless/realtek/rtw89/mac.c | 26 ++++++++ drivers/net/wireless/realtek/rtw89/mac.h | 81 +++++++++++++++++++++++ drivers/net/wireless/realtek/rtw89/usb.c | 18 +++++ 5 files changed, 142 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wirele= ss/realtek/rtw89/core.c index c069bde8b44e..d0b8cd999b49 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -1112,6 +1112,9 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwd= ev, if (addr_cam->valid && desc_info->mlo) upd_wlan_hdr =3D true; =20 + if (rtw89_is_tx_rpt_skb(tx_req->skb)) + rtw89_tx_rpt_init(rtwdev, tx_req); + is_bmc =3D (is_broadcast_ether_addr(hdr->addr1) || is_multicast_ether_addr(hdr->addr1)); =20 @@ -5846,6 +5849,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) wiphy_work_init(&rtwdev->cancel_6ghz_probe_work, rtw89_cancel_6ghz_probe_= work); INIT_WORK(&rtwdev->load_firmware_work, rtw89_load_firmware_work); =20 + spin_lock_init(&rtwdev->tx_rpt.skb_lock); skb_queue_head_init(&rtwdev->c2h_queue); rtw89_core_ppdu_sts_init(rtwdev); rtw89_traffic_stats_init(rtwdev, &rtwdev->stats); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wirele= ss/realtek/rtw89/core.h index 9372e30a0039..015d7833841f 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3517,6 +3517,14 @@ struct rtw89_phy_rate_pattern { #define RTW89_TX_LIFE_TIME 0x2 #define RTW89_TX_MACID_DROP 0x3 =20 +#define RTW89_MAX_TX_RPTS 16 +#define RTW89_MAX_TX_RPTS_MASK (RTW89_MAX_TX_RPTS - 1) +struct rtw89_tx_rpt { + struct sk_buff *skbs[RTW89_MAX_TX_RPTS]; + spinlock_t skb_lock; + atomic_t sn; +}; + #define RTW89_TX_WAIT_WORK_TIMEOUT msecs_to_jiffies(500) struct rtw89_tx_wait_info { struct rcu_head rcu_head; @@ -3528,6 +3536,8 @@ struct rtw89_tx_wait_info { =20 struct rtw89_tx_skb_data { struct rtw89_tx_wait_info __rcu *wait; + u8 tx_rpt_sn; + u8 tx_pkt_cnt_lmt; u8 hci_priv[]; }; =20 @@ -3697,6 +3707,7 @@ struct rtw89_hci_info { u32 rpwm_addr; u32 cpwm_addr; bool paused; + bool tx_rpt_enabled; }; =20 struct rtw89_chip_ops { @@ -6019,6 +6030,8 @@ struct rtw89_dev { struct list_head tx_waits; struct wiphy_delayed_work tx_wait_work; =20 + struct rtw89_tx_rpt tx_rpt; + struct rtw89_cam_info cam_info; =20 struct sk_buff_head c2h_queue; diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireles= s/realtek/rtw89/mac.c index e4e126a4428b..a6642c5761cb 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -5463,7 +5463,10 @@ rtw89_mac_c2h_mcc_status_rpt(struct rtw89_dev *rtwde= v, struct sk_buff *c2h, u32 static void rtw89_mac_c2h_tx_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 le= n) { + struct rtw89_tx_rpt *tx_rpt =3D &rtwdev->tx_rpt; + struct rtw89_tx_skb_data *skb_data; u8 sw_define, tx_status, txcnt; + struct sk_buff *skb; =20 if (rtwdev->chip->chip_id =3D=3D RTL8922A) { const struct rtw89_c2h_mac_tx_rpt_v2 *rpt_v2; @@ -5492,6 +5495,29 @@ rtw89_mac_c2h_tx_rpt(struct rtw89_dev *rtwdev, struc= t sk_buff *c2h, u32 len) rtw89_debug(rtwdev, RTW89_DBG_TXRX, "C2H TX RPT: sn %d, tx_status %d, txcnt %d\n", sw_define, tx_status, txcnt); + + scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) { + skb =3D tx_rpt->skbs[sw_define]; + + /* skip if no skb (normally shouldn't happen) */ + if (!skb) { + rtw89_debug(rtwdev, RTW89_DBG_TXRX, + "C2H TX RPT: no skb found in queue\n"); + return; + } + + skb_data =3D RTW89_TX_SKB_CB(skb); + + /* skip if TX attempt has failed and retry limit has not been + * reached yet + */ + if (tx_status !=3D RTW89_TX_DONE && + txcnt !=3D skb_data->tx_pkt_cnt_lmt) + return; + + tx_rpt->skbs[sw_define] =3D NULL; + rtw89_tx_rpt_tx_status(rtwdev, skb, tx_status); + } } =20 static void diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireles= s/realtek/rtw89/mac.h index 15c5c7e4033c..fde784b41bcf 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -1616,4 +1616,85 @@ int rtw89_mac_scan_offload(struct rtw89_dev *rtwdev, =20 return ret; } + +static inline +void rtw89_tx_rpt_init(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + struct rtw89_tx_rpt *tx_rpt =3D &rtwdev->tx_rpt; + + if (!rtwdev->hci.tx_rpt_enabled) + return; + + tx_req->desc_info.report =3D true; + /* firmware maintains a 4-bit sequence number */ + tx_req->desc_info.sn =3D atomic_inc_return(&tx_rpt->sn) & + RTW89_MAX_TX_RPTS_MASK; + tx_req->desc_info.tx_cnt_lmt_en =3D true; + tx_req->desc_info.tx_cnt_lmt =3D 8; +} + +static inline +bool rtw89_is_tx_rpt_skb(struct sk_buff *skb) +{ + struct ieee80211_tx_info *info =3D IEEE80211_SKB_CB(skb); + + return info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS; +} + +static inline +void rtw89_tx_rpt_tx_status(struct rtw89_dev *rtwdev, struct sk_buff *skb, + u8 tx_status) +{ + struct ieee80211_tx_info *info =3D IEEE80211_SKB_CB(skb); + + ieee80211_tx_info_clear_status(info); + + if (tx_status =3D=3D RTW89_TX_DONE) + info->flags |=3D IEEE80211_TX_STAT_ACK; + else + info->flags &=3D ~IEEE80211_TX_STAT_ACK; + + ieee80211_tx_status_irqsafe(rtwdev->hw, skb); +} + +static inline +void rtw89_tx_rpt_skb_add(struct rtw89_dev *rtwdev, struct sk_buff *skb) +{ + struct rtw89_tx_rpt *tx_rpt =3D &rtwdev->tx_rpt; + struct rtw89_tx_skb_data *skb_data; + u8 idx; + + skb_data =3D RTW89_TX_SKB_CB(skb); + idx =3D skb_data->tx_rpt_sn; + + scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) { + /* if skb having the similar seq number is still in the queue, + * this means the queue is overflowed - it isn't normal and + * should indicate firmware doesn't provide TX reports in time; + * report the old skb as dropped, we can't do much more here + */ + if (tx_rpt->skbs[idx]) + rtw89_tx_rpt_tx_status(rtwdev, tx_rpt->skbs[idx], + RTW89_TX_MACID_DROP); + tx_rpt->skbs[idx] =3D skb; + } +} + +static inline +void rtw89_tx_rpt_skbs_purge(struct rtw89_dev *rtwdev) +{ + struct rtw89_tx_rpt *tx_rpt =3D &rtwdev->tx_rpt; + struct sk_buff *skbs[RTW89_MAX_TX_RPTS]; + + scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) { + memcpy(skbs, tx_rpt->skbs, sizeof(tx_rpt->skbs)); + memset(tx_rpt->skbs, 0, sizeof(tx_rpt->skbs)); + } + + for (int i =3D 0; i < ARRAY_SIZE(skbs); i++) + if (skbs[i]) + rtw89_tx_rpt_tx_status(rtwdev, skbs[i], + RTW89_TX_MACID_DROP); +} #endif diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireles= s/realtek/rtw89/usb.c index c359b469aabe..5e587c93268e 100644 --- a/drivers/net/wireless/realtek/rtw89/usb.c +++ b/drivers/net/wireless/realtek/rtw89/usb.c @@ -216,6 +216,15 @@ static void rtw89_usb_write_port_complete(struct urb *= urb) skb_pull(skb, txdesc_size); =20 info =3D IEEE80211_SKB_CB(skb); + if (rtw89_is_tx_rpt_skb(skb)) { + if (urb->status =3D=3D 0) + rtw89_tx_rpt_skb_add(rtwdev, skb); + else + rtw89_tx_rpt_tx_status(rtwdev, skb, + RTW89_TX_MACID_DROP); + continue; + } + ieee80211_tx_info_clear_status(info); =20 if (urb->status =3D=3D 0) { @@ -378,6 +387,7 @@ static int rtw89_usb_ops_tx_write(struct rtw89_dev *rtw= dev, { struct rtw89_tx_desc_info *desc_info =3D &tx_req->desc_info; struct rtw89_usb *rtwusb =3D rtw89_usb_priv(rtwdev); + struct rtw89_tx_skb_data *skb_data; struct sk_buff *skb =3D tx_req->skb; struct rtw89_txwd_body *txdesc; u32 txdesc_size; @@ -404,6 +414,12 @@ static int rtw89_usb_ops_tx_write(struct rtw89_dev *rt= wdev, =20 le32p_replace_bits(&txdesc->dword0, 1, RTW89_TXWD_BODY0_STF_MODE); =20 + skb_data =3D RTW89_TX_SKB_CB(skb); + if (tx_req->desc_info.sn) + skb_data->tx_rpt_sn =3D tx_req->desc_info.sn; + if (tx_req->desc_info.tx_cnt_lmt) + skb_data->tx_pkt_cnt_lmt =3D tx_req->desc_info.tx_cnt_lmt; + skb_queue_tail(&rtwusb->tx_queue[desc_info->ch_dma], skb); =20 return 0; @@ -692,6 +708,7 @@ static void rtw89_usb_ops_reset(struct rtw89_dev *rtwde= v) struct rtw89_usb *rtwusb =3D rtw89_usb_priv(rtwdev); =20 rtw89_usb_cancel_tx_bufs(rtwusb); + rtw89_tx_rpt_skbs_purge(rtwdev); } =20 static int rtw89_usb_ops_start(struct rtw89_dev *rtwdev) @@ -977,6 +994,7 @@ int rtw89_usb_probe(struct usb_interface *intf, =20 rtwdev->hci.ops =3D &rtw89_usb_ops; rtwdev->hci.type =3D RTW89_HCI_TYPE_USB; + rtwdev->hci.tx_rpt_enabled =3D true; =20 ret =3D rtw89_usb_intf_init(rtwdev, intf); if (ret) { --=20 2.51.0 From nobody Sun Dec 14 11:18:47 2025 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6C614359FB7; Wed, 29 Oct 2025 19:03:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=83.149.199.84 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764589; cv=none; b=Rok9a1LH5pIPyLqIdbq8igVTXbYe8AFgaRp+wQ2zdx8310oi4AohHGaCv1snn9k4wFxmW428QrxcT2aIPOIiqpImFUgdO4LQOz0WycgUGf+pDnhG6Pj5jxGHmaj/3CjzZqFMfNiRQT5i/RH0GG6OZGLdmNtMTkCdBL+jsCh4GBk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764589; c=relaxed/simple; bh=8dIjjojbITvqNbsg3XwjMkl/uvpHaxTiczOpOe5mnTo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DjIjdDoOD6Sw5jNZ4Q4dogBh+OgMMq9v3PQ6bYY3kARYEvifQnVLedRWsQ22Q3VIKt1XsXl4B62lOhggPA5mP/1RtUuL7XFZi5g8Voq2mPJFrZKOS6r0fioJtVjnuWvL3ZsOyMAxsuSDxmUNN1U4FO5QGcD7vjQLpCVEkjUUJkE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru; spf=pass smtp.mailfrom=ispras.ru; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b=ZFQNmgMV; arc=none smtp.client-ip=83.149.199.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ispras.ru Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b="ZFQNmgMV" Received: from debian.intra.ispras.ru (unknown [10.10.165.6]) by mail.ispras.ru (Postfix) with ESMTPSA id 0CFF740777B7; Wed, 29 Oct 2025 19:03:02 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 0CFF740777B7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1761764582; bh=BWZ2dTTCVzN7XXif7Kg6X0B6A96hrFAgIhH5o4emZ7o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZFQNmgMVjP9By+1F07/iUYMl6nMsfN3sniibjMVt1tdNnDhk7wQmvtQUemMYGGJgt bMxhG0njH0L3UVfME78bOBhWR31OMZaqi3GPm0a+dvAorF2JV/X4BTYIenVvi22zyt S0cz+mqOiCMKbSIic6nGPW8zfHoiW6DhmMcExt8Y= From: Fedor Pchelkin To: Ping-Ke Shih , Bitterblue Smith Cc: Fedor Pchelkin , Zong-Zhe Yang , Po-Hao Huang , linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org Subject: [PATCH rtw-next v4 09/10] wifi: rtw89: provide TX reports for management frames Date: Wed, 29 Oct 2025 22:02:37 +0300 Message-ID: <20251029190241.1023856-10-pchelkin@ispras.ru> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251029190241.1023856-1-pchelkin@ispras.ru> References: <20251029190241.1023856-1-pchelkin@ispras.ru> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In order to provide TX reports for the management queue rtw89 should configure the firmware. Do this with SET_CMC_TBL_MGQ_RPT_EN() for the WiFi6 chips and with CCTLINFO_G7_W0_MGQ_RPT_EN flag for the WiFi7 ones. Suggested-by: Bitterblue Smith Signed-off-by: Fedor Pchelkin Acked-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/fw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless= /realtek/rtw89/fw.c index cb431c8a65ac..96f0463e66d6 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -3165,6 +3165,7 @@ int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *r= twdev, SET_CMC_TBL_ANTSEL_C(skb->data, 0); SET_CMC_TBL_ANTSEL_D(skb->data, 0); } + SET_CMC_TBL_MGQ_RPT_EN(skb->data, rtwdev->hci.tx_rpt_enabled); SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0); SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0); if (rtwvif_link->net_type =3D=3D RTW89_NET_TYPE_AP_MODE) @@ -3210,7 +3211,8 @@ int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev= *rtwdev, h2c->c0 =3D le32_encode_bits(mac_id, CCTLINFO_G7_C0_MACID) | le32_encode_bits(1, CCTLINFO_G7_C0_OP); =20 - h2c->w0 =3D le32_encode_bits(4, CCTLINFO_G7_W0_DATARATE); + h2c->w0 =3D le32_encode_bits(4, CCTLINFO_G7_W0_DATARATE) | + le32_encode_bits(rtwdev->hci.tx_rpt_enabled, CCTLINFO_G7_W0_MGQ_RPT_EN= ); h2c->m0 =3D cpu_to_le32(CCTLINFO_G7_W0_ALL); =20 h2c->w1 =3D le32_encode_bits(4, CCTLINFO_G7_W1_DATA_RTY_LOWEST_RATE) | --=20 2.51.0 From nobody Sun Dec 14 11:18:47 2025 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6D390359FB9; Wed, 29 Oct 2025 19:03:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=83.149.199.84 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764588; cv=none; b=lHZ9QPnb6JUkUTvSs8AbhnILFw2HpN84nwV1gI+ukKbTe0ofKhPDvX3v3M+UbBYAxH4be4JjfB90jfA/VTF/nTi2UwRXhUXr/WP3YmebcmjKGOJzNmFuvnaCln/eMTeLPrdyKhInxMhVosTeRV7DrekbQ2xGeeP8pSdBnvt0Pu0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761764588; c=relaxed/simple; bh=pijQ9ET9sbf5Z/xmTOQ1wqMPmTfdJyL6XbnyzRCiREY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K8nuB+nNCDFi/lSArgp1eii2R3aY9yqcTW12s1AUGneiZ/M+Vzt8KnbQk9Nml80rRSmWxRC9fuuivoOpbH5SLysTMtlHo75isNI4F80FQJPeijYhOxdtBAm/mlHr4DPkgR/JIkvf0BjmADEjHxmI9Yj5cDNMGvdXeVvW89PZ++o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru; spf=pass smtp.mailfrom=ispras.ru; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b=ChYG06Fn; arc=none smtp.client-ip=83.149.199.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ispras.ru Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ispras.ru Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ispras.ru header.i=@ispras.ru header.b="ChYG06Fn" Received: from debian.intra.ispras.ru (unknown [10.10.165.6]) by mail.ispras.ru (Postfix) with ESMTPSA id B4A9540777BB; Wed, 29 Oct 2025 19:03:02 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru B4A9540777BB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1761764582; bh=Vxs3WVgS9ScMqpuMyhAJMsLHgrTnmyHGhlT+Zk/Gc5o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ChYG06FnGy0v9gDlpQ9Kr8h6YH1EogwtcAq66+CYlg4aUhSWFz65NKz/GCKx4HjVK jXPrro/tRLNlJ0Cy5dX2VgQzKoHsv5OHppeYs3XHavIsYyQRAmbToS7vQqkONt5E/Q QChrli3s7PXOnwUfiexAETZGC9BuSBfRK9h9Z480= From: Fedor Pchelkin To: Ping-Ke Shih , Bitterblue Smith Cc: Fedor Pchelkin , Zong-Zhe Yang , Po-Hao Huang , linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org Subject: [PATCH rtw-next v4 10/10] wifi: rtw89: process TX wait skbs for USB via C2H handler Date: Wed, 29 Oct 2025 22:02:38 +0300 Message-ID: <20251029190241.1023856-11-pchelkin@ispras.ru> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251029190241.1023856-1-pchelkin@ispras.ru> References: <20251029190241.1023856-1-pchelkin@ispras.ru> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" TX wait skbs need to be completed when they are done. PCIe part does this inside rtw89_pci_tx_status() during RPP processing. Other HCIs use a mechanism based on C2H firmware messages. Store TX wait skbs inside TX report queue so that it'll be possible to identify completed items inside the C2H handler. Try to do this as similar to PCIe path as possible. When the corresponding TX wait skb is found inside TX report queue, unlink it from there and call rtw89_core_tx_wait_complete() to mark the completion. If the callee waiting for the completion has already timed out, the TX wait skb is placed into TX wait list (like PCIe part does). It's important that during HCI reset all pending TX wait frames should be completed inside hci.ops->reset method before calling rtw89_tx_wait_list_clear(). Found by Linux Verification Center (linuxtesting.org). Signed-off-by: Fedor Pchelkin Acked-by: Ping-Ke Shih --- v4: - minor `info =3D IEEE80211_SKB_CB` assignment reordering to make it lo= ok more like PCIe side; Acked-by kept (Ping-Ke) - add a comment on completing TX waits in ->reset (Ping-Ke)=20 v3: - use rcu_access_pointer() inside rtw89_core_is_tx_wait() (Zong-Zhe) - finally I've hopefully realized what you meant by doing TX wait skb handling here similar to PCIe. IMO this looks just elegant now compared to my previous submissions. Thanks, Ping-Ke! v2: store TX wait skbs in tx_rpt_queue (Ping-Ke) drivers/net/wireless/realtek/rtw89/core.c | 5 ++--- drivers/net/wireless/realtek/rtw89/core.h | 7 +++++++ drivers/net/wireless/realtek/rtw89/mac.h | 13 ++++++++++--- drivers/net/wireless/realtek/rtw89/usb.c | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wirele= ss/realtek/rtw89/core.c index d0b8cd999b49..c253d60e02b8 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -1112,7 +1112,7 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwd= ev, if (addr_cam->valid && desc_info->mlo) upd_wlan_hdr =3D true; =20 - if (rtw89_is_tx_rpt_skb(tx_req->skb)) + if (rtw89_is_tx_rpt_skb(rtwdev, tx_req->skb)) rtw89_tx_rpt_init(rtwdev, tx_req); =20 is_bmc =3D (is_broadcast_ether_addr(hdr->addr1) || @@ -1244,14 +1244,13 @@ static int rtw89_core_tx_write_link(struct rtw89_de= v *rtwdev, tx_req.rtwvif_link =3D rtwvif_link; tx_req.rtwsta_link =3D rtwsta_link; tx_req.desc_info.sw_mld =3D sw_mld; + rcu_assign_pointer(skb_data->wait, wait); =20 rtw89_traffic_stats_accu(rtwdev, rtwvif, skb, true, true); rtw89_wow_parse_akm(rtwdev, skb); rtw89_core_tx_update_desc_info(rtwdev, &tx_req); rtw89_core_tx_wake(rtwdev, &tx_req); =20 - rcu_assign_pointer(skb_data->wait, wait); - ret =3D rtw89_hci_tx_write(rtwdev, &tx_req); if (ret) { rtw89_err(rtwdev, "failed to transmit skb to HCI\n"); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wirele= ss/realtek/rtw89/core.h index 015d7833841f..dd3bf6fa9206 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -6325,6 +6325,7 @@ static inline int rtw89_hci_tx_write(struct rtw89_dev= *rtwdev, static inline void rtw89_hci_reset(struct rtw89_dev *rtwdev) { rtwdev->hci.ops->reset(rtwdev); + /* hci.ops->reset must complete all pending TX wait SKBs */ rtw89_tx_wait_list_clear(rtwdev); } =20 @@ -7406,6 +7407,12 @@ static inline struct sk_buff *rtw89_alloc_skb_for_rx= (struct rtw89_dev *rtwdev, return dev_alloc_skb(length); } =20 +static inline bool rtw89_core_is_tx_wait(struct rtw89_dev *rtwdev, + struct rtw89_tx_skb_data *skb_data) +{ + return rcu_access_pointer(skb_data->wait); +} + static inline bool rtw89_core_tx_wait_complete(struct rtw89_dev *rtwdev, struct rtw89_tx_skb_data *skb_data, u8 tx_status) diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireles= s/realtek/rtw89/mac.h index fde784b41bcf..5a3dc708f593 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -1635,19 +1635,26 @@ void rtw89_tx_rpt_init(struct rtw89_dev *rtwdev, } =20 static inline -bool rtw89_is_tx_rpt_skb(struct sk_buff *skb) +bool rtw89_is_tx_rpt_skb(struct rtw89_dev *rtwdev, struct sk_buff *skb) { + struct rtw89_tx_skb_data *skb_data =3D RTW89_TX_SKB_CB(skb); struct ieee80211_tx_info *info =3D IEEE80211_SKB_CB(skb); =20 - return info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS; + return rtw89_core_is_tx_wait(rtwdev, skb_data) || + (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS); } =20 static inline void rtw89_tx_rpt_tx_status(struct rtw89_dev *rtwdev, struct sk_buff *skb, u8 tx_status) { - struct ieee80211_tx_info *info =3D IEEE80211_SKB_CB(skb); + struct rtw89_tx_skb_data *skb_data =3D RTW89_TX_SKB_CB(skb); + struct ieee80211_tx_info *info; + + if (rtw89_core_tx_wait_complete(rtwdev, skb_data, tx_status)) + return; =20 + info =3D IEEE80211_SKB_CB(skb); ieee80211_tx_info_clear_status(info); =20 if (tx_status =3D=3D RTW89_TX_DONE) diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireles= s/realtek/rtw89/usb.c index 5e587c93268e..16b144732e0c 100644 --- a/drivers/net/wireless/realtek/rtw89/usb.c +++ b/drivers/net/wireless/realtek/rtw89/usb.c @@ -216,7 +216,7 @@ static void rtw89_usb_write_port_complete(struct urb *u= rb) skb_pull(skb, txdesc_size); =20 info =3D IEEE80211_SKB_CB(skb); - if (rtw89_is_tx_rpt_skb(skb)) { + if (rtw89_is_tx_rpt_skb(rtwdev, skb)) { if (urb->status =3D=3D 0) rtw89_tx_rpt_skb_add(rtwdev, skb); else --=20 2.51.0