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