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

#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
#include <linux/pci.h>
#include <linux/device.h>
#include <linux/errno.h>

#include "hinic_hw_if.h"
#include "hinic_hw_dev.h"
#include "hinic_port.h"
#include "hinic_dev.h"

enum mac_op {
	MAC_DEL,
	MAC_SET,
};

/**
 * change_mac - change(add or delete) mac address
 * @nic_dev: nic device
 * @addr: mac address
 * @vlan_id: vlan number to set with the mac
 * @op: add or delete the mac
 *
 * Return 0 - Success, negative - Failure
 **/
static int change_mac(struct hinic_dev *nic_dev, const u8 *addr,
		      u16 vlan_id, enum mac_op op)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_port_mac_cmd port_mac_cmd;
	struct hinic_hwif *hwif = hwdev->hwif;
	u16 out_size = sizeof(port_mac_cmd);
	struct pci_dev *pdev = hwif->pdev;
	enum hinic_port_cmd cmd;
	int err;

	if (op == MAC_SET)
		cmd = HINIC_PORT_CMD_SET_MAC;
	else
		cmd = HINIC_PORT_CMD_DEL_MAC;

	port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
	port_mac_cmd.vlan_id = vlan_id;
	memcpy(port_mac_cmd.mac, addr, ETH_ALEN);

	err = hinic_port_msg_cmd(hwdev, cmd, &port_mac_cmd,
				 sizeof(port_mac_cmd),
				 &port_mac_cmd, &out_size);
	if (err || out_size != sizeof(port_mac_cmd) ||
	    (port_mac_cmd.status &&
	     (port_mac_cmd.status != HINIC_PF_SET_VF_ALREADY || !HINIC_IS_VF(hwif)) &&
	     port_mac_cmd.status != HINIC_MGMT_STATUS_EXIST)) {
		dev_err(&pdev->dev, "Failed to change MAC, err: %d, status: 0x%x, out size: 0x%x\n",
			err, port_mac_cmd.status, out_size);
		return -EFAULT;
	}

	if (port_mac_cmd.status == HINIC_PF_SET_VF_ALREADY) {
		dev_warn(&pdev->dev, "PF has already set VF mac, ignore %s operation\n",
			 (op == MAC_SET) ? "set" : "del");
		return HINIC_PF_SET_VF_ALREADY;
	}

	if (cmd == HINIC_PORT_CMD_SET_MAC && port_mac_cmd.status ==
	    HINIC_MGMT_STATUS_EXIST)
		dev_warn(&pdev->dev, "MAC is repeated, ignore set operation\n");

	return 0;
}

