// SPDX-License-Identifier: ISC
/*
 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
 */

#include <linux/kernel.h>
#include <linux/firmware.h>
#include <linux/delay.h>

#include "mt76x02_mcu.h"

int mt76x02_mcu_parse_response(struct mt76_dev *mdev, int cmd,
			       struct sk_buff *skb, int seq)
{
	struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
	u32 *rxfce;

	if (!skb) {
		dev_err(mdev->dev,
			"MCU message %d (seq %d) timed out\n", cmd,
			seq);
		dev->mcu_timeout = 1;
		return -ETIMEDOUT;
	}

	rxfce = (u32 *)skb->cb;
	if (seq != FIELD_GET(MT_RX_FCE_INFO_CMD_SEQ, *rxfce))
		return -EAGAIN;

	return 0;
}
EXPORT_SYMBOL_GPL(mt76x02_mcu_parse_response);

int mt76x02_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
			 int len, bool wait_resp)
{
	struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
	unsigned long expires = jiffies + HZ;
	struct sk_buff *skb;
	u32 tx_info;
	int ret;
	u8 seq;

	if (dev->mcu_timeout)
		return -EIO;

	skb = mt76_mcu_msg_alloc(mdev, data, len);
	if (!skb)
		return -ENOMEM;

	mutex_lock(&mdev->mcu.mutex);

	seq = ++mdev->mcu.msg_seq & 0xf;
	if (!seq)
		seq = ++mdev->mcu.msg_seq & 0xf;

	tx_info = MT_MCU_MSG_TYPE_CMD |
		  FIELD_PREP(MT_MCU_MSG_CMD_TYPE, cmd) |
		  FIELD_PREP(MT_MCU_MSG_CMD_SEQ, seq) |
		  FIELD_PREP(MT_MCU_MSG_PORT, CPU_TX_PORT) |
		  FIELD_PREP(MT_MCU_MSG_LEN, skb->len);

	ret = mt76_tx_queue_skb_raw(dev, mdev->q_mcu[MT_MCUQ_WM], skb, tx_info);
	if (ret)
		goto out;

	while (wait_resp) {
		skb = mt76_mcu_get_response(&dev->mt76, expires);
		ret = mt76x02_mcu_parse_response(mdev, cmd, skb, seq);
		dev_kfree_skb(skb);
		if (ret != -EAGAIN)
			break;
	}

out:
	mutex_unlock(&mdev->mcu.mutex);

	return ret;
}
EXPORT_SYMBOL_GPL(mt76x02_mcu_msg_send);

int mt76x02_mcu_function_select(struct mt76x02_dev *dev, enum mcu_function func,
				u32 val)
{
	struct {
		__le32 id;
		__le32 value;
	} __packed __aligned(4) msg = {
		.id = cpu_to_le32(func),
		.value = cpu_to_le32(val),
	};
	bool wait = false;

	if (func != Q_SELECT)
		wait = true;

	return mt76_mcu_send_msg(&dev->mt76, CMD_FUN_SET_OP, &msg,
				 sizeof(msg), wait);
}
EXPORT_SYMBOL_GPL(mt76x02_mcu_function_select);

int mt76x02_mcu_set_radio_state(struct mt76x02_dev *dev, bool on)
{
	struct {
		__le32 mode;
		__le32 level;
	} __packed __aligned(4) msg = {
		.mode = cpu_to_le32(on ? RADIO_ON : RADIO_OFF),
		.level = cpu_to_le32(0),
	};

	return mt76_mcu_send_msg(&dev->mt76, CMD_POWER_SAVING_OP, &msg,
				 sizeof(msg), false);
}
EXPORT_SYMBOL_GPL(mt76x02_mcu_set_radio_state);

int mt76x02_mcu_calibrate(struct mt76x02_dev *dev, int type, u32 param)
{
	struct {
		__le32 id;
		__le32 value;
	} __packed __aligned(4) msg = {
		.id = cpu_to_le32(type),
		.value = cpu_to_le32(param),
	};
	bool is_mt76x2e = mt76_is_mmio(&dev->mt76) && is_mt76x2(dev);
	int ret;

	if (is_mt76x2e)
		mt76_rmw(dev, MT_MCU_COM_REG0, BIT(31), 0);

	ret = mt76_mcu_send_msg(&dev->mt76, CMD_CALIBRATION_OP, &msg,
				sizeof(msg), true);
	if (ret)
		return ret;

	if (is_mt76x2e &&
	    WARN_ON(!mt76_poll_msec(dev, MT_MCU_COM_REG0,
				    BIT(31), BIT(31), 100)))
		return -ETIMEDOUT;

	return 0;
}
EXPORT_SYMBOL_GPL(mt76x02_mcu_calibrate);

int mt76x02_mcu_cleanup(struct mt76x02_dev *dev)
{
	struct sk_buff *skb;

	mt76_wr(dev, MT_MCU_INT_LEVEL, 1);
	usleep_range(20000, 30000);

	while ((skb = skb_dequeue(&dev->mt76.mcu.res_q)) != NULL)
		dev_kfree_skb(skb);

	return 0;
}
EXPORT_SYMBOL_GPL(mt76x02_mcu_cleanup);

void mt76x02_set_ethtool_fwver(struct mt76x02_dev *dev,
			       const struct mt76x02_fw_header *h)
{
	u16 bld = le16_to_cpu(h->build_ver);
	u16 ver = le16_to_cpu(h->fw_ver);

	snprintf(dev->mt76.hw->wiphy->fw_version,
		 sizeof(dev->mt76.hw->wiphy->fw_version),
		 "%d.%d.%02d-b%x",
		 (ver >> 12) & 0xf, (ver >> 8) & 0xf, ver & 0xf, bld);
}
EXPORT_SYMBOL_GPL(mt76x02_set_ethtool_fwver);
