1 // SPDX-License-Identifier: ISC
3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
5 #include <linux/kernel.h>
6 #include <linux/firmware.h>
7 #include <linux/module.h>
11 #include "../mt76x02_usb.h"
13 #define MCU_FW_URB_MAX_PAYLOAD 0x38f8
14 #define MCU_FW_URB_SIZE (MCU_FW_URB_MAX_PAYLOAD + 12)
17 mt76x0u_upload_firmware(struct mt76x02_dev
*dev
,
18 const struct mt76x02_fw_header
*hdr
)
20 u8
*fw_payload
= (u8
*)(hdr
+ 1);
25 ivb
= kmemdup(fw_payload
, MT_MCU_IVB_SIZE
, GFP_KERNEL
);
29 ilm_len
= le32_to_cpu(hdr
->ilm_len
) - MT_MCU_IVB_SIZE
;
30 dev_dbg(dev
->mt76
.dev
, "loading FW - ILM %u + IVB %u\n",
31 ilm_len
, MT_MCU_IVB_SIZE
);
32 err
= mt76x02u_mcu_fw_send_data(dev
, fw_payload
+ MT_MCU_IVB_SIZE
,
33 ilm_len
, MCU_FW_URB_MAX_PAYLOAD
,
38 dlm_len
= le32_to_cpu(hdr
->dlm_len
);
39 dev_dbg(dev
->mt76
.dev
, "loading FW - DLM %u\n", dlm_len
);
40 err
= mt76x02u_mcu_fw_send_data(dev
,
41 fw_payload
+ le32_to_cpu(hdr
->ilm_len
),
42 dlm_len
, MCU_FW_URB_MAX_PAYLOAD
,
47 err
= mt76u_vendor_request(&dev
->mt76
, MT_VEND_DEV_MODE
,
48 USB_DIR_OUT
| USB_TYPE_VENDOR
,
49 0x12, 0, ivb
, MT_MCU_IVB_SIZE
);
53 if (!mt76_poll_msec(dev
, MT_MCU_COM_REG0
, 1, 1, 1000)) {
54 dev_err(dev
->mt76
.dev
, "Firmware failed to start\n");
59 dev_dbg(dev
->mt76
.dev
, "Firmware running!\n");
67 static int mt76x0_get_firmware(struct mt76x02_dev
*dev
,
68 const struct firmware
**fw
)
72 /* try to load mt7610e fw if available
73 * otherwise fall back to mt7610u one
75 err
= firmware_request_nowarn(fw
, MT7610E_FIRMWARE
, dev
->mt76
.dev
);
77 dev_info(dev
->mt76
.dev
, "%s not found, switching to %s",
78 MT7610E_FIRMWARE
, MT7610U_FIRMWARE
);
79 return request_firmware(fw
, MT7610U_FIRMWARE
,
85 static int mt76x0u_load_firmware(struct mt76x02_dev
*dev
)
87 const struct firmware
*fw
;
88 const struct mt76x02_fw_header
*hdr
;
92 mt76_wr(dev
, MT_USB_DMA_CFG
, (MT_USB_DMA_CFG_RX_BULK_EN
|
93 MT_USB_DMA_CFG_TX_BULK_EN
));
95 if (mt76x0_firmware_running(dev
))
98 ret
= mt76x0_get_firmware(dev
, &fw
);
102 if (!fw
|| !fw
->data
|| fw
->size
< sizeof(*hdr
))
105 hdr
= (const struct mt76x02_fw_header
*)fw
->data
;
107 if (le32_to_cpu(hdr
->ilm_len
) <= MT_MCU_IVB_SIZE
)
111 len
+= le32_to_cpu(hdr
->ilm_len
);
112 len
+= le32_to_cpu(hdr
->dlm_len
);
117 val
= le16_to_cpu(hdr
->fw_ver
);
118 dev_dbg(dev
->mt76
.dev
,
119 "Firmware Version: %d.%d.%02d Build: %x Build time: %.16s\n",
120 (val
>> 12) & 0xf, (val
>> 8) & 0xf, val
& 0xf,
121 le16_to_cpu(hdr
->build_ver
), hdr
->build_time
);
123 len
= le32_to_cpu(hdr
->ilm_len
);
125 mt76_wr(dev
, 0x1004, 0x2c);
127 mt76_set(dev
, MT_USB_DMA_CFG
,
128 (MT_USB_DMA_CFG_RX_BULK_EN
| MT_USB_DMA_CFG_TX_BULK_EN
) |
129 FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT
, 0x20));
130 mt76x02u_mcu_fw_reset(dev
);
131 usleep_range(5000, 6000);
133 mt76_wr(dev
, MT_FCE_PSE_CTRL
, 1);
135 /* FCE tx_fs_base_ptr */
136 mt76_wr(dev
, MT_TX_CPU_FROM_FCE_BASE_PTR
, 0x400230);
137 /* FCE tx_fs_max_cnt */
138 mt76_wr(dev
, MT_TX_CPU_FROM_FCE_MAX_COUNT
, 1);
139 /* FCE pdma enable */
140 mt76_wr(dev
, MT_FCE_PDMA_GLOBAL_CONF
, 0x44);
142 mt76_wr(dev
, MT_FCE_SKIP_FS
, 3);
144 val
= mt76_rr(dev
, MT_USB_DMA_CFG
);
145 val
|= MT_USB_DMA_CFG_UDMA_TX_WL_DROP
;
146 mt76_wr(dev
, MT_USB_DMA_CFG
, val
);
147 val
&= ~MT_USB_DMA_CFG_UDMA_TX_WL_DROP
;
148 mt76_wr(dev
, MT_USB_DMA_CFG
, val
);
150 ret
= mt76x0u_upload_firmware(dev
, hdr
);
151 release_firmware(fw
);
153 mt76_wr(dev
, MT_FCE_PSE_CTRL
, 1);
158 dev_err(dev
->mt76
.dev
, "Invalid firmware image\n");
159 release_firmware(fw
);
163 int mt76x0u_mcu_init(struct mt76x02_dev
*dev
)
167 ret
= mt76x0u_load_firmware(dev
);
171 set_bit(MT76_STATE_MCU_RUNNING
, &dev
->mt76
.state
);