// SPDX-License-Identifier: GPL-2.0-only
/* Huawei HiNIC PCI Express Linux driver
 * Copyright(c) 2017 Huawei Technologies Co., Ltd
 */

#include <linux/pci.h>
#include <linux/if_vlan.h>
#include <linux/interrupt.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>

#include "hinic_hw_dev.h"
#include "hinic_dev.h"
#include "hinic_hw_mbox.h"
#include "hinic_hw_cmdq.h"
#include "hinic_port.h"
#include "hinic_sriov.h"

static unsigned char set_vf_link_state;
module_param(set_vf_link_state, byte, 0444);
MODULE_PARM_DESC(set_vf_link_state, "Set vf link state, 0 represents link auto, 1 represents link always up, 2 represents link always down. - default is 0.");

#define HINIC_VLAN_PRIORITY_SHIFT 13
#define HINIC_ADD_VLAN_IN_MAC 0x8000
#define HINIC_TX_RATE_TABLE_FULL 12

static int hinic_set_mac(struct hinic_hwdev *hwdev, const u8 *mac_addr,
			 u16 vlan_id, u16 func_id)
{
	struct hinic_port_mac_cmd mac_info = {0};
	u16 out_size = sizeof(mac_info);
	int err;

	mac_info.func_idx = func_id;
	mac_info.vlan_id = vlan_id;
	memcpy(mac_info.mac, mac_addr, ETH_ALEN);

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_MAC, &mac_info,
				 sizeof(mac_info), &mac_info, &out_size);
	if (err || out_size != sizeof(mac_info) ||
	    (mac_info.status && mac_info.status != HINIC_MGMT_STATUS_EXIST)) {
		dev_err(&hwdev->func_to_io.hwif->pdev->dev, "Failed to set MAC, err: %d, status: 0x%x, out size: 0x%x\n",
			err, mac_info.status, out_size);
		return -EIO;
	}

	return 0;
}

static void hinic_notify_vf_link_status(struct hinic_hwdev *hwdev, u16 vf_id,
					u8 link_status)
{
	struct vf_data_storage *vf_infos = hwdev->func_to_io.vf_infos;
	struct hinic_port_link_status link = {0};
	u16 out_size = sizeof(link);
	int err;

	if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
		link.link = link_status;
		link.func_id = hinic_glb_pf_vf_offset(hwdev->hwif) + vf_id;
		err = hinic_mbox_to_vf(hwdev, HINIC_MOD_L2NIC,
				       vf_id, HINIC_PORT_CMD_LINK_STATUS_REPORT,
				       &link, sizeof(link),
				       &link, &out_size, 0);
		if (err || !out_size || link.status)
			dev_err(&hwdev->hwif->pdev->dev,
				"Send link change event to VF %d failed, err: %d, status: 0x%x, out_size: 0x%x\n",
				HW_VF_ID_TO_OS(vf_id), err,
				link.status, out_size);
	}
}

/* send link change event mbox msg to active vfs under the pf */
void hinic_notify_all_vfs_link_changed(struct hinic_hwdev *hwdev,
				       u8 link_status)
{
	struct hinic_func_to_io *nic_io = &hwdev->func_to_io;
	u16 i;

	nic_io->link_status = link_status;
	for (i = 1; i <= nic_io->max_vfs; i++) {
		if (!nic_io->vf_infos[HW_VF_ID_TO_OS(i)].link_forced)
			hinic_notify_vf_link_status(hwdev, i,  link_status);
	}
}

static u16 hinic_vf_info_vlanprio(struct hinic_hwdev *hwdev, int vf_id)
{
	struct hinic_func_to_io *nic_io = &hwdev->func_to_io;
	u16 pf_vlan, vlanprio;
	u8 pf_qos;

	pf_vlan = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan;
	pf_qos = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos;
	vlanprio = pf_vlan | pf_qos << HINIC_VLAN_PRIORITY_SHIFT;

	return vlanprio;
}

static int hinic_set_vf_vlan(struct hinic_hwdev *hwdev, bool add, u16 vid,
			     u8 qos, int vf_id)
{
	struct hinic_vf_vlan_config vf_vlan = {0};
	u16 out_size = sizeof(vf_vlan);
	int err;
	u8 cmd;

	/* VLAN 0 is a special case, don't allow it to be removed */
	if (!vid && !add)
		return 0;

	vf_vlan.func_id = hinic_glb_pf_vf_offset(hwdev->hwif) + vf_id;
	vf_vlan.vlan_id = vid;
	vf_vlan.qos = qos;

	if (add)
		cmd = HINIC_PORT_CMD_SET_VF_VLAN;
	else
		cmd = HINIC_PORT_CMD_CLR_VF_VLAN;

	err = hinic_port_msg_cmd(hwdev, cmd, &vf_vlan,
				 sizeof(vf_vlan), &vf_vlan, &out_size);
	if (err || !out_size || vf_vlan.status) {
		dev_err(&hwdev->hwif->pdev->dev, "Failed to set VF %d vlan, err: %d, status: 0x%x, out size: 0x%x\n",
			HW_VF_ID_TO_OS(vf_id), err, vf_vlan.status, out_size);
		return -EFAULT;
	}

	return 0;
}

static int hinic_set_vf_tx_rate_max_min(struct hinic_hwdev *hwdev, u16 vf_id,
					u32 max_rate, u32 min_rate)
{
	struct hinic_func_to_io *nic_io = &hwdev->func_to_io;
	struct hinic_tx_rate_cfg_max_min rate_cfg = {0};
	u16 out_size = sizeof(rate_cfg);
	int err;

	rate_cfg.func_id = hinic_glb_pf_vf_offset(hwdev->hwif) + vf_id;
	rate_cfg.max_rate = max_rate;
	rate_cfg.min_rate = min_rate;
	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_VF_MAX_MIN_RATE,
				 &rate_cfg, sizeof(rate_cfg), &rate_cfg,
				 &out_size);
	if ((rate_cfg.status != HINIC_MGMT_CMD_UNSUPPORTED &&
	     rate_cfg.status) || err || !out_size) {
		dev_err(&hwdev->hwif->pdev->dev, "Failed to set VF(%d) max rate(%d), min rate(%d), err: %d, status: 0x%x, out size: 0x%x\n",
			HW_VF_ID_TO_OS(vf_id), max_rate, min_rate, err,
			rate_cfg.status, out_size);
		return -EIO;
	}

	if (!rate_cfg.status) {
		nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].max_rate = max_rate;
		nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].min_rate = min_rate;
	}

	return rate_cfg.status;
}

