// 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];
	i40e_status 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];
	i40e_status 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 enum i40e_status_code
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;
	i40e_status status;
	u32 offset = 0, info = 0;

	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 enum i40e_status_code
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;
	i40e_status status;
	u32 offset = 0, info = 0;

	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;
	i40e_status status;
	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;

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