// SPDX-License-Identifier: ISC

#include <linux/firmware.h>
#include "mt7603.h"
#include "mcu.h"
#include "eeprom.h"

#define MCU_SKB_RESERVE	8

struct mt7603_fw_trailer {
	char fw_ver[10];
	char build_date[15];
	__le32 dl_len;
} __packed;

static int
__mt7603_mcu_msg_send(struct mt7603_dev *dev, struct sk_buff *skb,
		      int cmd, int *wait_seq)
{
	int hdrlen = dev->mcu_running ? sizeof(struct mt7603_mcu_txd) : 12;
	struct mt76_dev *mdev = &dev->mt76;
	struct mt7603_mcu_txd *txd;
	u8 seq;

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

	txd = (struct mt7603_mcu_txd *)skb_push(skb, hdrlen);

	txd->len = cpu_to_le16(skb->len);
	if (cmd == -MCU_CMD_FW_SCATTER)
		txd->pq_id = cpu_to_le16(MCU_PORT_QUEUE_FW);
	else
		txd->pq_id = cpu_to_le16(MCU_PORT_QUEUE);
	txd->pkt_type = MCU_PKT_ID;
	txd->seq = seq;

	if (cmd < 0) {
		txd->cid = -cmd;
		txd->set_query = MCU_Q_NA;
	} else {
		txd->cid = MCU_CMD_EXT_CID;
		txd->ext_cid = cmd;
		txd->set_query = MCU_Q_SET;
		txd->ext_cid_ack = 1;
	}

	if (wait_seq)
		*wait_seq = seq;

	return mt76_tx_queue_skb_raw(dev, MT_TXQ_MCU, skb, 0);
}

static int
mt7603_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
		    int len, bool wait_resp)
{
	struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
	unsigned long expires = jiffies + 3 * HZ;
	struct mt7603_mcu_rxd *rxd;
	struct sk_buff *skb;
	int ret, seq;

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

	mutex_lock(&mdev->mcu.mutex);

	ret = __mt7603_mcu_msg_send(dev, skb, cmd, &seq);
	if (ret)
		goto out;

	while (wait_resp) {
		bool check_seq = false;

		skb = mt76_mcu_get_response(&dev->mt76, expires);
		if (!skb) {
			dev_err(mdev->dev,
				"MCU message %d (seq %d) timed out\n",
				cmd, seq);
			dev->mcu_hang = MT7603_WATCHDOG_TIMEOUT;
			ret = -ETIMEDOUT;
			break;
		}

		rxd = (struct mt7603_mcu_rxd *)skb->data;
		if (seq == rxd->seq)
			check_seq = true;

		dev_kfree_skb(skb);

		if (check_seq)
			break;
	}

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

	return ret;
}

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)),
	};

	return __mt76_mcu_send_msg(&dev->mt76, -MCU_CMD_TARGET_ADDRESS_LEN_REQ,
				   &req, sizeof(req), true);
}

static int
mt7603_mcu_send_firmware(struct mt7603_dev *dev, const void *data, int len)
{
	int cur_len, ret = 0;

	while (len > 0) {
		cur_len = min_t(int, 4096 - sizeof(struct mt7603_mcu_txd),
				len);

		ret = __mt76_mcu_send_msg(&dev->mt76, -MCU_CMD_FW_SCATTER,
					  data, cur_len, false);
		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),
	};

	return __mt76_mcu_send_msg(&dev->mt76, -MCU_CMD_FW_START_REQ,
				   &req, sizeof(req), true);
}

static int
mt7603_mcu_restart(struct mt76_dev *dev)
{
	return __mt76_mcu_send_msg(dev, -MCU_CMD_RESTART_DL_REQ,
				   NULL, 0, true);
}

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;
	snprintf(dev->mt76.hw->wiphy->fw_version,
		 sizeof(dev->mt76.hw->wiphy->fw_version),
		 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
	dev_info(dev->mt76.dev, "firmware init done\n");

out:
	release_firmware(fw);

	return ret;
}