static int hinic_set_vf_rate_limit(struct hinic_hwdev *hwdev, u16 vf_id,
				   u32 tx_rate)
{
	struct hinic_func_to_io *nic_io = &hwdev->func_to_io;
	struct hinic_tx_rate_cfg rate_cfg = {0};
	u16 out_size = sizeof(rate_cfg);
	int err;

	rate_cfg.func_id = hinic_glb_pf_vf_offset(hwdev->hwif) + vf_id;
	rate_cfg.tx_rate = tx_rate;
	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_VF_RATE,
				 &rate_cfg, sizeof(rate_cfg), &rate_cfg,
				 &out_size);
	if (err || !out_size || rate_cfg.status) {
		dev_err(&hwdev->hwif->pdev->dev, "Failed to set VF(%d) rate(%d), err: %d, status: 0x%x, out size: 0x%x\n",
			HW_VF_ID_TO_OS(vf_id), tx_rate, err, rate_cfg.status,
			out_size);
		if (rate_cfg.status)
			return rate_cfg.status;

		return -EIO;
	}

	nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].max_rate = tx_rate;
	nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].min_rate = 0;

	return 0;
}

static int hinic_set_vf_tx_rate(struct hinic_hwdev *hwdev, u16 vf_id,
				u32 max_rate, u32 min_rate)
{
	int err;

	err = hinic_set_vf_tx_rate_max_min(hwdev, vf_id, max_rate, min_rate);
	if (err != HINIC_MGMT_CMD_UNSUPPORTED)
		return err;

	if (min_rate) {
		dev_err(&hwdev->hwif->pdev->dev, "Current firmware doesn't support to set min tx rate\n");
		return -EOPNOTSUPP;
	}

	dev_info(&hwdev->hwif->pdev->dev, "Current firmware doesn't support to set min tx rate, force min_tx_rate = max_tx_rate\n");

	return hinic_set_vf_rate_limit(hwdev, vf_id, max_rate);
}

static int hinic_init_vf_config(struct hinic_hwdev *hwdev, u16 vf_id)
{
	struct vf_data_storage *vf_info;
	u16 func_id, vlan_id;
	int err = 0;

	vf_info = hwdev->func_to_io.vf_infos + HW_VF_ID_TO_OS(vf_id);
	if (vf_info->pf_set_mac) {
		func_id = hinic_glb_pf_vf_offset(hwdev->hwif) + vf_id;

		vlan_id = 0;

		err = hinic_set_mac(hwdev, vf_info->vf_mac_addr, vlan_id,
				    func_id);
		if (err) {
			dev_err(&hwdev->func_to_io.hwif->pdev->dev, "Failed to set VF %d MAC\n",
				HW_VF_ID_TO_OS(vf_id));
			return err;
		}
	}

	if (hinic_vf_info_vlanprio(hwdev, vf_id)) {
		err = hinic_set_vf_vlan(hwdev, true, vf_info->pf_vlan,
					vf_info->pf_qos, vf_id);
		if (err) {
			dev_err(&hwdev->hwif->pdev->dev, "Failed to add VF %d VLAN_QOS\n",
				HW_VF_ID_TO_OS(vf_id));
			return err;
		}
	}

	if (vf_info->max_rate) {
		err = hinic_set_vf_tx_rate(hwdev, vf_id, vf_info->max_rate,
					   vf_info->min_rate);
		if (err) {
			dev_err(&hwdev->hwif->pdev->dev, "Failed to set VF %d max rate: %d, min rate: %d\n",
				HW_VF_ID_TO_OS(vf_id), vf_info->max_rate,
				vf_info->min_rate);
			return err;
		}
	}

	return 0;
}

static int hinic_register_vf_msg_handler(void *hwdev, u16 vf_id,
					 void *buf_in, u16 in_size,
					 void *buf_out, u16 *out_size)
{
	struct hinic_register_vf *register_info = buf_out;
	struct hinic_hwdev *hw_dev = hwdev;
	struct hinic_func_to_io *nic_io;
	int err;

	nic_io = &hw_dev->func_to_io;
	if (vf_id > nic_io->max_vfs) {
		dev_err(&hw_dev->hwif->pdev->dev, "Register VF id %d exceed limit[0-%d]\n",
			HW_VF_ID_TO_OS(vf_id), HW_VF_ID_TO_OS(nic_io->max_vfs));
		register_info->status = EFAULT;
		return -EFAULT;
	}

	*out_size = sizeof(*register_info);
	err = hinic_init_vf_config(hw_dev, vf_id);
	if (err) {
		register_info->status = EFAULT;
		return err;
	}

	nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = true;

	return 0;
}

static int hinic_unregister_vf_msg_handler(void *hwdev, u16 vf_id,
					   void *buf_in, u16 in_size,
					   void *buf_out, u16 *out_size)
{
	struct hinic_hwdev *hw_dev = hwdev;
	struct hinic_func_to_io *nic_io;

	nic_io = &hw_dev->func_to_io;
	*out_size = 0;
	if (vf_id > nic_io->max_vfs)
		return 0;

	nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = false;

	return 0;
}

static int hinic_change_vf_mtu_msg_handler(void *hwdev, u16 vf_id,
					   void *buf_in, u16 in_size,
					   void *buf_out, u16 *out_size)
{
	struct hinic_hwdev *hw_dev = hwdev;
	int err;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_CHANGE_MTU, buf_in,
				 in_size, buf_out, out_size);
	if (err) {
		dev_err(&hw_dev->hwif->pdev->dev, "Failed to set VF %u mtu\n",
			vf_id);
		return err;
	}

	return 0;
}

static int hinic_get_vf_mac_msg_handler(void *hwdev, u16 vf_id,
					void *buf_in, u16 in_size,
					void *buf_out, u16 *out_size)
{
	struct hinic_port_mac_cmd *mac_info = buf_out;
	struct hinic_hwdev *dev = hwdev;
	struct hinic_func_to_io *nic_io;
	struct vf_data_storage *vf_info;

	nic_io = &dev->func_to_io;
	vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);

	memcpy(mac_info->mac, vf_info->vf_mac_addr, ETH_ALEN);
	mac_info->status = 0;
	*out_size = sizeof(*mac_info);

	return 0;
}

