wifi: mt76: mt7925: load the appropriate CLC data based on hardware type
authorMing Yen Hsieh <mingyen.hsieh@mediatek.com>
Tue, 4 Mar 2025 11:36:44 +0000 (19:36 +0800)
committerFelix Fietkau <nbd@nbd.name>
Wed, 19 Mar 2025 13:47:03 +0000 (14:47 +0100)
Read the EEPROM to determine the hardware type and uses this to load the
correct CLC data.

Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
Link: https://patch.msgid.link/20250304113649.867387-1-mingyen.hsieh@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h

index 17baa653dab15a3dd763a3e5ce07398fbcb1127d..0f58a5afb77a56e1925756ffe094ff6fbf282aaa 100644 (file)
@@ -627,6 +627,54 @@ int mt7925_mcu_uni_rx_ba(struct mt792x_dev *dev,
                                 enable, false);
 }
 
+static int mt7925_mcu_read_eeprom(struct mt792x_dev *dev, u32 offset, u8 *val)
+{
+       struct {
+               u8 rsv[4];
+
+               __le16 tag;
+               __le16 len;
+
+               __le32 addr;
+               __le32 valid;
+               u8 data[MT7925_EEPROM_BLOCK_SIZE];
+       } __packed req = {
+               .tag = cpu_to_le16(1),
+               .len = cpu_to_le16(sizeof(req) - 4),
+               .addr = cpu_to_le32(round_down(offset,
+                                   MT7925_EEPROM_BLOCK_SIZE)),
+       };
+       struct evt {
+               u8 rsv[4];
+
+               __le16 tag;
+               __le16 len;
+
+               __le32 ver;
+               __le32 addr;
+               __le32 valid;
+               __le32 size;
+               __le32 magic_num;
+               __le32 type;
+               __le32 rsv1[4];
+               u8 data[32];
+       } __packed *res;
+       struct sk_buff *skb;
+       int ret;
+
+       ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WM_UNI_CMD_QUERY(EFUSE_CTRL),
+                                       &req, sizeof(req), true, &skb);
+       if (ret)
+               return ret;
+
+       res = (struct evt *)skb->data;
+       *val = res->data[offset % MT7925_EEPROM_BLOCK_SIZE];
+
+       dev_kfree_skb(skb);
+
+       return 0;
+}
+
 static int mt7925_load_clc(struct mt792x_dev *dev, const char *fw_name)
 {
        const struct mt76_connac2_fw_trailer *hdr;
@@ -635,13 +683,20 @@ static int mt7925_load_clc(struct mt792x_dev *dev, const char *fw_name)
        struct mt76_dev *mdev = &dev->mt76;
        struct mt792x_phy *phy = &dev->phy;
        const struct firmware *fw;
+       u8 *clc_base = NULL, hw_encap = 0;
        int ret, i, len, offset = 0;
-       u8 *clc_base = NULL;
 
        if (mt7925_disable_clc ||
            mt76_is_usb(&dev->mt76))
                return 0;
 
+       if (mt76_is_mmio(&dev->mt76)) {
+               ret = mt7925_mcu_read_eeprom(dev, MT_EE_HW_TYPE, &hw_encap);
+               if (ret)
+                       return ret;
+               hw_encap = u8_get_bits(hw_encap, MT_EE_HW_TYPE_ENCAP);
+       }
+
        ret = request_firmware(&fw, fw_name, mdev->dev);
        if (ret)
                return ret;
@@ -686,6 +741,10 @@ static int mt7925_load_clc(struct mt792x_dev *dev, const char *fw_name)
                if (phy->clc[clc->idx])
                        continue;
 
+               /* header content sanity */
+               if (u8_get_bits(clc->type, MT_EE_HW_TYPE_ENCAP) != hw_encap)
+                       continue;
+
                phy->clc[clc->idx] = devm_kmemdup(mdev->dev, clc,
                                                  le32_to_cpu(clc->len),
                                                  GFP_KERNEL);
index cb7b1a49fbd14ec09b39fda22005e004d5db8b91..073e433069e0e5832ea9cbe72921121ea998ecc6 100644 (file)
@@ -167,9 +167,12 @@ enum mt7925_eeprom_field {
        MT_EE_CHIP_ID =         0x000,
        MT_EE_VERSION =         0x002,
        MT_EE_MAC_ADDR =        0x004,
+       MT_EE_HW_TYPE =         0xa71,
        __MT_EE_MAX =           0x9ff
 };
 
+#define MT_EE_HW_TYPE_ENCAP     GENMASK(1, 0)
+
 enum {
        TXPWR_USER,
        TXPWR_EEPROM,