From 19b5d0918ba159bdb2ad248afe172502f558d65e Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Tue, 3 Feb 2026 23:55:31 +0800 Subject: [PATCH] wifi: mt76: avoid to set ACK for MCU command if wait_resp is not set When wait_resp is not set but the ACK option is enabled in the MCU TXD, the ACK event is enqueued to the MCU event queue without being dequeued by the original MCU command request. Any orphaned ACK events will only be removed from the queue when another MCU command requests a response. Due to sequence index mismatches, these events are discarded one by one until a matching sequence index is found. However, if several MCU commands that do not require a response continue to fill up the event queue, there is a risk that when an MCU command with wait_resp enabled is issued, it may dequeue the wrong event skb, especially if the queue contains events with all possible sequence indices. Signed-off-by: StanleyYP Wang Signed-off-by: Shayne Chen Link: https://patch.msgid.link/20260203155532.1098290-3-shayne.chen@mediatek.com Signed-off-by: Felix Fietkau --- mcu.c | 2 +- mt7996/mcu.c | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/mcu.c b/mcu.c index 535c3d8a..cbfb3bbe 100644 --- a/mcu.c +++ b/mcu.c @@ -98,7 +98,7 @@ retry: /* orig skb might be needed for retry, mcu_skb_send_msg consumes it */ if (orig_skb) skb_get(orig_skb); - ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq); + ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, wait_resp ? &seq : NULL); if (ret < 0) goto out; diff --git a/mt7996/mcu.c b/mt7996/mcu.c index 42f82519..164659b9 100644 --- a/mt7996/mcu.c +++ b/mt7996/mcu.c @@ -325,13 +325,12 @@ mt7996_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, uni_txd->pkt_type = MCU_PKT_ID; uni_txd->seq = seq; - if (cmd & __MCU_CMD_FIELD_QUERY) - uni_txd->option = MCU_CMD_UNI_QUERY_ACK; - else - uni_txd->option = MCU_CMD_UNI_EXT_ACK; + uni_txd->option = MCU_CMD_UNI; + if (!(cmd & __MCU_CMD_FIELD_QUERY)) + uni_txd->option |= MCU_CMD_SET; - if (mcu_cmd == MCU_UNI_CMD_SDO) - uni_txd->option &= ~MCU_CMD_ACK; + if (wait_seq) + uni_txd->option |= MCU_CMD_ACK; if ((cmd & __MCU_CMD_FIELD_WA) && (cmd & __MCU_CMD_FIELD_WM)) uni_txd->s2d_index = MCU_S2D_H2CN;