Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /*
0003  * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
0004  */
0005 
0006 #include <linux/firmware.h>
0007 
0008 #include "mt76x2u.h"
0009 #include "eeprom.h"
0010 #include "../mt76x02_usb.h"
0011 
0012 #define MT_CMD_HDR_LEN          4
0013 
0014 #define MCU_FW_URB_MAX_PAYLOAD      0x3900
0015 #define MCU_ROM_PATCH_MAX_PAYLOAD   2048
0016 
0017 #define MT76U_MCU_ILM_OFFSET        0x80000
0018 #define MT76U_MCU_DLM_OFFSET        0x110000
0019 #define MT76U_MCU_ROM_PATCH_OFFSET  0x90000
0020 
0021 static void mt76x2u_mcu_load_ivb(struct mt76x02_dev *dev)
0022 {
0023     mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE,
0024                  USB_DIR_OUT | USB_TYPE_VENDOR,
0025                  0x12, 0, NULL, 0);
0026 }
0027 
0028 static void mt76x2u_mcu_enable_patch(struct mt76x02_dev *dev)
0029 {
0030     struct mt76_usb *usb = &dev->mt76.usb;
0031     static const u8 data[] = {
0032         0x6f, 0xfc, 0x08, 0x01,
0033         0x20, 0x04, 0x00, 0x00,
0034         0x00, 0x09, 0x00,
0035     };
0036 
0037     memcpy(usb->data, data, sizeof(data));
0038     mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE,
0039                  USB_DIR_OUT | USB_TYPE_CLASS,
0040                  0x12, 0, usb->data, sizeof(data));
0041 }
0042 
0043 static void mt76x2u_mcu_reset_wmt(struct mt76x02_dev *dev)
0044 {
0045     struct mt76_usb *usb = &dev->mt76.usb;
0046     u8 data[] = {
0047         0x6f, 0xfc, 0x05, 0x01,
0048         0x07, 0x01, 0x00, 0x04
0049     };
0050 
0051     memcpy(usb->data, data, sizeof(data));
0052     mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE,
0053                  USB_DIR_OUT | USB_TYPE_CLASS,
0054                  0x12, 0, usb->data, sizeof(data));
0055 }
0056 
0057 static int mt76x2u_mcu_load_rom_patch(struct mt76x02_dev *dev)
0058 {
0059     bool rom_protect = !is_mt7612(dev);
0060     struct mt76x02_patch_header *hdr;
0061     u32 val, patch_mask, patch_reg;
0062     const struct firmware *fw;
0063     int err;
0064 
0065     if (rom_protect &&
0066         !mt76_poll_msec(dev, MT_MCU_SEMAPHORE_03, 1, 1, 600)) {
0067         dev_err(dev->mt76.dev,
0068             "could not get hardware semaphore for ROM PATCH\n");
0069         return -ETIMEDOUT;
0070     }
0071 
0072     if (mt76xx_rev(dev) >= MT76XX_REV_E3) {
0073         patch_mask = BIT(0);
0074         patch_reg = MT_MCU_CLOCK_CTL;
0075     } else {
0076         patch_mask = BIT(1);
0077         patch_reg = MT_MCU_COM_REG0;
0078     }
0079 
0080     if (rom_protect && (mt76_rr(dev, patch_reg) & patch_mask)) {
0081         dev_info(dev->mt76.dev, "ROM patch already applied\n");
0082         return 0;
0083     }
0084 
0085     err = request_firmware(&fw, MT7662_ROM_PATCH, dev->mt76.dev);
0086     if (err < 0)
0087         return err;
0088 
0089     if (!fw || !fw->data || fw->size <= sizeof(*hdr)) {
0090         dev_err(dev->mt76.dev, "failed to load firmware\n");
0091         err = -EIO;
0092         goto out;
0093     }
0094 
0095     hdr = (struct mt76x02_patch_header *)fw->data;
0096     dev_info(dev->mt76.dev, "ROM patch build: %.15s\n", hdr->build_time);
0097 
0098     /* enable USB_DMA_CFG */
0099     val = MT_USB_DMA_CFG_RX_BULK_EN |
0100           MT_USB_DMA_CFG_TX_BULK_EN |
0101           FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20);
0102     mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val);
0103 
0104     /* vendor reset */
0105     mt76x02u_mcu_fw_reset(dev);
0106     usleep_range(5000, 10000);
0107 
0108     /* enable FCE to send in-band cmd */
0109     mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1);
0110     /* FCE tx_fs_base_ptr */
0111     mt76_wr(dev, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230);
0112     /* FCE tx_fs_max_cnt */
0113     mt76_wr(dev, MT_TX_CPU_FROM_FCE_MAX_COUNT, 0x1);
0114     /* FCE pdma enable */
0115     mt76_wr(dev, MT_FCE_PDMA_GLOBAL_CONF, 0x44);
0116     /* FCE skip_fs_en */
0117     mt76_wr(dev, MT_FCE_SKIP_FS, 0x3);
0118 
0119     err = mt76x02u_mcu_fw_send_data(dev, fw->data + sizeof(*hdr),
0120                     fw->size - sizeof(*hdr),
0121                     MCU_ROM_PATCH_MAX_PAYLOAD,
0122                     MT76U_MCU_ROM_PATCH_OFFSET);
0123     if (err < 0) {
0124         err = -EIO;
0125         goto out;
0126     }
0127 
0128     mt76x2u_mcu_enable_patch(dev);
0129     mt76x2u_mcu_reset_wmt(dev);
0130     mdelay(20);
0131 
0132     if (!mt76_poll_msec(dev, patch_reg, patch_mask, patch_mask, 100)) {
0133         dev_err(dev->mt76.dev, "failed to load ROM patch\n");
0134         err = -ETIMEDOUT;
0135     }
0136 
0137 out:
0138     if (rom_protect)
0139         mt76_wr(dev, MT_MCU_SEMAPHORE_03, 1);
0140     release_firmware(fw);
0141     return err;
0142 }
0143 
0144 static int mt76x2u_mcu_load_firmware(struct mt76x02_dev *dev)
0145 {
0146     u32 val, dlm_offset = MT76U_MCU_DLM_OFFSET;
0147     const struct mt76x02_fw_header *hdr;
0148     int err, len, ilm_len, dlm_len;
0149     const struct firmware *fw;
0150 
0151     err = request_firmware(&fw, MT7662_FIRMWARE, dev->mt76.dev);
0152     if (err < 0)
0153         return err;
0154 
0155     if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
0156         err = -EINVAL;
0157         goto out;
0158     }
0159 
0160     hdr = (const struct mt76x02_fw_header *)fw->data;
0161     ilm_len = le32_to_cpu(hdr->ilm_len);
0162     dlm_len = le32_to_cpu(hdr->dlm_len);
0163     len = sizeof(*hdr) + ilm_len + dlm_len;
0164     if (fw->size != len) {
0165         err = -EINVAL;
0166         goto out;
0167     }
0168 
0169     val = le16_to_cpu(hdr->fw_ver);
0170     dev_info(dev->mt76.dev, "Firmware Version: %d.%d.%02d\n",
0171          (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf);
0172 
0173     val = le16_to_cpu(hdr->build_ver);
0174     dev_info(dev->mt76.dev, "Build: %x\n", val);
0175     dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time);
0176 
0177     /* vendor reset */
0178     mt76x02u_mcu_fw_reset(dev);
0179     usleep_range(5000, 10000);
0180 
0181     /* enable USB_DMA_CFG */
0182     val = MT_USB_DMA_CFG_RX_BULK_EN |
0183           MT_USB_DMA_CFG_TX_BULK_EN |
0184           FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20);
0185     mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val);
0186     /* enable FCE to send in-band cmd */
0187     mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1);
0188     /* FCE tx_fs_base_ptr */
0189     mt76_wr(dev, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230);
0190     /* FCE tx_fs_max_cnt */
0191     mt76_wr(dev, MT_TX_CPU_FROM_FCE_MAX_COUNT, 0x1);
0192     /* FCE pdma enable */
0193     mt76_wr(dev, MT_FCE_PDMA_GLOBAL_CONF, 0x44);
0194     /* FCE skip_fs_en */
0195     mt76_wr(dev, MT_FCE_SKIP_FS, 0x3);
0196 
0197     /* load ILM */
0198     err = mt76x02u_mcu_fw_send_data(dev, fw->data + sizeof(*hdr),
0199                     ilm_len, MCU_FW_URB_MAX_PAYLOAD,
0200                     MT76U_MCU_ILM_OFFSET);
0201     if (err < 0) {
0202         err = -EIO;
0203         goto out;
0204     }
0205 
0206     /* load DLM */
0207     if (mt76xx_rev(dev) >= MT76XX_REV_E3)
0208         dlm_offset += 0x800;
0209     err = mt76x02u_mcu_fw_send_data(dev, fw->data + sizeof(*hdr) + ilm_len,
0210                     dlm_len, MCU_FW_URB_MAX_PAYLOAD,
0211                     dlm_offset);
0212     if (err < 0) {
0213         err = -EIO;
0214         goto out;
0215     }
0216 
0217     mt76x2u_mcu_load_ivb(dev);
0218     if (!mt76_poll_msec(dev, MT_MCU_COM_REG0, 1, 1, 100)) {
0219         dev_err(dev->mt76.dev, "firmware failed to start\n");
0220         err = -ETIMEDOUT;
0221         goto out;
0222     }
0223 
0224     mt76_set(dev, MT_MCU_COM_REG0, BIT(1));
0225     /* enable FCE to send in-band cmd */
0226     mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1);
0227     mt76x02_set_ethtool_fwver(dev, hdr);
0228     dev_dbg(dev->mt76.dev, "firmware running\n");
0229 
0230 out:
0231     release_firmware(fw);
0232     return err;
0233 }
0234 
0235 int mt76x2u_mcu_fw_init(struct mt76x02_dev *dev)
0236 {
0237     int err;
0238 
0239     err = mt76x2u_mcu_load_rom_patch(dev);
0240     if (err < 0)
0241         return err;
0242 
0243     return mt76x2u_mcu_load_firmware(dev);
0244 }
0245 
0246 int mt76x2u_mcu_init(struct mt76x02_dev *dev)
0247 {
0248     int err;
0249 
0250     err = mt76x02_mcu_function_select(dev, Q_SELECT, 1);
0251     if (err < 0)
0252         return err;
0253 
0254     return mt76x02_mcu_set_radio_state(dev, true);
0255 }