Re: [RFC PATCH] ath11k: add ath11k_mac_op_flush_sta to properly flush pending packets

Florian Maurer <[email protected]>
Newsgroups org.infradead.lists.ath11k,org.kernel.vger.linux-wireless
Message-ID <GV1P250MB14330DE9B959725A5EE6DC7FE8CBA@GV1P250MB1433.EURP250.PROD.OUTLOOK.COM>
On Wed, 2025-10-08 at 08:09 +0200, Sebastian Gottschall wrote:
> Am 07.10.2025 um 15:59 schrieb Florian Maurer:
> > On Tue, 2025-10-07 at 14:38 +0200, Sebastian Gottschall wrote:
> > > Am 07.10.2025 um 10:11 schrieb Florian Maurer:
> > > 
> > > > When a STA is marked as no longer authorized, if the driver doesn't
> > > > implement flush_sta(), mac80211 calls ieee80211_flush_queues() to
> > > > flush hardware queues to avoid sending unencrypted frames.
> > > > 
> > > > This has became a problem for ath11k because ieee80211_flush_queues()
> > > > will stop all traffic and call ath11k_flush, which waits until the
> > > > whole HW queue is empty. In a busy environment this will trigger a
> > > > timeout warning and stalls other STAs.
> > > > 
> > > > Fix this by implementing flush_sta method using WMI command to flush
> > > > frames of a specific STA.
> > > > Flushed frames will be marked as discard in tx complete indication.
> > > > 
> > > > warning print "ath11k c000000.wifi: failed to flush transmit queue 0"
> > > > was observed on various openwrt devices, and is fixed through this patch.
> > > > 
> > > > Signed-off-by: Florian Maurer <[email protected]>
> > > > Tested-by: Florian Maurer  <[email protected]>
> > > > Co-authored-by: Benjamin Berg <[email protected]>
> > > > Tested-by: Flole <[email protected]>
> > > > ---
> > > > We tested this patch and it solved the problem of flushing the transmit
> > > > queues taking too long when the AP is busy.
> > > > We did not confirm if this flush is implemented to guarantee that no
> > > > unencrypted frames are sent out on station removal.
> > > > Could someone with more knowledge about the firmware behavior check
> > > > wether this approach is feasible or if a different approach should be
> > > > taken.
> > > > It is not clear to me if the approach taken in "wifi: ath10k: Flush
> > > > only requested txq in ath10k_flush()" might be better.
> > > > https://lore.kernel.org/linux-wireless/01d859e8e574a1f5d0b916333fe0b5cda859af9b.1732293922.git.repk@triplefau.lt/
> > > > 
> > > > Regards
> > > > Florian
> > > > 
> > > >    drivers/net/wireless/ath/ath11k/mac.c | 19 +++++++++++++++++++
> > > >    1 file changed, 19 insertions(+)
> > > > 
> > > > diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
> > > > index 106e2530b64e..a94649edd4ed 100644
> > > > --- a/drivers/net/wireless/ath/ath11k/mac.c
> > > > +++ b/drivers/net/wireless/ath/ath11k/mac.c
> > > > @@ -8330,6 +8330,24 @@ static void ath11k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *v
> > > >    	ath11k_mac_flush_tx_complete(ar);
> > > >    }
> > > >    
> > > > +static void ath11k_mac_op_flush_sta(struct ieee80211_hw *hw,
> > > > +							struct ieee80211_vif *vif,
> > > > +			    			struct ieee80211_sta *sta)
> > > > +{
> > > > +	struct ath11k_vif *arvif = (void *)vif->drv_priv;
> > > > +	struct ath11k *ar = hw->priv;
> > > > +	struct peer_flush_params params = {
> > > > +		.peer_tid_bitmap = 0xFF,
> > > > +		.vdev_id = arvif->vdev_id,
> > > > +	};
> > > > +	int ret = 0;
> > > > +
> > > > +	ret = ath11k_wmi_send_peer_flush_tids_cmd(ar, sta->addr, &params);
> > > > +	if (ret)
> > > > +		ath11k_warn(ar->ab, "failed to flush sta (sta %pM)\n",
> > > > +			    sta->addr);
> > > > +}
> > > > +
> > > >    static bool
> > > >    ath11k_mac_has_single_legacy_rate(struct ath11k *ar,
> > > >    				  enum nl80211_band band,
> > > > @@ -9920,6 +9938,7 @@ static const struct ieee80211_ops ath11k_ops = {
> > > >    	.set_bitrate_mask		= ath11k_mac_op_set_bitrate_mask,
> > > >    	.get_survey			= ath11k_mac_op_get_survey,
> > > >    	.flush				= ath11k_mac_op_flush,
> > > > +	.flush_sta			= ath11k_mac_op_flush_sta,
> > > >    	.sta_statistics			= ath11k_mac_op_sta_statistics,
> > > >    	CFG80211_TESTMODE_CMD(ath11k_tm_cmd)
> > > >    
> > > why is peer_tid_bitmap 0xff instead of 0xffffffff?
> > When setting it to 0xffffffff it fails with:
> > Assertion !CHK_TID_FLG(ptid, WAL_TID_IN_SCHEDQ) failedparam0 :zero,
> > param1 :zero, param2 :zero.
> > leading to a device reboot. See:
> > https://github.com/openwrt/openwrt/pull/20293#issuecomment-3367037471
> > It works with 0xffff though, but I don't quite know what the firmware
> > does/expects here. Maybe someone with more information can help.
> due the sources. BIT 17 has a special purpose named WMI_MGMT_TID
> all bits can be masked but bit 17 as it seems
> 
Setting more than 0xFF leads to firmware crashes in AP/MESH mode.
Setting bit 17 in AP mode crashes as well.

There is reason to believe that bits 25-28 should be flushed
in STA mode, which is done in the v3 of this patch:
https://patchwork.kernel.org/project/linux-wireless/patch/GV1P250MB1433E723AF90A69AEBB696DAE8CBA@GV1P250MB1433.EURP250.PROD.OUTLOOK.COM/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.