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

#include "i40e.h"

#include <linux/firmware.h>

/**
 * i40e_ddp_profiles_eq - checks if DDP profiles are the equivalent
 * @a: new profile info
 * @b: old profile info
 *
 * checks if DDP profiles are the equivalent.
 * Returns true if profiles are the same.
 **/
static bool i40e_ddp_profiles_eq(struct i40e_profile_info *a,
				 struct i40e_profile_info *b)
{
	return a->track_id == b->track_id &&
		!memcmp(&a->version, &b->version, sizeof(a->version)) &&
		!memcmp(&a->name, &b->name, I40E_DDP_NAME_SIZE);
}

/**
 * i40e_ddp_does_profile_exist - checks if DDP profile loaded already
 * @hw: HW data structure
 * @pinfo: DDP profile information structure
 *
 * checks if DDP profile loaded already.
 * Returns >0 if the profile exists.
 * Returns  0 if the profile is absent.
 * Returns <0 if error.
 **/
static int i40e_ddp_does_profile_exist(struct i40e_hw *hw,
				       struct i40e_profile_info *pinfo)
{
	struct i40e_ddp_profile_list *profile_list;
	u8 buff[I40E_PROFILE_LIST_SIZE];
	int status;
	int i;

	status = i40e_aq_get_ddp_list(hw, buff, I40E_PROFILE_LIST_SIZE, 0,
				      NULL);
	if (status)
		return -1;

	profile_list = (struct i40e_ddp_profile_list *)buff;
	for (i = 0; i < profile_list->p_count; i++) {
		if (i40e_ddp_profiles_eq(pinfo, &profile_list->p_info[i]))
			return 1;
	}
	return 0;
}

/**
 * i40e_ddp_profiles_overlap - checks if DDP profiles overlap.
 * @new: new profile info
 * @old: old profile info
 *
 * checks if DDP profiles overlap.
 * Returns true if profiles are overlap.
 **/
static bool i40e_ddp_profiles_overlap(struct i40e_profile_info *new,
				      struct i40e_profile_info *old)
{
	unsigned int group_id_old = (u8)((old->track_id & 0x00FF0000) >> 16);
	unsigned int group_id_new = (u8)((new->track_id & 0x00FF0000) >> 16);

	/* 0x00 group must be only the first */
	if (group_id_new == 0)
		return true;
	/* 0xFF group is compatible with anything else */
	if (group_id_new == 0xFF || group_id_old == 0xFF)
		return false;
	/* otherwise only profiles from the same group are compatible*/
	return group_id_old != group_id_new;
}

/**
 * i40e_ddp_does_profile_overlap - checks if DDP overlaps with existing one.
 * @hw: HW data structure
 * @pinfo: DDP profile information structure
 *
 * checks if DDP profile overlaps with existing one.
 * Returns >0 if the profile overlaps.
 * Returns  0 if the profile is ok.
 * Returns <0 if error.
 **/
static int i40e_ddp_does_profile_overlap(struct i40e_hw *hw,
					 struct i40e_profile_info *pinfo)
{
	struct i40e_ddp_profile_list *profile_list;
	u8 buff[I40E_PROFILE_LIST_SIZE];
	int status;
	int i;

	status = i40e_aq_get_ddp_list(hw, buff, I40E_PROFILE_LIST_SIZE, 0,
				      NULL);
	if (status)
		return -EIO;

	profile_list = (struct i40e_ddp_profile_list *)buff;
	for (i = 0; i < profile_list->p_count; i++) {
		if (i40e_ddp_profiles_overlap(pinfo,
					      &profile_list->p_info[i]))
			return 1;
	}
	return 0;
}

/**
 * i40e_add_pinfo
 * @hw: pointer to the hardware structure
 * @profile: pointer to the profile segment of the package
 * @profile_info_sec: buffer for information section
 * @track_id: package tracking id
 *
 * Register a profile to the list of loaded profiles.
 */