static int hinic_set_vf_mac_msg_handler(void *hwdev, u16 vf_id,
					void *buf_in, u16 in_size,
					void *buf_out, u16 *out_size)
{
	struct hinic_port_mac_cmd *mac_out = buf_out;
	struct hinic_port_mac_cmd *mac_in = buf_in;
	struct hinic_hwdev *hw_dev = hwdev;
	struct hinic_func_to_io *nic_io;
	struct vf_data_storage *vf_info;
	int err;

	nic_io =  &hw_dev->func_to_io;
	vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
	if (vf_info->pf_set_mac && !(vf_info->trust) &&
	    is_valid_ether_addr(mac_in->mac)) {
		dev_warn(&hw_dev->hwif->pdev->dev, "PF has already set VF %d MAC address\n",
			 HW_VF_ID_TO_OS(vf_id));
		mac_out->status = HINIC_PF_SET_VF_ALREADY;
		*out_size = sizeof(*mac_out);
		return 0;
	}

	err = hinic_port_msg_cmd(hw_dev, HINIC_PORT_CMD_SET_MAC, buf_in,
				 in_size, buf_out, out_size);
	if ((err &&  err != HINIC_MBOX_PF_BUSY_ACTIVE_FW) || !(*out_size)) {
		dev_err(&hw_dev->hwif->pdev->dev,
			"Failed to set VF %d MAC address, err: %d, status: 0x%x, out size: 0x%x\n",
			HW_VF_ID_TO_OS(vf_id), err, mac_out->status, *out_size);
		return -EFAULT;
	}

	return err;
}

static int hinic_del_vf_mac_msg_handler(void *hwdev, u16 vf_id,
					void *buf_in, u16 in_size,
					void *buf_out, u16 *out_size)
{
	struct hinic_port_mac_cmd *mac_out = buf_out;
	struct hinic_port_mac_cmd *mac_in = buf_in;
	struct hinic_hwdev *hw_dev = hwdev;
	struct hinic_func_to_io *nic_io;
	struct vf_data_storage *vf_info;
	int err;

	nic_io = &hw_dev->func_to_io;
	vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
	if (vf_info->pf_set_mac && is_valid_ether_addr(mac_in->mac) &&
	    !memcmp(vf_info->vf_mac_addr, mac_in->mac, ETH_ALEN)) {
		dev_warn(&hw_dev->hwif->pdev->dev, "PF has already set VF mac.\n");
		mac_out->status = HINIC_PF_SET_VF_ALREADY;
		*out_size = sizeof(*mac_out);
		return 0;
	}

	err = hinic_port_msg_cmd(hw_dev, HINIC_PORT_CMD_DEL_MAC, buf_in,
				 in_size, buf_out, out_size);
	if ((err && err != HINIC_MBOX_PF_BUSY_ACTIVE_FW) || !(*out_size)) {
		dev_err(&hw_dev->hwif->pdev->dev, "Failed to delete VF %d MAC, err: %d, status: 0x%x, out size: 0x%x\n",
			HW_VF_ID_TO_OS(vf_id), err, mac_out->status, *out_size);
		return -EFAULT;
	}

	return err;
}

static int hinic_get_vf_link_status_msg_handler(void *hwdev, u16 vf_id,
						void *buf_in, u16 in_size,
						void *buf_out, u16 *out_size)
{
	struct hinic_port_link_cmd *get_link = buf_out;
	struct hinic_hwdev *hw_dev = hwdev;
	struct vf_data_storage *vf_infos;
	struct hinic_func_to_io *nic_io;
	bool link_forced, link_up;

	nic_io = &hw_dev->func_to_io;
	vf_infos = nic_io->vf_infos;
	link_forced = vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced;
	link_up = vf_infos[HW_VF_ID_TO_OS(vf_id)].link_up;

	if (link_forced)
		get_link->state = link_up ?
			HINIC_LINK_STATE_UP : HINIC_LINK_STATE_DOWN;
	else
		get_link->state = nic_io->link_status;

	get_link->status = 0;
	*out_size = sizeof(*get_link);

	return 0;
}

static bool check_func_table(struct hinic_hwdev *hwdev, u16 func_idx,
			     void *buf_in, u16 in_size)
{
	struct hinic_cmd_fw_ctxt *function_table = buf_in;

	if (!hinic_mbox_check_func_id_8B(hwdev, func_idx, buf_in, in_size) ||
	    !function_table->rx_buf_sz)
		return false;

	return true;
}

static struct vf_cmd_msg_handle nic_vf_cmd_msg_handler[] = {
	{HINIC_PORT_CMD_VF_REGISTER, hinic_register_vf_msg_handler},
	{HINIC_PORT_CMD_VF_UNREGISTER, hinic_unregister_vf_msg_handler},
	{HINIC_PORT_CMD_CHANGE_MTU, hinic_change_vf_mtu_msg_handler},
	{HINIC_PORT_CMD_GET_MAC, hinic_get_vf_mac_msg_handler},
	{HINIC_PORT_CMD_SET_MAC, hinic_set_vf_mac_msg_handler},
	{HINIC_PORT_CMD_DEL_MAC, hinic_del_vf_mac_msg_handler},
	{HINIC_PORT_CMD_GET_LINK_STATE, hinic_get_vf_link_status_msg_handler},
};

static struct vf_cmd_check_handle nic_cmd_support_vf[] = {
	{HINIC_PORT_CMD_VF_REGISTER, NULL},
	{HINIC_PORT_CMD_VF_UNREGISTER, NULL},
	{HINIC_PORT_CMD_CHANGE_MTU, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_ADD_VLAN, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_DEL_VLAN, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_SET_MAC, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_GET_MAC, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_DEL_MAC, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_SET_RX_MODE, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_GET_PAUSE_INFO, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_GET_LINK_STATE, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_SET_LRO, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_SET_RX_CSUM, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_GET_VPORT_STAT, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_CLEAN_VPORT_STAT, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL,
	 hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_SET_RSS_HASH_ENGINE, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_GET_RSS_HASH_ENGINE, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_GET_RSS_CTX_TBL, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_SET_RSS_CTX_TBL, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_RSS_TEMP_MGR, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_RSS_CFG, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_FWCTXT_INIT, check_func_table},
	{HINIC_PORT_CMD_GET_MGMT_VERSION, NULL},
	{HINIC_PORT_CMD_SET_FUNC_STATE, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_GET_GLOBAL_QPN, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_SET_TSO, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_SET_RQ_IQ_MAP, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_LINK_STATUS_REPORT, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_UPDATE_MAC, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_GET_CAP, hinic_mbox_check_func_id_8B},
	{HINIC_PORT_CMD_GET_LINK_MODE, hinic_mbox_check_func_id_8B},
};

