// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2022, Intel Corporation. */

#include <linux/vmalloc.h>
#include "ice.h"
#include "ice_common.h"
#include "ice_fwlog.h"

bool ice_fwlog_ring_full(struct ice_fwlog_ring *rings)
{
	u16 head, tail;

	head = rings->head;
	tail = rings->tail;

	if (head < tail && (tail - head == (rings->size - 1)))
		return true;
	else if (head > tail && (tail == (head - 1)))
		return true;

	return false;
}

bool ice_fwlog_ring_empty(struct ice_fwlog_ring *rings)
{
	return rings->head == rings->tail;
}

void ice_fwlog_ring_increment(u16 *item, u16 size)
{
	*item = (*item + 1) & (size - 1);
}

static int ice_fwlog_alloc_ring_buffs(struct ice_fwlog_ring *rings)
{
	int i, nr_bytes;
	u8 *mem;

	nr_bytes = rings->size * ICE_AQ_MAX_BUF_LEN;
	mem = vzalloc(nr_bytes);
	if (!mem)
		return -ENOMEM;

	for (i = 0; i < rings->size; i++) {
		struct ice_fwlog_data *ring = &rings->rings[i];

		ring->data_size = ICE_AQ_MAX_BUF_LEN;
		ring->data = mem;
		mem += ICE_AQ_MAX_BUF_LEN;
	}

	return 0;
}

static void ice_fwlog_free_ring_buffs(struct ice_fwlog_ring *rings)
{
	int i;

	for (i = 0; i < rings->size; i++) {
		struct ice_fwlog_data *ring = &rings->rings[i];

		/* the first ring is the base memory for the whole range so
		 * free it
		 */
		if (!i)
			vfree(ring->data);

		ring->data = NULL;
		ring->data_size = 0;
	}
}

#define ICE_FWLOG_INDEX_TO_BYTES(n) ((128 * 1024) << (n))
/**
 * ice_fwlog_realloc_rings - reallocate the FW log rings
 * @hw: pointer to the HW structure
 * @index: the new index to use to allocate memory for the log data
 *
 */
void ice_fwlog_realloc_rings(struct ice_hw *hw, int index)
{
	struct ice_fwlog_ring ring;
	int status, ring_size;

	/* convert the number of bytes into a number of 4K buffers. externally
	 * the driver presents the interface to the FW log data as a number of
	 * bytes because that's easy for users to understand. internally the
	 * driver uses a ring of buffers because the driver doesn't know where
	 * the beginning and end of any line of log data is so the driver has
	 * to overwrite data as complete blocks. when the data is returned to
	 * the user the driver knows that the data is correct and the FW log
	 * can be correctly parsed by the tools
	 */
	ring_size = ICE_FWLOG_INDEX_TO_BYTES(index) / ICE_AQ_MAX_BUF_LEN;
	if (ring_size == hw->fwlog_ring.size)
		return;

	/* allocate space for the new rings and buffers then release the
	 * old rings and buffers. that way if we don't have enough
	 * memory then we at least have what we had before
	 */
	ring.rings = kcalloc(ring_size, sizeof(*ring.rings), GFP_KERNEL);
	if (!ring.rings)
		return;

	ring.size = ring_size;

	status = ice_fwlog_alloc_ring_buffs(&ring);
	if (status) {
		dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log ring data buffers\n");
		ice_fwlog_free_ring_buffs(&ring);
		kfree(ring.rings);
		return;
	}

	ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
	kfree(hw->fwlog_ring.rings);

	hw->fwlog_ring.rings = ring.rings;
	hw->fwlog_ring.size = ring.size;
	hw->fwlog_ring.index = index;
	hw->fwlog_ring.head = 0;
	hw->fwlog_ring.tail = 0;
}

/**
 * ice_fwlog_init - Initialize FW logging configuration
 * @hw: pointer to the HW structure
 *
 * This function should be called on driver initialization during
 * ice_init_hw().
 */
int ice_fwlog_init(struct ice_hw *hw)
{
	/* only support fw log commands on PF 0 */
	if (hw->bus.func)
		return -EINVAL;

	ice_fwlog_set_supported(hw);

	if (ice_fwlog_supported(hw)) {
		int status;

		/* read the current config from the FW and store it */
		status = ice_fwlog_get(hw, &hw->fwlog_cfg);
		if (status)
			return status;

		hw->fwlog_ring.rings = kcalloc(ICE_FWLOG_RING_SIZE_DFLT,
					       sizeof(*hw->fwlog_ring.rings),
					       GFP_KERNEL);
		if (!hw->fwlog_ring.rings) {
			dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log rings\n");
			return -ENOMEM;
		}

		hw->fwlog_ring.size = ICE_FWLOG_RING_SIZE_DFLT;
		hw->fwlog_ring.index = ICE_FWLOG_RING_SIZE_INDEX_DFLT;

		status = ice_fwlog_alloc_ring_buffs(&hw->fwlog_ring);
		if (status) {
			dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log ring data buffers\n");
			ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
			kfree(hw->fwlog_ring.rings);
			return status;
		}

		ice_debugfs_fwlog_init(hw->back);
	} else {
		dev_warn(ice_hw_to_dev(hw), "FW logging is not supported in this NVM image. Please update the NVM to get FW log support\n");
	}

	return 0;
}

