1 /* 2 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include <linux/kernel.h> 18 #include <linux/firmware.h> 19 #include <linux/delay.h> 20 21 #include "mt76x2.h" 22 #include "mcu.h" 23 #include "eeprom.h" 24 25 static int 26 mt76pci_load_rom_patch(struct mt76x02_dev *dev) 27 { 28 const struct firmware *fw = NULL; 29 struct mt76x02_patch_header *hdr; 30 bool rom_protect = !is_mt7612(dev); 31 int len, ret = 0; 32 __le32 *cur; 33 u32 patch_mask, patch_reg; 34 35 if (rom_protect && !mt76_poll(dev, MT_MCU_SEMAPHORE_03, 1, 1, 600)) { 36 dev_err(dev->mt76.dev, 37 "Could not get hardware semaphore for ROM PATCH\n"); 38 return -ETIMEDOUT; 39 } 40 41 if (mt76xx_rev(dev) >= MT76XX_REV_E3) { 42 patch_mask = BIT(0); 43 patch_reg = MT_MCU_CLOCK_CTL; 44 } else { 45 patch_mask = BIT(1); 46 patch_reg = MT_MCU_COM_REG0; 47 } 48 49 if (rom_protect && (mt76_rr(dev, patch_reg) & patch_mask)) { 50 dev_info(dev->mt76.dev, "ROM patch already applied\n"); 51 goto out; 52 } 53 54 ret = request_firmware(&fw, MT7662_ROM_PATCH, dev->mt76.dev); 55 if (ret) 56 goto out; 57 58 if (!fw || !fw->data || fw->size <= sizeof(*hdr)) { 59 ret = -EIO; 60 dev_err(dev->mt76.dev, "Failed to load firmware\n"); 61 goto out; 62 } 63 64 hdr = (struct mt76x02_patch_header *)fw->data; 65 dev_info(dev->mt76.dev, "ROM patch build: %.15s\n", hdr->build_time); 66 67 mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ROM_PATCH_OFFSET); 68 69 cur = (__le32 *) (fw->data + sizeof(*hdr)); 70 len = fw->size - sizeof(*hdr); 71 mt76_wr_copy(dev, MT_MCU_ROM_PATCH_ADDR, cur, len); 72 73 mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0); 74 75 /* Trigger ROM */ 76 mt76_wr(dev, MT_MCU_INT_LEVEL, 4); 77 78 if (!mt76_poll_msec(dev, patch_reg, patch_mask, patch_mask, 2000)) { 79 dev_err(dev->mt76.dev, "Failed to load ROM patch\n"); 80 ret = -ETIMEDOUT; 81 } 82 83 out: 84 /* release semaphore */ 85 if (rom_protect) 86 mt76_wr(dev, MT_MCU_SEMAPHORE_03, 1); 87 release_firmware(fw); 88 return ret; 89 } 90 91 static int 92 mt76pci_load_firmware(struct mt76x02_dev *dev) 93 { 94 const struct firmware *fw; 95 const struct mt76x02_fw_header *hdr; 96 int len, ret; 97 __le32 *cur; 98 u32 offset, val; 99 100 ret = request_firmware(&fw, MT7662_FIRMWARE, dev->mt76.dev); 101 if (ret) 102 return ret; 103 104 if (!fw || !fw->data || fw->size < sizeof(*hdr)) 105 goto error; 106 107 hdr = (const struct mt76x02_fw_header *)fw->data; 108 109 len = sizeof(*hdr); 110 len += le32_to_cpu(hdr->ilm_len); 111 len += le32_to_cpu(hdr->dlm_len); 112 113 if (fw->size != len) 114 goto error; 115 116 val = le16_to_cpu(hdr->fw_ver); 117 dev_info(dev->mt76.dev, "Firmware Version: %d.%d.%02d\n", 118 (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf); 119 120 val = le16_to_cpu(hdr->build_ver); 121 dev_info(dev->mt76.dev, "Build: %x\n", val); 122 dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time); 123 124 cur = (__le32 *) (fw->data + sizeof(*hdr)); 125 len = le32_to_cpu(hdr->ilm_len); 126 127 mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ILM_OFFSET); 128 mt76_wr_copy(dev, MT_MCU_ILM_ADDR, cur, len); 129 130 cur += len / sizeof(*cur); 131 len = le32_to_cpu(hdr->dlm_len); 132 133 if (mt76xx_rev(dev) >= MT76XX_REV_E3) 134 offset = MT_MCU_DLM_ADDR_E3; 135 else 136 offset = MT_MCU_DLM_ADDR; 137 138 mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_DLM_OFFSET); 139 mt76_wr_copy(dev, offset, cur, len); 140 141 mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0); 142 143 val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_2); 144 if (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, val) == 1) 145 mt76_set(dev, MT_MCU_COM_REG0, BIT(30)); 146 147 /* trigger firmware */ 148 mt76_wr(dev, MT_MCU_INT_LEVEL, 2); 149 if (!mt76_poll_msec(dev, MT_MCU_COM_REG0, 1, 1, 200)) { 150 dev_err(dev->mt76.dev, "Firmware failed to start\n"); 151 release_firmware(fw); 152 return -ETIMEDOUT; 153 } 154 155 mt76x02_set_ethtool_fwver(dev, hdr); 156 dev_info(dev->mt76.dev, "Firmware running!\n"); 157 158 release_firmware(fw); 159 160 return ret; 161 162 error: 163 dev_err(dev->mt76.dev, "Invalid firmware\n"); 164 release_firmware(fw); 165 return -ENOENT; 166 } 167 168 static int 169 mt76pci_mcu_restart(struct mt76_dev *mdev) 170 { 171 struct mt76x02_dev *dev; 172 int ret; 173 174 dev = container_of(mdev, struct mt76x02_dev, mt76); 175 176 mt76x02_mcu_cleanup(dev); 177 mt76x2_mac_reset(dev, true); 178 179 ret = mt76pci_load_firmware(dev); 180 if (ret) 181 return ret; 182 183 mt76_wr(dev, MT_WPDMA_RST_IDX, ~0); 184 185 return 0; 186 } 187 188 int mt76x2_mcu_init(struct mt76x02_dev *dev) 189 { 190 static const struct mt76_mcu_ops mt76x2_mcu_ops = { 191 .mcu_restart = mt76pci_mcu_restart, 192 .mcu_send_msg = mt76x02_mcu_msg_send, 193 }; 194 int ret; 195 196 dev->mt76.mcu_ops = &mt76x2_mcu_ops; 197 198 ret = mt76pci_load_rom_patch(dev); 199 if (ret) 200 return ret; 201 202 ret = mt76pci_load_firmware(dev); 203 if (ret) 204 return ret; 205 206 mt76x02_mcu_function_select(dev, Q_SELECT, 1); 207 return 0; 208 } 209