/**
 * hinic_port_add_mac - add mac address
 * @nic_dev: nic device
 * @addr: mac address
 * @vlan_id: vlan number to set with the mac
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_port_add_mac(struct hinic_dev *nic_dev,
		       const u8 *addr, u16 vlan_id)
{
	return change_mac(nic_dev, addr, vlan_id, MAC_SET);
}

/**
 * hinic_port_del_mac - remove mac address
 * @nic_dev: nic device
 * @addr: mac address
 * @vlan_id: vlan number that is connected to the mac
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_port_del_mac(struct hinic_dev *nic_dev, const u8 *addr,
		       u16 vlan_id)
{
	return change_mac(nic_dev, addr, vlan_id, MAC_DEL);
}

/**
 * hinic_port_get_mac - get the mac address of the nic device
 * @nic_dev: nic device
 * @addr: returned mac address
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_port_get_mac(struct hinic_dev *nic_dev, u8 *addr)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_port_mac_cmd port_mac_cmd;
	struct hinic_hwif *hwif = hwdev->hwif;
	u16 out_size = sizeof(port_mac_cmd);
	struct pci_dev *pdev = hwif->pdev;
	int err;

	port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MAC,
				 &port_mac_cmd, sizeof(port_mac_cmd),
				 &port_mac_cmd, &out_size);
	if (err || out_size != sizeof(port_mac_cmd) || port_mac_cmd.status) {
		dev_err(&pdev->dev, "Failed to get mac, err: %d, status: 0x%x, out size: 0x%x\n",
			err, port_mac_cmd.status, out_size);
		return -EFAULT;
	}

	memcpy(addr, port_mac_cmd.mac, ETH_ALEN);
	return 0;
}

/**
 * hinic_port_set_mtu - set mtu
 * @nic_dev: nic device
 * @new_mtu: new mtu
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_port_set_mtu(struct hinic_dev *nic_dev, int new_mtu)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_port_mtu_cmd port_mtu_cmd;
	struct hinic_hwif *hwif = hwdev->hwif;
	u16 out_size = sizeof(port_mtu_cmd);
	struct pci_dev *pdev = hwif->pdev;
	int err;

	port_mtu_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
	port_mtu_cmd.mtu = new_mtu;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_CHANGE_MTU,
				 &port_mtu_cmd, sizeof(port_mtu_cmd),
				 &port_mtu_cmd, &out_size);
	if (err || out_size != sizeof(port_mtu_cmd) || port_mtu_cmd.status) {
		dev_err(&pdev->dev, "Failed to set mtu, err: %d, status: 0x%x, out size: 0x%x\n",
			err, port_mtu_cmd.status, out_size);
		return -EFAULT;
	}

	return 0;
}

/**
 * hinic_port_add_vlan - add vlan to the nic device
 * @nic_dev: nic device
 * @vlan_id: the vlan number to add
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_port_add_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_port_vlan_cmd port_vlan_cmd;

	port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
	port_vlan_cmd.vlan_id = vlan_id;

	return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_ADD_VLAN,
				  &port_vlan_cmd, sizeof(port_vlan_cmd),
				  NULL, NULL);
}

/**
 * hinic_port_del_vlan - delete vlan from the nic device
 * @nic_dev: nic device
 * @vlan_id: the vlan number to delete
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_port_del_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_port_vlan_cmd port_vlan_cmd;

	port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
	port_vlan_cmd.vlan_id = vlan_id;

	return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_DEL_VLAN,
				 &port_vlan_cmd, sizeof(port_vlan_cmd),
				 NULL, NULL);
}

/**
 * hinic_port_set_rx_mode - set rx mode in the nic device
 * @nic_dev: nic device
 * @rx_mode: the rx mode to set
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_port_set_rx_mode(struct hinic_dev *nic_dev, u32 rx_mode)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_port_rx_mode_cmd rx_mode_cmd;

	rx_mode_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
	rx_mode_cmd.rx_mode = rx_mode;

	return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_MODE,
				  &rx_mode_cmd, sizeof(rx_mode_cmd),
				  NULL, NULL);
}

/**
 * hinic_port_link_state - get the link state
 * @nic_dev: nic device
 * @link_state: the returned link state
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_port_link_state(struct hinic_dev *nic_dev,
			  enum hinic_port_link_state *link_state)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct hinic_port_link_cmd link_cmd;
	struct pci_dev *pdev = hwif->pdev;
	u16 out_size = sizeof(link_cmd);
	int err;

	link_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_STATE,
				 &link_cmd, sizeof(link_cmd),
				 &link_cmd, &out_size);
	if (err || out_size != sizeof(link_cmd) || link_cmd.status) {
		dev_err(&pdev->dev, "Failed to get link state, err: %d, status: 0x%x, out size: 0x%x\n",
			err, link_cmd.status, out_size);
		return -EINVAL;
	}

	*link_state = link_cmd.state;
	return 0;
}

/**
 * hinic_port_set_state - set port state
 * @nic_dev: nic device
 * @state: the state to set
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_port_set_state(struct hinic_dev *nic_dev, enum hinic_port_state state)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_port_state_cmd port_state;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	u16 out_size = sizeof(port_state);
	int err;

	if (HINIC_IS_VF(hwdev->hwif))
		return 0;

	port_state.state = state;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PORT_STATE,
				 &port_state, sizeof(port_state),
				 &port_state, &out_size);
	if (err || out_size != sizeof(port_state) || port_state.status) {
		dev_err(&pdev->dev, "Failed to set port state, err: %d, status: 0x%x, out size: 0x%x\n",
			err, port_state.status, out_size);
		return -EFAULT;
	}

	return 0;
}

/**
 * hinic_port_set_func_state- set func device state
 * @nic_dev: nic device
 * @state: the state to set
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_port_set_func_state(struct hinic_dev *nic_dev,
			      enum hinic_func_port_state state)
{
	struct hinic_port_func_state_cmd func_state;
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	u16 out_size = sizeof(func_state);
	int err;

	func_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
	func_state.state = state;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_FUNC_STATE,
				 &func_state, sizeof(func_state),
				 &func_state, &out_size);
	if (err || out_size != sizeof(func_state) || func_state.status) {
		dev_err(&pdev->dev, "Failed to set port func state, err: %d, status: 0x%x, out size: 0x%x\n",
			err, func_state.status, out_size);
		return -EFAULT;
	}

	return 0;
}

/**
 * hinic_port_get_cap - get port capabilities
 * @nic_dev: nic device
 * @port_cap: returned port capabilities
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_port_get_cap(struct hinic_dev *nic_dev,
		       struct hinic_port_cap *port_cap)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	u16 out_size = sizeof(*port_cap);
	int err;

	port_cap->func_idx = HINIC_HWIF_FUNC_IDX(hwif);

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_CAP,
				 port_cap, sizeof(*port_cap),
				 port_cap, &out_size);
	if (err || out_size != sizeof(*port_cap) || port_cap->status) {
		dev_err(&pdev->dev,
			"Failed to get port capabilities, err: %d, status: 0x%x, out size: 0x%x\n",
			err, port_cap->status, out_size);
		return -EIO;
	}

	return 0;
}

/**
 * hinic_port_set_tso - set port tso configuration
 * @nic_dev: nic device
 * @state: the tso state to set
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_port_set_tso(struct hinic_dev *nic_dev, enum hinic_tso_state state)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct hinic_tso_config tso_cfg = {0};
	struct pci_dev *pdev = hwif->pdev;
	u16 out_size = sizeof(tso_cfg);
	int err;

	tso_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	tso_cfg.tso_en = state;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_TSO,
				 &tso_cfg, sizeof(tso_cfg),
				 &tso_cfg, &out_size);
	if (err || out_size != sizeof(tso_cfg) || tso_cfg.status) {
		dev_err(&pdev->dev,
			"Failed to set port tso, err: %d, status: 0x%x, out size: 0x%x\n",
			err, tso_cfg.status, out_size);
		return -EIO;
	}

	return 0;
}

int hinic_set_rx_csum_offload(struct hinic_dev *nic_dev, u32 en)
{
	struct hinic_checksum_offload rx_csum_cfg = {0};
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	u16 out_size = sizeof(rx_csum_cfg);
	struct hinic_hwif *hwif;
	struct pci_dev *pdev;
	int err;

	if (!hwdev)
		return -EINVAL;

	hwif = hwdev->hwif;
	pdev = hwif->pdev;
	rx_csum_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	rx_csum_cfg.rx_csum_offload = en;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_CSUM,
				 &rx_csum_cfg, sizeof(rx_csum_cfg),
				 &rx_csum_cfg, &out_size);
	if (err || !out_size || rx_csum_cfg.status) {
		dev_err(&pdev->dev,
			"Failed to set rx csum offload, err: %d, status: 0x%x, out size: 0x%x\n",
			err, rx_csum_cfg.status, out_size);
		return -EIO;
	}

	return 0;
}

int hinic_set_rx_vlan_offload(struct hinic_dev *nic_dev, u8 en)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_vlan_cfg vlan_cfg;
	struct hinic_hwif *hwif;
	struct pci_dev *pdev;
	u16 out_size;
	int err;

	if (!hwdev)
		return -EINVAL;

	out_size = sizeof(vlan_cfg);
	hwif = hwdev->hwif;
	pdev = hwif->pdev;
	vlan_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	vlan_cfg.vlan_rx_offload = en;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD,
				 &vlan_cfg, sizeof(vlan_cfg),
				 &vlan_cfg, &out_size);
	if (err || !out_size || vlan_cfg.status) {
		dev_err(&pdev->dev,
			"Failed to set rx vlan offload, err: %d, status: 0x%x, out size: 0x%x\n",
			err, vlan_cfg.status, out_size);
		return -EINVAL;
	}

	return 0;
}

int hinic_set_vlan_fliter(struct hinic_dev *nic_dev, u32 en)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	struct hinic_vlan_filter vlan_filter;
	u16 out_size = sizeof(vlan_filter);
	int err;

	if (!hwdev)
		return -EINVAL;

	vlan_filter.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
	vlan_filter.enable = en;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_VLAN_FILTER,
				 &vlan_filter, sizeof(vlan_filter),
				 &vlan_filter, &out_size);
	if (vlan_filter.status == HINIC_MGMT_CMD_UNSUPPORTED) {
		err = HINIC_MGMT_CMD_UNSUPPORTED;
	} else if ((err == HINIC_MBOX_VF_CMD_ERROR) &&
			   HINIC_IS_VF(hwif)) {
		err = HINIC_MGMT_CMD_UNSUPPORTED;
	} else if (err || !out_size || vlan_filter.status) {
		dev_err(&pdev->dev,
			"Failed to set vlan fliter, err: %d, status: 0x%x, out size: 0x%x\n",
			err, vlan_filter.status, out_size);
		err = -EINVAL;
	}

	return err;
}

int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct hinic_rq_num rq_num = { 0 };
	struct pci_dev *pdev = hwif->pdev;
	u16 out_size = sizeof(rq_num);
	int err;

	rq_num.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	rq_num.num_rqs = num_rqs;
	rq_num.rq_depth = ilog2(nic_dev->rq_depth);

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RQ_IQ_MAP,
				 &rq_num, sizeof(rq_num),
				 &rq_num, &out_size);
	if (err || !out_size || rq_num.status) {
		dev_err(&pdev->dev,
			"Failed to set rxq number, err: %d, status: 0x%x, out size: 0x%x\n",
			err, rq_num.status, out_size);
		return -EIO;
	}

	return 0;
}

static int hinic_set_rx_lro(struct hinic_dev *nic_dev, u8 ipv4_en, u8 ipv6_en,
			    u8 max_wqe_num)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_lro_config lro_cfg = { 0 };
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	u16 out_size = sizeof(lro_cfg);
	int err;

	lro_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	lro_cfg.lro_ipv4_en = ipv4_en;
	lro_cfg.lro_ipv6_en = ipv6_en;
	lro_cfg.lro_max_wqe_num = max_wqe_num;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO,
				 &lro_cfg, sizeof(lro_cfg),
				 &lro_cfg, &out_size);
	if (err || !out_size || lro_cfg.status) {
		dev_err(&pdev->dev,
			"Failed to set lro offload, err: %d, status: 0x%x, out size: 0x%x\n",
			err, lro_cfg.status, out_size);
		return -EIO;
	}

	return 0;
}

static int hinic_set_rx_lro_timer(struct hinic_dev *nic_dev, u32 timer_value)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_lro_timer lro_timer = { 0 };
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	u16 out_size = sizeof(lro_timer);
	int err;

	lro_timer.status = 0;
	lro_timer.type = 0;
	lro_timer.enable = 1;
	lro_timer.timer = timer_value;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO_TIMER,
				 &lro_timer, sizeof(lro_timer),
				 &lro_timer, &out_size);
	if (lro_timer.status == 0xFF) {
		/* For this case, we think status (0xFF) is OK */
		lro_timer.status = 0;
		dev_dbg(&pdev->dev,
			"Set lro timer not supported by the current FW version, it will be 1ms default\n");
	}

	if (err || !out_size || lro_timer.status) {
		dev_err(&pdev->dev,
			"Failed to set lro timer, err: %d, status: 0x%x, out size: 0x%x\n",
			err, lro_timer.status, out_size);

		return -EIO;
	}

	return 0;
}

