// SPDX-License-Identifier: GPL-2.0-only

#include <linux/ethtool.h>
#include <linux/firmware.h>

#include "common.h"
#include "module_fw.h"
#include "cmis.h"

struct cmis_fw_update_fw_mng_features {
	u8	start_cmd_payload_size;
	u16	max_duration_start;
	u16	max_duration_write;
	u16	max_duration_complete;
};

/* See section 9.4.2 "CMD 0041h: Firmware Management Features" in CMIS standard
 * revision 5.2.
 * struct cmis_cdb_fw_mng_features_rpl is a structured layout of the flat
 * array, ethtool_cmis_cdb_rpl::payload.
 */
struct cmis_cdb_fw_mng_features_rpl {
	u8	resv1;
	u8	resv2;
	u8	start_cmd_payload_size;
	u8	resv3;
	u8	read_write_len_ext;
	u8	write_mechanism;
	u8	resv4;
	u8	resv5;
	__be16	max_duration_start;
	__be16	resv6;
	__be16	max_duration_write;
	__be16	max_duration_complete;
	__be16	resv7;
};

#define CMIS_CDB_FW_WRITE_MECHANISM_LPL	0x01

static int
cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
				   struct net_device *dev,
				   struct cmis_fw_update_fw_mng_features *fw_mng,
				   struct ethnl_module_fw_flash_ntf_params *ntf_params)
{
	struct ethtool_cmis_cdb_cmd_args args = {};
	struct cmis_cdb_fw_mng_features_rpl *rpl;
	u8 flags = CDB_F_STATUS_VALID;
	int err;

	ethtool_cmis_cdb_check_completion_flag(cdb->cmis_rev, &flags);
	ethtool_cmis_cdb_compose_args(&args,
				      ETHTOOL_CMIS_CDB_CMD_FW_MANAGMENT_FEATURES,
				      NULL, 0, cdb->max_completion_time,
				      cdb->read_write_len_ext, 1000,
				      sizeof(*rpl), flags);

	err = ethtool_cmis_cdb_execute_cmd(dev, &args);
	if (err < 0) {
		ethnl_module_fw_flash_ntf_err(dev, ntf_params,
					      "FW Management Features command failed",
					      args.err_msg);
		return err;
	}

	rpl = (struct cmis_cdb_fw_mng_features_rpl *)args.req.payload;
	if (!(rpl->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_LPL)) {
		ethnl_module_fw_flash_ntf_err(dev, ntf_params,
					      "Write LPL is not supported",
					      NULL);
		return  -EOPNOTSUPP;
	}

	/* Above, we used read_write_len_ext that we got from CDB
	 * advertisement. Update it with the value that we got from module
	 * features query, which is specific for Firmware Management Commands
	 * (IDs 0100h-01FFh).
	 */
	cdb->read_write_len_ext = rpl->read_write_len_ext;
	fw_mng->start_cmd_payload_size = rpl->start_cmd_payload_size;
	fw_mng->max_duration_start = be16_to_cpu(rpl->max_duration_start);
	fw_mng->max_duration_write = be16_to_cpu(rpl->max_duration_write);
	fw_mng->max_duration_complete = be16_to_cpu(rpl->max_duration_complete);

	return 0;
}

/* See section 9.7.2 "CMD 0101h: Start Firmware Download" in CMIS standard
 * revision 5.2.
 * struct cmis_cdb_start_fw_download_pl is a structured layout of the
 * flat array, ethtool_cmis_cdb_request::payload.
 */
struct cmis_cdb_start_fw_download_pl {
	__struct_group(cmis_cdb_start_fw_download_pl_h, head, /* no attrs */,
			__be32	image_size;
			__be32	resv1;
	);
	u8 vendor_data[ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH -
		sizeof(struct cmis_cdb_start_fw_download_pl_h)];
};

static int
cmis_fw_update_start_download(struct ethtool_cmis_cdb *cdb,
			      struct ethtool_cmis_fw_update_params *fw_update,
			      struct cmis_fw_update_fw_mng_features *fw_mng)
{
	u8 vendor_data_size = fw_mng->start_cmd_payload_size;
	struct cmis_cdb_start_fw_download_pl pl = {};
	struct ethtool_cmis_cdb_cmd_args args = {};
	u8 lpl_len;
	int err;

	pl.image_size = cpu_to_be32(fw_update->fw->size);
	memcpy(pl.vendor_data, fw_update->fw->data, vendor_data_size);

	lpl_len = offsetof(struct cmis_cdb_start_fw_download_pl,
			   vendor_data[vendor_data_size]);

	ethtool_cmis_cdb_compose_args(&args,
				      ETHTOOL_CMIS_CDB_CMD_START_FW_DOWNLOAD,
				      (u8 *)&pl, lpl_len,
				      fw_mng->max_duration_start,
				      cdb->read_write_len_ext, 1000, 0,
				      CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);