#define CHECK_IPSU_15BIT	0X8000

static
struct hinic_sriov_info *hinic_get_sriov_info_by_pcidev(struct pci_dev *pdev)
{
	struct net_device *netdev = pci_get_drvdata(pdev);
	struct hinic_dev *nic_dev = netdev_priv(netdev);

	return &nic_dev->sriov_info;
}

static int hinic_check_mac_info(u8 status, u16 vlan_id)
{
	if ((status && status != HINIC_MGMT_STATUS_EXIST) ||
	    (vlan_id & CHECK_IPSU_15BIT &&
	     status == HINIC_MGMT_STATUS_EXIST))
		return -EINVAL;

	return 0;
}

#define HINIC_VLAN_ID_MASK	0x7FFF

static int hinic_update_mac(struct hinic_hwdev *hwdev, u8 *old_mac,
			    u8 *new_mac, u16 vlan_id, u16 func_id)
{
	struct hinic_port_mac_update mac_info = {0};
	u16 out_size = sizeof(mac_info);
	int err;

	if (!hwdev || !old_mac || !new_mac)
		return -EINVAL;

	if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
		dev_err(&hwdev->hwif->pdev->dev, "Invalid VLAN number: %d\n",
			(vlan_id & HINIC_VLAN_ID_MASK));
		return -EINVAL;
	}

	mac_info.func_id = func_id;
	mac_info.vlan_id = vlan_id;
	memcpy(mac_info.old_mac, old_mac, ETH_ALEN);
	memcpy(mac_info.new_mac, new_mac, ETH_ALEN);

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_UPDATE_MAC, &mac_info,
				 sizeof(mac_info), &mac_info, &out_size);

	if (err || !out_size ||
	    hinic_check_mac_info(mac_info.status, mac_info.vlan_id)) {
		dev_err(&hwdev->hwif->pdev->dev,
			"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x\n",
			err, mac_info.status, out_size);
		return -EINVAL;
	}

	if (mac_info.status == HINIC_MGMT_STATUS_EXIST)
		dev_warn(&hwdev->hwif->pdev->dev, "MAC is repeated. Ignore update operation\n");

	return 0;
}

static void hinic_get_vf_config(struct hinic_hwdev *hwdev, u16 vf_id,
				struct ifla_vf_info *ivi)
{
	struct vf_data_storage *vfinfo;

	vfinfo = hwdev->func_to_io.vf_infos + HW_VF_ID_TO_OS(vf_id);

	ivi->vf = HW_VF_ID_TO_OS(vf_id);
	memcpy(ivi->mac, vfinfo->vf_mac_addr, ETH_ALEN);
	ivi->vlan = vfinfo->pf_vlan;
	ivi->qos = vfinfo->pf_qos;
	ivi->spoofchk = vfinfo->spoofchk;
	ivi->trusted = vfinfo->trust;
	ivi->max_tx_rate = vfinfo->max_rate;
	ivi->min_tx_rate = vfinfo->min_rate;

	if (!vfinfo->link_forced)
		ivi->linkstate = IFLA_VF_LINK_STATE_AUTO;
	else if (vfinfo->link_up)
		ivi->linkstate = IFLA_VF_LINK_STATE_ENABLE;
	else
		ivi->linkstate = IFLA_VF_LINK_STATE_DISABLE;
}

int hinic_ndo_get_vf_config(struct net_device *netdev,
			    int vf, struct ifla_vf_info *ivi)
{
	struct hinic_dev *nic_dev = netdev_priv(netdev);
	struct hinic_sriov_info *sriov_info;

	sriov_info = &nic_dev->sriov_info;
	if (vf >= sriov_info->num_vfs)
		return -EINVAL;

	hinic_get_vf_config(sriov_info->hwdev, OS_VF_ID_TO_HW(vf), ivi);

	return 0;
}

static int hinic_set_vf_mac(struct hinic_hwdev *hwdev, int vf,
			    unsigned char *mac_addr)
{
	struct hinic_func_to_io *nic_io = &hwdev->func_to_io;
	struct vf_data_storage *vf_info;
	u16 func_id;
	int err;

	vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf);

	/* duplicate request, so just return success */
	if (vf_info->pf_set_mac &&
	    !memcmp(vf_info->vf_mac_addr, mac_addr, ETH_ALEN))
		return 0;

	vf_info->pf_set_mac = true;

	func_id = hinic_glb_pf_vf_offset(hwdev->hwif) + vf;
	err = hinic_update_mac(hwdev, vf_info->vf_mac_addr,
			       mac_addr, 0, func_id);
	if (err) {
		vf_info->pf_set_mac = false;
		return err;
	}

	memcpy(vf_info->vf_mac_addr, mac_addr, ETH_ALEN);

	return 0;
}

int hinic_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
{
	struct hinic_dev *nic_dev = netdev_priv(netdev);
	struct hinic_sriov_info *sriov_info;
	int err;

	sriov_info = &nic_dev->sriov_info;
	if (!is_valid_ether_addr(mac) || vf >= sriov_info->num_vfs)
		return -EINVAL;

	err = hinic_set_vf_mac(sriov_info->hwdev, OS_VF_ID_TO_HW(vf), mac);
	if (err)
		return err;

	netif_info(nic_dev, drv, netdev, "Setting MAC %pM on VF %d\n", mac, vf);
	netif_info(nic_dev, drv, netdev, "Reload the VF driver to make this change effective.");

	return 0;
}

static int hinic_add_vf_vlan(struct hinic_hwdev *hwdev, int vf_id,
			     u16 vlan, u8 qos)
{
	struct hinic_func_to_io *nic_io = &hwdev->func_to_io;
	int err;

	err = hinic_set_vf_vlan(hwdev, true, vlan, qos, vf_id);
	if (err)
		return err;

	nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan = vlan;
	nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos = qos;

	dev_info(&hwdev->hwif->pdev->dev, "Setting VLAN %d, QOS 0x%x on VF %d\n",
		 vlan, qos, HW_VF_ID_TO_OS(vf_id));
	return 0;
}

static int hinic_kill_vf_vlan(struct hinic_hwdev *hwdev, int vf_id)
{
	struct hinic_func_to_io *nic_io = &hwdev->func_to_io;
	int err;

	err = hinic_set_vf_vlan(hwdev, false,
				nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan,
				nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos,
				vf_id);
	if (err)
		return err;

	dev_info(&hwdev->hwif->pdev->dev, "Remove VLAN %d on VF %d\n",
		 nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan,
		 HW_VF_ID_TO_OS(vf_id));

	nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan = 0;
	nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos = 0;

	return 0;
}