int hinic_set_rx_lro_state(struct hinic_dev *nic_dev, u8 lro_en,
			   u32 lro_timer, u32 wqe_num)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	u8 ipv4_en;
	u8 ipv6_en;
	int err;

	if (!hwdev)
		return -EINVAL;

	ipv4_en = lro_en ? 1 : 0;
	ipv6_en = lro_en ? 1 : 0;

	err = hinic_set_rx_lro(nic_dev, ipv4_en, ipv6_en, (u8)wqe_num);
	if (err)
		return err;

	if (HINIC_IS_VF(nic_dev->hwdev->hwif))
		return 0;

	err = hinic_set_rx_lro_timer(nic_dev, lro_timer);
	if (err)
		return err;

	return 0;
}

int hinic_rss_set_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
			    const u32 *indir_table)
{
	struct hinic_rss_indirect_tbl *indir_tbl;
	struct hinic_func_to_io *func_to_io;
	struct hinic_cmdq_buf cmd_buf;
	struct hinic_hwdev *hwdev;
	struct hinic_hwif *hwif;
	struct pci_dev *pdev;
	u32 indir_size;
	u64 out_param;
	int err, i;
	u32 *temp;

	hwdev = nic_dev->hwdev;
	func_to_io = &hwdev->func_to_io;
	hwif = hwdev->hwif;
	pdev = hwif->pdev;

	err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
	if (err) {
		dev_err(&pdev->dev, "Failed to allocate cmdq buf\n");
		return err;
	}

	cmd_buf.size = sizeof(*indir_tbl);

	indir_tbl = cmd_buf.buf;
	indir_tbl->group_index = cpu_to_be32(tmpl_idx);

	for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) {
		indir_tbl->entry[i] = indir_table[i];

		if (0x3 == (i & 0x3)) {
			temp = (u32 *)&indir_tbl->entry[i - 3];
			*temp = cpu_to_be32(*temp);
		}
	}

	/* cfg the rss indirect table by command queue */
	indir_size = HINIC_RSS_INDIR_SIZE / 2;
	indir_tbl->offset = 0;
	indir_tbl->size = cpu_to_be32(indir_size);

	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
				     HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
				     &cmd_buf, &out_param);
	if (err || out_param != 0) {
		dev_err(&pdev->dev, "Failed to set rss indir table\n");
		err = -EFAULT;
		goto free_buf;
	}

	indir_tbl->offset = cpu_to_be32(indir_size);
	indir_tbl->size = cpu_to_be32(indir_size);
	memcpy(&indir_tbl->entry[0], &indir_tbl->entry[indir_size], indir_size);

	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
				     HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
				     &cmd_buf, &out_param);
	if (err || out_param != 0) {
		dev_err(&pdev->dev, "Failed to set rss indir table\n");
		err = -EFAULT;
	}

