From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr2-f35.google.com (mail-wr2-f35.google.com [74.125.225.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BC7F238D3EE for ; Fri, 2 Oct 2026 23:10:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.225.99 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790982649; cv=none; b=s2NSCi5RP1NknM7WOVIGtRYXFBJfX2IDKjnLrk8Bjzd1hHihQzXQ6NqPiy3OQynm7S67iwhoqYG0GOh82hzqlRZnmv4skLURp5MIYkoWGy0uIz4yNBe5uxslLfU4d8lL2Wp5833LjwTUIp4E00Wf0shNhjCYnutG5f0jG9m4cHY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790982649; c=relaxed/simple; bh=hPnGfVE/ERhFq2pn4wQsxIv0Cq0Ccgf6d+h71VG44k0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MLoEfvR5+QSxUKRXVlvVb4hV/98krxJQC5eNOLTXjUXvnxQMTARDMXdR8xgmJuJb55P6UsLWYuv0gyVPiSZp5Y1JTqzCa7GwV6HYpMmBIzK80/JQ0KQt/bxqXL6eaQgVWbhJnaiqGyG+BxV8zR5ffZLBQ2fmDP4fm4dnrMfeCUo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=MfgPwjHH; arc=none smtp.client-ip=74.125.225.99 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MfgPwjHH" Received: by mail-wr2-f35.google.com with SMTP id ffacd0b85a97d-48b059eae96so326981f8f.0 for ; Fri, 02 Oct 2026 16:10:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790982645; x=1791587445; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=lioJcKUCBYULewz3rYkxIVZrrHZaGImjRN4lkx+YRX0=; b=MfgPwjHHF2B7ArXvMea39d1iDFosj4mu5c3wZJXAtaAIKmjQqXIBfqNoOhNlboVawZ AUTUPTygcnbal9Myo2f3tAeORtTDsmCyiCskk62O8NrB+7lM5k4WOCvOFb0dpORUowyq ytdcuoDML9TykaB24q1dGjaZwNtJlE63+yFi7Na/LU125vxalHzeWSEGIft520pf5pvU cOw2sL9R5ydArloHuV1ii2qRQzQoJiAAxboPePHRtLJ0abtu4yOF2WRLIUr5rWbJfPEv TWFbXdT9hgHL+Wv7sOIz3FIjaFJmFvA6XOjdYTIsHV4U/NCInDeo/5g+Lry/TLP3Y6dA Noiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790982645; x=1791587445; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=lioJcKUCBYULewz3rYkxIVZrrHZaGImjRN4lkx+YRX0=; b=YHiJKwazER4aSJIPF8t6JT7qaKLk2Gv3pSy4Kb/E1D4ym75PMMakzysr6FRCc+5bvX UXqiiCmFhPb+i6qAVXmNJMckW/JV41syLzBS9M3KfBfRyTO+X7cFqic4gTl0nuVIrJ4/ WHuTneCEIelE26Ff3liVwxPD2Pj/+Oh3NcVQxmvd+4E12J1N6qxnhOqd5EA5wZCTy071 duUUF+ImJwDOqsE3C8rap8Lmh9aP9sbpNSuSi8GC+dvIKVIRT1jhGlV1hZBw5HOcW4Dw XqofkwKWLRZWpBt4FblBx529Lzt9obpSZPQ20cxtUavaEV/0Vmn+96ma4LGHb5Fg5chi xhJg== X-Forwarded-Encrypted: i=1; AKwUvBzXpoxIYiWknSn0Hc+2Mzjb3R81XdZI5Vi5G2P/+7poDuffeu7J3jXltEndAQDdwzq8NCWxBMU3pLUPYtA=@vger.kernel.org X-Gm-Message-State: AFq9FYL8755cMPwmgclGYTGV6AO5jBhwoVbsEWnNIYlwxRdwd6nlQ9JL M9ML/BqN9rKfS5QlZRBkznICGbLenTJ7Cnnr0VmQxE+cKkLuRP7ifP84Uo9RLAr4 X-Gm-Gg: AYBFou14YDyH1dF0OugAmqsRZERGPMa/EKZaNzpiZIKgRvFHpC+BIguw5hpthUyWSZn rGXDmFwdc9uyEUkfiMa0wW4hUwIOZCjR5VjdELEslpO4+rqrvr34BqCFHtITj3Z2q6+ySR1URWf ViHHxO8kfUWLjiYKXc8woVMjH43uKEdiXLge8SeWHUdndWYFTGdQMM0+SLDfW05/h6+vNYzdAv4 0jKhEMsqklDJVGtoIPvhCdB7tIh5x0mKXmyNPacL4VOnIr3irJL4h6ZDUmt7dbFYoF42P2JDC23 qQLCR0na6evHrLRnTtcl4g4nKSAHrez9fwxGkc20HVa/Yk/cIYEa05Q9FRsVi0s8QDdecjeY6bv JzLrpJPs7ALLv8UjtJ5gxUmGi2j2Mv2TGO57BRvP43aHvSgfsJ6pBMFQ8vPla4Ez9jz/IWQBQQD dpkMAKx87iDSnz8czpasghDysmfM7CFLsw3h/tAvl/PfwLfn47dC7rLOxLwwbX8a3zQowLbc7d2 B0TT6CykLM/zxB8/ZC2W20cMD4tKAEiWf8sRliCSavlg43KSpylLdk5m0NlEnzHVb2VCEcFftOT P5EgX6QLM4GINaPhrdFTKuljBm+6nN8W X-Received: by 2002:a5d:5f8e:0:b0:487:bcc:2c08 with SMTP id ffacd0b85a97d-48b1271cd1dmr7264130f8f.14.1790982644873; Fri, 02 Oct 2026 16:10:44 -0700 (PDT) Received: from omarchy ([2a02:ff0:1e10:93f:ce47:40ff:fef1:ce77]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48b380fab11sm8372266f8f.16.2026.10.02.16.10.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Oct 2026 16:10:44 -0700 (PDT) From: Abdurrahman Karadag To: pkshih@realtek.com Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, rtl8821cerfe2@gmail.com, Abdurrahman Karadag Subject: [PATCH rtw-next 1/2] wifi: rtw88: pci: wake the TX queues when the rings are reset Date: Sat, 3 Oct 2026 02:10:12 +0300 Message-ID: <20261002231013.11792-2-abdurrahmankaradag19@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20261002231013.11792-1-abdurrahmankaradag19@gmail.com> References: <20261002231013.11792-1-abdurrahmankaradag19@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit For a queue stopped by the PCI TX ring-full path, ring->queue_stopped is normally cleared and the stop reason released only from the completion loop in rtw_pci_tx_isr(). When the rings are reset the pending descriptors are dropped and their skbs are freed directly by rtw_pci_free_tx_ring_skbs(), so that loop never runs for them. The flag and the stop reason both survive the reset, and because the ring is now empty no completion will ever arrive to clear them. Any queue stopped that way stays stopped. This makes ieee80211_restart_hw() unable to recover a device that stopped a queue before the restart, which is the opposite of what the recovery is for. Reproduced on an RTL8821CE by pausing TX in hardware, which freezes the read index while the driver keeps submitting, the same shape the chip shows when it wedges on its own: # echo "522 f 1" > /sys/kernel/debug/ieee80211/phy0/rtw88/write_reg # ... push traffic until the ring fills ... BE 0x3a8: 0x0081007f, avail_desc() 1, BE queue stop reason 0x1 # (call rtw_fw_recovery() from a debug build) firmware crash, start reset and recover ieee80211 phy1: Hardware restart was requested wlan0: associated REG_TXPAUSE 0x00, BE 0x3a8: 0x00000000, ring empty BE queue stop reason 0x1, 100% packet loss, no recovery in 90 s The station reassociated twice during those 90 s, so the link was fine; only the queue was still stopped. With this patch the same sequence clears the stop reason and traffic returns within 2 s. Record the queue mappings this path stops and release them both from the completion loop and when the reset empties the ring. It has to be a set rather than one value: the stop runs after every submission that leaves fewer than two descriptors, rtw_pci_tx_write_data() still accepts a frame while one is left, and rtw_tx_queue_mapping() places management frames on the MGMT ring and multicast on HI0 whatever their skb queue mapping is, so one ring can stop two different queues before it is emptied. Keeping only the last one would leave the other stopped for good. Recording the mappings also limits the wake to the queues this ring-full path actually stopped, instead of waking every mac80211 queue. Fixes: e3037485c68e ("rtw88: new Realtek 802.11ac driver") Signed-off-by: Abdurrahman Karadag --- drivers/net/wireless/realtek/rtw88/pci.c | 45 ++++++++++++++++++++---- drivers/net/wireless/realtek/rtw88/pci.h | 1 + 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index 66d2e5f..ff751bf 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -473,9 +473,41 @@ static void rtw_pci_reset_buf_desc(struct rtw_dev *rtwdev) BIT_CLR_H2CQ_HOST_IDX | BIT_CLR_H2CQ_HW_IDX); } +static void rtw_pci_wake_stopped_queues(struct rtw_dev *rtwdev, + struct rtw_pci_tx_ring *ring) +{ + unsigned long q; + + for_each_set_bit(q, &ring->stopped_queues, rtwdev->hw->queues) + ieee80211_wake_queue(rtwdev->hw, q); + + ring->stopped_queues = 0; + ring->queue_stopped = false; +} + static void rtw_pci_reset_trx_ring(struct rtw_dev *rtwdev) { + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + struct rtw_pci_tx_ring *ring; + enum rtw_tx_queue_type queue; + rtw_pci_reset_buf_desc(rtwdev); + + /* + * The rings are empty again, so nothing is left whose completion + * could reach the wake in rtw_pci_tx_isr(). Release the queues this + * path stopped - the stop reasons it set are cleared nowhere else, + * and over an empty ring no completion will ever arrive to clear + * them. + */ + for (queue = 0; queue < RTK_MAX_TX_QUEUE_NUM; queue++) { + ring = &rtwpci->tx_rings[queue]; + + if (!ring->queue_stopped) + continue; + + rtw_pci_wake_stopped_queues(rtwdev, ring); + } } static void rtw_pci_enable_interrupt(struct rtw_dev *rtwdev, @@ -930,7 +962,10 @@ static int rtw_pci_tx_write(struct rtw_dev *rtwdev, ring = &rtwpci->tx_rings[queue]; spin_lock_bh(&rtwpci->irq_lock); if (avail_desc(ring->r.wp, ring->r.rp, ring->r.len) < 2) { - ieee80211_stop_queue(rtwdev->hw, skb_get_queue_mapping(skb)); + u16 q_map = skb_get_queue_mapping(skb); + + ieee80211_stop_queue(rtwdev->hw, q_map); + set_bit(q_map, &ring->stopped_queues); ring->queue_stopped = true; } spin_unlock_bh(&rtwpci->irq_lock); @@ -949,7 +984,6 @@ static void rtw_pci_tx_isr(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci, u32 count; u32 bd_idx_addr; u32 bd_idx, cur_rp, rp_idx; - u16 q_map; ring = &rtwpci->tx_rings[hw_queue]; @@ -981,11 +1015,8 @@ static void rtw_pci_tx_isr(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci, } if (ring->queue_stopped && - avail_desc(ring->r.wp, rp_idx, ring->r.len) > 4) { - q_map = skb_get_queue_mapping(skb); - ieee80211_wake_queue(hw, q_map); - ring->queue_stopped = false; - } + avail_desc(ring->r.wp, rp_idx, ring->r.len) > 4) + rtw_pci_wake_stopped_queues(rtwdev, ring); if (++rp_idx >= ring->r.len) rp_idx = 0; diff --git a/drivers/net/wireless/realtek/rtw88/pci.h b/drivers/net/wireless/realtek/rtw88/pci.h index 8ffdea1..04630d1 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.h +++ b/drivers/net/wireless/realtek/rtw88/pci.h @@ -188,6 +188,7 @@ struct rtw_pci_tx_ring { struct rtw_pci_ring r; struct sk_buff_head queue; bool queue_stopped; + unsigned long stopped_queues; }; struct rtw_pci_rx_buffer_desc { -- 2.55.0