static int hinic_update_mac_vlan(struct hinic_dev *nic_dev, u16 old_vlan,
				 u16 new_vlan, int vf_id)
{
	struct vf_data_storage *vf_info;
	u16 vlan_id;
	int err;

	if (!nic_dev || old_vlan >= VLAN_N_VID || new_vlan >= VLAN_N_VID)
		return -EINVAL;

	vf_info = nic_dev->hwdev->func_to_io.vf_infos + HW_VF_ID_TO_OS(vf_id);
	if (!vf_info->pf_set_mac)
		return 0;

	vlan_id = old_vlan;
	if (vlan_id)
		vlan_id |= HINIC_ADD_VLAN_IN_MAC;

	err = hinic_port_del_mac(nic_dev, vf_info->vf_mac_addr, vlan_id);
	if (err) {
		dev_err(&nic_dev->hwdev->hwif->pdev->dev, "Failed to delete VF %d MAC %pM vlan %d\n",
			HW_VF_ID_TO_OS(vf_id), vf_info->vf_mac_addr, old_vlan);
		return err;
	}

	vlan_id = new_vlan;
	if (vlan_id)
		vlan_id |= HINIC_ADD_VLAN_IN_MAC;

	err = hinic_port_add_mac(nic_dev, vf_info->vf_mac_addr, vlan_id);
	if (err) {
		dev_err(&nic_dev->hwdev->hwif->pdev->dev, "Failed to add VF %d MAC %pM vlan %d\n",
			HW_VF_ID_TO_OS(vf_id), vf_info->vf_mac_addr, new_vlan);
		goto out;
	}

	return 0;

out:
	vlan_id = old_vlan;
	if (vlan_id)
		vlan_id |= HINIC_ADD_VLAN_IN_MAC;
	hinic_port_add_mac(nic_dev, vf_info->vf_mac_addr, vlan_id);

	return err;
}

static int set_hw_vf_vlan(struct hinic_dev *nic_dev,
			  u16 cur_vlanprio, int vf, u16 vlan, u8 qos)
{
	u16 old_vlan = cur_vlanprio & VLAN_VID_MASK;
	int err = 0;

	if (vlan || qos) {
		if (cur_vlanprio) {
			err = hinic_kill_vf_vlan(nic_dev->hwdev,
						 OS_VF_ID_TO_HW(vf));
			if (err) {
				dev_err(&nic_dev->sriov_info.pdev->dev, "Failed to delete vf %d old vlan %d\n",
					vf, old_vlan);
				goto out;
			}
		}
		err = hinic_add_vf_vlan(nic_dev->hwdev,
					OS_VF_ID_TO_HW(vf), vlan, qos);
		if (err) {
			dev_err(&nic_dev->sriov_info.pdev->dev, "Failed to add vf %d new vlan %d\n",
				vf, vlan);
			goto out;
		}
	} else {
		err = hinic_kill_vf_vlan(nic_dev->hwdev, OS_VF_ID_TO_HW(vf));
		if (err) {
			dev_err(&nic_dev->sriov_info.pdev->dev, "Failed to delete vf %d vlan %d\n",
				vf, old_vlan);
			goto out;
		}
	}

	err = hinic_update_mac_vlan(nic_dev, old_vlan, vlan,
				    OS_VF_ID_TO_HW(vf));

out:
	return err;
}

int hinic_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos,
			  __be16 vlan_proto)
{
	struct hinic_dev *nic_dev = netdev_priv(netdev);
	struct hinic_sriov_info *sriov_info;
	u16 vlanprio, cur_vlanprio;

	sriov_info = &nic_dev->sriov_info;
	if (vf >= sriov_info->num_vfs || vlan > 4095 || qos > 7)
		return -EINVAL;
	if (vlan_proto != htons(ETH_P_8021Q))
		return -EPROTONOSUPPORT;
	vlanprio = vlan | qos << HINIC_VLAN_PRIORITY_SHIFT;
	cur_vlanprio = hinic_vf_info_vlanprio(nic_dev->hwdev,
					      OS_VF_ID_TO_HW(vf));
	/* duplicate request, so just return success */
	if (vlanprio == cur_vlanprio)
		return 0;

	return set_hw_vf_vlan(nic_dev, cur_vlanprio, vf, vlan, qos);
}

static int hinic_set_vf_trust(struct hinic_hwdev *hwdev, u16 vf_id,
			      bool trust)
{
	struct vf_data_storage *vf_infos;
	struct hinic_func_to_io *nic_io;

	if (!hwdev)
		return -EINVAL;

	nic_io = &hwdev->func_to_io;
	vf_infos = nic_io->vf_infos;
	vf_infos[vf_id].trust = trust;

	return 0;
}

int hinic_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting)
{
	struct hinic_dev *adapter = netdev_priv(netdev);
	struct hinic_sriov_info *sriov_info;
	struct hinic_func_to_io *nic_io;
	bool cur_trust;
	int err;

	sriov_info = &adapter->sriov_info;
	nic_io = &adapter->hwdev->func_to_io;

	if (vf >= sriov_info->num_vfs)
		return -EINVAL;

	cur_trust = nic_io->vf_infos[vf].trust;
	/* same request, so just return success */
	if ((setting && cur_trust) || (!setting && !cur_trust))
		return 0;

	err = hinic_set_vf_trust(adapter->hwdev, vf, setting);
	if (!err)
		dev_info(&sriov_info->pdev->dev, "Set VF %d trusted %s succeed\n",
			 vf, setting ? "on" : "off");
	else
		dev_err(&sriov_info->pdev->dev, "Failed set VF %d trusted %s\n",
			vf, setting ? "on" : "off");

	return err;
}