free_buf:
	hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);

	return err;
}

int hinic_rss_get_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
			    u32 *indir_table)
{
	struct hinic_rss_indir_table rss_cfg = { 0 };
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	u16 out_size = sizeof(rss_cfg);
	int err = 0, i;

	rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	rss_cfg.template_id = tmpl_idx;

	err = hinic_port_msg_cmd(hwdev,
				 HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL,
				 &rss_cfg, sizeof(rss_cfg), &rss_cfg,
				 &out_size);
	if (err || !out_size || rss_cfg.status) {
		dev_err(&pdev->dev, "Failed to get indir table, err: %d, status: 0x%x, out size: 0x%x\n",
			err, rss_cfg.status, out_size);
		return -EINVAL;
	}

	hinic_be32_to_cpu(rss_cfg.indir, HINIC_RSS_INDIR_SIZE);
	for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++)
		indir_table[i] = rss_cfg.indir[i];

	return 0;
}

int hinic_set_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
		       struct hinic_rss_type rss_type)
{
	struct hinic_rss_context_tbl *ctx_tbl;
	struct hinic_func_to_io *func_to_io;
	struct hinic_cmdq_buf cmd_buf;
	struct hinic_hwdev *hwdev;
	struct hinic_hwif *hwif;
	struct pci_dev *pdev;
	u64 out_param;
	u32 ctx = 0;
	int err;

	hwdev = nic_dev->hwdev;
	func_to_io = &hwdev->func_to_io;
	hwif = hwdev->hwif;
	pdev = hwif->pdev;

	err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
	if (err) {
		dev_err(&pdev->dev, "Failed to allocate cmd buf\n");
		return -ENOMEM;
	}