int mt7603_mcu_init(struct mt7603_dev *dev)
{
	static const struct mt76_mcu_ops mt7603_mcu_ops = {
		.mcu_send_msg = mt7603_mcu_msg_send,
		.mcu_restart = mt7603_mcu_restart,
	};

	dev->mt76.mcu_ops = &mt7603_mcu_ops;
	return mt7603_load_firmware(dev);
}

void mt7603_mcu_exit(struct mt7603_dev *dev)
{
	__mt76_mcu_restart(&dev->mt76);
	skb_queue_purge(&dev->mt76.mcu.res_q);
}

int mt7603_mcu_set_eeprom(struct mt7603_dev *dev)
{
	static const u16 req_fields[] = {
#define WORD(_start)			\
		_start,			\
		_start + 1
#define GROUP_2G(_start)		\
		WORD(_start),		\
		WORD(_start + 2),	\
		WORD(_start + 4)

		MT_EE_NIC_CONF_0 + 1,
		WORD(MT_EE_NIC_CONF_1),
		MT_EE_WIFI_RF_SETTING,
		MT_EE_TX_POWER_DELTA_BW40,
		MT_EE_TX_POWER_DELTA_BW80 + 1,
		MT_EE_TX_POWER_EXT_PA_5G,
		MT_EE_TEMP_SENSOR_CAL,
		GROUP_2G(MT_EE_TX_POWER_0_START_2G),
		GROUP_2G(MT_EE_TX_POWER_1_START_2G),
		WORD(MT_EE_TX_POWER_CCK),
		WORD(MT_EE_TX_POWER_OFDM_2G_6M),
		WORD(MT_EE_TX_POWER_OFDM_2G_24M),
		WORD(MT_EE_TX_POWER_OFDM_2G_54M),
		WORD(MT_EE_TX_POWER_HT_BPSK_QPSK),
		WORD(MT_EE_TX_POWER_HT_16_64_QAM),
		WORD(MT_EE_TX_POWER_HT_64_QAM),
		MT_EE_ELAN_RX_MODE_GAIN,
		MT_EE_ELAN_RX_MODE_NF,
		MT_EE_ELAN_RX_MODE_P1DB,
		MT_EE_ELAN_BYPASS_MODE_GAIN,
		MT_EE_ELAN_BYPASS_MODE_NF,
		MT_EE_ELAN_BYPASS_MODE_P1DB,
		WORD(MT_EE_STEP_NUM_NEG_6_7),
		WORD(MT_EE_STEP_NUM_NEG_4_5),
		WORD(MT_EE_STEP_NUM_NEG_2_3),
		WORD(MT_EE_STEP_NUM_NEG_0_1),
		WORD(MT_EE_REF_STEP_24G),
		WORD(MT_EE_STEP_NUM_PLUS_1_2),
		WORD(MT_EE_STEP_NUM_PLUS_3_4),
		WORD(MT_EE_STEP_NUM_PLUS_5_6),
		MT_EE_STEP_NUM_PLUS_7,
		MT_EE_XTAL_FREQ_OFFSET,
		MT_EE_XTAL_TRIM_2_COMP,
		MT_EE_XTAL_TRIM_3_COMP,
		MT_EE_XTAL_WF_RFCAL,

		/* unknown fields below */
		WORD(0x24),
		0x34,
		0x39,
		0x3b,
		WORD(0x42),
		WORD(0x9e),
		0xf2,
		WORD(0xf8),
		0xfa,
		0x12e,
		WORD(0x130), WORD(0x132), WORD(0x134), WORD(0x136),
		WORD(0x138), WORD(0x13a), WORD(0x13c), WORD(0x13e),

#undef GROUP_2G
#undef WORD

	};
	struct req_data {
		__le16 addr;
		u8 val;
		u8 pad;
	} __packed;
	struct {
		u8 buffer_mode;
		u8 len;
		u8 pad[2];
	} req_hdr = {
		.buffer_mode = 1,
		.len = ARRAY_SIZE(req_fields) - 1,
	};
	const int size = 0xff * sizeof(struct req_data);
	u8 *req, *eep = (u8 *)dev->mt76.eeprom.data;
	int i, ret, len = sizeof(req_hdr) + size;
	struct req_data *data;

	BUILD_BUG_ON(ARRAY_SIZE(req_fields) * sizeof(*data) > size);

	req = kmalloc(len, GFP_KERNEL);
	if (!req)
		return -ENOMEM;

	memcpy(req, &req_hdr, sizeof(req_hdr));
	data = (struct req_data *)(req + sizeof(req_hdr));
	memset(data, 0, size);
	for (i = 0; i < ARRAY_SIZE(req_fields); i++) {
		data[i].addr = cpu_to_le16(req_fields[i]);
		data[i].val = eep[req_fields[i]];
	}

	ret = __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_EFUSE_BUFFER_MODE,
				  req, len, true);
	kfree(req);

	return ret;
}