int hinic_ndo_set_vf_bw(struct net_device *netdev,
			int vf, int min_tx_rate, int max_tx_rate)
{
	u32 speeds[] = {SPEED_10, SPEED_100, SPEED_1000, SPEED_10000,
			SPEED_25000, SPEED_40000, SPEED_100000};
	struct hinic_dev *nic_dev = netdev_priv(netdev);
	struct hinic_port_cap port_cap = { 0 };
	enum hinic_port_link_state link_state;
	int err;

	if (vf >= nic_dev->sriov_info.num_vfs) {
		netif_err(nic_dev, drv, netdev, "VF number must be less than %d\n",
			  nic_dev->sriov_info.num_vfs);
		return -EINVAL;
	}

	if (max_tx_rate < min_tx_rate) {
		netif_err(nic_dev, drv, netdev, "Max rate %d must be greater than or equal to min rate %d\n",
			  max_tx_rate, min_tx_rate);
		return -EINVAL;
	}

	err = hinic_port_link_state(nic_dev, &link_state);
	if (err) {
		netif_err(nic_dev, drv, netdev,
			  "Get link status failed when setting vf tx rate\n");
		return -EIO;
	}

	if (link_state == HINIC_LINK_STATE_DOWN) {
		netif_err(nic_dev, drv, netdev,
			  "Link status must be up when setting vf tx rate\n");
		return -EPERM;
	}

	err = hinic_port_get_cap(nic_dev, &port_cap);
	if (err || port_cap.speed > LINK_SPEED_100GB)
		return -EIO;

	/* rate limit cannot be less than 0 and greater than link speed */
	if (max_tx_rate < 0 || max_tx_rate > speeds[port_cap.speed]) {
		netif_err(nic_dev, drv, netdev, "Max tx rate must be in [0 - %d]\n",
			  speeds[port_cap.speed]);
		return -EINVAL;
	}

	err = hinic_set_vf_tx_rate(nic_dev->hwdev, OS_VF_ID_TO_HW(vf),
				   max_tx_rate, min_tx_rate);
	if (err) {
		netif_err(nic_dev, drv, netdev,
			  "Unable to set VF %d max rate %d min rate %d%s\n",
			  vf, max_tx_rate, min_tx_rate,
			  err == HINIC_TX_RATE_TABLE_FULL ?
			  ", tx rate profile is full" : "");
		return -EIO;
	}

	netif_info(nic_dev, drv, netdev,
		   "Set VF %d max tx rate %d min tx rate %d successfully\n",
		   vf, max_tx_rate, min_tx_rate);

	return 0;
}

static int hinic_set_vf_spoofchk(struct hinic_hwdev *hwdev, u16 vf_id,
				 bool spoofchk)
{
	struct hinic_spoofchk_set spoofchk_cfg = {0};
	struct vf_data_storage *vf_infos = NULL;
	u16 out_size = sizeof(spoofchk_cfg);
	int err;

	if (!hwdev)
		return -EINVAL;

	vf_infos = hwdev->func_to_io.vf_infos;

	spoofchk_cfg.func_id = hinic_glb_pf_vf_offset(hwdev->hwif) + vf_id;
	spoofchk_cfg.state = spoofchk ? 1 : 0;
	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_ENABLE_SPOOFCHK,
				 &spoofchk_cfg, sizeof(spoofchk_cfg),
				 &spoofchk_cfg, &out_size);
	if (spoofchk_cfg.status == HINIC_MGMT_CMD_UNSUPPORTED) {
		err = HINIC_MGMT_CMD_UNSUPPORTED;
	} else if (err || !out_size || spoofchk_cfg.status) {
		dev_err(&hwdev->hwif->pdev->dev, "Failed to set VF(%d) spoofchk, err: %d, status: 0x%x, out size: 0x%x\n",
			HW_VF_ID_TO_OS(vf_id), err, spoofchk_cfg.status,
			out_size);
		err = -EIO;
	}

	vf_infos[HW_VF_ID_TO_OS(vf_id)].spoofchk = spoofchk;

	return err;
}

int hinic_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting)
{
	struct hinic_dev *nic_dev = netdev_priv(netdev);
	struct hinic_sriov_info *sriov_info;
	bool cur_spoofchk;
	int err;

	sriov_info = &nic_dev->sriov_info;
	if (vf >= sriov_info->num_vfs)
		return -EINVAL;

	cur_spoofchk = nic_dev->hwdev->func_to_io.vf_infos[vf].spoofchk;

	/* same request, so just return success */
	if ((setting && cur_spoofchk) || (!setting && !cur_spoofchk))
		return 0;

	err = hinic_set_vf_spoofchk(sriov_info->hwdev,
				    OS_VF_ID_TO_HW(vf), setting);
	if (!err) {
		netif_info(nic_dev, drv, netdev, "Set VF %d spoofchk %s successfully\n",
			   vf, setting ? "on" : "off");
	} else if (err == HINIC_MGMT_CMD_UNSUPPORTED) {
		netif_err(nic_dev, drv, netdev,
			  "Current firmware doesn't support to set vf spoofchk, need to upgrade latest firmware version\n");
		err = -EOPNOTSUPP;
	}

	return err;
}

static int hinic_set_vf_link_state(struct hinic_hwdev *hwdev, u16 vf_id,
				   int link)
{
	struct hinic_func_to_io *nic_io = &hwdev->func_to_io;
	struct vf_data_storage *vf_infos = nic_io->vf_infos;
	u8 link_status = 0;

	switch (link) {
	case HINIC_IFLA_VF_LINK_STATE_AUTO:
		vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = false;
		vf_infos[HW_VF_ID_TO_OS(vf_id)].link_up = nic_io->link_status ?
			true : false;
		link_status = nic_io->link_status;
		break;
	case HINIC_IFLA_VF_LINK_STATE_ENABLE:
		vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = true;
		vf_infos[HW_VF_ID_TO_OS(vf_id)].link_up = true;
		link_status = HINIC_LINK_UP;
		break;
	case HINIC_IFLA_VF_LINK_STATE_DISABLE:
		vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = true;
		vf_infos[HW_VF_ID_TO_OS(vf_id)].link_up = false;
		link_status = HINIC_LINK_DOWN;
		break;
	default:
		return -EINVAL;
	}

	/* Notify the VF of its new link state */
	hinic_notify_vf_link_status(hwdev, vf_id, link_status);

	return 0;
}

int hinic_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
{
	struct hinic_dev *nic_dev = netdev_priv(netdev);
	struct hinic_sriov_info *sriov_info;

	sriov_info = &nic_dev->sriov_info;

	if (vf_id >= sriov_info->num_vfs) {
		netif_err(nic_dev, drv, netdev,
			  "Invalid VF Identifier %d\n", vf_id);
		return -EINVAL;
	}

	return hinic_set_vf_link_state(sriov_info->hwdev,
				      OS_VF_ID_TO_HW(vf_id), link);
}