	ctx |=  HINIC_RSS_TYPE_SET(1, VALID) |
		HINIC_RSS_TYPE_SET(rss_type.ipv4, IPV4) |
		HINIC_RSS_TYPE_SET(rss_type.ipv6, IPV6) |
		HINIC_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) |
		HINIC_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) |
		HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) |
		HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) |
		HINIC_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) |
		HINIC_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6);

	cmd_buf.size = sizeof(struct hinic_rss_context_tbl);

	ctx_tbl = (struct hinic_rss_context_tbl *)cmd_buf.buf;
	ctx_tbl->group_index = cpu_to_be32(tmpl_idx);
	ctx_tbl->offset = 0;
	ctx_tbl->size = sizeof(u32);
	ctx_tbl->size = cpu_to_be32(ctx_tbl->size);
	ctx_tbl->rsvd = 0;
	ctx_tbl->ctx = cpu_to_be32(ctx);

	/* cfg the rss context table by command queue */
	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
				     HINIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
				     &cmd_buf, &out_param);

	hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);

	if (err || out_param != 0) {
		dev_err(&pdev->dev, "Failed to set rss context table, err: %d\n",
			err);
		return -EFAULT;
	}

	return 0;
}

int hinic_get_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
		       struct hinic_rss_type *rss_type)
{
	struct hinic_rss_context_table ctx_tbl = { 0 };
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	u16 out_size = sizeof(ctx_tbl);
	struct hinic_hwif *hwif;
	struct pci_dev *pdev;
	int err;

	if (!hwdev || !rss_type)
		return -EINVAL;

	hwif = hwdev->hwif;
	pdev = hwif->pdev;

	ctx_tbl.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	ctx_tbl.template_id = tmpl_idx;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_CTX_TBL,
				 &ctx_tbl, sizeof(ctx_tbl),
				 &ctx_tbl, &out_size);
	if (err || !out_size || ctx_tbl.status) {
		dev_err(&pdev->dev, "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x\n",
			err, ctx_tbl.status, out_size);
		return -EINVAL;
	}

	rss_type->ipv4          = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV4);
	rss_type->ipv6          = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6);
	rss_type->ipv6_ext      = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT);
	rss_type->tcp_ipv4      = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4);
	rss_type->tcp_ipv6      = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6);
	rss_type->tcp_ipv6_ext  = HINIC_RSS_TYPE_GET(ctx_tbl.context,
						     TCP_IPV6_EXT);
	rss_type->udp_ipv4      = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4);
	rss_type->udp_ipv6      = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6);

	return 0;
}

int hinic_rss_set_template_tbl(struct hinic_dev *nic_dev, u32 template_id,
			       const u8 *temp)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct hinic_rss_key rss_key = { 0 };
	struct pci_dev *pdev = hwif->pdev;
	u16 out_size = sizeof(rss_key);
	int err;

	rss_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	rss_key.template_id = template_id;
	memcpy(rss_key.key, temp, HINIC_RSS_KEY_SIZE);

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL,
				 &rss_key, sizeof(rss_key),
				 &rss_key, &out_size);
	if (err || !out_size || rss_key.status) {
		dev_err(&pdev->dev,
			"Failed to set rss hash key, err: %d, status: 0x%x, out size: 0x%x\n",
			err, rss_key.status, out_size);
		return -EINVAL;
	}

	return 0;
}

int hinic_rss_get_template_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
			       u8 *temp)
{
	struct hinic_rss_template_key temp_key = { 0 };
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	u16 out_size = sizeof(temp_key);
	struct hinic_hwif *hwif;
	struct pci_dev *pdev;
	int err;

	if (!hwdev || !temp)
		return -EINVAL;

	hwif = hwdev->hwif;
	pdev = hwif->pdev;

	temp_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	temp_key.template_id = tmpl_idx;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL,
				 &temp_key, sizeof(temp_key),
				 &temp_key, &out_size);
	if (err || !out_size || temp_key.status) {
		dev_err(&pdev->dev, "Failed to set hash key, err: %d, status: 0x%x, out size: 0x%x\n",
			err, temp_key.status, out_size);
		return -EINVAL;
	}

	memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE);

	return 0;
}

int hinic_rss_set_hash_engine(struct hinic_dev *nic_dev, u8 template_id,
			      u8 type)
{
	struct hinic_rss_engine_type rss_engine = { 0 };
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	u16 out_size = sizeof(rss_engine);
	int err;

	rss_engine.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	rss_engine.hash_engine = type;
	rss_engine.template_id = template_id;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_HASH_ENGINE,
				 &rss_engine, sizeof(rss_engine),
				 &rss_engine, &out_size);
	if (err || !out_size || rss_engine.status) {
		dev_err(&pdev->dev,
			"Failed to set hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
			err, rss_engine.status, out_size);
		return -EINVAL;
	}

	return 0;
}

