1 /* 2 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 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/firmware.h> 18 19 #include "mt76x2u.h" 20 #include "eeprom.h" 21 #include "../mt76x02_usb.h" 22 23 #define MT_CMD_HDR_LEN 4 24 25 #define MCU_FW_URB_MAX_PAYLOAD 0x3900 26 #define MCU_ROM_PATCH_MAX_PAYLOAD 2048 27 28 #define MT76U_MCU_ILM_OFFSET 0x80000 29 #define MT76U_MCU_DLM_OFFSET 0x110000 30 #define MT76U_MCU_ROM_PATCH_OFFSET 0x90000 31 32 static void mt76x2u_mcu_load_ivb(struct mt76x02_dev *dev) 33 { 34 mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE, 35 USB_DIR_OUT | USB_TYPE_VENDOR, 36 0x12, 0, NULL, 0); 37 } 38 39 static void mt76x2u_mcu_enable_patch(struct mt76x02_dev *dev) 40 { 41 struct mt76_usb *usb = &dev->mt76.usb; 42 static const u8 data[] = { 43 0x6f, 0xfc, 0x08, 0x01, 44 0x20, 0x04, 0x00, 0x00, 45 0x00, 0x09, 0x00, 46 }; 47 48 memcpy(usb->data, data, sizeof(data)); 49 mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE, 50 USB_DIR_OUT | USB_TYPE_CLASS, 51 0x12, 0, usb->data, sizeof(data)); 52 } 53 54 static void mt76x2u_mcu_reset_wmt(struct mt76x02_dev *dev) 55 { 56 struct mt76_usb *usb = &dev->mt76.usb; 57 u8 data[] = { 58 0x6f, 0xfc, 0x05, 0x01, 59 0x07, 0x01, 0x00, 0x04 60 }; 61 62 memcpy(usb->data, data, sizeof(data)); 63 mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE, 64 USB_DIR_OUT | USB_TYPE_CLASS, 65 0x12, 0, usb->data, sizeof(data)); 66 } 67 68 static int mt76x2u_mcu_load_rom_patch(struct mt76x02_dev *dev) 69 { 70 bool rom_protect = !is_mt7612(dev); 71 struct mt76x02_patch_header *hdr; 72 u32 val, patch_mask, patch_reg; 73 const struct firmware *fw; 74 int err; 75 76 if (rom_protect && 77 !mt76_poll_msec(dev, MT_MCU_SEMAPHORE_03, 1, 1, 600)) { 78 dev_err(dev->mt76.dev, 79 "could not get hardware semaphore for ROM PATCH\n"); 80 return -ETIMEDOUT; 81 } 82 83 if (mt76xx_rev(dev) >= MT76XX_REV_E3) { 84 patch_mask = BIT(0); 85 patch_reg = MT_MCU_CLOCK_CTL; 86 } else { 87 patch_mask = BIT(1); 88 patch_reg = MT_MCU_COM_REG0; 89 } 90 91 if (rom_protect && (mt76_rr(dev, patch_reg) & patch_mask)) { 92 dev_info(dev->mt76.dev, "ROM patch already applied\n"); 93 return 0; 94 } 95 96 err = request_firmware(&fw, MT7662_ROM_PATCH, dev->mt76.dev); 97 if (err < 0) 98 return err; 99 100 if (!fw || !fw->data || fw->size <= sizeof(*hdr)) { 101 dev_err(dev->mt76.dev, "failed to load firmware\n"); 102 err = -EIO; 103 goto out; 104 } 105 106 hdr = (struct mt76x02_patch_header *)fw->data; 107 dev_info(dev->mt76.dev, "ROM patch build: %.15s\n", hdr->build_time); 108 109 /* enable USB_DMA_CFG */ 110 val = MT_USB_DMA_CFG_RX_BULK_EN | 111 MT_USB_DMA_CFG_TX_BULK_EN | 112 FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20); 113 mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val); 114 115 /* vendor reset */ 116 mt76x02u_mcu_fw_reset(dev); 117 usleep_range(5000, 10000); 118 119 /* enable FCE to send in-band cmd */ 120 mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1); 121 /* FCE tx_fs_base_ptr */ 122 mt76_wr(dev, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230); 123 /* FCE tx_fs_max_cnt */ 124 mt76_wr(dev, MT_TX_CPU_FROM_FCE_MAX_COUNT, 0x1); 125 /* FCE pdma enable */ 126 mt76_wr(dev, MT_FCE_PDMA_GLOBAL_CONF, 0x44); 127 /* FCE skip_fs_en */ 128 mt76_wr(dev, MT_FCE_SKIP_FS, 0x3); 129 130 err = mt76x02u_mcu_fw_send_data(dev, fw->data + sizeof(*hdr), 131 fw->size - sizeof(*hdr), 132 MCU_ROM_PATCH_MAX_PAYLOAD, 133 MT76U_MCU_ROM_PATCH_OFFSET); 134 if (err < 0) { 135 err = -EIO; 136 goto out; 137 } 138 139 mt76x2u_mcu_enable_patch(dev); 140 mt76x2u_mcu_reset_wmt(dev); 141 mdelay(20); 142 143 if (!mt76_poll_msec(dev, patch_reg, patch_mask, patch_mask, 100)) { 144 dev_err(dev->mt76.dev, "failed to load ROM patch\n"); 145 err = -ETIMEDOUT; 146 } 147 148 out: 149 if (rom_protect) 150 mt76_wr(dev, MT_MCU_SEMAPHORE_03, 1); 151 release_firmware(fw); 152 return err; 153 } 154 155 static int mt76x2u_mcu_load_firmware(struct mt76x02_dev *dev) 156 { 157 u32 val, dlm_offset = MT76U_MCU_DLM_OFFSET; 158 const struct mt76x02_fw_header *hdr; 159 int err, len, ilm_len, dlm_len; 160 const struct firmware *fw; 161 162 err = request_firmware(&fw, MT7662_FIRMWARE, dev->mt76.dev); 163 if (err < 0) 164 return err; 165 166 if (!fw || !fw->data || fw->size < sizeof(*hdr)) { 167 err = -EINVAL; 168 goto out; 169 } 170 171 hdr = (const struct mt76x02_fw_header *)fw->data; 172 ilm_len = le32_to_cpu(hdr->ilm_len); 173 dlm_len = le32_to_cpu(hdr->dlm_len); 174 len = sizeof(*hdr) + ilm_len + dlm_len; 175 if (fw->size != len) { 176 err = -EINVAL; 177 goto out; 178 } 179 180 val = le16_to_cpu(hdr->fw_ver); 181 dev_info(dev->mt76.dev, "Firmware Version: %d.%d.%02d\n", 182 (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf); 183 184 val = le16_to_cpu(hdr->build_ver); 185 dev_info(dev->mt76.dev, "Build: %x\n", val); 186 dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time); 187 188 /* vendor reset */ 189 mt76x02u_mcu_fw_reset(dev); 190 usleep_range(5000, 10000); 191 192 /* enable USB_DMA_CFG */ 193 val = MT_USB_DMA_CFG_RX_BULK_EN | 194 MT_USB_DMA_CFG_TX_BULK_EN | 195 FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20); 196 mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val); 197 /* enable FCE to send in-band cmd */ 198 mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1); 199 /* FCE tx_fs_base_ptr */ 200 mt76_wr(dev, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230); 201 /* FCE tx_fs_max_cnt */ 202 mt76_wr(dev, MT_TX_CPU_FROM_FCE_MAX_COUNT, 0x1); 203 /* FCE pdma enable */ 204 mt76_wr(dev, MT_FCE_PDMA_GLOBAL_CONF, 0x44); 205 /* FCE skip_fs_en */ 206 mt76_wr(dev, MT_FCE_SKIP_FS, 0x3); 207 208 /* load ILM */ 209 err = mt76x02u_mcu_fw_send_data(dev, fw->data + sizeof(*hdr), 210 ilm_len, MCU_FW_URB_MAX_PAYLOAD, 211 MT76U_MCU_ILM_OFFSET); 212 if (err < 0) { 213 err = -EIO; 214 goto out; 215 } 216 217 /* load DLM */ 218 if (mt76xx_rev(dev) >= MT76XX_REV_E3) 219 dlm_offset += 0x800; 220 err = mt76x02u_mcu_fw_send_data(dev, fw->data + sizeof(*hdr) + ilm_len, 221 dlm_len, MCU_FW_URB_MAX_PAYLOAD, 222 dlm_offset); 223 if (err < 0) { 224 err = -EIO; 225 goto out; 226 } 227 228 mt76x2u_mcu_load_ivb(dev); 229 if (!mt76_poll_msec(dev, MT_MCU_COM_REG0, 1, 1, 100)) { 230 dev_err(dev->mt76.dev, "firmware failed to start\n"); 231 err = -ETIMEDOUT; 232 goto out; 233 } 234 235 mt76_set(dev, MT_MCU_COM_REG0, BIT(1)); 236 /* enable FCE to send in-band cmd */ 237 mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1); 238 mt76x02_set_ethtool_fwver(dev, hdr); 239 dev_dbg(dev->mt76.dev, "firmware running\n"); 240 241 out: 242 release_firmware(fw); 243 return err; 244 } 245 246 int mt76x2u_mcu_fw_init(struct mt76x02_dev *dev) 247 { 248 int err; 249 250 err = mt76x2u_mcu_load_rom_patch(dev); 251 if (err < 0) 252 return err; 253 254 return mt76x2u_mcu_load_firmware(dev); 255 } 256 257 int mt76x2u_mcu_init(struct mt76x02_dev *dev) 258 { 259 int err; 260 261 err = mt76x02_mcu_function_select(dev, Q_SELECT, 1); 262 if (err < 0) 263 return err; 264 265 return mt76x02_mcu_set_radio_state(dev, true); 266 } 267