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 
0008 #include "mt76x0.h"
0009 #include "mcu.h"
0010 
0011 #define MT_MCU_IVB_ADDR     (MT_MCU_ILM_ADDR + 0x54000 - MT_MCU_IVB_SIZE)
0012 
0013 static int mt76x0e_load_firmware(struct mt76x02_dev *dev)
0014 {
0015     bool is_combo_chip = mt76_chip(&dev->mt76) != 0x7610;
0016     u32 val, ilm_len, dlm_len, offset = 0;
0017     const struct mt76x02_fw_header *hdr;
0018     const struct firmware *fw;
0019     const char *firmware;
0020     const u8 *fw_payload;
0021     int len, err;
0022 
0023     if (is_combo_chip)
0024         firmware = MT7650E_FIRMWARE;
0025     else
0026         firmware = MT7610E_FIRMWARE;
0027 
0028     err = request_firmware(&fw, firmware, dev->mt76.dev);
0029     if (err)
0030         return err;
0031 
0032     if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
0033         err = -EIO;
0034         goto out;
0035     }
0036 
0037     hdr = (const struct mt76x02_fw_header *)fw->data;
0038 
0039     len = sizeof(*hdr);
0040     len += le32_to_cpu(hdr->ilm_len);
0041     len += le32_to_cpu(hdr->dlm_len);
0042 
0043     if (fw->size != len) {
0044         err = -EIO;
0045         goto out;
0046     }
0047 
0048     fw_payload = fw->data + sizeof(*hdr);
0049 
0050     val = le16_to_cpu(hdr->fw_ver);
0051     dev_info(dev->mt76.dev, "Firmware Version: %d.%d.%02d\n",
0052          (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf);
0053 
0054     val = le16_to_cpu(hdr->fw_ver);
0055     dev_dbg(dev->mt76.dev,
0056         "Firmware Version: %d.%d.%02d Build: %x Build time: %.16s\n",
0057         (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf,
0058         le16_to_cpu(hdr->build_ver), hdr->build_time);
0059 
0060     if (is_combo_chip && !mt76_poll(dev, MT_MCU_SEMAPHORE_00, 1, 1, 600)) {
0061         dev_err(dev->mt76.dev,
0062             "Could not get hardware semaphore for loading fw\n");
0063         err = -ETIMEDOUT;
0064         goto out;
0065     }
0066 
0067     /* upload ILM. */
0068     mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0);
0069     ilm_len = le32_to_cpu(hdr->ilm_len);
0070     if (is_combo_chip) {
0071         ilm_len -= MT_MCU_IVB_SIZE;
0072         offset = MT_MCU_IVB_SIZE;
0073     }
0074     dev_dbg(dev->mt76.dev, "loading FW - ILM %u\n", ilm_len);
0075     mt76_wr_copy(dev, MT_MCU_ILM_ADDR + offset, fw_payload + offset,
0076              ilm_len);
0077 
0078     /* upload IVB. */
0079     if (is_combo_chip) {
0080         dev_dbg(dev->mt76.dev, "loading FW - IVB %u\n",
0081             MT_MCU_IVB_SIZE);
0082         mt76_wr_copy(dev, MT_MCU_IVB_ADDR, fw_payload, MT_MCU_IVB_SIZE);
0083     }
0084 
0085     /* upload DLM. */
0086     mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_DLM_OFFSET);
0087     dlm_len = le32_to_cpu(hdr->dlm_len);
0088     dev_dbg(dev->mt76.dev, "loading FW - DLM %u\n", dlm_len);
0089     mt76_wr_copy(dev, MT_MCU_ILM_ADDR,
0090              fw_payload + le32_to_cpu(hdr->ilm_len), dlm_len);
0091 
0092     /* trigger firmware */
0093     mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0);
0094     if (is_combo_chip)
0095         mt76_wr(dev, MT_MCU_INT_LEVEL, 0x3);
0096     else
0097         mt76_wr(dev, MT_MCU_RESET_CTL, 0x300);
0098 
0099     if (!mt76_poll_msec(dev, MT_MCU_COM_REG0, 1, 1, 1000)) {
0100         dev_err(dev->mt76.dev, "Firmware failed to start\n");
0101         err = -ETIMEDOUT;
0102         goto out;
0103     }
0104 
0105     mt76x02_set_ethtool_fwver(dev, hdr);
0106     dev_dbg(dev->mt76.dev, "Firmware running!\n");
0107 
0108 out:
0109     if (is_combo_chip)
0110         mt76_wr(dev, MT_MCU_SEMAPHORE_00, 0x1);
0111     release_firmware(fw);
0112 
0113     return err;
0114 }
0115 
0116 int mt76x0e_mcu_init(struct mt76x02_dev *dev)
0117 {
0118     static const struct mt76_mcu_ops mt76x0e_mcu_ops = {
0119         .mcu_send_msg = mt76x02_mcu_msg_send,
0120         .mcu_parse_response = mt76x02_mcu_parse_response,
0121     };
0122     int err;
0123 
0124     dev->mt76.mcu_ops = &mt76x0e_mcu_ops;
0125 
0126     err = mt76x0e_load_firmware(dev);
0127     if (err < 0)
0128         return err;
0129 
0130     set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
0131 
0132     return 0;
0133 }