int hinic_rss_get_hash_engine(struct hinic_dev *nic_dev, u8 tmpl_idx, u8 *type)
{
	struct hinic_rss_engine_type hash_type = { 0 };
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	u16 out_size = sizeof(hash_type);
	struct hinic_hwif *hwif;
	struct pci_dev *pdev;
	int err;

	if (!hwdev || !type)
		return -EINVAL;

	hwif = hwdev->hwif;
	pdev = hwif->pdev;

	hash_type.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	hash_type.template_id = tmpl_idx;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_HASH_ENGINE,
				 &hash_type, sizeof(hash_type),
				 &hash_type, &out_size);
	if (err || !out_size || hash_type.status) {
		dev_err(&pdev->dev, "Failed to get hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
			err, hash_type.status, out_size);
		return -EINVAL;
	}

	*type = hash_type.hash_engine;
	return 0;
}

int hinic_rss_cfg(struct hinic_dev *nic_dev, u8 rss_en, u8 template_id)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_rss_config rss_cfg = { 0 };
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	u16 out_size = sizeof(rss_cfg);
	int err;

	rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	rss_cfg.rss_en = rss_en;
	rss_cfg.template_id = template_id;
	rss_cfg.rq_priority_number = 0;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_CFG,
				 &rss_cfg, sizeof(rss_cfg),
				 &rss_cfg, &out_size);
	if (err || !out_size || rss_cfg.status) {
		dev_err(&pdev->dev,
			"Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x\n",
			err, rss_cfg.status, out_size);
		return -EINVAL;
	}

	return 0;
}

int hinic_rss_template_alloc(struct hinic_dev *nic_dev, u8 *tmpl_idx)
{
	struct hinic_rss_template_mgmt template_mgmt = { 0 };
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	u16 out_size = sizeof(template_mgmt);
	struct pci_dev *pdev = hwif->pdev;
	int err;

	template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
				 &template_mgmt, sizeof(template_mgmt),
				 &template_mgmt, &out_size);
	if (err || !out_size || template_mgmt.status) {
		dev_err(&pdev->dev, "Failed to alloc rss template, err: %d, status: 0x%x, out size: 0x%x\n",
			err, template_mgmt.status, out_size);
		return -EINVAL;
	}

	*tmpl_idx = template_mgmt.template_id;

	return 0;
}

int hinic_rss_template_free(struct hinic_dev *nic_dev, u8 tmpl_idx)
{
	struct hinic_rss_template_mgmt template_mgmt = { 0 };
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	u16 out_size = sizeof(template_mgmt);
	struct pci_dev *pdev = hwif->pdev;
	int err;

	template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	template_mgmt.template_id = tmpl_idx;
	template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
				 &template_mgmt, sizeof(template_mgmt),
				 &template_mgmt, &out_size);
	if (err || !out_size || template_mgmt.status) {
		dev_err(&pdev->dev, "Failed to free rss template, err: %d, status: 0x%x, out size: 0x%x\n",
			err, template_mgmt.status, out_size);
		return -EINVAL;
	}

	return 0;
}

int hinic_get_vport_stats(struct hinic_dev *nic_dev,
			  struct hinic_vport_stats *stats)
{
	struct hinic_cmd_vport_stats vport_stats = { 0 };
	struct hinic_port_stats_info stats_info = { 0 };
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	u16 out_size = sizeof(vport_stats);
	struct pci_dev *pdev = hwif->pdev;
	int err;

	stats_info.stats_version = HINIC_PORT_STATS_VERSION;
	stats_info.func_id = HINIC_HWIF_FUNC_IDX(hwif);
	stats_info.stats_size = sizeof(vport_stats);

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_VPORT_STAT,
				 &stats_info, sizeof(stats_info),
				 &vport_stats, &out_size);
	if (err || !out_size || vport_stats.status) {
		dev_err(&pdev->dev,
			"Failed to get function statistics, err: %d, status: 0x%x, out size: 0x%x\n",
			err, vport_stats.status, out_size);
		return -EFAULT;
	}

	memcpy(stats, &vport_stats.stats, sizeof(*stats));
	return 0;
}

int hinic_get_phy_port_stats(struct hinic_dev *nic_dev,
			     struct hinic_phy_port_stats *stats)
{
	struct hinic_port_stats_info stats_info = { 0 };
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct hinic_port_stats *port_stats;
	u16 out_size = sizeof(*port_stats);
	struct pci_dev *pdev = hwif->pdev;
	int err;

	port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
	if (!port_stats)
		return -ENOMEM;

	stats_info.stats_version = HINIC_PORT_STATS_VERSION;
	stats_info.stats_size = sizeof(*port_stats);

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PORT_STATISTICS,
				 &stats_info, sizeof(stats_info),
				 port_stats, &out_size);
	if (err || !out_size || port_stats->status) {
		dev_err(&pdev->dev,
			"Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
			err, port_stats->status, out_size);
		err = -EINVAL;
		goto out;
	}

	memcpy(stats, &port_stats->stats, sizeof(*stats));

out:
	kfree(port_stats);

	return err;
}

