mt76: mt7921: Add mt7922 support
authorDeren Wu <deren.wu@mediatek.com>
Thu, 15 Jul 2021 17:34:19 +0000 (01:34 +0800)
committerFelix Fietkau <nbd@nbd.name>
Wed, 20 Oct 2021 08:36:30 +0000 (10:36 +0200)
Add new chip mt7922 in mt7921 module with following items
1. new chip ID / fw bin name
2. is_mt7922()
check chip type for different fw files
3. mt7921_get_data_mode()
check security type of fw (backward compatible)

Co-developed-by: Jimmy Hu <Jimmy.Hu@mediatek.com>
Signed-off-by: Jimmy Hu <Jimmy.Hu@mediatek.com>
Signed-off-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt76_connac.h
drivers/net/wireless/mediatek/mt76/mt7921/eeprom.c
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
drivers/net/wireless/mediatek/mt76/mt7921/pci.c

index f49d97d0a1c51d3d2304458737d28e7193861a5a..e7f01c2978a28d0db4c1088ebe44a6a4a95c3598 100644 (file)
@@ -85,9 +85,14 @@ struct mt76_connac_coredump {
 
 extern const struct wiphy_wowlan_support mt76_connac_wowlan_support;
 
+static inline bool is_mt7922(struct mt76_dev *dev)
+{
+       return mt76_chip(dev) == 0x7922;
+}
+
 static inline bool is_mt7921(struct mt76_dev *dev)
 {
-       return mt76_chip(dev) == 0x7961;
+       return mt76_chip(dev) == 0x7961 || is_mt7922(dev);
 }
 
 static inline bool is_mt7663(struct mt76_dev *dev)
index 691d14a1a7bf7464301233387c00b5bda04f0585..4d0a4aeac6bf109a52897d35f801407027496b6e 100644 (file)
@@ -36,6 +36,7 @@ static int mt7921_check_eeprom(struct mt7921_dev *dev)
        val = get_unaligned_le16(eeprom);
 
        switch (val) {
+       case 0x7922:
        case 0x7961:
                return 0;
        default:
index 8d3cf4f9914115ba037440466486111b77d7ba1b..b686d62295ce7f536eb4efaa0c571f0253be3ebe 100644 (file)
@@ -82,9 +82,17 @@ struct mt7921_fw_region {
 #define FW_START_OVERRIDE              BIT(0)
 #define FW_START_WORKING_PDA_CR4       BIT(2)
 
+#define PATCH_SEC_NOT_SUPPORT          GENMASK(31, 0)
 #define PATCH_SEC_TYPE_MASK            GENMASK(15, 0)
 #define PATCH_SEC_TYPE_INFO            0x2
 
+#define PATCH_SEC_ENC_TYPE_MASK                GENMASK(31, 24)
+#define PATCH_SEC_ENC_TYPE_PLAIN               0x00
+#define PATCH_SEC_ENC_TYPE_AES                 0x01
+#define PATCH_SEC_ENC_TYPE_SCRAMBLE            0x02
+#define PATCH_SEC_ENC_SCRAMBLE_INFO_MASK       GENMASK(15, 0)
+#define PATCH_SEC_ENC_AES_KEY_MASK             GENMASK(7, 0)
+
 #define to_wcid_lo(id)                 FIELD_GET(GENMASK(7, 0), (u16)id)
 #define to_wcid_hi(id)                 FIELD_GET(GENMASK(9, 8), (u16)id)
 
@@ -742,6 +750,46 @@ static int mt7921_driver_own(struct mt7921_dev *dev)
        return 0;
 }
 
+static u32 mt7921_get_data_mode(struct mt7921_dev *dev, u32 info)
+{
+       u32 mode = DL_MODE_NEED_RSP;
+
+       if (info == PATCH_SEC_NOT_SUPPORT)
+               return mode;
+
+       switch (FIELD_GET(PATCH_SEC_ENC_TYPE_MASK, info)) {
+       case PATCH_SEC_ENC_TYPE_PLAIN:
+               break;
+       case PATCH_SEC_ENC_TYPE_AES:
+               mode |= DL_MODE_ENCRYPT;
+               mode |= FIELD_PREP(DL_MODE_KEY_IDX,
+                               (info & PATCH_SEC_ENC_AES_KEY_MASK)) & DL_MODE_KEY_IDX;
+               mode |= DL_MODE_RESET_SEC_IV;
+               break;
+       case PATCH_SEC_ENC_TYPE_SCRAMBLE:
+               mode |= DL_MODE_ENCRYPT;
+               mode |= DL_CONFIG_ENCRY_MODE_SEL;
+               mode |= DL_MODE_RESET_SEC_IV;
+               break;
+       default:
+               dev_err(dev->mt76.dev, "Encryption type not support!\n");
+       }
+
+       return mode;
+}
+
+static char *mt7921_patch_name(struct mt7921_dev *dev)
+{
+       char *ret;
+
+       if (is_mt7922(&dev->mt76))
+               ret = MT7922_ROM_PATCH;
+       else
+               ret = MT7921_ROM_PATCH;
+
+       return ret;
+}
+
 static int mt7921_load_patch(struct mt7921_dev *dev)
 {
        const struct mt7921_patch_hdr *hdr;
@@ -759,7 +807,7 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
                return -EAGAIN;
        }
 
-       ret = request_firmware(&fw, MT7921_ROM_PATCH, dev->mt76.dev);
+       ret = request_firmware(&fw, mt7921_patch_name(dev), dev->mt76.dev);
        if (ret)
                goto out;
 
@@ -777,7 +825,8 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
        for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) {
                struct mt7921_patch_sec *sec;
                const u8 *dl;
-               u32 len, addr;
+               u32 len, addr, mode;
+               u32 sec_info = 0;
 
                sec = (struct mt7921_patch_sec *)(fw->data + sizeof(*hdr) +
                                                  i * sizeof(*sec));
@@ -790,9 +839,11 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
                addr = be32_to_cpu(sec->info.addr);
                len = be32_to_cpu(sec->info.len);
                dl = fw->data + be32_to_cpu(sec->offs);
+               sec_info = be32_to_cpu(sec->info.sec_key_idx);
+               mode = mt7921_get_data_mode(dev, sec_info);
 
                ret = mt76_connac_mcu_init_download(&dev->mt76, addr, len,
-                                                   DL_MODE_NEED_RSP);
+                                                   mode);
                if (ret) {
                        dev_err(dev->mt76.dev, "Download request failed\n");
                        goto out;
@@ -889,13 +940,25 @@ mt7921_mcu_send_ram_firmware(struct mt7921_dev *dev,
        return mt76_connac_mcu_start_firmware(&dev->mt76, override, option);
 }
 
+static char *mt7921_ram_name(struct mt7921_dev *dev)
+{
+       char *ret;
+
+       if (is_mt7922(&dev->mt76))
+               ret = MT7922_FIRMWARE_WM;
+       else
+               ret = MT7921_FIRMWARE_WM;
+
+       return ret;
+}
+
 static int mt7921_load_ram(struct mt7921_dev *dev)
 {
        const struct mt7921_fw_trailer *hdr;
        const struct firmware *fw;
        int ret;
 
-       ret = request_firmware(&fw, MT7921_FIRMWARE_WM, dev->mt76.dev);
+       ret = request_firmware(&fw, mt7921_ram_name(dev), dev->mt76.dev);
        if (ret)
                return ret;
 
index 6e9e4dfb3928fdac7c8f382e4e5f69c45a11dd4a..51bcaa59926846eb26ae27b7c09598dc332db1da 100644 (file)
@@ -33,6 +33,9 @@
 #define MT7921_FIRMWARE_WM             "mediatek/WIFI_RAM_CODE_MT7961_1.bin"
 #define MT7921_ROM_PATCH               "mediatek/WIFI_MT7961_patch_mcu_1_2_hdr.bin"
 
+#define MT7922_FIRMWARE_WM             "mediatek/WIFI_RAM_CODE_MT7922_1.bin"
+#define MT7922_ROM_PATCH               "mediatek/WIFI_MT7922_patch_mcu_1_1_hdr.bin"
+
 #define MT7921_EEPROM_SIZE             3584
 #define MT7921_TOKEN_SIZE              8192
 
index 33782e1ee312875290144319e832fbfd7cc848a4..97ca8290881fc0448f53cdfda4dbd8861f919ab3 100644 (file)
@@ -14,6 +14,7 @@
 
 static const struct pci_device_id mt7921_pci_device_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7961) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7922) },
        { },
 };
 
@@ -336,6 +337,8 @@ module_pci_driver(mt7921_pci_driver);
 MODULE_DEVICE_TABLE(pci, mt7921_pci_device_table);
 MODULE_FIRMWARE(MT7921_FIRMWARE_WM);
 MODULE_FIRMWARE(MT7921_ROM_PATCH);
+MODULE_FIRMWARE(MT7922_FIRMWARE_WM);
+MODULE_FIRMWARE(MT7922_ROM_PATCH);
 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
 MODULE_LICENSE("Dual BSD/GPL");