// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
 * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
 * Copyright (C) 2023 Intel Corporation
 */
#include "iwl-trans.h"
#include "iwl-tm-infc.h"
#include "iwl-drv.h"
#include "iwl-prph.h"
#include "iwl-io.h"

static int iwl_tm_send_hcmd(struct iwl_testmode *testmode,
			    struct iwl_tm_data *data_in,
			    struct iwl_tm_data *data_out)
{
	struct iwl_tm_cmd_request *hcmd_req = data_in->data;
	struct iwl_tm_cmd_request *cmd_resp;
	u32 reply_len, resp_size;
	struct iwl_rx_packet *pkt;
	struct iwl_host_cmd host_cmd = {
		.id = hcmd_req->id,
		.data[0] = hcmd_req->data,
		.len[0] = hcmd_req->len,
		.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
	};
	int ret;

	if (!testmode->send_hcmd)
		return -EOPNOTSUPP;

	if (hcmd_req->want_resp)
		host_cmd.flags |= CMD_WANT_SKB;

	mutex_lock(testmode->mutex);
	ret = testmode->send_hcmd(testmode->op_mode, &host_cmd);
	mutex_unlock(testmode->mutex);
	if (ret)
		return ret;
	/* if no reply is required, we are done */
	if (!(host_cmd.flags & CMD_WANT_SKB))
		return 0;

	/* Retrieve response packet */
	pkt = host_cmd.resp_pkt;
	reply_len = iwl_rx_packet_len(pkt);

	/* Set response data */
	resp_size = sizeof(struct iwl_tm_cmd_request) + reply_len;
	cmd_resp = kzalloc(resp_size, GFP_KERNEL);
	if (!cmd_resp) {
		ret = -ENOMEM;
		goto out;
	}
	cmd_resp->id = hcmd_req->id;
	cmd_resp->len = reply_len;
	memcpy(cmd_resp->data, &(pkt->hdr), reply_len);

	data_out->data = cmd_resp;
	data_out->len = resp_size;
	ret = 0;

out:
	iwl_free_resp(&host_cmd);
	return ret;
}

static void iwl_tm_execute_reg_ops(struct iwl_testmode *testmode,
				   struct iwl_tm_regs_request *request,
				   struct iwl_tm_regs_request *result)
{
	struct iwl_tm_reg_op *cur_op;
	u32 idx, read_idx;

	for (idx = 0, read_idx = 0; idx < request->num; idx++) {
		cur_op = &request->reg_ops[idx];

		if  (cur_op->op_type == IWL_TM_REG_OP_READ) {
			cur_op->value = iwl_read32(testmode->trans,
						   cur_op->address);
			memcpy(&result->reg_ops[read_idx], cur_op,
			       sizeof(*cur_op));
			read_idx++;
		} else {
			/* IWL_TM_REG_OP_WRITE is the only possible option */
			iwl_write32(testmode->trans, cur_op->address,
				    cur_op->value);
		}
	}
}

static int iwl_tm_reg_ops(struct iwl_testmode *testmode,
			  struct iwl_tm_data *data_in,
			  struct iwl_tm_data *data_out)
{
	struct iwl_tm_reg_op *cur_op;
	struct iwl_tm_regs_request *request = data_in->data;
	struct iwl_tm_regs_request *result;
	u32 result_size;
	u32 idx, read_idx;
	bool is_grab_nic_access_required = true;

	/* Calculate result size (result is returned only for read ops) */
	for (idx = 0, read_idx = 0; idx < request->num; idx++) {
		if (request->reg_ops[idx].op_type == IWL_TM_REG_OP_READ)
			read_idx++;
		/* check if there is an operation that it is not */
		/* in the CSR range (0x00000000 - 0x000003FF)    */
		/* and not in the AL range			 */
		cur_op = &request->reg_ops[idx];
		if (IS_AL_ADDR(cur_op->address) || cur_op->address < HBUS_BASE)
			is_grab_nic_access_required = false;
	}
	result_size = sizeof(struct iwl_tm_regs_request) +
		      read_idx * sizeof(struct iwl_tm_reg_op);

	result = kzalloc(result_size, GFP_KERNEL);
	if (!result)
		return -ENOMEM;
	result->num = read_idx;
	if (is_grab_nic_access_required) {
		if (!iwl_trans_grab_nic_access(testmode->trans)) {
			kfree(result);
			return -EBUSY;
		}
		iwl_tm_execute_reg_ops(testmode, request, result);
		iwl_trans_release_nic_access(testmode->trans);
	} else {
		iwl_tm_execute_reg_ops(testmode, request, result);
	}

	data_out->data = result;
	data_out->len = result_size;

	return 0;
}

static int iwl_tm_get_dev_info(struct iwl_testmode *testmode,
			       struct iwl_tm_data *data_out)
{
	struct iwl_tm_dev_info *dev_info;
	const u8 driver_ver[] = BACKPORTS_GIT_TRACKED;