/**
 * ice_fwlog_deinit - unroll FW logging configuration
 * @hw: pointer to the HW structure
 *
 * This function should be called in ice_deinit_hw().
 */
void ice_fwlog_deinit(struct ice_hw *hw)
{
	struct ice_pf *pf = hw->back;
	int status;

	/* only support fw log commands on PF 0 */
	if (hw->bus.func)
		return;

	/* make sure FW logging is disabled to not put the FW in a weird state
	 * for the next driver load
	 */
	hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_ARQ_ENA;
	status = ice_fwlog_set(hw, &hw->fwlog_cfg);
	if (status)
		dev_warn(ice_hw_to_dev(hw), "Unable to turn off FW logging, status: %d\n",
			 status);

	kfree(pf->ice_debugfs_pf_fwlog_modules);

	pf->ice_debugfs_pf_fwlog_modules = NULL;

	status = ice_fwlog_unregister(hw);
	if (status)
		dev_warn(ice_hw_to_dev(hw), "Unable to unregister FW logging, status: %d\n",
			 status);

	if (hw->fwlog_ring.rings) {
		ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
		kfree(hw->fwlog_ring.rings);
	}
}

/**
 * ice_fwlog_supported - Cached for whether FW supports FW logging or not
 * @hw: pointer to the HW structure
 *
 * This will always return false if called before ice_init_hw(), so it must be
 * called after ice_init_hw().
 */
bool ice_fwlog_supported(struct ice_hw *hw)
{
	return hw->fwlog_supported;
}

/**
 * ice_aq_fwlog_set - Set FW logging configuration AQ command (0xFF30)
 * @hw: pointer to the HW structure
 * @entries: entries to configure
 * @num_entries: number of @entries
 * @options: options from ice_fwlog_cfg->options structure
 * @log_resolution: logging resolution
 */
static int
ice_aq_fwlog_set(struct ice_hw *hw, struct ice_fwlog_module_entry *entries,
		 u16 num_entries, u16 options, u16 log_resolution)
{
	struct ice_aqc_fw_log_cfg_resp *fw_modules;
	struct ice_aqc_fw_log *cmd;
	struct ice_aq_desc desc;
	int status;
	int i;

	fw_modules = kcalloc(num_entries, sizeof(*fw_modules), GFP_KERNEL);
	if (!fw_modules)
		return -ENOMEM;

	for (i = 0; i < num_entries; i++) {
		fw_modules[i].module_identifier =
			cpu_to_le16(entries[i].module_id);
		fw_modules[i].log_level = entries[i].log_level;
	}

	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_config);
	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);

	cmd = &desc.params.fw_log;

	cmd->cmd_flags = ICE_AQC_FW_LOG_CONF_SET_VALID;
	cmd->ops.cfg.log_resolution = cpu_to_le16(log_resolution);
	cmd->ops.cfg.mdl_cnt = cpu_to_le16(num_entries);

	if (options & ICE_FWLOG_OPTION_ARQ_ENA)
		cmd->cmd_flags |= ICE_AQC_FW_LOG_CONF_AQ_EN;
	if (options & ICE_FWLOG_OPTION_UART_ENA)
		cmd->cmd_flags |= ICE_AQC_FW_LOG_CONF_UART_EN;

	status = ice_aq_send_cmd(hw, &desc, fw_modules,
				 sizeof(*fw_modules) * num_entries,
				 NULL);

	kfree(fw_modules);

	return status;
}

/**
 * ice_fwlog_set - Set the firmware logging settings
 * @hw: pointer to the HW structure
 * @cfg: config used to set firmware logging
 *
 * This function should be called whenever the driver needs to set the firmware
 * logging configuration. It can be called on initialization, reset, or during
 * runtime.
 *
 * If the PF wishes to receive FW logging then it must register via
 * ice_fwlog_register. Note, that ice_fwlog_register does not need to be called
 * for init.
 */
int ice_fwlog_set(struct ice_hw *hw, struct ice_fwlog_cfg *cfg)
{
	if (!ice_fwlog_supported(hw))
		return -EOPNOTSUPP;

	return ice_aq_fwlog_set(hw, cfg->module_entries,
				ICE_AQC_FW_LOG_ID_MAX, cfg->options,
				cfg->log_resolution);
}

/**
 * ice_aq_fwlog_get - Get the current firmware logging configuration (0xFF32)
 * @hw: pointer to the HW structure
 * @cfg: firmware logging configuration to populate
 */