static int mt7603_mcu_set_tx_power(struct mt7603_dev *dev)
{
	struct {
		u8 center_channel;
		u8 tssi;
		u8 temp_comp;
		u8 target_power[2];
		u8 rate_power_delta[14];
		u8 bw_power_delta;
		u8 ch_power_delta[6];
		u8 temp_comp_power[17];
		u8 reserved;
	} req = {
		.center_channel = dev->mphy.chandef.chan->hw_value,
#define EEP_VAL(n) ((u8 *)dev->mt76.eeprom.data)[n]
		.tssi = EEP_VAL(MT_EE_NIC_CONF_1 + 1),
		.temp_comp = EEP_VAL(MT_EE_NIC_CONF_1),
		.target_power = {
			EEP_VAL(MT_EE_TX_POWER_0_START_2G + 2),
			EEP_VAL(MT_EE_TX_POWER_1_START_2G + 2)
		},
		.bw_power_delta = EEP_VAL(MT_EE_TX_POWER_DELTA_BW40),
		.ch_power_delta = {
			EEP_VAL(MT_EE_TX_POWER_0_START_2G + 3),
			EEP_VAL(MT_EE_TX_POWER_0_START_2G + 4),
			EEP_VAL(MT_EE_TX_POWER_0_START_2G + 5),
			EEP_VAL(MT_EE_TX_POWER_1_START_2G + 3),
			EEP_VAL(MT_EE_TX_POWER_1_START_2G + 4),
			EEP_VAL(MT_EE_TX_POWER_1_START_2G + 5)
		},
#undef EEP_VAL
	};
	u8 *eep = (u8 *)dev->mt76.eeprom.data;

	memcpy(req.rate_power_delta, eep + MT_EE_TX_POWER_CCK,
	       sizeof(req.rate_power_delta));

	memcpy(req.temp_comp_power, eep + MT_EE_STEP_NUM_NEG_6_7,
	       sizeof(req.temp_comp_power));

	return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_TX_POWER_CTRL,
				   &req, sizeof(req), true);
}

int mt7603_mcu_set_channel(struct mt7603_dev *dev)
{
	struct cfg80211_chan_def *chandef = &dev->mphy.chandef;
	struct ieee80211_hw *hw = mt76_hw(dev);
	int n_chains = hweight8(dev->mphy.antenna_mask);
	struct {
		u8 control_chan;
		u8 center_chan;
		u8 bw;
		u8 tx_streams;
		u8 rx_streams;
		u8 _res0[7];
		u8 txpower[21];
		u8 _res1[3];
	} req = {
		.control_chan = chandef->chan->hw_value,
		.center_chan = chandef->chan->hw_value,
		.bw = MT_BW_20,
		.tx_streams = n_chains,
		.rx_streams = n_chains,
	};
	s8 tx_power;
	int i, ret;

	if (dev->mphy.chandef.width == NL80211_CHAN_WIDTH_40) {
		req.bw = MT_BW_40;
		if (chandef->center_freq1 > chandef->chan->center_freq)
			req.center_chan += 2;
		else
			req.center_chan -= 2;
	}

	tx_power = hw->conf.power_level * 2;
	if (dev->mphy.antenna_mask == 3)
		tx_power -= 6;
	tx_power = min(tx_power, dev->tx_power_limit);

	dev->mphy.txpower_cur = tx_power;

	for (i = 0; i < ARRAY_SIZE(req.txpower); i++)
		req.txpower[i] = tx_power;

	ret = __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_CHANNEL_SWITCH,
				  &req, sizeof(req), true);
	if (ret)
		return ret;

	return mt7603_mcu_set_tx_power(dev);
}
