static int mt7603_mcu_init_download(struct mt7603_dev *dev, u32 addr, u32 len) { struct { __le32 addr; __le32 len; __le32 mode; } req = { .addr = cpu_to_le32(addr), .len = cpu_to_le32(len), .mode = cpu_to_le32(BIT(31)), }; struct sk_buff *skb = mt7603_mcu_msg_alloc(&req, sizeof(req)); return mt7603_mcu_msg_send(dev, skb, -MCU_CMD_TARGET_ADDRESS_LEN_REQ, MCU_Q_NA); } static int mt7603_mcu_send_firmware(struct mt7603_dev *dev, const void *data, int len) { struct sk_buff *skb; int ret = 0; while (len > 0) { int cur_len = min_t(int, 4096 - sizeof(struct mt7603_mcu_txd), len); skb = mt7603_mcu_msg_alloc(data, cur_len); if (!skb) return -ENOMEM; ret = __mt7603_mcu_msg_send(dev, skb, -MCU_CMD_FW_SCATTER, MCU_Q_NA, NULL); if (ret) break; data += cur_len; len -= cur_len; } return ret; } static int mt7603_mcu_start_firmware(struct mt7603_dev *dev, u32 addr) { struct { __le32 override; __le32 addr; } req = { .override = cpu_to_le32(addr ? 1 : 0), .addr = cpu_to_le32(addr), }; struct sk_buff *skb = mt7603_mcu_msg_alloc(&req, sizeof(req)); return mt7603_mcu_msg_send(dev, skb, -MCU_CMD_FW_START_REQ, MCU_Q_NA); } static int mt7603_mcu_restart(struct mt7603_dev *dev) { struct sk_buff *skb = mt7603_mcu_msg_alloc(NULL, 0); return mt7603_mcu_msg_send(dev, skb, -MCU_CMD_RESTART_DL_REQ, MCU_Q_NA); } static int mt7603_load_firmware(struct mt7603_dev *dev) { const struct firmware *fw; const struct mt7603_fw_trailer *hdr; const char *firmware; int dl_len; u32 addr, val; int ret; if (is_mt7628(dev)) { if (mt76xx_rev(dev) == MT7628_REV_E1) firmware = MT7628_FIRMWARE_E1; else firmware = MT7628_FIRMWARE_E2; } else { if (mt76xx_rev(dev) < MT7603_REV_E2) firmware = MT7603_FIRMWARE_E1; else firmware = MT7603_FIRMWARE_E2; } ret = request_firmware(&fw, firmware, dev->mt76.dev); if (ret) return ret; if (!fw || !fw->data || fw->size < sizeof(*hdr)) { dev_err(dev->mt76.dev, "Invalid firmware\n"); ret = -EINVAL; goto out; } hdr = (const struct mt7603_fw_trailer *)(fw->data + fw->size - sizeof(*hdr)); dev_info(dev->mt76.dev, "Firmware Version: %.10s\n", hdr->fw_ver); dev_info(dev->mt76.dev, "Build Time: %.15s\n", hdr->build_date); addr = mt7603_reg_map(dev, 0x50012498); mt76_wr(dev, addr, 0x5); mt76_wr(dev, addr, 0x5); udelay(1); /* switch to bypass mode */ mt76_rmw(dev, MT_SCH_4, MT_SCH_4_FORCE_QID, MT_SCH_4_BYPASS | FIELD_PREP(MT_SCH_4_FORCE_QID, 5)); val = mt76_rr(dev, MT_TOP_MISC2); if (val & BIT(1)) { dev_info(dev->mt76.dev, "Firmware already running...\n"); goto running; } if (!mt76_poll_msec(dev, MT_TOP_MISC2, BIT(0) | BIT(1), BIT(0), 500)) { dev_err(dev->mt76.dev, "Timeout waiting for ROM code to become ready\n"); ret = -EIO; goto out; } dl_len = le32_to_cpu(hdr->dl_len) + 4; ret = mt7603_mcu_init_download(dev, MCU_FIRMWARE_ADDRESS, dl_len); if (ret) { dev_err(dev->mt76.dev, "Download request failed\n"); goto out; } ret = mt7603_mcu_send_firmware(dev, fw->data, dl_len); if (ret) { dev_err(dev->mt76.dev, "Failed to send firmware to device\n"); goto out; } ret = mt7603_mcu_start_firmware(dev, MCU_FIRMWARE_ADDRESS); if (ret) { dev_err(dev->mt76.dev, "Failed to start firmware\n"); goto out; } if (!mt76_poll_msec(dev, MT_TOP_MISC2, BIT(1), BIT(1), 500)) { dev_err(dev->mt76.dev, "Timeout waiting for firmware to initialize\n"); ret = -EIO; goto out; } running: mt76_clear(dev, MT_SCH_4, MT_SCH_4_FORCE_QID | MT_SCH_4_BYPASS); mt76_set(dev, MT_SCH_4, BIT(8)); mt76_clear(dev, MT_SCH_4, BIT(8)); dev->mcu_running = true; dev_info(dev->mt76.dev, "firmware init done\n"); out: release_firmware(fw); return ret; } int mt7603_mcu_init(struct mt7603_dev *dev) { mutex_init(&dev->mt76.mmio.mcu.mutex); return mt7603_load_firmware(dev); }
dev->mt76.drv = &drv_ops; return dev; } static void mt7603_set_tmac_template(struct mt7603_dev *dev) { u32 desc[5] = { [1] = MT76_SET(MT_TXD3_REM_TX_COUNT, 0xf), [3] = MT_TXD5_SW_POWER_MGMT }; u32 addr; int i; addr = mt7603_reg_map(dev, MT_CLIENT_BASE_PHYS_ADDR); addr += MT_CLIENT_TMAC_INFO_TEMPLATE; for (i = 0; i < ARRAY_SIZE(desc); i++) mt76_wr(dev, addr + 4 * i, desc[i]); } static void mt7603_dma_sched_init(struct mt7603_dev *dev) { int page_size = 128; int page_count; int max_len = 1792; int max_amsdu_len = 4096; int max_mcu_len = 4096; int max_beacon_len = 512 * 8 + max_len; int max_mcast_count = 3;