static int ice_aq_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg)
{
	struct ice_aqc_fw_log_cfg_resp *fw_modules;
	struct ice_aqc_fw_log *cmd;
	struct ice_aq_desc desc;
	u16 module_id_cnt;
	int status;
	void *buf;
	int i;

	memset(cfg, 0, sizeof(*cfg));

	buf = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_query);
	cmd = &desc.params.fw_log;

	cmd->cmd_flags = ICE_AQC_FW_LOG_AQ_QUERY;

	status = ice_aq_send_cmd(hw, &desc, buf, ICE_AQ_MAX_BUF_LEN, NULL);
	if (status) {
		ice_debug(hw, ICE_DBG_FW_LOG, "Failed to get FW log configuration\n");
		goto status_out;
	}

	module_id_cnt = le16_to_cpu(cmd->ops.cfg.mdl_cnt);
	if (module_id_cnt < ICE_AQC_FW_LOG_ID_MAX) {
		ice_debug(hw, ICE_DBG_FW_LOG, "FW returned less than the expected number of FW log module IDs\n");
	} else if (module_id_cnt > ICE_AQC_FW_LOG_ID_MAX) {
		ice_debug(hw, ICE_DBG_FW_LOG, "FW returned more than expected number of FW log module IDs, setting module_id_cnt to software expected max %u\n",
			  ICE_AQC_FW_LOG_ID_MAX);
		module_id_cnt = ICE_AQC_FW_LOG_ID_MAX;
	}

	cfg->log_resolution = le16_to_cpu(cmd->ops.cfg.log_resolution);
	if (cmd->cmd_flags & ICE_AQC_FW_LOG_CONF_AQ_EN)
		cfg->options |= ICE_FWLOG_OPTION_ARQ_ENA;
	if (cmd->cmd_flags & ICE_AQC_FW_LOG_CONF_UART_EN)
		cfg->options |= ICE_FWLOG_OPTION_UART_ENA;
	if (cmd->cmd_flags & ICE_AQC_FW_LOG_QUERY_REGISTERED)
		cfg->options |= ICE_FWLOG_OPTION_IS_REGISTERED;

	fw_modules = (struct ice_aqc_fw_log_cfg_resp *)buf;

	for (i = 0; i < module_id_cnt; i++) {
		struct ice_aqc_fw_log_cfg_resp *fw_module = &fw_modules[i];

		cfg->module_entries[i].module_id =
			le16_to_cpu(fw_module->module_identifier);
		cfg->module_entries[i].log_level = fw_module->log_level;
	}

status_out:
	kfree(buf);
	return status;
}

/**
 * ice_fwlog_get - Get the firmware logging settings
 * @hw: pointer to the HW structure
 * @cfg: config to populate based on current firmware logging settings
 */
int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg)
{
	if (!ice_fwlog_supported(hw))
		return -EOPNOTSUPP;

	return ice_aq_fwlog_get(hw, cfg);
}

/**
 * ice_aq_fwlog_register - Register PF for firmware logging events (0xFF31)
 * @hw: pointer to the HW structure
 * @reg: true to register and false to unregister
 */
static int ice_aq_fwlog_register(struct ice_hw *hw, bool reg)
{
	struct ice_aq_desc desc;

	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_register);

	if (reg)
		desc.params.fw_log.cmd_flags = ICE_AQC_FW_LOG_AQ_REGISTER;

	return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
}

/**
 * ice_fwlog_register - Register the PF for firmware logging
 * @hw: pointer to the HW structure
 *
 * After this call the PF will start to receive firmware logging based on the
 * configuration set in ice_fwlog_set.
 */
int ice_fwlog_register(struct ice_hw *hw)
{
	int status;

	if (!ice_fwlog_supported(hw))
		return -EOPNOTSUPP;

	status = ice_aq_fwlog_register(hw, true);
	if (status)
		ice_debug(hw, ICE_DBG_FW_LOG, "Failed to register for firmware logging events over ARQ\n");
	else
		hw->fwlog_cfg.options |= ICE_FWLOG_OPTION_IS_REGISTERED;

	return status;
}

/**
 * ice_fwlog_unregister - Unregister the PF from firmware logging
 * @hw: pointer to the HW structure
 */
int ice_fwlog_unregister(struct ice_hw *hw)
{
	int status;

	if (!ice_fwlog_supported(hw))
		return -EOPNOTSUPP;

	status = ice_aq_fwlog_register(hw, false);
	if (status)
		ice_debug(hw, ICE_DBG_FW_LOG, "Failed to unregister from firmware logging events over ARQ\n");
	else
		hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_IS_REGISTERED;

	return status;
}

/**
 * ice_fwlog_set_supported - Set if FW logging is supported by FW
 * @hw: pointer to the HW struct
 *
 * If FW returns success to the ice_aq_fwlog_get call then it supports FW
 * logging, else it doesn't. Set the fwlog_supported flag accordingly.
 *
 * This function is only meant to be called during driver init to determine if
 * the FW support FW logging.
 */
void ice_fwlog_set_supported(struct ice_hw *hw)
{
	struct ice_fwlog_cfg *cfg;
	int status;

	hw->fwlog_supported = false;

	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
	if (!cfg)
		return;

	/* don't call ice_fwlog_get() because that would check to see if FW
	 * logging is supported which is what the driver is determining now
	 */
	status = ice_aq_fwlog_get(hw, cfg);
	if (status)
		ice_debug(hw, ICE_DBG_FW_LOG, "ice_aq_fwlog_get failed, FW logging is not supported on this version of FW, status %d\n",
			  status);
	else
		hw->fwlog_supported = true;

	kfree(cfg);
}
