From 525c3eb2351f7292f4bc3ee276b6bc6e0614be5d Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Mon, 15 Jun 2026 16:21:37 -0500 Subject: [PATCH] wifi: mt76: mt7925: support new WoW pattern TLV Newer mt7925 firmware uses a shorter WoW pattern TLV with rsv[3]. Select the v2 layout based on the firmware build date, while keeping the old layout for older firmware. This also makes the WoW pattern handling compatible with newer devices such as MT7928. Tested-by: Stella Liu Signed-off-by: Sean Wang Link: https://patch.msgid.link/20260615212137.477893-1-sean.wang@kernel.org Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt7925/mcu.c | 30 +++++++++++++++++-- .../net/wireless/mediatek/mt76/mt7925/mcu.h | 3 ++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index c792c1befc1e..e7e553b4f716 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -11,6 +11,7 @@ #define MT_STA_BFER BIT(0) #define MT_STA_BFEE BIT(1) +#define MT7925_WOW_PATTERN_NEW_FW_DATE "20260414153105" static bool mt7925_vif_is_nan(struct ieee80211_vif *vif) { @@ -229,6 +230,23 @@ mt7925_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif, sizeof(req), true); } +static bool mt7925_mcu_wow_pattern_old_tlv(struct mt76_dev *dev) +{ + const char *fw_version = dev->hw->wiphy->fw_version; + const char *build_date = strrchr(fw_version, '-'); + + if (!is_mt7925(dev)) + return false; + + if (!build_date) + return false; + + build_date++; + + return strncmp(build_date, MT7925_WOW_PATTERN_NEW_FW_DATE, + strlen(MT7925_WOW_PATTERN_NEW_FW_DATE)) < 0; +} + static int mt7925_mcu_set_wow_pattern(struct mt76_dev *dev, struct ieee80211_vif *vif, @@ -238,6 +256,8 @@ mt7925_mcu_set_wow_pattern(struct mt76_dev *dev, struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt7925_wow_pattern_tlv *tlv; struct sk_buff *skb; + int tlv_len; + bool old_tlv; struct { u8 bss_idx; u8 pad[3]; @@ -245,14 +265,18 @@ mt7925_mcu_set_wow_pattern(struct mt76_dev *dev, .bss_idx = mvif->idx, }; - skb = mt76_mcu_msg_alloc(dev, NULL, sizeof(hdr) + sizeof(*tlv)); + old_tlv = mt7925_mcu_wow_pattern_old_tlv(dev); + tlv_len = old_tlv ? sizeof(struct mt7925_wow_pattern_tlv) : + MT7925_WOW_PATTERN_TLV_V2_SIZE; + + skb = mt76_mcu_msg_alloc(dev, NULL, sizeof(hdr) + tlv_len); if (!skb) return -ENOMEM; skb_put_data(skb, &hdr, sizeof(hdr)); - tlv = (struct mt7925_wow_pattern_tlv *)skb_put(skb, sizeof(*tlv)); + tlv = (struct mt7925_wow_pattern_tlv *)skb_put_zero(skb, tlv_len); tlv->tag = cpu_to_le16(UNI_SUSPEND_WOW_PATTERN); - tlv->len = cpu_to_le16(sizeof(*tlv)); + tlv->len = cpu_to_le16(tlv_len); tlv->bss_idx = 0xF; tlv->data_len = pattern->pattern_len; tlv->enable = enable; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h index 1613c4765186..154f792a56bc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h @@ -608,6 +608,9 @@ struct mt7925_wow_pattern_tlv { u8 rsv[4]; }; +#define MT7925_WOW_PATTERN_TLV_V2_SIZE \ + (offsetof(struct mt7925_wow_pattern_tlv, rsv) + 3) + struct roc_acquire_tlv { __le16 tag; __le16 len;