/* pf receive message from vf */
static int nic_pf_mbox_handler(void *hwdev, u16 vf_id, u8 cmd, void *buf_in,
			       u16 in_size, void *buf_out, u16 *out_size)
{
	u8 size = ARRAY_SIZE(nic_cmd_support_vf);
	struct vf_cmd_msg_handle *vf_msg_handle;
	struct hinic_hwdev *dev = hwdev;
	struct hinic_func_to_io *nic_io;
	struct hinic_pfhwdev *pfhwdev;
	int err = 0;
	u32 i;

	if (!hwdev)
		return -EINVAL;

	if (!hinic_mbox_check_cmd_valid(hwdev, nic_cmd_support_vf, vf_id, cmd,
					buf_in, in_size, size)) {
		dev_err(&dev->hwif->pdev->dev,
			"PF Receive VF nic cmd: 0x%x, mbox len: 0x%x is invalid\n",
			cmd, in_size);
		return HINIC_MBOX_VF_CMD_ERROR;
	}

	pfhwdev = container_of(dev, struct hinic_pfhwdev, hwdev);
	nic_io = &dev->func_to_io;
	for (i = 0; i < ARRAY_SIZE(nic_vf_cmd_msg_handler); i++) {
		vf_msg_handle = &nic_vf_cmd_msg_handler[i];
		if (cmd == vf_msg_handle->cmd &&
		    vf_msg_handle->cmd_msg_handler) {
			err = vf_msg_handle->cmd_msg_handler(hwdev, vf_id,
							     buf_in, in_size,
							     buf_out,
							     out_size);
			break;
		}
	}
	if (i == ARRAY_SIZE(nic_vf_cmd_msg_handler))
		err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC,
					cmd, buf_in, in_size, buf_out,
					out_size, HINIC_MGMT_MSG_SYNC);

	if (err &&  err != HINIC_MBOX_PF_BUSY_ACTIVE_FW)
		dev_err(&nic_io->hwif->pdev->dev, "PF receive VF L2NIC cmd: %d process error, err:%d\n",
			cmd, err);
	return err;
}

static int cfg_mbx_pf_proc_vf_msg(void *hwdev, u16 vf_id, u8 cmd, void *buf_in,
				  u16 in_size, void *buf_out, u16 *out_size)
{
	struct hinic_dev_cap *dev_cap = buf_out;
	struct hinic_hwdev *dev = hwdev;
	struct hinic_cap *cap;

	cap = &dev->nic_cap;
	memset(dev_cap, 0, sizeof(*dev_cap));

	dev_cap->max_vf = cap->max_vf;
	dev_cap->max_sqs = cap->max_vf_qps;
	dev_cap->max_rqs = cap->max_vf_qps;
	dev_cap->port_id = dev->port_id;

	*out_size = sizeof(*dev_cap);

	return 0;
}

static int hinic_init_vf_infos(struct hinic_func_to_io *nic_io, u16 vf_id)
{
	struct vf_data_storage *vf_infos = nic_io->vf_infos;

	if (set_vf_link_state > HINIC_IFLA_VF_LINK_STATE_DISABLE) {
		dev_warn(&nic_io->hwif->pdev->dev, "Module Parameter set_vf_link_state value %d is out of range, resetting to %d\n",
			 set_vf_link_state, HINIC_IFLA_VF_LINK_STATE_AUTO);
		set_vf_link_state = HINIC_IFLA_VF_LINK_STATE_AUTO;
	}

	switch (set_vf_link_state) {
	case HINIC_IFLA_VF_LINK_STATE_AUTO:
		vf_infos[vf_id].link_forced = false;
		break;
	case HINIC_IFLA_VF_LINK_STATE_ENABLE:
		vf_infos[vf_id].link_forced = true;
		vf_infos[vf_id].link_up = true;
		break;
	case HINIC_IFLA_VF_LINK_STATE_DISABLE:
		vf_infos[vf_id].link_forced = true;
		vf_infos[vf_id].link_up = false;
		break;
	default:
		dev_err(&nic_io->hwif->pdev->dev, "Invalid input parameter set_vf_link_state: %d\n",
			set_vf_link_state);
		return -EINVAL;
	}

	return 0;
}

static void hinic_clear_vf_infos(struct hinic_dev *nic_dev, u16 vf_id)
{
	struct vf_data_storage *vf_infos;

	vf_infos = nic_dev->hwdev->func_to_io.vf_infos + HW_VF_ID_TO_OS(vf_id);
	if (vf_infos->pf_set_mac)
		hinic_port_del_mac(nic_dev, vf_infos->vf_mac_addr, 0);

	if (hinic_vf_info_vlanprio(nic_dev->hwdev, vf_id))
		hinic_kill_vf_vlan(nic_dev->hwdev, vf_id);

	if (vf_infos->max_rate)
		hinic_set_vf_tx_rate(nic_dev->hwdev, vf_id, 0, 0);

	if (vf_infos->spoofchk)
		hinic_set_vf_spoofchk(nic_dev->hwdev, vf_id, false);

	if (vf_infos->trust)
		hinic_set_vf_trust(nic_dev->hwdev, vf_id, false);

	memset(vf_infos, 0, sizeof(*vf_infos));
	/* set vf_infos to default */
	hinic_init_vf_infos(&nic_dev->hwdev->func_to_io, HW_VF_ID_TO_OS(vf_id));
}

static int hinic_deinit_vf_hw(struct hinic_sriov_info *sriov_info,
			      u16 start_vf_id, u16 end_vf_id)
{
	struct hinic_dev *nic_dev;
	u16 func_idx, idx;

	nic_dev = container_of(sriov_info, struct hinic_dev, sriov_info);

	for (idx = start_vf_id; idx <= end_vf_id; idx++) {
		func_idx = hinic_glb_pf_vf_offset(nic_dev->hwdev->hwif) + idx;
		hinic_set_wq_page_size(nic_dev->hwdev, func_idx,
				       HINIC_HW_WQ_PAGE_SIZE);
		hinic_clear_vf_infos(nic_dev, idx);
	}

	return 0;
}

