wifi: mt76: mt7996: ensure 4-byte alignment for beacon commands
authorBenjamin Lin <benjamin-jw.lin@mediatek.com>
Fri, 26 Jan 2024 09:09:16 +0000 (17:09 +0800)
committerFelix Fietkau <nbd@nbd.name>
Thu, 22 Feb 2024 08:55:18 +0000 (09:55 +0100)
If TLV includes beacon content, its length might not be 4-byte aligned.
Make sure the length is aligned before sending beacon commands to FW.

Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
drivers/net/wireless/mediatek/mt76/mt7996/mcu.h

index 024e73c948d8619de4477893d9d6fb896b563e71..e46a9d4920a8e22161e87e8a5c79ff1bf88bb236 100644 (file)
@@ -732,13 +732,10 @@ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb)
 static struct tlv *
 mt7996_mcu_add_uni_tlv(struct sk_buff *skb, u16 tag, u16 len)
 {
-       struct tlv *ptlv, tlv = {
-               .tag = cpu_to_le16(tag),
-               .len = cpu_to_le16(len),
-       };
+       struct tlv *ptlv = skb_put(skb, len);
 
-       ptlv = skb_put(skb, len);
-       memcpy(ptlv, &tlv, sizeof(tlv));
+       ptlv->tag = cpu_to_le16(tag);
+       ptlv->len = cpu_to_le16(len);
 
        return ptlv;
 }
@@ -2522,7 +2519,7 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
        info = IEEE80211_SKB_CB(skb);
        info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx);
 
-       len = sizeof(*bcn) + MT_TXD_SIZE + skb->len;
+       len = ALIGN(sizeof(*bcn) + MT_TXD_SIZE + skb->len, 4);
        tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_BCN_CONTENT, len);
        bcn = (struct bss_bcn_content_tlv *)tlv;
        bcn->enable = en;
@@ -2591,8 +2588,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
        info->band = band;
        info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx);
 
-       len = sizeof(*discov) + MT_TXD_SIZE + skb->len;
-
+       len = ALIGN(sizeof(*discov) + MT_TXD_SIZE + skb->len, 4);
        tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_OFFLOAD, len);
 
        discov = (struct bss_inband_discovery_tlv *)tlv;
index 36cacc495c75d3854ed3ea297cc68f3b91860f72..43468bcaffc6dd8e972acbf1e1fdc6a1927ba053 100644 (file)
@@ -800,10 +800,10 @@ enum {
                                         sizeof(struct sta_rec_hdr_trans) +     \
                                         sizeof(struct tlv))
 
-#define MT7996_MAX_BEACON_SIZE         1342
+#define MT7996_MAX_BEACON_SIZE         1338
 #define MT7996_BEACON_UPDATE_SIZE      (sizeof(struct bss_req_hdr) +           \
                                         sizeof(struct bss_bcn_content_tlv) +   \
-                                        MT_TXD_SIZE +                          \
+                                        4 + MT_TXD_SIZE +                      \
                                         sizeof(struct bss_bcn_cntdwn_tlv) +    \
                                         sizeof(struct bss_bcn_mbss_tlv))
 #define MT7996_MAX_BSS_OFFLOAD_SIZE    (MT7996_MAX_BEACON_SIZE +               \