	dev_info = kzalloc(sizeof(*dev_info) + (strlen(driver_ver) + 1) *
			   sizeof(u8), GFP_KERNEL);
	if (!dev_info)
		return -ENOMEM;

	dev_info->dev_id = testmode->trans->hw_id;
	dev_info->fw_ver = testmode->fw->ucode_ver;
	dev_info->vendor_id = PCI_VENDOR_ID_INTEL;
	dev_info->silicon_step = testmode->trans->hw_rev_step;

	/* TODO: Assign real value when feature is implemented */
	dev_info->build_ver = 0x00;

	strcpy(dev_info->driver_ver, driver_ver);

	data_out->data = dev_info;
	data_out->len = sizeof(*dev_info);

	return 0;
}

static bool iwl_tm_addr_range_prph(struct iwl_testmode *testmode, u32 addr)
{
	struct iwl_trans *trans = testmode->trans;

	if (addr >= IWL_ABS_LMAC1_PRPH_START &&
	    addr < IWL_ABS_LMAC1_PRPH_START + PRPH_END)
		return true;

	if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
		return false;

	if (fw_has_capa(&testmode->fw->ucode_capa,
			IWL_UCODE_TLV_CAPA_CDB_SUPPORT) &&
	     addr >= IWL_ABS_LMAC2_PRPH_START &&
	     addr < IWL_ABS_LMAC2_PRPH_START + PRPH_END)
		return true;

	if (addr >= IWL_ABS_UMAC_PRPH_START &&
	    addr < IWL_ABS_UMAC_PRPH_START + PRPH_END)
		return true;

	return false;
}

static int iwl_tm_indirect_read(struct iwl_testmode *testmode,
				struct iwl_tm_data *data_in,
				struct iwl_tm_data *data_out)
{
	struct iwl_trans *trans = testmode->trans;
	struct iwl_tm_sram_read_request *cmd_in = data_in->data;
	u32 addr = cmd_in->offset;
	u32 size = cmd_in->length;
	u32 *buf32, size32, i;

	if (size & (sizeof(u32) - 1))
		return -EINVAL;

	data_out->data = kmalloc(size, GFP_KERNEL);
	if (!data_out->data)
		return -ENOMEM;

	data_out->len = size;

	size32 = size / sizeof(u32);
	buf32 = data_out->data;

	mutex_lock(testmode->mutex);

	/* Hard-coded periphery absolute address */
	if (iwl_tm_addr_range_prph(testmode, addr)) {
		if (!iwl_trans_grab_nic_access(trans)) {
			mutex_unlock(testmode->mutex);
			return -EBUSY;
		}
		for (i = 0; i < size32; i++)
			buf32[i] = iwl_trans_read_prph(trans,
						       addr + i * sizeof(u32));
		iwl_trans_release_nic_access(trans);
	} else {
		/* target memory (SRAM) */
		iwl_trans_read_mem(trans, addr, buf32, size32);
	}

	mutex_unlock(testmode->mutex);
	return 0;
}

static int iwl_tm_indirect_write(struct iwl_testmode *testmode,
				 struct iwl_tm_data *data_in)
{
	struct iwl_trans *trans = testmode->trans;
	struct iwl_tm_sram_write_request *cmd_in = data_in->data;
	u32 addr = cmd_in->offset;
	u32 size = cmd_in->len;
	u8 *buf = cmd_in->buffer;
	u32 *buf32 = (u32 *)buf, size32 = size / sizeof(u32);
	u32 val, i;

	mutex_lock(testmode->mutex);
	if (iwl_tm_addr_range_prph(testmode, addr)) {
		/* Periphery writes can be 1-3 bytes long, or DWORDs */
		if (size < 4) {
			memcpy(&val, buf, size);
			if (!iwl_trans_grab_nic_access(trans)) {
				mutex_unlock(testmode->mutex);
				return -EBUSY;
			}
			iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
				    (addr & 0x000FFFFF) | ((size - 1) << 24));
			iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
			iwl_trans_release_nic_access(trans);
		} else {
			if (size % sizeof(u32)) {
				mutex_unlock(testmode->mutex);
				return -EINVAL;
			}

			for (i = 0; i < size32; i++)
				iwl_write_prph(trans, addr + i * sizeof(u32),
					       buf32[i]);
		}
	} else {
		iwl_trans_write_mem(trans, addr, buf32, size32);
	}
	mutex_unlock(testmode->mutex);

	return 0;
}

static int iwl_tm_get_fw_info(struct iwl_testmode *testmode,
			      struct iwl_tm_data *data_out)
{
	struct iwl_tm_get_fw_info *fw_info;
	u32 api_len, capa_len;
	u32 *bitmap;
	int i;