static int
i40e_add_pinfo(struct i40e_hw *hw, struct i40e_profile_segment *profile,
	       u8 *profile_info_sec, u32 track_id)
{
	struct i40e_profile_section_header *sec;
	struct i40e_profile_info *pinfo;
	u32 offset = 0, info = 0;
	int status;

	sec = (struct i40e_profile_section_header *)profile_info_sec;
	sec->tbl_size = 1;
	sec->data_end = sizeof(struct i40e_profile_section_header) +
			sizeof(struct i40e_profile_info);
	sec->section.type = SECTION_TYPE_INFO;
	sec->section.offset = sizeof(struct i40e_profile_section_header);
	sec->section.size = sizeof(struct i40e_profile_info);
	pinfo = (struct i40e_profile_info *)(profile_info_sec +
					     sec->section.offset);
	pinfo->track_id = track_id;
	pinfo->version = profile->version;
	pinfo->op = I40E_DDP_ADD_TRACKID;

	/* Clear reserved field */
	memset(pinfo->reserved, 0, sizeof(pinfo->reserved));
	memcpy(pinfo->name, profile->name, I40E_DDP_NAME_SIZE);

	status = i40e_aq_write_ddp(hw, (void *)sec, sec->data_end,
				   track_id, &offset, &info, NULL);
	return status;
}

/**
 * i40e_del_pinfo - delete DDP profile info from NIC
 * @hw: HW data structure
 * @profile: DDP profile segment to be deleted
 * @profile_info_sec: DDP profile section header
 * @track_id: track ID of the profile for deletion
 *
 * Removes DDP profile from the NIC.
 **/
static int
i40e_del_pinfo(struct i40e_hw *hw, struct i40e_profile_segment *profile,
	       u8 *profile_info_sec, u32 track_id)
{
	struct i40e_profile_section_header *sec;
	struct i40e_profile_info *pinfo;
	u32 offset = 0, info = 0;
	int status;

	sec = (struct i40e_profile_section_header *)profile_info_sec;
	sec->tbl_size = 1;
	sec->data_end = sizeof(struct i40e_profile_section_header) +
			sizeof(struct i40e_profile_info);
	sec->section.type = SECTION_TYPE_INFO;
	sec->section.offset = sizeof(struct i40e_profile_section_header);
	sec->section.size = sizeof(struct i40e_profile_info);
	pinfo = (struct i40e_profile_info *)(profile_info_sec +
					     sec->section.offset);
	pinfo->track_id = track_id;
	pinfo->version = profile->version;
	pinfo->op = I40E_DDP_REMOVE_TRACKID;

	/* Clear reserved field */
	memset(pinfo->reserved, 0, sizeof(pinfo->reserved));
	memcpy(pinfo->name, profile->name, I40E_DDP_NAME_SIZE);

	status = i40e_aq_write_ddp(hw, (void *)sec, sec->data_end,
				   track_id, &offset, &info, NULL);
	return status;
}

/**
 * i40e_ddp_is_pkg_hdr_valid - performs basic pkg header integrity checks
 * @netdev: net device structure (for logging purposes)
 * @pkg_hdr: pointer to package header
 * @size_huge: size of the whole DDP profile package in size_t
 *
 * Checks correctness of pkg header: Version, size too big/small, and
 * all segment offsets alignment and boundaries. This function lets
 * reject non DDP profile file to be loaded by administrator mistake.
 **/
static bool i40e_ddp_is_pkg_hdr_valid(struct net_device *netdev,
				      struct i40e_package_header *pkg_hdr,
				      size_t size_huge)
{
	u32 size = 0xFFFFFFFFU & size_huge;
	u32 pkg_hdr_size;
	u32 segment;

	if (!pkg_hdr)
		return false;

	if (pkg_hdr->version.major > 0) {
		struct i40e_ddp_version ver = pkg_hdr->version;

		netdev_err(netdev, "Unsupported DDP profile version %u.%u.%u.%u",
			   ver.major, ver.minor, ver.update, ver.draft);
		return false;
	}
	if (size_huge > size) {
		netdev_err(netdev, "Invalid DDP profile - size is bigger than 4G");
		return false;
	}
	if (size < (sizeof(struct i40e_package_header) +
		sizeof(struct i40e_metadata_segment) + sizeof(u32) * 2)) {
		netdev_err(netdev, "Invalid DDP profile - size is too small.");
		return false;
	}

	pkg_hdr_size = sizeof(u32) * (pkg_hdr->segment_count + 2U);
	if (size < pkg_hdr_size) {
		netdev_err(netdev, "Invalid DDP profile - too many segments");
		return false;
	}
	for (segment = 0; segment < pkg_hdr->segment_count; ++segment) {
		u32 offset = pkg_hdr->segment_offset[segment];

		if (0xFU & offset) {
			netdev_err(netdev,
				   "Invalid DDP profile %u segment alignment",
				   segment);
			return false;
		}
		if (pkg_hdr_size > offset || offset >= size) {
			netdev_err(netdev,
				   "Invalid DDP profile %u segment offset",
				   segment);
			return false;
		}
	}

	return true;
}

