mt76: mt7663: add the possibility to load firmware v2
authorLorenzo Bianconi <lorenzo@kernel.org>
Tue, 28 Apr 2020 13:34:09 +0000 (15:34 +0200)
committerFelix Fietkau <nbd@nbd.name>
Tue, 12 May 2020 17:52:33 +0000 (19:52 +0200)
mt7663 firmware v2 is used for embedded devices since it has more completed
features in AP mode.
Add the capability to specify which firmware load first (v3 or v2)
using prefer_offload_fw kernel parameter and fallback to the other one
if the selected firmware fails to load

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
drivers/net/wireless/mediatek/mt76/mt7615/pci.c
drivers/net/wireless/mediatek/mt76/mt7615/usb.c

index 8f745c64e9d9027dddb55a274c88c7f9adc58bed..f4966d29d09816ce09dda0e84737b29b43b9e9a1 100644 (file)
 #include "mac.h"
 #include "eeprom.h"
 
+static bool prefer_offload_fw = true;
+module_param(prefer_offload_fw, bool, 0644);
+MODULE_PARM_DESC(prefer_offload_fw,
+                "Prefer client mode offload firmware (MT7663)");
+
 struct mt7615_patch_hdr {
        char build_date[16];
        char platform[4];
@@ -1728,7 +1733,7 @@ static int mt7615_load_patch(struct mt7615_dev *dev, u32 addr, const char *name)
                return -EAGAIN;
        }
 
-       ret = request_firmware(&fw, name, dev->mt76.dev);
+       ret = firmware_request_nowarn(&fw, name, dev->mt76.dev);
        if (ret)
                goto out;
 
@@ -2081,8 +2086,49 @@ out:
        return ret;
 }
 
+static int
+mt7663_load_rom_patch(struct mt7615_dev *dev, const char **n9_firmware)
+{
+       const char *selected_rom, *secondary_rom = MT7663_ROM_PATCH;
+       const char *primary_rom = MT7663_OFFLOAD_ROM_PATCH;
+       int ret;
+
+       if (!prefer_offload_fw) {
+               secondary_rom = MT7663_OFFLOAD_ROM_PATCH;
+               primary_rom = MT7663_ROM_PATCH;
+       }
+       selected_rom = primary_rom;
+
+       ret = mt7615_load_patch(dev, MT7663_PATCH_ADDRESS, primary_rom);
+       if (ret) {
+               dev_info(dev->mt76.dev, "%s not found, switching to %s",
+                        primary_rom, secondary_rom);
+               ret = mt7615_load_patch(dev, MT7663_PATCH_ADDRESS,
+                                       secondary_rom);
+               if (ret) {
+                       dev_err(dev->mt76.dev, "failed to load %s",
+                               secondary_rom);
+                       return ret;
+               }
+               selected_rom = secondary_rom;
+       }
+
+       if (!strcmp(selected_rom, MT7663_OFFLOAD_ROM_PATCH)) {
+               *n9_firmware = MT7663_OFFLOAD_FIRMWARE_N9;
+               dev->fw_ver = MT7615_FIRMWARE_V3;
+               dev->mcu_ops = &uni_update_ops;
+       } else {
+               *n9_firmware = MT7663_FIRMWARE_N9;
+               dev->fw_ver = MT7615_FIRMWARE_V2;
+               dev->mcu_ops = &sta_update_ops;
+       }
+
+       return 0;
+}
+
 int __mt7663_load_firmware(struct mt7615_dev *dev)
 {
+       const char *n9_firmware;
        int ret;
 
        ret = mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY);
@@ -2091,14 +2137,11 @@ int __mt7663_load_firmware(struct mt7615_dev *dev)
                return -EIO;
        }
 
-       ret = mt7615_load_patch(dev, MT7663_PATCH_ADDRESS, MT7663_ROM_PATCH);
+       ret = mt7663_load_rom_patch(dev, &n9_firmware);
        if (ret)
                return ret;
 
-       dev->fw_ver = MT7615_FIRMWARE_V3;
-       dev->mcu_ops = &uni_update_ops;
-
-       ret = mt7663_load_n9(dev, MT7663_FIRMWARE_N9);
+       ret = mt7663_load_n9(dev, n9_firmware);
        if (ret)
                return ret;
 
index 44eb3d8dca789d0f970b61cfb935fb2eedffb8ab..0476b9426b0315ff855ebf866b006904f9b46074 100644 (file)
 #define MT7615_FIRMWARE_V2             2
 #define MT7615_FIRMWARE_V3             3
 
-#define MT7663_ROM_PATCH               "mediatek/mt7663pr2h.bin"
-#define MT7663_FIRMWARE_N9              "mediatek/mt7663_n9_v3.bin"
+#define MT7663_OFFLOAD_ROM_PATCH       "mediatek/mt7663pr2h.bin"
+#define MT7663_OFFLOAD_FIRMWARE_N9     "mediatek/mt7663_n9_v3.bin"
+#define MT7663_ROM_PATCH               "mediatek/mt7663pr2h_rebb.bin"
+#define MT7663_FIRMWARE_N9             "mediatek/mt7663_n9_rebb.bin"
 
 #define MT7615_EEPROM_SIZE             1024
 #define MT7615_TOKEN_SIZE              4096
index 21b3ec29aa12273118c2f7cce945f37a955af9c1..f9469198cabd092fbdd4b37a404cefcbf0bf0e1e 100644 (file)
@@ -68,5 +68,7 @@ MODULE_DEVICE_TABLE(pci, mt7615_pci_device_table);
 MODULE_FIRMWARE(MT7615_FIRMWARE_CR4);
 MODULE_FIRMWARE(MT7615_FIRMWARE_N9);
 MODULE_FIRMWARE(MT7615_ROM_PATCH);
+MODULE_FIRMWARE(MT7663_OFFLOAD_FIRMWARE_N9);
+MODULE_FIRMWARE(MT7663_OFFLOAD_ROM_PATCH);
 MODULE_FIRMWARE(MT7663_FIRMWARE_N9);
 MODULE_FIRMWARE(MT7663_ROM_PATCH);
index bcd131969923e5415b10d1c06db1494bea40b48f..9353175b139bce0c5fdbaa8d28639409dec8235d 100644 (file)
@@ -386,6 +386,8 @@ mt7663u_resume(struct usb_interface *intf)
 }
 
 MODULE_DEVICE_TABLE(usb, mt7615_device_table);
+MODULE_FIRMWARE(MT7663_OFFLOAD_FIRMWARE_N9);
+MODULE_FIRMWARE(MT7663_OFFLOAD_ROM_PATCH);
 MODULE_FIRMWARE(MT7663_FIRMWARE_N9);
 MODULE_FIRMWARE(MT7663_ROM_PATCH);