xref: /freebsd/sys/contrib/dev/mediatek/mt76/mt7921/pci_mcu.c (revision cbb3ec25236ba72f91cbdf23f8b78b9d1af0cedf)
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