From: Vick Cheng mt7925_mcu_regval() always sent sizeof(req) - the full union - regardless of which member (basic reg or RF reg) was active. The two members differ in size, so the firmware received trailing zero bytes which it parsed as extra TLV entries, causing a dead loop. Pass the size of the active member instead of the union size. Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips") Signed-off-by: Vick Cheng --- drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index 5532e1722d17..64bba015f5f8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -90,6 +90,7 @@ int mt7925_mcu_regval(struct mt792x_dev *dev, u32 regidx, u32 *val, bool set) }; } __packed * res, req; struct sk_buff *skb; + int cmd_len; int ret; if (u32_get_bits(regidx, MT_RF_REG_HDR) == RF_REG_PREFIX) { @@ -98,20 +99,22 @@ int mt7925_mcu_regval(struct mt792x_dev *dev, u32 regidx, u32 *val, bool set) req.rf_reg.ant = cpu_to_le16(u32_get_bits(regidx, MT_RF_REG_ANT)); req.rf_reg.idx = cpu_to_le32(regidx); req.rf_reg.data = set ? cpu_to_le32(*val) : 0; + cmd_len = sizeof(req.__rsv) + sizeof(req.rf_reg); } else { req.reg.tag = cpu_to_le16(UNI_CMD_ACCESS_REG_BASIC); req.reg.len = cpu_to_le16(sizeof(req.reg)); req.reg.idx = cpu_to_le32(regidx); req.reg.data = set ? cpu_to_le32(*val) : 0; + cmd_len = sizeof(req.__rsv) + sizeof(req.reg); } if (set) return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(REG_ACCESS), - &req, sizeof(req), true); + &req, cmd_len, true); ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WM_UNI_CMD_QUERY(REG_ACCESS), - &req, sizeof(req), true, &skb); + &req, cmd_len, true, &skb); if (ret) return ret; -- 2.45.2