Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /*
0003  * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
0004  */
0005 #include <linux/kernel.h>
0006 #include <linux/firmware.h>
0007 #include <linux/module.h>
0008 
0009 #include "mt76x0.h"
0010 #include "mcu.h"
0011 #include "../mt76x02_usb.h"
0012 
0013 #define MCU_FW_URB_MAX_PAYLOAD      0x38f8
0014 #define MCU_FW_URB_SIZE         (MCU_FW_URB_MAX_PAYLOAD + 12)
0015 
0016 static int
0017 mt76x0u_upload_firmware(struct mt76x02_dev *dev,
0018             const struct mt76x02_fw_header *hdr)
0019 {
0020     u8 *fw_payload = (u8 *)(hdr + 1);
0021     u32 ilm_len, dlm_len;
0022     void *ivb;
0023     int err;
0024 
0025     ivb = kmemdup(fw_payload, MT_MCU_IVB_SIZE, GFP_KERNEL);
0026     if (!ivb)
0027         return -ENOMEM;
0028 
0029     ilm_len = le32_to_cpu(hdr->ilm_len) - MT_MCU_IVB_SIZE;
0030     dev_dbg(dev->mt76.dev, "loading FW - ILM %u + IVB %u\n",
0031         ilm_len, MT_MCU_IVB_SIZE);
0032     err = mt76x02u_mcu_fw_send_data(dev, fw_payload + MT_MCU_IVB_SIZE,
0033                     ilm_len, MCU_FW_URB_MAX_PAYLOAD,
0034                     MT_MCU_IVB_SIZE);
0035     if (err)
0036         goto out;
0037 
0038     dlm_len = le32_to_cpu(hdr->dlm_len);
0039     dev_dbg(dev->mt76.dev, "loading FW - DLM %u\n", dlm_len);
0040     err = mt76x02u_mcu_fw_send_data(dev,
0041                     fw_payload + le32_to_cpu(hdr->ilm_len),
0042                     dlm_len, MCU_FW_URB_MAX_PAYLOAD,
0043                     MT_MCU_DLM_OFFSET);
0044     if (err)
0045         goto out;
0046 
0047     err = mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE,
0048                    USB_DIR_OUT | USB_TYPE_VENDOR,
0049                    0x12, 0, ivb, MT_MCU_IVB_SIZE);
0050     if (err < 0)
0051         goto out;
0052 
0053     if (!mt76_poll_msec(dev, MT_MCU_COM_REG0, 1, 1, 1000)) {
0054         dev_err(dev->mt76.dev, "Firmware failed to start\n");
0055         err = -ETIMEDOUT;
0056         goto out;
0057     }
0058 
0059     dev_dbg(dev->mt76.dev, "Firmware running!\n");
0060 
0061 out:
0062     kfree(ivb);
0063 
0064     return err;
0065 }
0066 
0067 static int mt76x0_get_firmware(struct mt76x02_dev *dev,
0068                    const struct firmware **fw)
0069 {
0070     int err;
0071 
0072     /* try to load mt7610e fw if available
0073      * otherwise fall back to mt7610u one
0074      */
0075     err = firmware_request_nowarn(fw, MT7610E_FIRMWARE, dev->mt76.dev);
0076     if (err) {
0077         dev_info(dev->mt76.dev, "%s not found, switching to %s",
0078              MT7610E_FIRMWARE, MT7610U_FIRMWARE);
0079         return request_firmware(fw, MT7610U_FIRMWARE,
0080                     dev->mt76.dev);
0081     }
0082     return 0;
0083 }
0084 
0085 static int mt76x0u_load_firmware(struct mt76x02_dev *dev)
0086 {
0087     const struct firmware *fw;
0088     const struct mt76x02_fw_header *hdr;
0089     int len, ret;
0090     u32 val;
0091 
0092     mt76_wr(dev, MT_USB_DMA_CFG, (MT_USB_DMA_CFG_RX_BULK_EN |
0093                       MT_USB_DMA_CFG_TX_BULK_EN));
0094 
0095     if (mt76x0_firmware_running(dev))
0096         return 0;
0097 
0098     ret = mt76x0_get_firmware(dev, &fw);
0099     if (ret)
0100         return ret;
0101 
0102     if (!fw || !fw->data || fw->size < sizeof(*hdr))
0103         goto err_inv_fw;
0104 
0105     hdr = (const struct mt76x02_fw_header *)fw->data;
0106 
0107     if (le32_to_cpu(hdr->ilm_len) <= MT_MCU_IVB_SIZE)
0108         goto err_inv_fw;
0109 
0110     len = sizeof(*hdr);
0111     len += le32_to_cpu(hdr->ilm_len);
0112     len += le32_to_cpu(hdr->dlm_len);
0113 
0114     if (fw->size != len)
0115         goto err_inv_fw;
0116 
0117     val = le16_to_cpu(hdr->fw_ver);
0118     dev_dbg(dev->mt76.dev,
0119         "Firmware Version: %d.%d.%02d Build: %x Build time: %.16s\n",
0120         (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf,
0121         le16_to_cpu(hdr->build_ver), hdr->build_time);
0122 
0123     len = le32_to_cpu(hdr->ilm_len);
0124 
0125     mt76_wr(dev, 0x1004, 0x2c);
0126 
0127     mt76_set(dev, MT_USB_DMA_CFG,
0128          (MT_USB_DMA_CFG_RX_BULK_EN | MT_USB_DMA_CFG_TX_BULK_EN) |
0129          FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20));
0130     mt76x02u_mcu_fw_reset(dev);
0131     usleep_range(5000, 6000);
0132 
0133     mt76_wr(dev, MT_FCE_PSE_CTRL, 1);
0134 
0135     /* FCE tx_fs_base_ptr */
0136     mt76_wr(dev, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230);
0137     /* FCE tx_fs_max_cnt */
0138     mt76_wr(dev, MT_TX_CPU_FROM_FCE_MAX_COUNT, 1);
0139     /* FCE pdma enable */
0140     mt76_wr(dev, MT_FCE_PDMA_GLOBAL_CONF, 0x44);
0141     /* FCE skip_fs_en */
0142     mt76_wr(dev, MT_FCE_SKIP_FS, 3);
0143 
0144     val = mt76_rr(dev, MT_USB_DMA_CFG);
0145     val |= MT_USB_DMA_CFG_UDMA_TX_WL_DROP;
0146     mt76_wr(dev, MT_USB_DMA_CFG, val);
0147     val &= ~MT_USB_DMA_CFG_UDMA_TX_WL_DROP;
0148     mt76_wr(dev, MT_USB_DMA_CFG, val);
0149 
0150     ret = mt76x0u_upload_firmware(dev, hdr);
0151     release_firmware(fw);
0152 
0153     mt76_wr(dev, MT_FCE_PSE_CTRL, 1);
0154 
0155     return ret;
0156 
0157 err_inv_fw:
0158     dev_err(dev->mt76.dev, "Invalid firmware image\n");
0159     release_firmware(fw);
0160     return -ENOENT;
0161 }
0162 
0163 int mt76x0u_mcu_init(struct mt76x02_dev *dev)
0164 {
0165     int ret;
0166 
0167     ret = mt76x0u_load_firmware(dev);
0168     if (ret < 0)
0169         return ret;
0170 
0171     set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
0172 
0173     return 0;
0174 }