	err = ethtool_cmis_cdb_execute_cmd(fw_update->dev, &args);
	if (err < 0)
		ethnl_module_fw_flash_ntf_err(fw_update->dev,
					      &fw_update->ntf_params,
					      "Start FW download command failed",
					      args.err_msg);

	return err;
}

/* See section 9.7.4 "CMD 0103h: Write Firmware Block LPL" in CMIS standard
 * revision 5.2.
 * struct cmis_cdb_write_fw_block_lpl_pl is a structured layout of the
 * flat array, ethtool_cmis_cdb_request::payload.
 */
struct cmis_cdb_write_fw_block_lpl_pl {
	__be32	block_address;
	u8 fw_block[ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH - sizeof(__be32)];
};

static int
cmis_fw_update_write_image(struct ethtool_cmis_cdb *cdb,
			   struct ethtool_cmis_fw_update_params *fw_update,
			   struct cmis_fw_update_fw_mng_features *fw_mng)
{
	u8 start = fw_mng->start_cmd_payload_size;
	u32 offset, max_block_size, max_lpl_len;
	u32 image_size = fw_update->fw->size;
	int err;

	max_lpl_len = min_t(u32,
			    ethtool_cmis_get_max_payload_size(cdb->read_write_len_ext),
			    ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH);
	max_block_size =
		max_lpl_len - sizeof_field(struct cmis_cdb_write_fw_block_lpl_pl,
					   block_address);

	for (offset = start; offset < image_size; offset += max_block_size) {
		struct cmis_cdb_write_fw_block_lpl_pl pl = {
			.block_address = cpu_to_be32(offset - start),
		};
		struct ethtool_cmis_cdb_cmd_args args = {};
		u32 block_size, lpl_len;

		ethnl_module_fw_flash_ntf_in_progress(fw_update->dev,
						      &fw_update->ntf_params,
						      offset - start,
						      image_size);
		block_size = min_t(u32, max_block_size, image_size - offset);
		memcpy(pl.fw_block, &fw_update->fw->data[offset], block_size);
		lpl_len = block_size +
			sizeof_field(struct cmis_cdb_write_fw_block_lpl_pl,
				     block_address);

		ethtool_cmis_cdb_compose_args(&args,
					      ETHTOOL_CMIS_CDB_CMD_WRITE_FW_BLOCK_LPL,
					      (u8 *)&pl, lpl_len,
					      fw_mng->max_duration_write,
					      cdb->read_write_len_ext, 1, 0,
					      CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);

		err = ethtool_cmis_cdb_execute_cmd(fw_update->dev, &args);
		if (err < 0) {
			ethnl_module_fw_flash_ntf_err(fw_update->dev,
						      &fw_update->ntf_params,
						      "Write FW block LPL command failed",
						      args.err_msg);
			return err;
		}
	}

	return 0;
}

static int
cmis_fw_update_complete_download(struct ethtool_cmis_cdb *cdb,
				 struct net_device *dev,
				 struct cmis_fw_update_fw_mng_features *fw_mng,
				 struct ethnl_module_fw_flash_ntf_params *ntf_params)
{
	struct ethtool_cmis_cdb_cmd_args args = {};
	int err;

	ethtool_cmis_cdb_compose_args(&args,
				      ETHTOOL_CMIS_CDB_CMD_COMPLETE_FW_DOWNLOAD,
				      NULL, 0, fw_mng->max_duration_complete,
				      cdb->read_write_len_ext, 1000, 0,
				      CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);

	err = ethtool_cmis_cdb_execute_cmd(dev, &args);
	if (err < 0)
		ethnl_module_fw_flash_ntf_err(dev, ntf_params,
					      "Complete FW download command failed",
					      args.err_msg);

	return err;
}

static int
cmis_fw_update_download_image(struct ethtool_cmis_cdb *cdb,
			      struct ethtool_cmis_fw_update_params *fw_update,
			      struct cmis_fw_update_fw_mng_features *fw_mng)
{
	int err;

	err = cmis_fw_update_start_download(cdb, fw_update, fw_mng);
	if (err < 0)
		return err;

	err = cmis_fw_update_write_image(cdb, fw_update, fw_mng);
	if (err < 0)
		return err;

	err = cmis_fw_update_complete_download(cdb, fw_update->dev, fw_mng,
					       &fw_update->ntf_params);
	if (err < 0)
		return err;

	return 0;
}

enum {
	CMIS_MODULE_LOW_PWR	= 1,
	CMIS_MODULE_READY	= 3,
};

static bool module_is_ready(u8 data)
{
	u8 state = (data >> 1) & 7;

	return state == CMIS_MODULE_READY || state == CMIS_MODULE_LOW_PWR;
}

#define CMIS_MODULE_READY_MAX_DURATION_MSEC	1000
#define CMIS_MODULE_STATE_OFFSET		3