int hinic_get_mgmt_version(struct hinic_dev *nic_dev, u8 *mgmt_ver)
{
	struct hinic_hwdev *hwdev = nic_dev->hwdev;
	struct hinic_version_info up_ver = {0};
	u16 out_size = sizeof(up_ver);
	struct hinic_hwif *hwif;
	struct pci_dev *pdev;
	int err;

	if (!hwdev)
		return -EINVAL;

	hwif = hwdev->hwif;
	pdev = hwif->pdev;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MGMT_VERSION,
				 &up_ver, sizeof(up_ver), &up_ver,
				 &out_size);
	if (err || !out_size || up_ver.status) {
		dev_err(&pdev->dev,
			"Failed to get mgmt version, err: %d, status: 0x%x, out size: 0x%x\n",
			err, up_ver.status, out_size);
		return -EINVAL;
	}

	snprintf(mgmt_ver, HINIC_MGMT_VERSION_MAX_LEN, "%s", up_ver.ver);

	return 0;
}

int hinic_get_link_mode(struct hinic_hwdev *hwdev,
			struct hinic_link_mode_cmd *link_mode)
{
	u16 out_size;
	int err;

	if (!hwdev || !link_mode)
		return -EINVAL;

	link_mode->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
	out_size = sizeof(*link_mode);

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_MODE,
				 link_mode, sizeof(*link_mode),
				 link_mode, &out_size);
	if (err || !out_size || link_mode->status) {
		dev_err(&hwdev->hwif->pdev->dev,
			"Failed to get link mode, err: %d, status: 0x%x, out size: 0x%x\n",
			err, link_mode->status, out_size);
		return -EIO;
	}

	return 0;
}

int hinic_set_autoneg(struct hinic_hwdev *hwdev, bool enable)
{
	struct hinic_set_autoneg_cmd autoneg = {0};
	u16 out_size = sizeof(autoneg);
	int err;

	if (!hwdev)
		return -EINVAL;

	autoneg.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
	autoneg.enable = enable;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_AUTONEG,
				 &autoneg, sizeof(autoneg),
				 &autoneg, &out_size);
	if (err || !out_size || autoneg.status) {
		dev_err(&hwdev->hwif->pdev->dev, "Failed to %s autoneg, err: %d, status: 0x%x, out size: 0x%x\n",
			enable ? "enable" : "disable", err, autoneg.status,
			out_size);
		return -EIO;
	}

	return 0;
}

int hinic_set_speed(struct hinic_hwdev *hwdev, enum nic_speed_level speed)
{
	struct hinic_speed_cmd speed_info = {0};
	u16 out_size = sizeof(speed_info);
	int err;

	if (!hwdev)
		return -EINVAL;

	speed_info.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
	speed_info.speed = speed;

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

	return 0;
}

int hinic_set_link_settings(struct hinic_hwdev *hwdev,
			    struct hinic_link_ksettings_info *info)
{
	u16 out_size = sizeof(*info);
	int err;

	err = hinic_hilink_msg_cmd(hwdev, HINIC_HILINK_CMD_SET_LINK_SETTINGS,
				   info, sizeof(*info), info, &out_size);
	if ((info->status != HINIC_MGMT_CMD_UNSUPPORTED &&
	     info->status) || err || !out_size) {
		dev_err(&hwdev->hwif->pdev->dev,
			"Failed to set link settings, err: %d, status: 0x%x, out size: 0x%x\n",
			err, info->status, out_size);
		return -EFAULT;
	}

	return info->status;
}

int hinic_get_hw_pause_info(struct hinic_hwdev *hwdev,
			    struct hinic_pause_config *pause_info)
{
	u16 out_size = sizeof(*pause_info);
	int err;

	pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PAUSE_INFO,
				 pause_info, sizeof(*pause_info),
				 pause_info, &out_size);
	if (err || !out_size || pause_info->status) {
		dev_err(&hwdev->hwif->pdev->dev, "Failed to get pause info, err: %d, status: 0x%x, out size: 0x%x\n",
			err, pause_info->status, out_size);
		return -EIO;
	}

	return 0;
}

int hinic_set_hw_pause_info(struct hinic_hwdev *hwdev,
			    struct hinic_pause_config *pause_info)
{
	u16 out_size = sizeof(*pause_info);
	int err;

	pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PAUSE_INFO,
				 pause_info, sizeof(*pause_info),
				 pause_info, &out_size);
	if (err || !out_size || pause_info->status) {
		dev_err(&hwdev->hwif->pdev->dev, "Failed to set pause info, err: %d, status: 0x%x, out size: 0x%x\n",
			err, pause_info->status, out_size);
		return -EIO;
	}

	return 0;
}

int hinic_dcb_set_pfc(struct hinic_hwdev *hwdev, u8 pfc_en, u8 pfc_bitmap)
{
	struct hinic_nic_cfg *nic_cfg = &hwdev->func_to_io.nic_cfg;
	struct hinic_set_pfc pfc = {0};
	u16 out_size = sizeof(pfc);
	int err;

	if (HINIC_IS_VF(hwdev->hwif))
		return 0;

	mutex_lock(&nic_cfg->cfg_mutex);

	pfc.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
	pfc.pfc_bitmap = pfc_bitmap;
	pfc.pfc_en = pfc_en;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PFC,
				 &pfc, sizeof(pfc), &pfc, &out_size);
	if (err || pfc.status || !out_size) {
		dev_err(&hwdev->hwif->pdev->dev, "Failed to %s pfc, err: %d, status: 0x%x, out size: 0x%x\n",
			pfc_en ? "enable" : "disable", err, pfc.status,
			out_size);
		mutex_unlock(&nic_cfg->cfg_mutex);
		return -EIO;
	}

	/* pause settings is opposite from pfc */
	nic_cfg->rx_pause = pfc_en ? 0 : 1;
	nic_cfg->tx_pause = pfc_en ? 0 : 1;

	mutex_unlock(&nic_cfg->cfg_mutex);

	return 0;
}

