pci_mcu.c (4528B)
1// SPDX-License-Identifier: ISC 2/* 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 */ 5 6#include <linux/kernel.h> 7#include <linux/firmware.h> 8#include <linux/delay.h> 9 10#include "mt76x2.h" 11#include "mcu.h" 12#include "eeprom.h" 13 14static int 15mt76pci_load_rom_patch(struct mt76x02_dev *dev) 16{ 17 const struct firmware *fw = NULL; 18 struct mt76x02_patch_header *hdr; 19 bool rom_protect = !is_mt7612(dev); 20 int len, ret = 0; 21 __le32 *cur; 22 u32 patch_mask, patch_reg; 23 24 if (rom_protect && !mt76_poll(dev, MT_MCU_SEMAPHORE_03, 1, 1, 600)) { 25 dev_err(dev->mt76.dev, 26 "Could not get hardware semaphore for ROM PATCH\n"); 27 return -ETIMEDOUT; 28 } 29 30 if (mt76xx_rev(dev) >= MT76XX_REV_E3) { 31 patch_mask = BIT(0); 32 patch_reg = MT_MCU_CLOCK_CTL; 33 } else { 34 patch_mask = BIT(1); 35 patch_reg = MT_MCU_COM_REG0; 36 } 37 38 if (rom_protect && (mt76_rr(dev, patch_reg) & patch_mask)) { 39 dev_info(dev->mt76.dev, "ROM patch already applied\n"); 40 goto out; 41 } 42 43 ret = request_firmware(&fw, MT7662_ROM_PATCH, dev->mt76.dev); 44 if (ret) 45 goto out; 46 47 if (!fw || !fw->data || fw->size <= sizeof(*hdr)) { 48 ret = -EIO; 49 dev_err(dev->mt76.dev, "Failed to load firmware\n"); 50 goto out; 51 } 52 53 hdr = (struct mt76x02_patch_header *)fw->data; 54 dev_info(dev->mt76.dev, "ROM patch build: %.15s\n", hdr->build_time); 55 56 mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ROM_PATCH_OFFSET); 57 58 cur = (__le32 *)(fw->data + sizeof(*hdr)); 59 len = fw->size - sizeof(*hdr); 60 mt76_wr_copy(dev, MT_MCU_ROM_PATCH_ADDR, cur, len); 61 62 mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0); 63 64 /* Trigger ROM */ 65 mt76_wr(dev, MT_MCU_INT_LEVEL, 4); 66 67 if (!mt76_poll_msec(dev, patch_reg, patch_mask, patch_mask, 2000)) { 68 dev_err(dev->mt76.dev, "Failed to load ROM patch\n"); 69 ret = -ETIMEDOUT; 70 } 71 72out: 73 /* release semaphore */ 74 if (rom_protect) 75 mt76_wr(dev, MT_MCU_SEMAPHORE_03, 1); 76 release_firmware(fw); 77 return ret; 78} 79 80static int 81mt76pci_load_firmware(struct mt76x02_dev *dev) 82{ 83 const struct firmware *fw; 84 const struct mt76x02_fw_header *hdr; 85 int len, ret; 86 __le32 *cur; 87 u32 offset, val; 88 89 ret = request_firmware(&fw, MT7662_FIRMWARE, dev->mt76.dev); 90 if (ret) 91 return ret; 92 93 if (!fw || !fw->data || fw->size < sizeof(*hdr)) 94 goto error; 95 96 hdr = (const struct mt76x02_fw_header *)fw->data; 97 98 len = sizeof(*hdr); 99 len += le32_to_cpu(hdr->ilm_len); 100 len += le32_to_cpu(hdr->dlm_len); 101 102 if (fw->size != len) 103 goto error; 104 105 val = le16_to_cpu(hdr->fw_ver); 106 dev_info(dev->mt76.dev, "Firmware Version: %d.%d.%02d\n", 107 (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf); 108 109 val = le16_to_cpu(hdr->build_ver); 110 dev_info(dev->mt76.dev, "Build: %x\n", val); 111 dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time); 112 113 cur = (__le32 *)(fw->data + sizeof(*hdr)); 114 len = le32_to_cpu(hdr->ilm_len); 115 116 mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ILM_OFFSET); 117 mt76_wr_copy(dev, MT_MCU_ILM_ADDR, cur, len); 118 119 cur += len / sizeof(*cur); 120 len = le32_to_cpu(hdr->dlm_len); 121 122 if (mt76xx_rev(dev) >= MT76XX_REV_E3) 123 offset = MT_MCU_DLM_ADDR_E3; 124 else 125 offset = MT_MCU_DLM_ADDR; 126 127 mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_DLM_OFFSET); 128 mt76_wr_copy(dev, offset, cur, len); 129 130 mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0); 131 132 val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_2); 133 if (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, val) == 1) 134 mt76_set(dev, MT_MCU_COM_REG0, BIT(30)); 135 136 /* trigger firmware */ 137 mt76_wr(dev, MT_MCU_INT_LEVEL, 2); 138 if (!mt76_poll_msec(dev, MT_MCU_COM_REG0, 1, 1, 200)) { 139 dev_err(dev->mt76.dev, "Firmware failed to start\n"); 140 release_firmware(fw); 141 return -ETIMEDOUT; 142 } 143 144 mt76x02_set_ethtool_fwver(dev, hdr); 145 dev_info(dev->mt76.dev, "Firmware running!\n"); 146 147 release_firmware(fw); 148 149 return ret; 150 151error: 152 dev_err(dev->mt76.dev, "Invalid firmware\n"); 153 release_firmware(fw); 154 return -ENOENT; 155} 156 157static int 158mt76pci_mcu_restart(struct mt76_dev *mdev) 159{ 160 struct mt76x02_dev *dev; 161 int ret; 162 163 dev = container_of(mdev, struct mt76x02_dev, mt76); 164 165 mt76x02_mcu_cleanup(dev); 166 mt76x2_mac_reset(dev, true); 167 168 ret = mt76pci_load_firmware(dev); 169 if (ret) 170 return ret; 171 172 mt76_wr(dev, MT_WPDMA_RST_IDX, ~0); 173 174 return 0; 175} 176 177int mt76x2_mcu_init(struct mt76x02_dev *dev) 178{ 179 static const struct mt76_mcu_ops mt76x2_mcu_ops = { 180 .mcu_restart = mt76pci_mcu_restart, 181 .mcu_send_msg = mt76x02_mcu_msg_send, 182 .mcu_parse_response = mt76x02_mcu_parse_response, 183 }; 184 int ret; 185 186 dev->mt76.mcu_ops = &mt76x2_mcu_ops; 187 188 ret = mt76pci_load_rom_patch(dev); 189 if (ret) 190 return ret; 191 192 ret = mt76pci_load_firmware(dev); 193 if (ret) 194 return ret; 195 196 mt76x02_mcu_function_select(dev, Q_SELECT, 1); 197 return 0; 198}