16c92544dSBjoern A. Zeeb // SPDX-License-Identifier: ISC
26c92544dSBjoern A. Zeeb /* Copyright (C) 2021 MediaTek Inc. */
36c92544dSBjoern A. Zeeb
46c92544dSBjoern A. Zeeb #include "mt7921.h"
56c92544dSBjoern A. Zeeb #include "mcu.h"
66c92544dSBjoern A. Zeeb
mt7921e_driver_own(struct mt792x_dev * dev)7*cbb3ec25SBjoern A. Zeeb int mt7921e_driver_own(struct mt792x_dev *dev)
86c92544dSBjoern A. Zeeb {
96c92544dSBjoern A. Zeeb u32 reg = mt7921_reg_map_l1(dev, MT_TOP_LPCR_HOST_BAND0);
106c92544dSBjoern A. Zeeb
116c92544dSBjoern A. Zeeb mt76_wr(dev, reg, MT_TOP_LPCR_HOST_DRV_OWN);
126c92544dSBjoern A. Zeeb if (!mt76_poll_msec(dev, reg, MT_TOP_LPCR_HOST_FW_OWN,
136c92544dSBjoern A. Zeeb 0, 500)) {
146c92544dSBjoern A. Zeeb dev_err(dev->mt76.dev, "Timeout for driver own\n");
156c92544dSBjoern A. Zeeb return -EIO;
166c92544dSBjoern A. Zeeb }
176c92544dSBjoern A. Zeeb
186c92544dSBjoern A. Zeeb return 0;
196c92544dSBjoern A. Zeeb }
206c92544dSBjoern A. Zeeb
216c92544dSBjoern A. Zeeb static int
mt7921_mcu_send_message(struct mt76_dev * mdev,struct sk_buff * skb,int cmd,int * seq)226c92544dSBjoern A. Zeeb mt7921_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
236c92544dSBjoern A. Zeeb int cmd, int *seq)
246c92544dSBjoern A. Zeeb {
25*cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
266c92544dSBjoern A. Zeeb enum mt76_mcuq_id txq = MT_MCUQ_WM;
276c92544dSBjoern A. Zeeb int ret;
286c92544dSBjoern A. Zeeb
296c92544dSBjoern A. Zeeb ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq);
306c92544dSBjoern A. Zeeb if (ret)
316c92544dSBjoern A. Zeeb return ret;
326c92544dSBjoern A. Zeeb
336c92544dSBjoern A. Zeeb mdev->mcu.timeout = 3 * HZ;
346c92544dSBjoern A. Zeeb
356c92544dSBjoern A. Zeeb if (cmd == MCU_CMD(FW_SCATTER))
366c92544dSBjoern A. Zeeb txq = MT_MCUQ_FWDL;
376c92544dSBjoern A. Zeeb
386c92544dSBjoern A. Zeeb return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[txq], skb, 0);
396c92544dSBjoern A. Zeeb }
406c92544dSBjoern A. Zeeb
mt7921e_mcu_init(struct mt792x_dev * dev)41*cbb3ec25SBjoern A. Zeeb int mt7921e_mcu_init(struct mt792x_dev *dev)
426c92544dSBjoern A. Zeeb {
436c92544dSBjoern A. Zeeb static const struct mt76_mcu_ops mt7921_mcu_ops = {
446c92544dSBjoern A. Zeeb .headroom = sizeof(struct mt76_connac2_mcu_txd),
456c92544dSBjoern A. Zeeb .mcu_skb_send_msg = mt7921_mcu_send_message,
466c92544dSBjoern A. Zeeb .mcu_parse_response = mt7921_mcu_parse_response,
476c92544dSBjoern A. Zeeb };
486c92544dSBjoern A. Zeeb int err;
496c92544dSBjoern A. Zeeb
506c92544dSBjoern A. Zeeb dev->mt76.mcu_ops = &mt7921_mcu_ops;
516c92544dSBjoern A. Zeeb
526c92544dSBjoern A. Zeeb err = mt7921e_driver_own(dev);
536c92544dSBjoern A. Zeeb if (err)
546c92544dSBjoern A. Zeeb return err;
556c92544dSBjoern A. Zeeb
566c92544dSBjoern A. Zeeb mt76_rmw_field(dev, MT_PCIE_MAC_PM, MT_PCIE_MAC_PM_L0S_DIS, 1);
576c92544dSBjoern A. Zeeb
586c92544dSBjoern A. Zeeb err = mt7921_run_firmware(dev);
596c92544dSBjoern A. Zeeb
606c92544dSBjoern A. Zeeb mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_FWDL], false);
616c92544dSBjoern A. Zeeb
626c92544dSBjoern A. Zeeb return err;
636c92544dSBjoern A. Zeeb }
64