static int
cmis_fw_update_wait_for_module_state(struct net_device *dev, u8 flags)
{
	u8 state;

	return ethtool_cmis_wait_for_cond(dev, flags, CDB_F_MODULE_STATE_VALID,
					  CMIS_MODULE_READY_MAX_DURATION_MSEC,
					  CMIS_MODULE_STATE_OFFSET,
					  module_is_ready, NULL, &state);
}

/* See section 9.7.10 "CMD 0109h: Run Firmware Image" in CMIS standard
 * revision 5.2.
 * struct cmis_cdb_run_fw_image_pl is a structured layout of the flat
 * array, ethtool_cmis_cdb_request::payload.
 */
struct cmis_cdb_run_fw_image_pl {
	u8 resv1;
	u8 image_to_run;
	u16 delay_to_reset;
};

static int
cmis_fw_update_run_image(struct ethtool_cmis_cdb *cdb, struct net_device *dev,
			 struct ethnl_module_fw_flash_ntf_params *ntf_params)
{
	struct ethtool_cmis_cdb_cmd_args args = {};
	struct cmis_cdb_run_fw_image_pl pl = {0};
	int err;

	ethtool_cmis_cdb_compose_args(&args, ETHTOOL_CMIS_CDB_CMD_RUN_FW_IMAGE,
				      (u8 *)&pl, sizeof(pl),
				      cdb->max_completion_time,
				      cdb->read_write_len_ext, 1000, 0,
				      CDB_F_MODULE_STATE_VALID);

	err = ethtool_cmis_cdb_execute_cmd(dev, &args);
	if (err < 0) {
		ethnl_module_fw_flash_ntf_err(dev, ntf_params,
					      "Run image command failed",
					      args.err_msg);
		return err;
	}

	err = cmis_fw_update_wait_for_module_state(dev, args.flags);
	if (err < 0)
		ethnl_module_fw_flash_ntf_err(dev, ntf_params,
					      "Module is not ready on time after reset",
					      NULL);

	return err;
}

static int
cmis_fw_update_commit_image(struct ethtool_cmis_cdb *cdb,
			    struct net_device *dev,
			    struct ethnl_module_fw_flash_ntf_params *ntf_params)
{
	struct ethtool_cmis_cdb_cmd_args args = {};
	int err;

	ethtool_cmis_cdb_compose_args(&args,
				      ETHTOOL_CMIS_CDB_CMD_COMMIT_FW_IMAGE,
				      NULL, 0, cdb->max_completion_time,
				      cdb->read_write_len_ext, 1000, 0,
				      CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);

	err = ethtool_cmis_cdb_execute_cmd(dev, &args);
	if (err < 0)
		ethnl_module_fw_flash_ntf_err(dev, ntf_params,
					      "Commit image command failed",
					      args.err_msg);

	return err;
}

static int cmis_fw_update_reset(struct net_device *dev)
{
	__u32 reset_data = ETH_RESET_PHY;

	return dev->ethtool_ops->reset(dev, &reset_data);
}

void
ethtool_cmis_fw_update(struct ethtool_cmis_fw_update_params *fw_update)
{
	struct ethnl_module_fw_flash_ntf_params *ntf_params =
						&fw_update->ntf_params;
	struct cmis_fw_update_fw_mng_features fw_mng = {0};
	struct net_device *dev = fw_update->dev;
	struct ethtool_cmis_cdb *cdb;
	int err;

	cdb = ethtool_cmis_cdb_init(dev, &fw_update->params, ntf_params);
	if (IS_ERR(cdb))
		goto err_send_ntf;

	ethnl_module_fw_flash_ntf_start(dev, ntf_params);

	err = cmis_fw_update_fw_mng_features_get(cdb, dev, &fw_mng, ntf_params);
	if (err < 0)
		goto err_cdb_fini;

	err = cmis_fw_update_download_image(cdb, fw_update, &fw_mng);
	if (err < 0)
		goto err_cdb_fini;

	err = cmis_fw_update_run_image(cdb, dev, ntf_params);
	if (err < 0)
		goto err_cdb_fini;

	/* The CDB command "Run Firmware Image" resets the firmware, so the new
	 * one might have different settings.
	 * Free the old CDB instance, and init a new one.
	 */
	ethtool_cmis_cdb_fini(cdb);

	cdb = ethtool_cmis_cdb_init(dev, &fw_update->params, ntf_params);
	if (IS_ERR(cdb))
		goto err_send_ntf;

	err = cmis_fw_update_commit_image(cdb, dev, ntf_params);
	if (err < 0)
		goto err_cdb_fini;

	err = cmis_fw_update_reset(dev);
	if (err < 0)
		goto err_cdb_fini;

	ethnl_module_fw_flash_ntf_complete(dev, ntf_params);
	ethtool_cmis_cdb_fini(cdb);
	return;

err_cdb_fini:
	ethtool_cmis_cdb_fini(cdb);
err_send_ntf:
	ethnl_module_fw_flash_ntf_err(dev, ntf_params, NULL, NULL);
}