/**
 * i40e_ddp_load - performs DDP loading
 * @netdev: net device structure
 * @data: buffer containing recipe file
 * @size: size of the buffer
 * @is_add: true when loading profile, false when rolling back the previous one
 *
 * Checks correctness and loads DDP profile to the NIC. The function is
 * also used for rolling back previously loaded profile.
 **/
int i40e_ddp_load(struct net_device *netdev, const u8 *data, size_t size,
		  bool is_add)
{
	u8 profile_info_sec[sizeof(struct i40e_profile_section_header) +
			    sizeof(struct i40e_profile_info)];
	struct i40e_metadata_segment *metadata_hdr;
	struct i40e_profile_segment *profile_hdr;
	struct i40e_profile_info pinfo;
	struct i40e_package_header *pkg_hdr;
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	struct i40e_vsi *vsi = np->vsi;
	struct i40e_pf *pf = vsi->back;
	u32 track_id;
	int istatus;
	int status;

	pkg_hdr = (struct i40e_package_header *)data;
	if (!i40e_ddp_is_pkg_hdr_valid(netdev, pkg_hdr, size))
		return -EINVAL;

	if (size < (sizeof(struct i40e_package_header) +
		    sizeof(struct i40e_metadata_segment) + sizeof(u32) * 2)) {
		netdev_err(netdev, "Invalid DDP recipe size.");
		return -EINVAL;
	}

	/* Find beginning of segment data in buffer */
	metadata_hdr = (struct i40e_metadata_segment *)
		i40e_find_segment_in_package(SEGMENT_TYPE_METADATA, pkg_hdr);
	if (!metadata_hdr) {
		netdev_err(netdev, "Failed to find metadata segment in DDP recipe.");
		return -EINVAL;
	}

	track_id = metadata_hdr->track_id;
	profile_hdr = (struct i40e_profile_segment *)
		i40e_find_segment_in_package(SEGMENT_TYPE_I40E, pkg_hdr);
	if (!profile_hdr) {
		netdev_err(netdev, "Failed to find profile segment in DDP recipe.");
		return -EINVAL;
	}

	pinfo.track_id = track_id;
	pinfo.version = profile_hdr->version;
	if (is_add)
		pinfo.op = I40E_DDP_ADD_TRACKID;
	else
		pinfo.op = I40E_DDP_REMOVE_TRACKID;

	memcpy(pinfo.name, profile_hdr->name, I40E_DDP_NAME_SIZE);

	/* Check if profile data already exists*/
	istatus = i40e_ddp_does_profile_exist(&pf->hw, &pinfo);
	if (istatus < 0) {
		netdev_err(netdev, "Failed to fetch loaded profiles.");
		return istatus;
	}
	if (is_add) {
		if (istatus > 0) {
			netdev_err(netdev, "DDP profile already loaded.");
			return -EINVAL;
		}
		istatus = i40e_ddp_does_profile_overlap(&pf->hw, &pinfo);
		if (istatus < 0) {
			netdev_err(netdev, "Failed to fetch loaded profiles.");
			return istatus;
		}
		if (istatus > 0) {
			netdev_err(netdev, "DDP profile overlaps with existing one.");
			return -EINVAL;
		}
	} else {
		if (istatus == 0) {
			netdev_err(netdev,
				   "DDP profile for deletion does not exist.");
			return -EINVAL;
		}
	}

	/* Load profile data */
	if (is_add) {
		status = i40e_write_profile(&pf->hw, profile_hdr, track_id);
		if (status) {
			if (status == I40E_ERR_DEVICE_NOT_SUPPORTED) {
				netdev_err(netdev,
					   "Profile is not supported by the device.");
				return -EPERM;
			}
			netdev_err(netdev, "Failed to write DDP profile.");
			return -EIO;
		}
	} else {
		status = i40e_rollback_profile(&pf->hw, profile_hdr, track_id);
		if (status) {
			netdev_err(netdev, "Failed to remove DDP profile.");
			return -EIO;
		}
	}

	/* Add/remove profile to/from profile list in FW */
	if (is_add) {
		status = i40e_add_pinfo(&pf->hw, profile_hdr, profile_info_sec,
					track_id);
		if (status) {
			netdev_err(netdev, "Failed to add DDP profile info.");
			return -EIO;
		}
	} else {
		status = i40e_del_pinfo(&pf->hw, profile_hdr, profile_info_sec,
					track_id);
		if (status) {
			netdev_err(netdev, "Failed to restore DDP profile info.");
			return -EIO;
		}
	}

	return 0;
}