	if (!testmode->fw_major_ver || !testmode->fw_minor_ver)
		return -EOPNOTSUPP;

	api_len = 4 * DIV_ROUND_UP(NUM_IWL_UCODE_TLV_API, 32);
	capa_len = 4 * DIV_ROUND_UP(NUM_IWL_UCODE_TLV_CAPA, 32);

	fw_info = kzalloc(sizeof(*fw_info) + api_len + capa_len, GFP_KERNEL);
	if (!fw_info)
		return -ENOMEM;

	fw_info->fw_major_ver = testmode->fw_major_ver;
	fw_info->fw_minor_ver = testmode->fw_minor_ver;
	fw_info->fw_capa_api_len = api_len;
	fw_info->fw_capa_flags = testmode->fw->ucode_capa.flags;
	fw_info->fw_capa_len = capa_len;

	bitmap = (u32 *)fw_info->data;
	for (i = 0; i < NUM_IWL_UCODE_TLV_API; i++) {
		if (fw_has_api(&testmode->fw->ucode_capa,
			       (__force iwl_ucode_tlv_api_t)i))
			bitmap[i / 32] |= BIT(i % 32);
	}

	bitmap = (u32 *)(fw_info->data + api_len);
	for (i = 0; i < NUM_IWL_UCODE_TLV_CAPA; i++) {
		if (fw_has_capa(&testmode->fw->ucode_capa,
				(__force iwl_ucode_tlv_capa_t)i))
			bitmap[i / 32] |= BIT(i % 32);
	}

	data_out->data = fw_info;
	data_out->len = sizeof(*fw_info) + api_len + capa_len;

	return 0;
}

/**
 * iwl_tm_execute_cmd - Implementation of test command executor
 * @testmode:	  iwl_testmode, holds all relevant data for execution
 * @cmd:	  User space command's index
 * @data_in:	  Input data. "data" field is to be casted to relevant
 *		  data structure. All verification must be done in the
 *		  caller function, therefor assuming that input data
 *		  length is valid.
 * @data_out:	  Will be allocated inside, freeing is in the caller's
 *		  responsibility
 * Returns: an error code indicating success or failure
 */
int iwl_tm_execute_cmd(struct iwl_testmode *testmode, u32 cmd,
		       struct iwl_tm_data *data_in,
		       struct iwl_tm_data *data_out)
{
	const struct iwl_test_ops *test_ops;

	if (!testmode->trans->op_mode) {
		IWL_ERR(testmode->trans, "No op_mode!\n");
		return -ENODEV;
	}
	if (WARN_ON_ONCE(!testmode->op_mode || !data_in))
		return -EINVAL;

	test_ops = &testmode->trans->op_mode->ops->test_ops;

	if (test_ops->cmd_exec) {
		bool cmd_supported = false;
		int ret;

		ret = test_ops->cmd_exec(testmode, cmd, data_in, data_out,
					 &cmd_supported);

		if (cmd_supported)
			return ret;
	}

	switch (cmd) {
	case IWL_TM_USER_CMD_HCMD:
		return iwl_tm_send_hcmd(testmode, data_in, data_out);
	case IWL_TM_USER_CMD_REG_ACCESS:
		return iwl_tm_reg_ops(testmode, data_in, data_out);
	case IWL_TM_USER_CMD_SRAM_WRITE:
		return iwl_tm_indirect_write(testmode, data_in);
	case IWL_TM_USER_CMD_SRAM_READ:
		return iwl_tm_indirect_read(testmode, data_in, data_out);
	case IWL_TM_USER_CMD_GET_DEVICE_INFO:
		return iwl_tm_get_dev_info(testmode, data_out);
	case IWL_TM_USER_CMD_GET_FW_INFO:
		return iwl_tm_get_fw_info(testmode, data_out);
	default:
		return -EOPNOTSUPP;
	}
}

void iwl_tm_init(struct iwl_trans *trans, const struct iwl_fw *fw,
		 struct mutex *mutex, void *op_mode)
{
	struct iwl_testmode *testmode = &trans->testmode;

	testmode->trans = trans;
	testmode->fw = fw;
	testmode->mutex = mutex;
	testmode->op_mode = op_mode;

	if (trans->op_mode->ops->test_ops.send_hcmd)
		testmode->send_hcmd = trans->op_mode->ops->test_ops.send_hcmd;
}
IWL_EXPORT_SYMBOL(iwl_tm_init);

void iwl_tm_set_fw_ver(struct iwl_trans *trans, u32 fw_major_ver,
		       u32 fw_minor_var)
{
	struct iwl_testmode *testmode = &trans->testmode;

	testmode->fw_major_ver = fw_major_ver;
	testmode->fw_minor_ver = fw_minor_var;
}
IWL_EXPORT_SYMBOL(iwl_tm_set_fw_ver);
