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