/**
 * i40e_ddp_restore - restore previously loaded profile and remove from list
 * @pf: PF data struct
 *
 * Restores previously loaded profile stored on the list in driver memory.
 * After rolling back removes entry from the list.
 **/
static int i40e_ddp_restore(struct i40e_pf *pf)
{
	struct i40e_ddp_old_profile_list *entry;
	struct net_device *netdev = pf->vsi[pf->lan_vsi]->netdev;
	int status = 0;

	if (!list_empty(&pf->ddp_old_prof)) {
		entry = list_first_entry(&pf->ddp_old_prof,
					 struct i40e_ddp_old_profile_list,
					 list);
		status = i40e_ddp_load(netdev, entry->old_ddp_buf,
				       entry->old_ddp_size, false);
		list_del(&entry->list);
		kfree(entry);
	}
	return status;
}

/**
 * i40e_ddp_flash - callback function for ethtool flash feature
 * @netdev: net device structure
 * @flash: kernel flash structure
 *
 * Ethtool callback function used for loading and unloading DDP profiles.
 **/
int i40e_ddp_flash(struct net_device *netdev, struct ethtool_flash *flash)
{
	const struct firmware *ddp_config;
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	struct i40e_vsi *vsi = np->vsi;
	struct i40e_pf *pf = vsi->back;
	int status = 0;

	/* Check for valid region first */
	if (flash->region != I40_DDP_FLASH_REGION) {
		netdev_err(netdev, "Requested firmware region is not recognized by this driver.");
		return -EINVAL;
	}
	if (pf->hw.bus.func != 0) {
		netdev_err(netdev, "Any DDP operation is allowed only on Phy0 NIC interface");
		return -EINVAL;
	}

	/* If the user supplied "-" instead of file name rollback previously
	 * stored profile.
	 */
	if (strncmp(flash->data, "-", 2) != 0) {
		struct i40e_ddp_old_profile_list *list_entry;
		char profile_name[sizeof(I40E_DDP_PROFILE_PATH)
				  + I40E_DDP_PROFILE_NAME_MAX];

		profile_name[sizeof(profile_name) - 1] = 0;
		strncpy(profile_name, I40E_DDP_PROFILE_PATH,
			sizeof(profile_name) - 1);
		strncat(profile_name, flash->data, I40E_DDP_PROFILE_NAME_MAX);
		/* Load DDP recipe. */
		status = request_firmware(&ddp_config, profile_name,
					  &netdev->dev);
		if (status) {
			netdev_err(netdev, "DDP recipe file request failed.");
			return status;
		}

		status = i40e_ddp_load(netdev, ddp_config->data,
				       ddp_config->size, true);

		if (!status) {
			list_entry =
			  kzalloc(sizeof(struct i40e_ddp_old_profile_list) +
				  ddp_config->size, GFP_KERNEL);
			if (!list_entry) {
				netdev_info(netdev, "Failed to allocate memory for previous DDP profile data.");
				netdev_info(netdev, "New profile loaded but roll-back will be impossible.");
			} else {
				memcpy(list_entry->old_ddp_buf,
				       ddp_config->data, ddp_config->size);
				list_entry->old_ddp_size = ddp_config->size;
				list_add(&list_entry->list, &pf->ddp_old_prof);
			}
		}

		release_firmware(ddp_config);
	} else {
		if (!list_empty(&pf->ddp_old_prof)) {
			status = i40e_ddp_restore(pf);
		} else {
			netdev_warn(netdev, "There is no DDP profile to restore.");
			status = -ENOENT;
		}
	}
	return status;
}