int hinic_vf_func_init(struct hinic_hwdev *hwdev)
{
	struct hinic_register_vf register_info = {0};
	u16 out_size = sizeof(register_info);
	struct hinic_func_to_io *nic_io;
	int err = 0;
	u32 size, i;

	err = hinic_vf_mbox_random_id_init(hwdev);
	if (err) {
		dev_err(&hwdev->hwif->pdev->dev, "Failed to init vf mbox random id, err: %d\n",
			err);
		return err;
	}

	nic_io = &hwdev->func_to_io;

	if (HINIC_IS_VF(hwdev->hwif)) {
		err = hinic_mbox_to_pf(hwdev, HINIC_MOD_L2NIC,
				       HINIC_PORT_CMD_VF_REGISTER,
				       &register_info, sizeof(register_info),
				       &register_info, &out_size, 0);
		if (err || register_info.status || !out_size) {
			dev_err(&hwdev->hwif->pdev->dev,
				"Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
				err, register_info.status, out_size);
			return -EIO;
		}
	} else {
		err = hinic_register_pf_mbox_cb(hwdev, HINIC_MOD_CFGM,
						cfg_mbx_pf_proc_vf_msg);
		if (err) {
			dev_err(&hwdev->hwif->pdev->dev,
				"Register PF mailbox callback failed\n");
			return err;
		}
		nic_io->max_vfs = hwdev->nic_cap.max_vf;
		size = sizeof(*nic_io->vf_infos) * nic_io->max_vfs;
		if (size != 0) {
			nic_io->vf_infos = kzalloc(size, GFP_KERNEL);
			if (!nic_io->vf_infos) {
				err = -ENOMEM;
				goto out_free_nic_io;
			}

			for (i = 0; i < nic_io->max_vfs; i++) {
				err = hinic_init_vf_infos(nic_io, i);
				if (err)
					goto err_init_vf_infos;
			}

			err = hinic_register_pf_mbox_cb(hwdev, HINIC_MOD_L2NIC,
							nic_pf_mbox_handler);
			if (err)
				goto err_register_pf_mbox_cb;
		}
	}

	return 0;

err_register_pf_mbox_cb:
err_init_vf_infos:
	kfree(nic_io->vf_infos);
out_free_nic_io:
	return err;
}

void hinic_vf_func_free(struct hinic_hwdev *hwdev)
{
	struct hinic_register_vf unregister = {0};
	u16 out_size = sizeof(unregister);
	int err;

	if (HINIC_IS_VF(hwdev->hwif)) {
		err = hinic_mbox_to_pf(hwdev, HINIC_MOD_L2NIC,
				       HINIC_PORT_CMD_VF_UNREGISTER,
				       &unregister, sizeof(unregister),
				       &unregister, &out_size, 0);
		if (err || !out_size || unregister.status)
			dev_err(&hwdev->hwif->pdev->dev, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
				err, unregister.status, out_size);
	} else {
		if (hwdev->func_to_io.vf_infos) {
			hinic_unregister_pf_mbox_cb(hwdev, HINIC_MOD_L2NIC);
			kfree(hwdev->func_to_io.vf_infos);
		}
	}
}

static int hinic_init_vf_hw(struct hinic_hwdev *hwdev, u16 start_vf_id,
			    u16 end_vf_id)
{
	u16 i, func_idx;
	int err;

	/* vf use 256K as default wq page size, and can't change it */
	for (i = start_vf_id; i <= end_vf_id; i++) {
		func_idx = hinic_glb_pf_vf_offset(hwdev->hwif) + i;
		err = hinic_set_wq_page_size(hwdev, func_idx,
					     HINIC_DEFAULT_WQ_PAGE_SIZE);
		if (err)
			return err;
	}

	return 0;
}

int hinic_pci_sriov_disable(struct pci_dev *pdev)
{
	struct hinic_sriov_info *sriov_info;
	u16 tmp_vfs;

	sriov_info = hinic_get_sriov_info_by_pcidev(pdev);
	/* if SR-IOV is already disabled then nothing will be done */
	if (!sriov_info->sriov_enabled)
		return 0;

	set_bit(HINIC_SRIOV_DISABLE, &sriov_info->state);

	/* If our VFs are assigned we cannot shut down SR-IOV
	 * without causing issues, so just leave the hardware
	 * available but disabled
	 */
	if (pci_vfs_assigned(sriov_info->pdev)) {
		clear_bit(HINIC_SRIOV_DISABLE, &sriov_info->state);
		dev_warn(&pdev->dev, "Unloading driver while VFs are assigned - VFs will not be deallocated\n");
		return -EPERM;
	}
	sriov_info->sriov_enabled = false;

	/* disable iov and allow time for transactions to clear */
	pci_disable_sriov(sriov_info->pdev);

	tmp_vfs = (u16)sriov_info->num_vfs;
	sriov_info->num_vfs = 0;
	hinic_deinit_vf_hw(sriov_info, OS_VF_ID_TO_HW(0),
			   OS_VF_ID_TO_HW(tmp_vfs - 1));

	clear_bit(HINIC_SRIOV_DISABLE, &sriov_info->state);

	return 0;
}

int hinic_pci_sriov_enable(struct pci_dev *pdev, int num_vfs)
{
	struct hinic_sriov_info *sriov_info;
	int err;

	sriov_info = hinic_get_sriov_info_by_pcidev(pdev);

	if (test_and_set_bit(HINIC_SRIOV_ENABLE, &sriov_info->state)) {
		dev_err(&pdev->dev,
			"SR-IOV enable in process, please wait, num_vfs %d\n",
			num_vfs);
		return -EPERM;
	}

	err = hinic_init_vf_hw(sriov_info->hwdev, OS_VF_ID_TO_HW(0),
			       OS_VF_ID_TO_HW((u16)num_vfs - 1));
	if (err) {
		dev_err(&sriov_info->pdev->dev,
			"Failed to init vf in hardware before enable sriov, error %d\n",
			err);
		clear_bit(HINIC_SRIOV_ENABLE, &sriov_info->state);
		return err;
	}

	err = pci_enable_sriov(sriov_info->pdev, num_vfs);
	if (err) {
		dev_err(&pdev->dev,
			"Failed to enable SR-IOV, error %d\n", err);
		clear_bit(HINIC_SRIOV_ENABLE, &sriov_info->state);
		return err;
	}

	sriov_info->sriov_enabled = true;
	sriov_info->num_vfs = num_vfs;
	clear_bit(HINIC_SRIOV_ENABLE, &sriov_info->state);

	return num_vfs;
}

int hinic_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
{
	struct hinic_sriov_info *sriov_info;

	sriov_info = hinic_get_sriov_info_by_pcidev(dev);

	if (test_bit(HINIC_FUNC_REMOVE, &sriov_info->state))
		return -EBUSY;

	if (!num_vfs)
		return hinic_pci_sriov_disable(dev);
	else
		return hinic_pci_sriov_enable(dev, num_vfs);
}