int hinic_set_loopback_mode(struct hinic_hwdev *hwdev, u32 mode, u32 enable)
{
	struct hinic_port_loopback lb = {0};
	u16 out_size = sizeof(lb);
	int err;

	lb.mode = mode;
	lb.en = enable;

	if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
		dev_err(&hwdev->hwif->pdev->dev,
			"Invalid loopback mode %d to set\n", mode);
		return -EINVAL;
	}

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LOOPBACK_MODE,
				 &lb, sizeof(lb), &lb, &out_size);
	if (err || !out_size || lb.status) {
		dev_err(&hwdev->hwif->pdev->dev,
			"Failed to set loopback mode %d en %d, err: %d, status: 0x%x, out size: 0x%x\n",
			mode, enable, err, lb.status, out_size);
		return -EIO;
	}

	return 0;
}

static int _set_led_status(struct hinic_hwdev *hwdev, u8 port,
			   enum hinic_led_type type,
			   enum hinic_led_mode mode, u8 reset)
{
	struct hinic_led_info led_info = {0};
	u16 out_size = sizeof(led_info);
	struct hinic_pfhwdev *pfhwdev;
	int err;

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	led_info.port = port;
	led_info.reset = reset;

	led_info.type = type;
	led_info.mode = mode;

	err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
				HINIC_COMM_CMD_SET_LED_STATUS,
				&led_info, sizeof(led_info),
				&led_info, &out_size, HINIC_MGMT_MSG_SYNC);
	if (err || led_info.status || !out_size) {
		dev_err(&hwdev->hwif->pdev->dev, "Failed to set led status, err: %d, status: 0x%x, out size: 0x%x\n",
			err, led_info.status, out_size);
		return -EIO;
	}

	return 0;
}

int hinic_set_led_status(struct hinic_hwdev *hwdev, u8 port,
			 enum hinic_led_type type, enum hinic_led_mode mode)
{
	if (!hwdev)
		return -EINVAL;

	return _set_led_status(hwdev, port, type, mode, 0);
}

int hinic_reset_led_status(struct hinic_hwdev *hwdev, u8 port)
{
	int err;

	if (!hwdev)
		return -EINVAL;

	err = _set_led_status(hwdev, port, HINIC_LED_TYPE_INVALID,
			      HINIC_LED_MODE_INVALID, 1);
	if (err)
		dev_err(&hwdev->hwif->pdev->dev,
			"Failed to reset led status\n");

	return err;
}

static bool hinic_if_sfp_absent(struct hinic_hwdev *hwdev)
{
	struct hinic_cmd_get_light_module_abs sfp_abs = {0};
	u16 out_size = sizeof(sfp_abs);
	u8 port_id = hwdev->port_id;
	int err;

	sfp_abs.port_id = port_id;
	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_SFP_ABS,
				 &sfp_abs, sizeof(sfp_abs), &sfp_abs,
				 &out_size);
	if (sfp_abs.status || err || !out_size) {
		dev_err(&hwdev->hwif->pdev->dev,
			"Failed to get port%d sfp absent status, err: %d, status: 0x%x, out size: 0x%x\n",
			port_id, err, sfp_abs.status, out_size);
		return true;
	}

	return ((sfp_abs.abs_status == 0) ? false : true);
}

int hinic_get_sfp_eeprom(struct hinic_hwdev *hwdev, u8 *data, u16 *len)
{
	struct hinic_cmd_get_std_sfp_info sfp_info = {0};
	u16 out_size = sizeof(sfp_info);
	u8 port_id;
	int err;

	if (!hwdev || !data || !len)
		return -EINVAL;

	port_id = hwdev->port_id;

	if (hinic_if_sfp_absent(hwdev))
		return -ENXIO;

	sfp_info.port_id = port_id;
	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_STD_SFP_INFO,
				 &sfp_info, sizeof(sfp_info), &sfp_info,
				 &out_size);
	if (sfp_info.status || err || !out_size) {
		dev_err(&hwdev->hwif->pdev->dev,
			"Failed to get port%d sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
			port_id, err, sfp_info.status, out_size);
		return -EIO;
	}

	*len = min_t(u16, sfp_info.eeprom_len, STD_SFP_INFO_MAX_SIZE);
	memcpy(data, sfp_info.sfp_info, STD_SFP_INFO_MAX_SIZE);

	return 0;
}

int hinic_get_sfp_type(struct hinic_hwdev *hwdev, u8 *data0, u8 *data1)
{
	u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
	u16 len;
	int err;

	if (hinic_if_sfp_absent(hwdev))
		return -ENXIO;

	err = hinic_get_sfp_eeprom(hwdev, sfp_data, &len);
	if (err)
		return err;

	*data0 = sfp_data[0];
	*data1 = sfp_data[1];

	return 0;
}
